From feb6422bea97d7ccbc0062c2ee6175b13f5e6b40 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 29 Dec 2021 18:18:25 +0100 Subject: [PATCH] wanpipe-3.3.2.tgz --- ChangeLog.beta | 208 + ChangeLog.stable | 404 - Makefile | 100 +- README-2.config | 41 +- README.changes | 88 +- Setup | 711 +- api/aft/Makefile | 14 +- api/aft/aft_api | Bin 20351 -> 0 bytes api/aft/aft_api.c | 10 +- api/aft/aft_api_events | Bin 42961 -> 0 bytes api/aft/aft_api_events.c | 8 +- api/aft/aft_api_repeater.c | 596 + api/aft/aft_echo | Bin 17274 -> 0 bytes api/aft/aft_echo.c | 316 - api/aft/aft_integrity | Bin 18322 -> 0 bytes api/chdlc/Makefile | 8 +- api/chdlc/chdlc_modem_cmd | Bin 0 -> 17232 bytes .../chdlc_modem_cmd.c} | 346 +- api/fr/Makefile | 10 +- api/lib/lib_api.c | 4 +- api/lib/lib_api.h | 16 +- .../.deps/libsangoma_la-libsangoma.Plo | 17 +- .../.deps/libsangoma_la-sangoma_pri.Plo | 337 +- api/libsangoma/.svn/all-wcprops | 215 + api/libsangoma/.svn/entries | 384 +- .../.svn/prop-base/config.status.svn-base | 5 + .../.svn/prop-base/libtool.svn-base | 5 + .../.svn/text-base/Makefile.svn-base | 679 + .../.svn/text-base/aclocal.m4.svn-base | 6945 ------ .../.svn/text-base/config.log.svn-base | 1053 + .../.svn/text-base/config.status.svn-base | 983 + .../.svn/text-base/libsangoma.c.svn-base | 114 +- .../.svn/text-base/libsangoma.h.svn-base | 16 +- .../.svn/text-base/libtool.svn-base | 7340 ++++++ .../.svn/text-base/svn-commit.2.tmp.svn-base | 5 + .../.svn/text-base/svn-commit.tmp.svn-base | 5 + api/libsangoma/Makefile | 33 +- api/libsangoma/Makefile.in | 19 +- api/libsangoma/aclocal.m4 | 1998 +- api/libsangoma/autom4te.cache/output.0 | 20518 ++++++++++++++++ api/libsangoma/autom4te.cache/output.1 | 20506 +++++++++++++++ api/libsangoma/autom4te.cache/requests | 350 + api/libsangoma/autom4te.cache/traces.0 | 9212 +++++++ api/libsangoma/autom4te.cache/traces.1 | 441 + api/libsangoma/config.log | 1017 +- api/libsangoma/config.status | 15 +- api/libsangoma/configure | 4966 ++-- api/libsangoma/examples/.svn/all-wcprops | 35 + api/libsangoma/examples/.svn/entries | 54 +- api/libsangoma/libsangoma.c | 112 +- api/libsangoma/libsangoma.h | 16 +- api/libsangoma/libtool | 106 +- api/libsangoma/svn-commit.2.tmp | 5 + api/libsangoma/svn-commit.tmp | 5 +- api/tdmapi/Makefile | 23 +- api/tdmapi/aft_tdm_hdlc_test | Bin 0 -> 14729 bytes api/tdmapi/aft_tdm_hdlc_test.c | 9 +- api/tdmapi/aft_tdm_voice_api | Bin 0 -> 17436 bytes api/tdmapi/aft_tdm_voice_api.c | 2 +- api/tdmapi/aft_tdm_voice_api_dtmf | Bin 0 -> 15943 bytes api/tdmapi/aft_tdm_voice_api_dtmf.c | 254 + api/tdmapi/aft_tdm_voice_api_rbs | Bin 0 -> 17940 bytes api/tdmapi/aft_tdm_voice_api_rbs.c | 2 +- api/tdmapi/aft_tdm_voice_api_rm_dtmf | Bin 0 -> 17898 bytes api/tdmapi/aft_tdm_voice_api_rm_dtmf.c | 445 + api/tdmapi/aft_tdm_voice_api_rxhook | Bin 0 -> 17638 bytes api/tdmapi/aft_tdm_voice_api_rxhook.c | 448 + api/tdmapi/aft_tdm_voice_api_switch.c | 368 - api/wanec_apilib | 2 +- deb_control/wanpipe.deb | 2 +- patches/kdrivers/diff | 451 + patches/kdrivers/diff.sh | 4 + patches/kdrivers/include/.sdla_aft_te1.h.swp | Bin 0 -> 16384 bytes patches/kdrivers/include/.wanpipe.h.swp | Bin 53248 -> 0 bytes patches/kdrivers/include/aft_a104.h | 2 +- patches/kdrivers/include/aft_analog.h | 2 +- patches/kdrivers/include/aft_bri.h | 55 + patches/kdrivers/include/if_wanpipe.h | 2 +- patches/kdrivers/include/if_wanpipe_common.h | 56 +- patches/kdrivers/include/sdla_56k.h | 2 +- patches/kdrivers/include/sdla_adccp.h | 451 +- patches/kdrivers/include/sdla_adsl.h | 13 +- patches/kdrivers/include/sdla_adsl_iface.h | 2 + patches/kdrivers/include/sdla_aft_te1.h | 387 +- patches/kdrivers/include/sdla_aft_te1.h~ | 1585 -- patches/kdrivers/include/sdla_aft_te3.h | 16 +- patches/kdrivers/include/sdla_asy.h | 154 +- patches/kdrivers/include/sdla_asyhdlc.h | 59 +- patches/kdrivers/include/sdla_atm.orig.h | 794 + patches/kdrivers/include/sdla_bri.h | 366 + patches/kdrivers/include/sdla_bscmp.h | 126 +- patches/kdrivers/include/sdla_bscstrm.h | 25 +- patches/kdrivers/include/sdla_bstrm.h | 66 +- patches/kdrivers/include/sdla_chdlc.h | 345 +- patches/kdrivers/include/sdla_fr.h | 332 +- patches/kdrivers/include/sdla_front_end.h | 113 +- patches/kdrivers/include/sdla_front_end.h~ | 547 - patches/kdrivers/include/sdla_hdlc.h | 194 +- patches/kdrivers/include/sdla_mp_fr.h | 14 +- patches/kdrivers/include/sdla_ppp.h | 216 +- patches/kdrivers/include/sdla_remora.h | 114 +- patches/kdrivers/include/sdla_serial.h | 62 + patches/kdrivers/include/sdla_tdmv.h | 1 + patches/kdrivers/include/sdla_tdmv.mar8.h | 70 - patches/kdrivers/include/sdla_te1.h | 111 +- patches/kdrivers/include/sdla_te1_ds.h | 18 +- patches/kdrivers/include/sdla_te1_pmc.h | 8 +- patches/kdrivers/include/sdla_te3.h | 2 - patches/kdrivers/include/sdla_te3.h~ | 116 - patches/kdrivers/include/sdla_x25.h | 465 +- patches/kdrivers/include/sdla_xilinx.h | 30 +- patches/kdrivers/include/sdladrv.h | 503 +- patches/kdrivers/include/sdlapci.h | 23 +- patches/kdrivers/include/sdlasfm.h | 62 +- patches/kdrivers/include/ss7_linux.h | 62 +- patches/kdrivers/include/wanec_iface.h | 1 + patches/kdrivers/include/wanpipe.h | 93 +- patches/kdrivers/include/wanpipe.h~ | 1014 - patches/kdrivers/include/wanpipe_abstr.h | 52 +- .../kdrivers/include/wanpipe_abstr_types.h | 36 + patches/kdrivers/include/wanpipe_cfg.h | 288 +- .../kdrivers/include/wanpipe_codec_iface.h | 2 +- patches/kdrivers/include/wanpipe_common.h | 1166 +- patches/kdrivers/include/wanpipe_common.h~ | 2442 -- patches/kdrivers/include/wanpipe_debug.h | 206 +- patches/kdrivers/include/wanpipe_defines.h | 213 +- patches/kdrivers/include/wanpipe_ec_kernel.h | 7 +- patches/kdrivers/include/wanpipe_events.h | 28 +- patches/kdrivers/include/wanpipe_fr_iface.h | 4 + patches/kdrivers/include/wanpipe_iface.h | 18 +- patches/kdrivers/include/wanpipe_includes.h | 59 +- patches/kdrivers/include/wanpipe_kernel.h | 114 +- patches/kdrivers/include/wanpipe_kernel.h~ | 513 - patches/kdrivers/include/wanpipe_lapb_iface.h | 5 +- patches/kdrivers/include/wanpipe_lip.h | 227 +- patches/kdrivers/include/wanpipe_lip_kernel.h | 6 + patches/kdrivers/include/wanpipe_sppp_iface.h | 12 + patches/kdrivers/include/wanpipe_tdm_api.h | 282 +- .../kdrivers/include/wanpipe_tdm_api_iface.h | 326 + patches/kdrivers/include/wanpipe_version.h | 62 +- patches/kdrivers/include/wanproc.h | 2 + patches/kdrivers/include/wanrouter.h | 53 +- patches/kdrivers/include/xhfc24succ.h | 2113 ++ patches/kdrivers/src/diff | 390 + .../src/lip/bin/wanpipe_lip_atm.gcc3.i386.o | Bin 27936 -> 27456 bytes .../bin/wanpipe_lip_atm.gcc3.i386.regparm.o | Bin 27968 -> 27464 bytes .../src/lip/bin/wanpipe_lip_atm.gcc3.i686.o | Bin 30640 -> 30552 bytes .../bin/wanpipe_lip_atm.gcc3.i686.regparm.o | Bin 29552 -> 29344 bytes .../src/lip/bin/wanpipe_sppp.gcc3.i386.o | Bin 34452 -> 34452 bytes .../lip/bin/wanpipe_sppp.gcc3.i386.regparm.o | Bin 34644 -> 34644 bytes .../src/lip/bin/wanpipe_sppp.gcc3.i686.o | Bin 37532 -> 37532 bytes .../lip/bin/wanpipe_sppp.gcc3.i686.regparm.o | Bin 36428 -> 36428 bytes .../src/lip/lip_katm/wanpipe_katm_iface.o | Bin 140380 -> 0 bytes .../src/lip/lip_katm/wanpipe_katm_sub.o | Bin 144716 -> 0 bytes patches/kdrivers/src/lip/wanpipe_lip_bh.c | 59 +- patches/kdrivers/src/lip/wanpipe_lip_bh.c~ | 237 - patches/kdrivers/src/lip/wanpipe_lip_iface.c | 141 +- patches/kdrivers/src/lip/wanpipe_lip_iface.c~ | 1538 -- patches/kdrivers/src/lip/wanpipe_lip_netdev.c | 100 +- .../kdrivers/src/lip/wanpipe_lip_netdev.c~ | 612 - patches/kdrivers/src/lip/wanpipe_lip_prot.c | 1 - patches/kdrivers/src/lip/wanpipe_lip_sub.c | 2 +- patches/kdrivers/src/lip/wanpipe_lip_tty.c | 2 +- patches/kdrivers/src/net/Makefile | 12 +- patches/kdrivers/src/net/Module.symvers | 112 +- patches/kdrivers/src/net/aft_a104.c | 425 +- patches/kdrivers/src/net/aft_analog.c | 471 +- patches/kdrivers/src/net/aft_bri.c | 1818 ++ patches/kdrivers/src/net/diff | 1654 +- patches/kdrivers/src/net/modules.order | 7 - patches/kdrivers/src/net/output | 1385 -- patches/kdrivers/src/net/sdla_56k.c | 112 +- patches/kdrivers/src/net/sdla_8te1.c | 1539 +- patches/kdrivers/src/net/sdla_adccp.c | 41 +- patches/kdrivers/src/net/sdla_adsl.c | 1934 +- patches/kdrivers/src/net/sdla_aft_te1.c | 3408 ++- patches/kdrivers/src/net/sdla_aft_te1.c~ | 11637 +++++++++ patches/kdrivers/src/net/sdla_aft_te3.c | 364 +- patches/kdrivers/src/net/sdla_aft_te3.c~ | 5908 ----- patches/kdrivers/src/net/sdla_asyhdlc.c | 52 +- patches/kdrivers/src/net/sdla_atm.c | 28 +- patches/kdrivers/src/net/sdla_bitstrm.c | 290 +- patches/kdrivers/src/net/sdla_bri.c | 3356 +++ patches/kdrivers/src/net/sdla_bri_tdmv.c | 1302 + patches/kdrivers/src/net/sdla_bsc.c | 10 +- patches/kdrivers/src/net/sdla_bscstrm.c | 12 +- patches/kdrivers/src/net/sdla_chdlc.c | 71 +- patches/kdrivers/src/net/sdla_ec.c | 5 +- patches/kdrivers/src/net/sdla_ec_dev.c | 2 +- patches/kdrivers/src/net/sdla_edac.c | 2 - patches/kdrivers/src/net/sdla_edu.c | 12 +- patches/kdrivers/src/net/sdla_fr.c | 29 +- patches/kdrivers/src/net/sdla_ft1.c | 2 +- patches/kdrivers/src/net/sdla_mp_fr.c | 38 +- patches/kdrivers/src/net/sdla_pos.c | 10 +- patches/kdrivers/src/net/sdla_ppp.c | 25 +- patches/kdrivers/src/net/sdla_remora.c | 920 +- patches/kdrivers/src/net/sdla_remora_tdmv.c | 172 +- patches/kdrivers/src/net/sdla_sdlc.c | 14 +- patches/kdrivers/src/net/sdla_serial.c | 1016 + patches/kdrivers/src/net/sdla_tdmv.c | 196 +- patches/kdrivers/src/net/sdla_te1.c | 916 +- patches/kdrivers/src/net/sdla_te3.c | 300 +- patches/kdrivers/src/net/sdla_te3.c~ | 1268 - patches/kdrivers/src/net/sdla_x25.c | 22 +- patches/kdrivers/src/net/sdla_xilinx.c | 235 +- patches/kdrivers/src/net/sdladrv.c | 5959 +++-- patches/kdrivers/src/net/sdladrv_fe.c | 731 +- patches/kdrivers/src/net/sdladrv_utils.c | 295 + patches/kdrivers/src/net/sdlamain.c | 85 +- patches/kdrivers/src/net/wanpipe_abstr.c | 55 +- patches/kdrivers/src/net/wanpipe_codec.c | 4 +- patches/kdrivers/src/net/wanpipe_codec_law.c | 4 +- .../kdrivers/src/net/wanpipe_linux_iface.c | 34 +- patches/kdrivers/src/net/wanpipe_multppp.c | 69 +- patches/kdrivers/src/net/wanpipe_syncppp.c | 40 +- patches/kdrivers/src/net/wanpipe_tdm_api.c | 946 +- patches/kdrivers/src/net/wanpipe_utils.c | 64 +- patches/kdrivers/src/wan_aften/wan_aften.c | 89 +- patches/kdrivers/src/wan_aften/wan_aften.h | 11 + .../kdrivers/src/wan_aften/wan_aften_src.o | Bin 208336 -> 226164 bytes .../src/wan_aften/wanpipe_linux_iface.o | Bin 133956 -> 135340 bytes .../src/wanrouter/.af_wanpipe_src.o.d | 186 + patches/kdrivers/src/wanrouter/af_wanpipe.c | 65 +- .../src/wanrouter/af_wanpipe_datascope.o | Bin 171168 -> 171944 bytes .../kdrivers/src/wanrouter/af_wanpipe_src.o | Bin 179868 -> 0 bytes patches/kdrivers/src/wanrouter/waniface.o | Bin 143196 -> 148275 bytes patches/kdrivers/src/wanrouter/wanmain.c | 38 +- patches/kdrivers/src/wanrouter/wanmain.o | Bin 225492 -> 242797 bytes patches/kdrivers/src/wanrouter/wanproc.c | 54 +- patches/kdrivers/src/wanrouter/wanproc.o | Bin 211384 -> 219488 bytes patches/kdrivers/wanec/.#wanec_cmd.c.1.49 | 2176 ++ patches/kdrivers/wanec/.#wanec_cmd.c.1.62 | 2332 ++ .../kdrivers/wanec/.tmp_versions/wanec.mod | 4 +- patches/kdrivers/wanec/Makefile.Windows | 9 + patches/kdrivers/wanec/Makefile6.FreeBSD | 2 +- .../apilib/bt/octapi_bt0_private.h | 2 + .../include/apilib/octapi_llman.h | 1 + .../include/oct6100api/oct6100_apiud.h | 8 +- .../oct6100api/oct6100_api/oct6100_user.c | 85 +- .../oct6100api/oct6100_channel_priv.h | 9 + .../oct6100_apiw_linux/oct6100api.mak | 4 +- patches/kdrivers/wanec/sources | 25 +- patches/kdrivers/wanec/wanec | 1 + patches/kdrivers/wanec/wanec.mod.c | 4 +- patches/kdrivers/wanec/wanec_cmd.c | 1357 +- patches/kdrivers/wanec/wanec_cmd.nc.c | 2189 ++ patches/kdrivers/wanec/wanec_dev.c | 1 + patches/kdrivers/wanec/wanec_iface.c | 1458 +- patches/kdrivers/wanec/wanec_iface.h | 481 +- patches/kdrivers/wanec/wanec_iface_api.h | 197 + patches/kdrivers/wanec/wanec_utils.c | 199 +- rpmspec/wanpipe-mod.spec | 451 +- rpmspec/wanpipe-util.spec | 536 +- rpmspec/wanpipe.spec | 451 +- .../wanpipe1.rtp | 46 +- samples/wanrouter | 667 +- samples/wanrouter.org | 2986 --- ssmg/sangoma_bri/Makefile | 22 + ssmg/sangoma_bri/install.sh | 23 + ssmg/sangoma_bri/sangoma_brid.i686 | Bin 0 -> 464184 bytes ssmg/sangoma_bri/sangoma_brid.x86_64 | Bin 0 -> 573952 bytes ssmg/sangoma_bri/smg_ctrl | 199 + ssmg/sangoma_mgd.trunk/.svn/all-wcprops | 2 +- ssmg/sangoma_mgd.trunk/.svn/entries | 100 +- .../.svn/tmp/tempfile.10.tmp | 306 + .../.svn/tmp/tempfile.11.tmp | 119 + .../.svn/tmp/tempfile.12.tmp | 5018 ++++ .../.svn/tmp/tempfile.13.tmp | 5020 ++++ .../.svn/tmp/tempfile.14.tmp | 602 + .../tmp/tempfile.15.tmp} | 21 +- .../.svn/tmp/tempfile.16.tmp | 600 + .../.svn/tmp/tempfile.17.tmp | 119 + .../sangoma_mgd.trunk/.svn/tmp/tempfile.2.tmp | 4783 +++- .../sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp | 17 +- .../sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp | 606 +- .../sangoma_mgd.trunk/.svn/tmp/tempfile.5.tmp | 228 + .../sangoma_mgd.trunk/.svn/tmp/tempfile.6.tmp | 97 + .../sangoma_mgd.trunk/.svn/tmp/tempfile.7.tmp | 4940 ++++ .../sangoma_mgd.trunk/.svn/tmp/tempfile.8.tmp | 388 + .../tmp/tempfile.9.tmp} | 18 +- ssmg/sangoma_mgd.trunk/Makefile | 13 +- ssmg/sangoma_mgd.trunk/app/.svn/entries | 10 +- .../chan_woomera.trunk/.pbxdir | 2 +- .../chan_woomera.trunk/.svn/all-wcprops | 30 +- .../chan_woomera.trunk/.svn/entries | 54 +- .../text-base/Changelog.chan_woomera.svn-base | 11 + .../.svn/text-base/Makefile.svn-base | 5 + .../.svn/text-base/chan_woomera.c.svn-base | 47 +- .../.svn/tmp/tempfile.2.tmp | 12 +- .../.svn/tmp/tempfile.3.tmp | 181 +- .../.svn/tmp/tempfile.4.tmp | 4766 +--- .../.svn/tmp/tempfile.5.tmp | 4609 ++++ .../.svn/tmp/tempfile.6.tmp | 81 + .../.svn/tmp/tempfile.7.tmp | 4635 ++++ .../.svn/tmp/tempfile.8.tmp | 4694 ++++ .../chan_woomera.trunk/Changelog.chan_woomera | 11 + .../chan_woomera.trunk/Makefile | 5 + .../chan_woomera.trunk/chan_woomera.c | 47 +- .../chan_woomera.trunk/svn-commit.tmp | 5 - ssmg/sangoma_mgd.trunk/conf/.svn/entries | 10 +- .../conf_bri/.svn/all-wcprops | 17 + ssmg/sangoma_mgd.trunk/conf_bri/.svn/entries | 52 + ssmg/sangoma_mgd.trunk/conf_bri/.svn/format | 1 + .../.svn/text-base/woomera_ext.conf.svn-base | 35 + .../.svn/text-base/woomera_iax.conf.svn-base | 6 + .../conf_bri/woomera_ext.conf | 30 + .../conf_bri/woomera_iax.conf | 7 + .../conf_ss7/.svn/all-wcprops | 17 + ssmg/sangoma_mgd.trunk/conf_ss7/.svn/entries | 52 + ssmg/sangoma_mgd.trunk/conf_ss7/.svn/format | 1 + .../.svn/text-base/woomera_ext.conf.svn-base | 35 + .../.svn/text-base/woomera_iax.conf.svn-base | 6 + .../conf_ss7/woomera_ext.conf | 35 + .../conf_ss7/woomera_iax.conf | 7 + ssmg/sangoma_mgd.trunk/install | 152 +- ssmg/sangoma_mgd.trunk/lib/.svn/entries | 6 +- .../lib/libteletone/.deps/.svn/entries | 10 +- .../lib/libteletone/.svn/all-wcprops | 12 +- .../lib/libteletone/.svn/entries | 96 +- .../lib/libteletone/Makefile | 16 +- .../lib/libteletone/config.log | 185 +- .../lib/libteletone/config.status | 22 +- .../sangoma_mgd.trunk/lib/libteletone/libtool | 307 +- .../lib/libteletone/src/.svn/entries | 16 +- ssmg/sangoma_mgd.trunk/lib/svn-commit.tmp | 12 - ssmg/sangoma_mgd.trunk/sangoma_mgd.c | 33 +- .../sangoma_mgd.conf.sample.bri | 61 + .../sangoma_mgd.conf.sample.ss7 | 61 + ssmg/sangoma_mgd.trunk/sangoma_mgd.h | 7 +- ssmg/sangoma_mgd.trunk/scripts/.svn/entries | 14 +- .../scripts/callgen/.svn/entries | 14 +- .../scripts/callgen/sample.call.template | 2 +- .../scripts/init.d/.svn/all-wcprops | 2 +- .../scripts/init.d/.svn/entries | 16 +- .../.svn/text-base/smgss7_init_ctrl.svn-base | 4 - .../scripts/init.d/smgss7_init_ctrl | 4 - ssmg/sangoma_mgd.trunk/sigboost.h | 1 + ssmg/sangoma_mgd.trunk/svn-commit.tmp | 11 - ssmg/sangoma_mgd.trunk/tmp2.26345 | 6 + util/ft1/Makefile | 6 +- util/ft1/ft1_config.c | 10 +- util/ft1/wanpipe_cfgft1 | 37 +- util/lxdialog/Makefile | 2 +- util/lxdialog/dialog.h | 6 + util/lxdialog/inputbox.c | 2 +- util/lxdialog/lxdialog.c | 2 +- util/lxdialog/util.c | 2 +- util/misc/Makefile | 2 +- util/misc/wp_x25_event_read | Bin 6745 -> 7424 bytes util/misc/wp_x25_event_read.c | 1 + util/sdladump/sdladump.c | 61 +- util/tmp_davidy/wancfg_zaptel-dy.tgz | Bin 35387 -> 0 bytes .../wancfg_zaptel/.#wancfg_zaptel.pl.1.27 | 1920 -- util/tmp_davidy/wancfg_zaptel/A10u.pm | 417 - util/tmp_davidy/wancfg_zaptel/A10x.pm | 429 - util/tmp_davidy/wancfg_zaptel/A20x.pm | 164 - util/tmp_davidy/wancfg_zaptel/Card.pm | 117 - util/tmp_davidy/wancfg_zaptel/Makefile | 25 - util/tmp_davidy/wancfg_zaptel/clean.sh | 4 - util/tmp_davidy/wancfg_zaptel/install.sh | 29 - util/tmp_davidy/wancfg_zaptel/setup-sangoma | 5 - .../wancfg_zaptel/templates/smg_bri.conf | 12 - .../templates/smgbri_start_script | 24 - .../templates/smgbri_start_script_addon | 24 - .../templates/smgbri_stop_script | 2 - .../templates/ss7_a100/wanpipe.ss7.1 | 20 - .../templates/ss7_a100/wanpipe.ss7.2 | 2 - .../templates/ss7_a100/wanpipe.ss7.3 | 3 - .../templates/ss7_a100/wanpipe.ss7.4 | 21 - .../templates/ss7_a100/wanpipe.ss7.5 | 9 - .../templates/ss7_a100/wanpipe.ss7.6 | 11 - .../ss7_a100/wanpipe.tdmvoiceapi.a100 | 52 - .../templates/ss7_a10u/wanpipe.ss7.1 | 20 - .../templates/ss7_a10u/wanpipe.ss7.2 | 2 - .../templates/ss7_a10u/wanpipe.ss7.3 | 3 - .../templates/ss7_a10u/wanpipe.ss7.4 | 20 - .../templates/ss7_a10u/wanpipe.ss7.5 | 9 - .../templates/ss7_a10u/wanpipe.ss7.6 | 11 - .../wancfg_zaptel/templates/wanpipe.tdm.a100 | 51 - .../wancfg_zaptel/templates/wanpipe.tdm.a10u | 50 - .../wancfg_zaptel/templates/wanpipe.tdm.a200 | 44 - .../templates/wanpipe.tdm_api.a100 | 52 - .../templates/wanpipe.tdm_api.a500 | 44 - .../templates/wanrouter.rc.template | 41 - .../templates/wanrouter.rc.template.FreeBSD | 34 - .../wancfg_zaptel/templates/woomera.conf | 12 - .../wancfg_zaptel/templates/zapata-auto.conf | 7 - .../wancfg_zaptel/templates/zapata.conf | 29 - .../wancfg_zaptel/templates/zaptel.conf | 5 - .../wancfg_zaptel/templates/zaptel_cfg_script | 29 - .../templates/zaptel_cfg_script.FreeBSD | 6 - util/tmp_davidy/wancfg_zaptel/uninstall.sh | 13 - util/tmp_davidy/wancfg_zaptel/wancfg_smg | 45 - util/tmp_davidy/wancfg_zaptel/wancfg_tdmapi | 45 - util/tmp_davidy/wancfg_zaptel/wancfg_zaptel | 45 - util/wan_aftup/A101dm_0040_V31.BIN | Bin 0 -> 212392 bytes util/wan_aftup/A101dm_0040_V34.BIN | Bin 212392 -> 0 bytes util/wan_aftup/A102dm_0040_V31.BIN | Bin 0 -> 212392 bytes util/wan_aftup/A102dm_0040_V33.BIN | Bin 212392 -> 0 bytes util/wan_aftup/A104d_0100_V24.BIN | Bin 0 -> 402936 bytes util/wan_aftup/A104d_0100_V25.BIN | Bin 0 -> 402936 bytes util/wan_aftup/A104d_0100_V26.BIN | Bin 402936 -> 0 bytes util/wan_aftup/A104dm_0100_V31.BIN | Bin 0 -> 402936 bytes util/wan_aftup/A104dm_0100_V33.BIN | Bin 402936 -> 0 bytes util/wan_aftup/A108dm_0100_V31.BIN | Bin 0 -> 402936 bytes util/wan_aftup/A108dm_0100_V33.BIN | Bin 402936 -> 0 bytes util/wan_aftup/A140_0100_V02.BIN | Bin 0 -> 402936 bytes util/wan_aftup/A140_0100_V03.BIN | Bin 0 -> 402936 bytes util/wan_aftup/A200_0040_V08.BIN | Bin 0 -> 212392 bytes util/wan_aftup/A200_0040_V11.BIN | Bin 212392 -> 0 bytes util/wan_aftup/A301_0040_V07.BIN | Bin 0 -> 212392 bytes util/wan_aftup/A301_0040_V08.BIN | Bin 0 -> 212392 bytes util/wan_aftup/A301_0040_V09.BIN | Bin 212392 -> 0 bytes util/wan_aftup/A301_V05_prod.BIN | Bin 524288 -> 0 bytes util/wan_aftup/A400_0040_V09.BIN | Bin 0 -> 212392 bytes util/wan_aftup/A400_0040_V11.BIN | Bin 212392 -> 0 bytes util/wan_aftup/A500_0040_V32.BIN | Bin 0 -> 212392 bytes util/wan_aftup/ChangeLog.a101dm | 14 - util/wan_aftup/ChangeLog.a102dm | 15 - util/wan_aftup/ChangeLog.a104d | 9 - util/wan_aftup/ChangeLog.a104dm | 16 - util/wan_aftup/ChangeLog.a108dm | 16 - util/wan_aftup/ChangeLog.a200 | 15 - util/wan_aftup/ChangeLog.a400 | 15 - util/wan_aftup/Makefile | 4 +- util/wan_aftup/update_aft_firm.sh | 6 +- util/wan_aftup/wan_aft_flash_shark.c | 4 + util/wan_aftup/wan_aft_prg.c | 14 + util/wan_aftup/wan_aftup.c | 50 +- util/wan_aftup/wan_plxctrl.c | 802 +- util/wan_plxctrl/check_plx.sh | 39 - util/wan_plxctrl/wan_plxctrl.c | 307 +- util/wan_plxctrl/wan_plxup.c | 64 +- util/wan_plxctrl/wan_plxup.h | 2 +- util/wancfg/.#menu_hardware_probe.cpp.1.20 | 997 + util/wancfg/.zaptel_conf_file_reader.cpp.swp | Bin 0 -> 16384 bytes util/wancfg/Makefile.Linux | 2 +- util/wancfg/Makefile6.FreeBSD | 6 +- util/wancfg/conf_file_reader.cpp | 131 +- util/wancfg/conf_file_reader.h | 4 +- util/wancfg/conf_file_writer.cpp | 188 +- util/wancfg/cpp_string.cpp | 2 +- .../input_box_number_of_logical_channels.cpp | 10 + util/wancfg/list_element.h | 2 +- util/wancfg/list_element_chan_def.h | 17 +- util/wancfg/list_element_sangoma_card.h | 6 + util/wancfg/main.cpp | 93 +- util/wancfg/menu_aft_logical_channel_cfg.cpp | 3 +- .../wancfg/menu_aft_logical_channels_list.cpp | 4 + util/wancfg/menu_hardware_card_type.cpp | 52 +- util/wancfg/menu_hardware_probe.cpp | 88 +- util/wancfg/menu_hardware_probe.h | 2 +- .../menu_hardware_serial_select_medium.cpp | 4 +- util/wancfg/menu_hardware_setup.cpp | 657 +- util/wancfg/menu_hardware_setup.h | 45 + ...enu_hardware_te1_card_advanced_options.cpp | 519 +- .../menu_hardware_te1_card_advanced_options.h | 14 + .../menu_net_interface_ip_configuration.cpp | 7 +- .../menu_net_interface_operation_mode.cpp | 93 +- util/wancfg/menu_net_interface_setup.cpp | 54 +- util/wancfg/menu_net_interface_setup.h | 2 +- util/wancfg/menu_new_device_configuration.cpp | 28 +- util/wancfg/menu_select_card_type_manualy.cpp | 34 + util/wancfg/menu_select_protocol.cpp | 32 +- util/wancfg/menu_wan_channel_cfg.cpp | 17 +- util/wancfg/menu_wan_channel_cfg_v1.cpp | 3 +- util/wancfg/text_box.cpp | 2 +- util/wancfg/wancfg.h | 31 +- util/wancfg_legacy/Makefile | 8 +- util/wancfg_legacy/Makefile.BSD | 5 + util/wancfg_legacy/Makefile.Linux | 7 + util/wancfg_legacy/wancfg_legacy | 40 +- util/wancfg_legacy/xupdate | 4 + util/wancfg_zaptel/.#wancfg_zaptel.1.5 | 45 - util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 | 1920 -- util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 | 1977 -- util/wancfg_zaptel/A10u.pm | 213 +- util/wancfg_zaptel/A50x.pm | 14 +- .../A50x.pm => wancfg_zaptel/A50x.pm.old} | 22 +- util/wancfg_zaptel/diff | 122 +- util/wancfg_zaptel/setup-sangoma | 11 +- util/wancfg_zaptel/templates/smg_bri.conf | 41 +- util/wancfg_zaptel/templates/wanpipe.tdm.a200 | 2 - .../templates/wanpipe.tdm_api.a500 | 2 +- util/wancfg_zaptel/wancfg_smg | 8 +- util/wancfg_zaptel/wancfg_tdmapi | 9 +- util/wancfg_zaptel/wancfg_zaptel.pl | 195 +- .../wancfg_zaptel.pl.old} | 931 +- util/wanconfig/Makefile | 2 +- util/wanconfig/diff | 139 + util/wanconfig/file | 1697 -- util/wanconfig/wanconfig.c | 544 +- util/wanec_apilib/wanec_api.c | 556 +- util/wanec_apilib/wanec_api.h | 97 +- util/wanec_apilib/wanec_api_lib.c | 291 +- util/wanec_client/.#Makefile.Linux.1.15 | 62 + util/wanec_client/Makefile | 66 +- util/wanec_client/Makefile.FreeBSD | 33 + util/wanec_client/Makefile.Linux | 69 + util/wanec_client/Makefile.OpenBSD | 76 + util/wanec_client/Makefile.org | 60 + util/wanec_client/Makefile6.FreeBSD | 34 + util/wanec_client/Makefile_test | 30 + util/wanec_client/wan_ec_arg.l | 230 +- util/wanec_client/wan_ec_arg.y | 324 +- util/wanec_client/wan_ecmain.c | 275 +- util/wanec_client/wan_ecmain.h | 23 +- util/wanpipemon.old/Makefile | 103 - util/wanpipemon.old/aftpipemon.c | 1342 - util/wanpipemon.old/aftpipemon.o | Bin 29172 -> 0 bytes util/wanpipemon.old/atmpipemon.c | 1280 - util/wanpipemon.old/atmpipemon.o | Bin 26004 -> 0 bytes util/wanpipemon.old/bpipemon-old.c | 1458 -- util/wanpipemon.old/bpipemon.c | 574 - util/wanpipemon.old/bpipemon.o | Bin 12172 -> 0 bytes util/wanpipemon.old/cpipemon.c | 1862 -- util/wanpipemon.old/cpipemon.o | Bin 35808 -> 0 bytes util/wanpipemon.old/diff | 358 - util/wanpipemon.old/docommand.c | 249 - util/wanpipemon.old/dslpipemon.c | 1044 - util/wanpipemon.old/dslpipemon.o | Bin 19996 -> 0 bytes util/wanpipemon.old/fe_lib.c | 1290 - util/wanpipemon.old/fe_lib.h | 80 - util/wanpipemon.old/fe_lib.o | Bin 39700 -> 0 bytes util/wanpipemon.old/fpipemon.c | 1312 - util/wanpipemon.old/fpipemon.o | Bin 28124 -> 0 bytes util/wanpipemon.old/mppipemon.c | 1375 -- util/wanpipemon.old/ppipemon.c | 1375 -- util/wanpipemon.old/ppipemon.o | Bin 31008 -> 0 bytes util/wanpipemon.old/prot_trace.c | 1892 -- util/wanpipemon.old/prot_trace.o | Bin 26604 -> 0 bytes util/wanpipemon.old/prot_trace.orig.c | 1249 - util/wanpipemon.old/ss7pipemon.c | 1196 - util/wanpipemon.old/ss7pipemon.o | Bin 19048 -> 0 bytes util/wanpipemon.old/wangui.c | 594 - util/wanpipemon.old/wangui.o | Bin 9156 -> 0 bytes util/wanpipemon.old/wanpipemon | Bin 231902 -> 0 bytes util/wanpipemon.old/wanpipemon.c | 1402 -- util/wanpipemon.old/wanpipemon.h | 492 - util/wanpipemon.old/wanpipemon.o | Bin 32852 -> 0 bytes util/wanpipemon.old/wpkbdmon.c | 363 - util/wanpipemon.old/xml_lib.c | 125 - util/wanpipemon.old/xml_lib.o | Bin 2972 -> 0 bytes util/wanpipemon.old/xpipemon.c | 1111 - util/wanpipemon.old/xpipemon.o | Bin 26780 -> 0 bytes util/wanpipemon.old/zapmon.c | 627 - util/{wanpipemon.old => wanpipemon}/' | 0 util/wanpipemon/aftpipemon.c | 11 +- util/wanpipemon/atmpipemon.c | 1 - util/wanpipemon/cpipemon.c | 1 - util/wanpipemon/dslpipemon.c | 130 +- util/wanpipemon/isdn.pcap | 0 util/wanpipemon/prot_trace.c | 67 +- util/wanpipemon/trace.pcap | Bin 3528 -> 0 bytes util/wanpipemon/wanpipemon.c | 15 +- util/wanpipemon/wanpipemon.h | 11 - util/wanpipemon/wanpipemon_api.tgz | Bin 0 -> 5952 bytes .../wp_trace_pcap.bin | Bin util/wanpipemon_legacy/aftpipemon.c | 6 +- util/wanpipemon_legacy/atmpipemon.c | 18 +- util/wanpipemon_legacy/cpipemon.c | 6 +- util/wanpipemon_legacy/docommand.c | 4 +- util/wanpipemon_legacy/dslpipemon.c | 47 +- util/wanpipemon_legacy/fpipemon.c | 12 +- util/wanpipemon_legacy/ppipemon.c | 6 +- util/wanpipemon_legacy/prot_trace.c | 123 +- util/wanpipemon_legacy/wangui.c | 30 +- util/wanpipemon_legacy/wanpipemon.h | 2 +- util/wanpipemon_legacy/wanpipemon_legacy.c | 28 +- util/wanpipemon_legacy/xpipemon.c | 4 +- zaptel/zaptel.patch | 31 - zaptel/zaptel.path | 1 - 573 files changed, 164586 insertions(+), 89251 deletions(-) create mode 100644 ChangeLog.beta delete mode 100644 ChangeLog.stable mode change 120000 => 100644 README.changes delete mode 100755 api/aft/aft_api delete mode 100755 api/aft/aft_api_events create mode 100644 api/aft/aft_api_repeater.c delete mode 100755 api/aft/aft_echo delete mode 100644 api/aft/aft_echo.c delete mode 100755 api/aft/aft_integrity create mode 100755 api/chdlc/chdlc_modem_cmd rename api/{aft/aft_integrity.c => chdlc/chdlc_modem_cmd.c} (57%) create mode 100644 api/libsangoma/.svn/all-wcprops create mode 100644 api/libsangoma/.svn/prop-base/config.status.svn-base create mode 100644 api/libsangoma/.svn/prop-base/libtool.svn-base create mode 100644 api/libsangoma/.svn/text-base/Makefile.svn-base delete mode 100644 api/libsangoma/.svn/text-base/aclocal.m4.svn-base create mode 100644 api/libsangoma/.svn/text-base/config.log.svn-base create mode 100644 api/libsangoma/.svn/text-base/config.status.svn-base create mode 100644 api/libsangoma/.svn/text-base/libtool.svn-base create mode 100644 api/libsangoma/.svn/text-base/svn-commit.2.tmp.svn-base create mode 100644 api/libsangoma/.svn/text-base/svn-commit.tmp.svn-base create mode 100644 api/libsangoma/autom4te.cache/output.0 create mode 100644 api/libsangoma/autom4te.cache/output.1 create mode 100644 api/libsangoma/autom4te.cache/requests create mode 100644 api/libsangoma/autom4te.cache/traces.0 create mode 100644 api/libsangoma/autom4te.cache/traces.1 create mode 100644 api/libsangoma/examples/.svn/all-wcprops create mode 100644 api/libsangoma/svn-commit.2.tmp create mode 100755 api/tdmapi/aft_tdm_hdlc_test create mode 100755 api/tdmapi/aft_tdm_voice_api create mode 100755 api/tdmapi/aft_tdm_voice_api_dtmf create mode 100644 api/tdmapi/aft_tdm_voice_api_dtmf.c create mode 100755 api/tdmapi/aft_tdm_voice_api_rbs create mode 100755 api/tdmapi/aft_tdm_voice_api_rm_dtmf create mode 100644 api/tdmapi/aft_tdm_voice_api_rm_dtmf.c create mode 100755 api/tdmapi/aft_tdm_voice_api_rxhook create mode 100644 api/tdmapi/aft_tdm_voice_api_rxhook.c delete mode 100644 api/tdmapi/aft_tdm_voice_api_switch.c create mode 100644 patches/kdrivers/diff create mode 100755 patches/kdrivers/diff.sh create mode 100644 patches/kdrivers/include/.sdla_aft_te1.h.swp delete mode 100644 patches/kdrivers/include/.wanpipe.h.swp create mode 100755 patches/kdrivers/include/aft_bri.h delete mode 100644 patches/kdrivers/include/sdla_aft_te1.h~ create mode 100644 patches/kdrivers/include/sdla_atm.orig.h create mode 100755 patches/kdrivers/include/sdla_bri.h delete mode 100644 patches/kdrivers/include/sdla_front_end.h~ create mode 100644 patches/kdrivers/include/sdla_serial.h delete mode 100644 patches/kdrivers/include/sdla_tdmv.mar8.h delete mode 100644 patches/kdrivers/include/sdla_te3.h~ create mode 120000 patches/kdrivers/include/wanec_iface.h delete mode 100644 patches/kdrivers/include/wanpipe.h~ create mode 100644 patches/kdrivers/include/wanpipe_abstr_types.h delete mode 100644 patches/kdrivers/include/wanpipe_common.h~ delete mode 100644 patches/kdrivers/include/wanpipe_kernel.h~ create mode 100644 patches/kdrivers/include/wanpipe_tdm_api_iface.h create mode 100755 patches/kdrivers/include/xhfc24succ.h create mode 100644 patches/kdrivers/src/diff delete mode 100644 patches/kdrivers/src/lip/lip_katm/wanpipe_katm_iface.o delete mode 100644 patches/kdrivers/src/lip/lip_katm/wanpipe_katm_sub.o delete mode 100644 patches/kdrivers/src/lip/wanpipe_lip_bh.c~ delete mode 100644 patches/kdrivers/src/lip/wanpipe_lip_iface.c~ delete mode 100644 patches/kdrivers/src/lip/wanpipe_lip_netdev.c~ create mode 100755 patches/kdrivers/src/net/aft_bri.c delete mode 100644 patches/kdrivers/src/net/modules.order delete mode 100644 patches/kdrivers/src/net/output create mode 100644 patches/kdrivers/src/net/sdla_aft_te1.c~ delete mode 100644 patches/kdrivers/src/net/sdla_aft_te3.c~ create mode 100755 patches/kdrivers/src/net/sdla_bri.c create mode 100755 patches/kdrivers/src/net/sdla_bri_tdmv.c create mode 100644 patches/kdrivers/src/net/sdla_serial.c delete mode 100644 patches/kdrivers/src/net/sdla_te3.c~ create mode 100644 patches/kdrivers/src/net/sdladrv_utils.c create mode 100644 patches/kdrivers/src/wanrouter/.af_wanpipe_src.o.d delete mode 100644 patches/kdrivers/src/wanrouter/af_wanpipe_src.o create mode 100644 patches/kdrivers/wanec/.#wanec_cmd.c.1.49 create mode 100644 patches/kdrivers/wanec/.#wanec_cmd.c.1.62 create mode 100755 patches/kdrivers/wanec/Makefile.Windows create mode 120000 patches/kdrivers/wanec/wanec create mode 100644 patches/kdrivers/wanec/wanec_cmd.nc.c create mode 100644 patches/kdrivers/wanec/wanec_iface_api.h rename util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u => samples/wanpipe1.rtp (51%) delete mode 100644 samples/wanrouter.org create mode 100644 ssmg/sangoma_bri/Makefile create mode 100755 ssmg/sangoma_bri/install.sh create mode 100755 ssmg/sangoma_bri/sangoma_brid.i686 create mode 100755 ssmg/sangoma_bri/sangoma_brid.x86_64 create mode 100755 ssmg/sangoma_bri/smg_ctrl create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.10.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.11.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.12.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.13.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.14.tmp rename ssmg/sangoma_mgd.trunk/{sangoma_mgd-2008-03-07.c => .svn/tmp/tempfile.15.tmp} (99%) create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.16.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.17.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.5.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.6.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.7.tmp create mode 100644 ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.8.tmp rename ssmg/sangoma_mgd.trunk/{sangoma_mgd.orig.c => .svn/tmp/tempfile.9.tmp} (99%) create mode 100644 ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.5.tmp create mode 100644 ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.6.tmp create mode 100644 ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.7.tmp create mode 100644 ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.8.tmp delete mode 100644 ssmg/sangoma_mgd.trunk/chan_woomera.trunk/svn-commit.tmp create mode 100644 ssmg/sangoma_mgd.trunk/conf_bri/.svn/all-wcprops create mode 100644 ssmg/sangoma_mgd.trunk/conf_bri/.svn/entries create mode 100644 ssmg/sangoma_mgd.trunk/conf_bri/.svn/format create mode 100644 ssmg/sangoma_mgd.trunk/conf_bri/.svn/text-base/woomera_ext.conf.svn-base create mode 100644 ssmg/sangoma_mgd.trunk/conf_bri/.svn/text-base/woomera_iax.conf.svn-base create mode 100644 ssmg/sangoma_mgd.trunk/conf_bri/woomera_ext.conf create mode 100644 ssmg/sangoma_mgd.trunk/conf_bri/woomera_iax.conf create mode 100644 ssmg/sangoma_mgd.trunk/conf_ss7/.svn/all-wcprops create mode 100644 ssmg/sangoma_mgd.trunk/conf_ss7/.svn/entries create mode 100644 ssmg/sangoma_mgd.trunk/conf_ss7/.svn/format create mode 100644 ssmg/sangoma_mgd.trunk/conf_ss7/.svn/text-base/woomera_ext.conf.svn-base create mode 100644 ssmg/sangoma_mgd.trunk/conf_ss7/.svn/text-base/woomera_iax.conf.svn-base create mode 100644 ssmg/sangoma_mgd.trunk/conf_ss7/woomera_ext.conf create mode 100644 ssmg/sangoma_mgd.trunk/conf_ss7/woomera_iax.conf delete mode 100644 ssmg/sangoma_mgd.trunk/lib/svn-commit.tmp create mode 100644 ssmg/sangoma_mgd.trunk/sangoma_mgd.conf.sample.bri create mode 100644 ssmg/sangoma_mgd.trunk/sangoma_mgd.conf.sample.ss7 delete mode 100644 ssmg/sangoma_mgd.trunk/svn-commit.tmp create mode 100644 ssmg/sangoma_mgd.trunk/tmp2.26345 delete mode 100644 util/tmp_davidy/wancfg_zaptel-dy.tgz delete mode 100755 util/tmp_davidy/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 delete mode 100644 util/tmp_davidy/wancfg_zaptel/A10u.pm delete mode 100644 util/tmp_davidy/wancfg_zaptel/A10x.pm delete mode 100644 util/tmp_davidy/wancfg_zaptel/A20x.pm delete mode 100644 util/tmp_davidy/wancfg_zaptel/Card.pm delete mode 100644 util/tmp_davidy/wancfg_zaptel/Makefile delete mode 100755 util/tmp_davidy/wancfg_zaptel/clean.sh delete mode 100755 util/tmp_davidy/wancfg_zaptel/install.sh delete mode 100755 util/tmp_davidy/wancfg_zaptel/setup-sangoma delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/smg_bri.conf delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/smgbri_start_script_addon delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/smgbri_stop_script delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.1 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.2 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.3 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.4 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.5 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.ss7.6 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a100/wanpipe.tdmvoiceapi.a100 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.1 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.2 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.3 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.4 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.5 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.ss7.6 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a100 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a10u delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm.a200 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a100 delete mode 100755 util/tmp_davidy/wancfg_zaptel/templates/wanpipe.tdm_api.a500 delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/wanrouter.rc.template delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/wanrouter.rc.template.FreeBSD delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/woomera.conf delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/zapata-auto.conf delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/zapata.conf delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/zaptel.conf delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script delete mode 100644 util/tmp_davidy/wancfg_zaptel/templates/zaptel_cfg_script.FreeBSD delete mode 100755 util/tmp_davidy/wancfg_zaptel/uninstall.sh delete mode 100644 util/tmp_davidy/wancfg_zaptel/wancfg_smg delete mode 100755 util/tmp_davidy/wancfg_zaptel/wancfg_tdmapi delete mode 100755 util/tmp_davidy/wancfg_zaptel/wancfg_zaptel create mode 100644 util/wan_aftup/A101dm_0040_V31.BIN delete mode 100644 util/wan_aftup/A101dm_0040_V34.BIN create mode 100644 util/wan_aftup/A102dm_0040_V31.BIN delete mode 100644 util/wan_aftup/A102dm_0040_V33.BIN create mode 100644 util/wan_aftup/A104d_0100_V24.BIN create mode 100644 util/wan_aftup/A104d_0100_V25.BIN delete mode 100644 util/wan_aftup/A104d_0100_V26.BIN create mode 100644 util/wan_aftup/A104dm_0100_V31.BIN delete mode 100644 util/wan_aftup/A104dm_0100_V33.BIN create mode 100644 util/wan_aftup/A108dm_0100_V31.BIN delete mode 100644 util/wan_aftup/A108dm_0100_V33.BIN create mode 100644 util/wan_aftup/A140_0100_V02.BIN create mode 100644 util/wan_aftup/A140_0100_V03.BIN create mode 100644 util/wan_aftup/A200_0040_V08.BIN delete mode 100644 util/wan_aftup/A200_0040_V11.BIN create mode 100644 util/wan_aftup/A301_0040_V07.BIN create mode 100755 util/wan_aftup/A301_0040_V08.BIN delete mode 100644 util/wan_aftup/A301_0040_V09.BIN delete mode 100644 util/wan_aftup/A301_V05_prod.BIN create mode 100644 util/wan_aftup/A400_0040_V09.BIN delete mode 100644 util/wan_aftup/A400_0040_V11.BIN create mode 100644 util/wan_aftup/A500_0040_V32.BIN delete mode 100755 util/wan_plxctrl/check_plx.sh create mode 100644 util/wancfg/.#menu_hardware_probe.cpp.1.20 create mode 100644 util/wancfg/.zaptel_conf_file_reader.cpp.swp mode change 100644 => 120000 util/wancfg_legacy/Makefile create mode 100644 util/wancfg_legacy/Makefile.BSD create mode 100644 util/wancfg_legacy/Makefile.Linux create mode 100755 util/wancfg_legacy/xupdate delete mode 100755 util/wancfg_zaptel/.#wancfg_zaptel.1.5 delete mode 100755 util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 delete mode 100755 util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 rename util/{tmp_davidy/wancfg_zaptel/A50x.pm => wancfg_zaptel/A50x.pm.old} (88%) rename util/{tmp_davidy/wancfg_zaptel/wancfg_zaptel.pl => wancfg_zaptel/wancfg_zaptel.pl.old} (68%) create mode 100644 util/wanconfig/diff delete mode 100644 util/wanconfig/file create mode 100755 util/wanec_client/.#Makefile.Linux.1.15 mode change 100755 => 120000 util/wanec_client/Makefile create mode 100755 util/wanec_client/Makefile.FreeBSD create mode 100755 util/wanec_client/Makefile.Linux create mode 100755 util/wanec_client/Makefile.OpenBSD create mode 100755 util/wanec_client/Makefile.org create mode 100755 util/wanec_client/Makefile6.FreeBSD create mode 100755 util/wanec_client/Makefile_test delete mode 100644 util/wanpipemon.old/Makefile delete mode 100644 util/wanpipemon.old/aftpipemon.c delete mode 100644 util/wanpipemon.old/aftpipemon.o delete mode 100644 util/wanpipemon.old/atmpipemon.c delete mode 100644 util/wanpipemon.old/atmpipemon.o delete mode 100644 util/wanpipemon.old/bpipemon-old.c delete mode 100644 util/wanpipemon.old/bpipemon.c delete mode 100644 util/wanpipemon.old/bpipemon.o delete mode 100644 util/wanpipemon.old/cpipemon.c delete mode 100644 util/wanpipemon.old/cpipemon.o delete mode 100644 util/wanpipemon.old/diff delete mode 100644 util/wanpipemon.old/docommand.c delete mode 100644 util/wanpipemon.old/dslpipemon.c delete mode 100644 util/wanpipemon.old/dslpipemon.o delete mode 100644 util/wanpipemon.old/fe_lib.c delete mode 100644 util/wanpipemon.old/fe_lib.h delete mode 100644 util/wanpipemon.old/fe_lib.o delete mode 100644 util/wanpipemon.old/fpipemon.c delete mode 100644 util/wanpipemon.old/fpipemon.o delete mode 100644 util/wanpipemon.old/mppipemon.c delete mode 100644 util/wanpipemon.old/ppipemon.c delete mode 100644 util/wanpipemon.old/ppipemon.o delete mode 100644 util/wanpipemon.old/prot_trace.c delete mode 100644 util/wanpipemon.old/prot_trace.o delete mode 100644 util/wanpipemon.old/prot_trace.orig.c delete mode 100644 util/wanpipemon.old/ss7pipemon.c delete mode 100644 util/wanpipemon.old/ss7pipemon.o delete mode 100644 util/wanpipemon.old/wangui.c delete mode 100644 util/wanpipemon.old/wangui.o delete mode 100755 util/wanpipemon.old/wanpipemon delete mode 100644 util/wanpipemon.old/wanpipemon.c delete mode 100644 util/wanpipemon.old/wanpipemon.h delete mode 100644 util/wanpipemon.old/wanpipemon.o delete mode 100644 util/wanpipemon.old/wpkbdmon.c delete mode 100644 util/wanpipemon.old/xml_lib.c delete mode 100644 util/wanpipemon.old/xml_lib.o delete mode 100644 util/wanpipemon.old/xpipemon.c delete mode 100644 util/wanpipemon.old/xpipemon.o delete mode 100644 util/wanpipemon.old/zapmon.c rename util/{wanpipemon.old => wanpipemon}/' (100%) delete mode 100644 util/wanpipemon/isdn.pcap delete mode 100644 util/wanpipemon/trace.pcap create mode 100644 util/wanpipemon/wanpipemon_api.tgz rename util/{wanpipemon.old => wanpipemon}/wp_trace_pcap.bin (100%) delete mode 100644 zaptel/zaptel.patch delete mode 100644 zaptel/zaptel.path diff --git a/ChangeLog.beta b/ChangeLog.beta new file mode 100644 index 0000000..6351887 --- /dev/null +++ b/ChangeLog.beta @@ -0,0 +1,208 @@ +------------------------------------------------------------------------------ +WANPIPE TDM VOICE - IP/WAN Package + +Linux Voice TDM/WAN Router Package +For more info visit: http://wiki.sangoma.com +------------------------------------------------------------------------------ +Author: Nenad Corbic +Copyright (c) 1995-2008 Sangoma Technologies Inc. +------------------------------------------------------------------------------ + +* Wed Feb 12 2008 Nenad Corbic - Beta - 3.3.2 +====================================================================== + +- Support for A500 hardware support with NetBricks BRI Stack +- Major A500 driver updates and fixes +- Serial A142/A144 hardware support +- AFT A056 56K hardware support + +- Support for HW DTMF + +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. + + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands + +- Updated loopback commands for AFT Maxim cards + +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols + +- Updated legacy protocols for new front end architecture + +- + + +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p8 +====================================================================== + +- wancfg_zaptel now asks for the default_tei value for +- BRI cards in TE mode + +- Fix for HWEC not being enabled when non-consecutive modules are using +- in BRI cards + +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p4 +====================================================================== + +- Fixed AFT memory leak + Memory leak introduced in 3.3 release +- Fixed AFT 56K bug + Bug introduced in 3.3 releae + + +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p3 +====================================================================== + +- Fix bug in BRI protocol for fast local hangups. + +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.2.p1 +====================================================================== + +- Bug fix in Hardware EC code for E1. + Bug introduced in 3.3 release. + + +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.1 +==================================================================== + + +* Mon Jan 16 2008 Nenad Corbic - Beta - 3.3.0.22 +==================================================================== + +- BRI protocol:Increased internal timer that could cause issue in systems with +- more than 8 BRI spans + +* Mon Jan 15 2008 Nenad Corbic - Beta - 3.3.0.21 +==================================================================== + +- BRI protocol:Fix for smg_brid daemon crashing on race condition +- BRI protocol:default_tei parameter is not ignored when using point to +- multipoint anymore + +* Mon Jan 14 2008 Nenad Corbic - Beta - 3.3.0.20 +==================================================================== + +- BRI protocol: Additional prefix options. +- BRI protocol: Check is caller ID number is all digits on incoming calls +- Sangoma MGD: Removed dynamic user period causing skb panics +- chan_woomera: Fixed issue with rxgain and txgain values set to 0 if +- coding not set in woomera.conf +- wancfg_zaptel: Support for fractional T1/E1 spans. +- wancfg_zaptel: fix issue BRI always being configured as bri_net introduced in v3.3.0.19 + +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.19 +==================================================================== + +- Support for national/international prefix in BRI stack + +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.18 +==================================================================== + +- Changed Makefile in wanpipe/api/fr causing compilation errors + + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.17 +==================================================================== + +- Fix for smg_ctrl boot script starting before network services on some systems +- Support for language parameter in chan_woomera + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.16 +==================================================================== + +- Fix for Sangoma BRI Daemon crashing on incoming call if chan_woomera is not installed on that system + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.15 +==================================================================== + +- Fix for caller ID value being corrupted sometimes +- Support for call confirmation in chan_woomera + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.14 +==================================================================== + +- Fix in smg_brid not releasing some b-channels properly +- Fix in wancfg_smg not setting MTU to 80 when configuring cards for SS7 + +* Fri Dec 14 2007 Nenad Corbic - Beta - 3.3.0.13 +==================================================================== + +- Fix for Kernel panic on 64-bit systems when enabling hardware echo canceller + + +* Thu Dec 5 2007 Nenad Corbic - Beta - 3.3.0.11 +==================================================================== + +- Support for AFT Serial Cards +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. + + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands + +- Fixed HWEC_PERSIST_DISABLE + This option was broken in previous release + This option lets Asterisk control HWEC + on each call start/stop. + By default all hwec channels are enabled on + device startup. + +- Updated SMG/SS7 +- Updated loopback commands for AFT Maxim cards + +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols + +- Fixed add_timer warnings for ALL AFT cards + Caused when a port is left in unconnected state. + +- Updated legacy protocols for new front end architecture + +- Updated Setup script + + + +* Thu Nov 8 2007 Nenad Corbic - Beta - 3.3.0.4 +==================================================================== + +- Fixed A101/2 (Old) bug introduced in previous releaes + +* Mon Oct 31 2007 Nenad Corbic - Beta - 3.3.0.4 +==================================================================== + +- Updated BRI caller name +- Updaged Setup + + +* Mon Oct 15 2007 Nenad Corbic - Beta - 3.3.0.1 +==================================================================== + +- Major Updates +- New BRI architecture/support + SMG with Netbricks BRI Stack +- Support for Hardware DTMF + + +* Thu Aug 22 2007 Nenad Corbic - Beta - 3.3.0.p3 +====================================================================== + +- Updated wancfg_zaptel to support HW DTMF + + +* Thu Aug 21 2007 Nenad Corbic - Beta - 3.3.0.p2 +====================================================================== + +- Major Updates +- Hardware DTMF for Asterisk and TDM API diff --git a/ChangeLog.stable b/ChangeLog.stable deleted file mode 100644 index 4521ba6..0000000 --- a/ChangeLog.stable +++ /dev/null @@ -1,404 +0,0 @@ ------------------------------------------------------------------------------- -WANPIPE - -Linux Voice TDM/WAN Router Package ------------------------------------------------------------------------------- -Author: Nenad Corbic -Copyright (c) 1995-2008 Sangoma Technologies Inc. ------------------------------------------------------------------------------- - -* Thu Aug 21 2008 Nenad Corbic - Stable - 3.2.7.1 -======================================================================== -- Fixed bug in wancfg_zaptel configuration utility - This bug was introduced in previous release. It will set d-channels - as "dchan" instead of "hardhdlc" for zaptel-1.4.x . - No driver changes. - -* Thu Jul 16 2008 Nenad Corbic - Stable - 3.2.7 -======================================================================== - -- Removed the Excessive Error check that disables the port. - This feature was introduced in 3.2.6 release. - Some lines are extremely noisy on startup which can cause - excessive crc errors (5000 per sec). In this case driver would - take the port down for few sec before bringing it back up in order to - avoid irq overlaod. This release will only print the - warning but will not take any up/down actions. - -- Added support for new PLX2 or TUNDRA PCIe chip. - - -* Thu Jun 4 2008 Nenad Corbic - Stable - 3.2.6 -======================================================================== - -- Updated hwprobe to add A056 card - -- Updated for 2.6.25 kernel - -- wanpipemon PRI/BRI wireshark tracing - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - -- LIP Layer Update - Optimized packet handling in bh - -- Fixed WAN Protocol for 2.6.24 kernels and higher - -- AFT TE1 Code - Defaulted Maxim T1 Rx Level to 36DB - Defaulted Maxim E1 Rx Level to 42DB - This will improve T1/E1 connectivity on noisy or low power lines. - -- Wanpipemon PRI/BRI PCAP Tracing for Wireshark - Using wanpipemon dchan trace one can now capture - pcap files that can be opened by Wireshark. - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - - -- Add pci parity check to wanrouter - wanrouter parity -> displays current system pci parity - wanrouter parity off -> disables system pci parity - wanrouter parity on -> enables system pci parity - - /etc/wanpipe/wanrouter.rc - WAN_PCI_PARITY=OFF -> on wanrouter start disable pci parity - -> event logged in /var/log/wanrouter - - On some servers pci parity can cause NMI interrupts that - can lead to reboots. Parity can be caused by unsuported - or buggy pci/bridge chipsets. The above commands can be used - to combat pci parity reboots. - - Another option is to disable PCI parity in BIOS :) - - - -* Thu Apr 4 2008 Nenad Corbic - Stable - 3.2.5.1 -======================================================================== - -- RTP TAP Bug fix - The driver was sending out invalid rtp tap header - http://wiki.sangoma.com/wanpipe-voice-rtp-tap - - -* Thu Apr 2 2008 Nenad Corbic - Stable - 3.2.5 -======================================================================== - -- T3/E3 Update - Fixed T3 Loopback commands - -- Updated T3/E3 Driver - Performance improvement on T3/E3 drivers when handling - VOIP and Data traffic. - -- Update ifconfig MTU change from protocol interface - - -* Thu Mar 6 2008 Nenad Corbic - Stable - 3.2.4 -======================================================================== - -- Updated for 2.6.24 kernels - TDM Voice (Zaptel) tested with 2.6.24 kernel. - Known issues: WAN protocols are broken for 2.6.24 kernels. - Its a compilation issue that will be fixed ASAP. - -- TDM API bug fix - Check for max frame size on audio stream - -- Updated for Zaptel 1.4.9 - -- AFT IRQ Throttling feature - This feature is use to protect the server from - terrible lines. In some cases a bad hdlc line can - cause thousands of interrupts per sec. Rx errors are now - throttled so that system does not get compromized. - -- AFT RTP TAP Feature - RTP TAP Feature allows user to tap voice channels during - Asterisk-Zaptel/TMD API operation at the driver/kernel level. - Each voice stream is encapsulated in UDP/RTP header and transmitted over - neghbouring ethernet address directly from kenrel space. - Tapping 4E1s worth of voice channels adds estra 2% system load :) - http://wiki.sangoma.com/wanpipe-voice-rtp-tap - -- AFT Software Ring Buffers on A200/A400 Analog Cards - This feature improves analog preformance under Asterisk/TDM API - mode. In particualr it improves faxing reliability and - minimizes frame slippage due to system load or bad incoming - clock from the line. - Note: All AFT T1/E1 cards have this feature in hardare :) - - -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.3 -======================================================================== - -- No changes from 3.2.2 - Version updated for versioning sake. - -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 -======================================================================== - -- AFT Maxim Front end update - Implemented graceful recovery on short circuit. - -- AFT Driver update - Added a check for TDM IRQ timeout. - On some machines its possible for TDM IRQ to timeout. - -- SMG updated - Fixed wancfg_smg - MTU not properly set on ports 2 and up - Voice only ports were not being added to startup sequence - Updated for callweaver - -- Added Zaptel 1.4 HW HDLC Support - No Sangoma zaptel patch needed with Zaptel 1.4 - -- Added HWEC Noise flag in wanpipe config file - -- Updated SMG -- Updated E1 Unframed on Maxim Cards - -- Updates for AFT PMC and MAXIM framers - PMC - lowered LOS sensitivity - Fixes fake up/down state changes on - started inactive lines. - - MAXIM - lowered sensistivy - Fixes cable cross talk on 8 port cards. - - Enabled Unframed E1 - - Enabled Tri-State Mode - - Fixed loopback commands - -- Fixed HWEC_PERSIST_DISABLE - This option was broken in previous release - This option lets Asterisk control HWEC - on each call start/stop. - By default all hwec channels are enabled on - device startup. - -- Updated SMG/SS7 -- Updated loopback commands for AFT Maxim cards - -- Updated for AstLinux - The make file can now build all WAN and Voice Protocols - -- Fixed add_timer warnings for ALL AFT cards - Caused when a port is left in unconnected state. - -- Updated legacy protocols for new front end architecture - -- Updated Setup script - - -* Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 -===================================================================== - -- Setup Zap Chunk Size Patch updated for Zaptel 1.4 - Patch allows running zaptel in 8,16,40,80 chunk size. - However wct drivers must be removed from compilation :) - Patch is now fixed for Zaptel 1.4 - -- Update to All AFT drivers for 64bit 2.6.22 kernel. - Updated affects: AFT A101/2/4/8/200/400 (all cards) - The major 2.6.20+ updates extend to 64bit as well. - Previous drivers segfaulted under 2.6.22 64bit - kernels. This does not affect you if you are running - kennels lower than 2.6.22. - -- Updated legacy drivers for 2.6.22 kernel - - - -* Wed Oct 3 2007 Nenad Corbic - Stable - 3.2.0 -===================================================================== - -- The Beta 3.1.X releases has now been declared as STABLE 3.2.X - -- Fixed AMI/D4 on MAXIM (A101/2/4/8D) cards -- Fixed A200/A400 tip/ring no dial tone issues. -- Fixed 2.6.22 support and above -- Fixed RPM Build post install issue -- Updated Setup install script - Option to build for zaptel: ./Setup zaptel -- Working E&M/RBS/CAS Channel Bank support for MAXIM (A101/2/4/8) cards. -- Fixed wanpipe crashing on system shutdown on some machines. - Caused by RedHat /var/lock/subsys mandatory lock file. -- New Firmware for all MAXIM Cards (A101/2/4/8D) - Firmware V33: Fixes EC Chip Security errors that can cause - PRI to go down on some computers. Firmware is backward compatible - to any previous release. -- Faxes/Modems working through hardware echo canceler. - Tested at 56K from one port to another. - New octasic update. -- Analog Network SYNC Feature for Fax Support - Analog cards can be synced to T1/E1 clock - from adjacent A101/2/4/8 cards for flawless faxing - from FXO/FXS to T1/E1. - -- Known Issues: - T1/E1 High Impedance Tap for MAXIM (A101/2/4/8D) cards. - It works on original PMC A101/2/4 cards - -For more info: http://wiki.sangoma.com - - -* Mon Oct 1 2007 Nenad Corbic - Beta - 3.1.4.6 -==================================================================== - -- Fixed Makefile for 2.6.22.9 kernel. -- Fixed all gcc4 warnings. - - -* Tue Sep 26 2007 Nenad Corbic - Beta - 3.1.4.5 -==================================================================== - -- Updated Setup install script -- A200/A400 Analog driver update - Fixed noise issue introduced in 3.1.4.3 release -- Updated SMG for Asterisk 1.4 & Callweaver - - -* Tue Sep 18 2007 Nenad Corbic - Beta - 3.1.4.3 -==================================================================== - -- A200/A400 Analog driver update - Fixed a problem where analog port starts up without - dialtone. - -* Tue Sep 14 2007 Nenad Corbic - Beta - 3.1.4.2 -==================================================================== - -- Update for 2.6.22 kernel. -- wanrouter startup script update for redhat distros. - Fixes the issue on system shutdown, where wanpipe - module sometimes do not unload due to /var/lock/subsys/ - lockfile check. This issue is only related or RedHat style distros. - - -* Tue Aug 15 2007 Nenad Corbic - Beta - 3.1.4 -==================================================================== - -- Added A101-SH old config support. - So onld A101u or A101c config file can be used with new A101-SH cards. - -- Updated KATM support in the LIP Layer. - Used to connect Kernel ATM Layer to Wanpipe ATM AAL5 layer - over all AFT cards. - -- Added a sanity checker for enabling HWEC. - Used to prevent duble hwec enable. - -- Added wancfg_tdmapi configurator - -- Updated SMG - - -* Mon Jun 30 2007 Nenad Corbic - Beta - 3.1.3 -==================================================================== - -- Update to Ocatsic Hardware Echo Canceler Library - Turned of the NOISE suppression because it can interfere - with faxes. If you faxes did not work properly on 3.1.2 - release they will work fine with this one. - -- Cleaned up the Setup installation script. - - -* Mon Jun 16 2007 Nenad Corbic - Beta - 3.1.2 -==================================================================== - -- Update to Octasic Hardware Echo Canceler library - This is a very important update that affects all AFT cards - with octasic hardware echo canceler. The new octasic update - fixes faxing/modem issues over octasic hwec. The previous - release contained a bug that limited the faxing/modem speeds - to 26k. The new update properly detects fax/modem and works - with full speed of 33k fax and 56k modem. - -- A200/A400 Updated - This update fixes the offhook startup failure. - On startup if fxs is offhook driver will start correctly - -- Wanpipe Startup order changed - The wanpipe startup scripts on bootup were previously - set too early "S03wanrouter". This caused unpredictable - behaviour on some systems. We have now moved wanrouter - startup on boot up to "S11wanrouter", after networking - code. - -- Zaptel Adjustable Chunk Size Feature - Wanpipe drivers can work with 1,2,5 and 10ms - chunk size. Zaptel also supports this, however - the wct4xx driver breaks compilation when chunk - size is changed. ./Setup can how change the - zaptel chunk size for you and update zaptel - Makefiles to remove wct4xx driver out. - - Zaptel with 1ms generates 1000 interrupts per sec - Zaptel with 10ms generates 100 interrupts per sec. - - As you can see its a drastic interrupt performance - increase. - - NOTE: This breaks software echo cancelation, but - its not needed since we have hwec. - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.1 -==================================================================== - -- A101/2/4/8 (MAXIM) AFT Update IMPORTANT - A major bug fix for AFT Maxim E1 cards for E1 CRC4 Mode. - On some lines the E1/CRC4 mode causes line errors on - the telco side which results in PRI not coming up. - - Symptiom: E1 is up (no alarms) on local side but pri is - not coming up! (Only in E1 CRC4 Mode) - -- A101/2/4/8 (MAXIM) Mandatory Firmware Update - An echo canceler bug has been fixed for all AFT - MAXIM Cards A101/2/4/8dm. New firmware version is V31. - If you are running MAXIM cards with hwec wiht older - firmware version you must upgrade. - -- Updated SMG - Fixed DTMF synchronization - - - -- Updated SMG - Fixed DTMF synchronization - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.0.1 -==================================================================== - -- Minor release -- Contains zaptel patch for zaptel 1.2.17 and above. -- No driver changes - -* Fri May 17 2007 Nenad Corbic - Beta - 3.1.0 -==================================================================== - -- Major new BETA wanpipe release - Changed wanpipe versioning: - Release: A.B.C.D - A - Major Relase number - B - Indicates Stable or Beta - Odd number is Beta - Even number is Stable - C - Minor Release number - D - Optional pre-release and custom releases - -- Fixed RBS Support for all Maxim cards A101/2/4/8. - -- Support for 2.6.20 kernels. - -- Support for New: A101D A102D A104D Maxim cards - : -- Support for New: AFT 56K DDS card - -- Redesigned TDM API Events - -- TDM API Analog Support - diff --git a/Makefile b/Makefile index 145ff76..d534e2a 100644 --- a/Makefile +++ b/Makefile @@ -19,29 +19,6 @@ ifndef ZAPDIR ZAPDIR=/usr/src/zaptel endif -#Check if zaptel exists -ifneq (,$(wildcard $(ZAPDIR)/zaptel.h)) - ZAPDIR_PRIV=$(ZAPDIR) - ENABLE_WANPIPEMON_ZAP=YES - EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE - ZAP_OPTS= --zaptel-path=$(ZAPDIR) - ZAP_PROT=TDM -else - ifneq (,$(wildcard $(ZAPDIR)/kernel/zaptel.h)) - ZAPDIR=/usr/src/zaptel/kernel - ZAPDIR_PRIV=$(ZAPDIR) - ENABLE_WANPIPEMON_ZAP=YES - EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE - ZAP_OPTS= --zaptel-path=$(ZAPDIR) - ZAP_PROT=TDM - else - ZAP_OPTS= - ZAP_PROT= - ZAPDIR_PRIV= - ENABLE_WANPIPEMON_ZAP=NO - endif -endif - #Kernel version and location ifndef KVER KVER=$(shell uname -r) @@ -59,6 +36,10 @@ endif ifndef ARCH ARCH=$(shell uname -m) endif +ifndef ASTDIR + ASTDIR=/usr/src/asterisk +endif + INSTALLPREFIX= @@ -84,32 +65,23 @@ EXTRA_UTIL_FLAGS += -I$(PWD)/patches/kdrivers/wanec -I$(PWD)/patches/kdrivers/wa ENABLE_WANPIPEMON_ZAP=NO ZAPHDLC_PRIV=/etc/wanpipe/.zaphdlc -RM = @rm -rf -JUNK = *~ *.bak DEADJOE #Check if zaptel exists -#ifneq (,$(wildcard $(ZAPDIR)/zaptel.h)) -# ZAPDIR_PRIV=$(ZAPDIR) -# ENABLE_WANPIPEMON_ZAP=YES -# EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE -# ZAP_OPTS= --zaptel-path=$(ZAPDIR) -# ZAP_PROT=TDM -#else -# ifneq (,$(wildcard $(ZAPDIR)/kernel/zaptel.h)) -# ZAPDIR=/usr/src/zaptel/kernel -# ZAPDIR_PRIV=$(ZAPDIR) -# ENABLE_WANPIPEMON_ZAP=YES -# EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE -# ZAP_OPTS= --zaptel-path=$(ZAPDIR) -# ZAP_PROT=TDM -# else -# ZAP_OPTS= -# ZAP_PROT= -# ZAPDIR_PRIV= -# ENABLE_WANPIPEMON_ZAP=NO -# endif -#endif +ifneq (,$(wildcard $(ZAPDIR)/zaptel.h)) + ZAPDIR_PRIV=$(ZAPDIR) + ENABLE_WANPIPEMON_ZAP=YES + EXTRA_CFLGS+= -DSTANDALONE_ZAPATA -DBUILDING_TONEZONE + ZAP_OPTS= --zaptel-path=$(ZAPDIR) + ZAP_PROT=TDM +else + ZAP_OPTS= + ZAP_PROT= + ZAPDIR_PRIV= + ENABLE_WANPIPEMON_ZAP=NO +endif +RM = @rm -rf +JUNK = *~ *.bak DEADJOE # First pass, kernel Makefile reads module objects @@ -121,17 +93,13 @@ else #This will check for zaptel, kenrel source and build utilites and kernel modules #within local directory structure +all: _checkzap _checksrc all_bin_kmod all_util -#Build with all binaries -all: _checkzap _checksrc all_bin_kmod all_util - -#Build only source (NO WAN protocols) all_src: _checkzap _checksrc all_kmod all_util - #Build only kernel modules all_kmod: _checkzap _checksrc _cleanoldwanpipe _check_kver - $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KDIR) SUBDIRS=$(WAN_DIR) EXTRA_FLAGS="$(EXTRA_CFLAGS) $(shell cat ./patches/kfeatures)" ZAPDIR=$(ZAPDIR_PRIV) ZAPHDLC=$(ZAPHDLC_PRIV) HOMEDIR=$(PWD) modules + $(MAKE) KBUILD_VERBOSE=$(KBUILD_VERBOSE) -C $(KDIR) SUBDIRS=$(WAN_DIR) EXTRA_FLAGS="$(EXTRA_CFLAGS) $(shell cat ./patches/kfeatures)" ZAPDIR=$(ZAPDIR_PRIV) ZAPHDLC=$(ZAPHDLC_PRIV) HOMEDIR=$(PWD) modules all_bin_kmod: _checkzap _checksrc _cleanoldwanpipe _check_kver @if [ -e $(PWD)/ast_build_dir ]; then \ @@ -183,7 +151,7 @@ _check_kver: _checkzap: @echo @echo " +--------- Wanpipe Build Info --------------+" - @echo + @echo @if [ ! -e $(ZAPDIR)/zaptel.h ]; then \ echo " Compiling Wanpipe without ZAPTEL Support!"; \ ZAPDIR_PRIV=; \ @@ -215,12 +183,12 @@ install_kmod: install -m 644 -D $(WAN_DIR)/sdladrv.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/sdladrv.${MODTYPE} install -m 644 -D $(WAN_DIR)/wanpipe.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe.${MODTYPE} @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE} - @if [ -e $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} ]; then \ + @if [ -f $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} ]; then \ echo "install -m 644 -D $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE}"; \ install -m 644 -D $(WAN_DIR)/wanpipe_syncppp.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/drivers/net/wan/wanpipe_syncppp.${MODTYPE}; \ fi @rm -f $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; - @if [ -e $(WAN_DIR)/wanpipe_lip.${MODTYPE} ]; then \ + @if [ -f $(WAN_DIR)/wanpipe_lip.${MODTYPE} ]; then \ echo "install -m 644 -D $(WAN_DIR)/wanpipe_lip.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}"; \ install -m 644 -D $(WAN_DIR)/wanpipe_lip.${MODTYPE} $(INSTALLPREFIX)/$(KINSTDIR)/net/wanrouter/wanpipe_lip.${MODTYPE}; \ fi @@ -243,6 +211,14 @@ clean_util: install_util: $(MAKE) -C util install SYSINC=$(PWD)/$(WINCLUDE) CC=$(CC) PREFIX=$(INSTALLPREFIX) +install_smgbri: + $(MAKE) -C ssmg/sangoma_mgd.trunk/ install SYSINC=$(PWD)/$(WINCLUDE) CC=$(CC) PREFIX=$(INSTALLPREFIX) + install -D -m 755 ssmg/sangoma_bri/smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl + install -D -m 755 ssmg/sangoma_bri/sangoma_brid $(INSTALLPREFIX)/usr/sbin/sangoma_brid + $(MAKE) -C ssmg/libsangoma.trunk/ install DESTDIR=$(INSTALLPREFIX) + $(MAKE) -C ssmg/sangoma_mgd.trunk/lib/libteletone install DESTDIR=$(INSTALLPREFIX) + + #Install etc files install_etc: @if [ ! -e $(INSTALLPREFIX)/etc/wanpipe ]; then \ @@ -277,3 +253,17 @@ install_inc: @\cp -f $(PWD)/patches/kdrivers/include/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ @\cp -rf $(PWD)/patches/kdrivers/wanec/oct6100_api/include/ $(INSTALLPREFIX)/usr/include/wanpipe/oct6100_api @\cp -rf $(PWD)/patches/kdrivers/wanec/*.h $(INSTALLPREFIX)/usr/include/wanpipe/ + +smgbri: + @cd ssmg/libsangoma.trunk; ./configure --prefix=/usr ; cd ../..; + $(MAKE) -C ssmg/libsangoma.trunk/ CC=$(CC) PREFIX=$(INSTALLPREFIX) KDIR=$(KDIR) + @cd ssmg/sangoma_mgd.trunk/lib/libteletone; ./configure --prefix=/usr ; cd ../../..; + $(MAKE) -C ssmg/sangoma_mgd.trunk/lib/libteletone CC=$(CC) PREFIX=$(INSTALLPREFIX) KDIR=$(KDIR) + $(MAKE) -C ssmg/sangoma_mgd.trunk/ CC=$(CC) PREFIX=$(INSTALLPREFIX) KDIR=$(KDIR) ASTDIR=$(ASTDIR) + + +clean_smgbri: + $(MAKE) -C ssmg/libsangoma.trunk/ clean CC=$(CC) PREFIX=$(INSTALLPREFIX) KDIR=$(KDIR) + $(MAKE) -C ssmg/sangoma_mgd.trunk/lib/libteletone clean CC=$(CC) PREFIX=$(INSTALLPREFIX) KDIR=$(KDIR) + $(MAKE) -C ssmg/sangoma_mgd.trunk/ clean CC=$(CC) PREFIX=$(INSTALLPREFIX) KDIR=$(KDIR) + diff --git a/README-2.config b/README-2.config index b00f7d6..792a91f 100644 --- a/README-2.config +++ b/README-2.config @@ -2,29 +2,31 @@ Wanpipe Configuration ====================== For Latest Info please visit -------------------------------------------------- http://wiki.sangoma.com -------------------------------------------------- -Asterisk/Zaptel Configuration --> /usr/sbin/wancfg_zaptel - -TDM API Config --> /usr/sbin/wancfg_tdmapi - -SMG/SS7 Config --> /usr/sbin/wancfg_smg - -WAN Configuration --> /usr/sbin/wancfg - 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 @@ -38,16 +40,11 @@ the sample configuration files located in Things you should know before starting /usr/sbin/wancfg: - 1. Operatoin Mode: - VOICE : Asterisk/Zaptel, TDM API - WAN/IP: Frame Relay, MultiLink PPP etc.. - - 2. Protocol: - Asterisk/Voice/TDM, + 1. Protocol: Frame Relay, MulitPort Frame Relay, CHDLC, PPP, MultiPort PPP, ADSL, X25 ... - 3. Protocol/IP Info: + 2. Protocol/IP Info: Frame Relay: Type of Status Signaling (LMI, ANSI, or Q.933 Number of DLCI to configure @@ -94,7 +91,7 @@ Things you should know before starting /usr/sbin/wancfg: IP Info: (Not needed for PPPoE) - 4. CSU/DSU Info: + 3. CSU/DSU Info: T1/E1: Encoding Framing diff --git a/README.changes b/README.changes deleted file mode 120000 index 7d3ae4f..0000000 --- a/README.changes +++ /dev/null @@ -1 +0,0 @@ -ChangeLog.stable \ No newline at end of file diff --git a/README.changes b/README.changes new file mode 100644 index 0000000..55a688e --- /dev/null +++ b/README.changes @@ -0,0 +1,87 @@ +WANPIPE OFFICIAL RELEASE CHANGE LOG +=================================== + + +Author: Nenad Corbic + + +Wanpipe Linux Web Page: +------------------- +For latest docs please visit Sangoma Wiki +Sangoma Wiki: http://wiki.sangoma.com + + +MAJOR CHANGES +------------- + + o The 2.3.4 release contains: + + AFT A108 & A108D Drivers. + Updated TDMV Channelized Driver for Asterisk + with support for hardware echo cancellation. + + TDM API Drivers. + Used to create custom TDM applications over + sangoma AFT devices. + + Sangoma Signal Media Gateway: + SS7 Support for Asterisk + + LIP Protocol Layer: + New protocols: ATM (AAL5), Frame Relay EEK + + + o The 2.3.3 release contains: + + AFT A104 TDMV Channelized Driver for Asterisk + The A104 TDMV Driver uses the channelization feature + of the A104 Card, to DMA 8byte chunks directly + into Zaptel buffers. + + AFT A104 TDMV DCHAN Feature + The DCHAN PRI has hardware HDLC support. + + 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 The 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 RE-COMPILATION 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. + diff --git a/Setup b/Setup index 9997c58..9507417 100755 --- a/Setup +++ b/Setup @@ -1,4 +1,4 @@ -#!/bin/bash -p +#!/bin/sh # # Setup WANPIPE WAN Router Installation/Removal Script. # @@ -9,8 +9,9 @@ # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ---------------------------------------------------------------------------- -# May 30, 2008 Jignesh Patel Fixed bootscript installation failure -# Oct 26, 2007 Konrad Hammel Updated minor start script bug +# Mar 12, 2008 Konrad Hammel Updated for Zaptel-1.4.9 (kernel sub-dir) +# Jan 24, 2008 Jignesh Patel Zaptel Patch Update for 1.4.x +# Nov 13, 2007 Konrad Hammel Minor Updates for aesthetics and usability # Nov 27, 2005 David Rokhvarg Added Echo Debugging option # Mar 18, 2002 Nenad Corbic Added BSCSTRM protocol # Mar 01, 2002 Nenad Corbic Added option to split rpm build into @@ -540,13 +541,13 @@ prepare() missing_packages=$missing_packages"libtermcap-devel " fi - echo -n "Checking for bison..." - eval "type bison 2> /dev/null > /dev/null" + echo -n "Checking for yacc..." + eval "type yacc 2> /dev/null > /dev/null" if [ $? -eq 0 ]; then echo "OK" - else - echo "Failed!" - missing_packages=$missing_packages"bison " + else + echo "Failed!" + missing_packages=$missing_packages"yacc " fi echo @@ -601,10 +602,10 @@ prepare() echo -e " Required for Wancfg configuration utility." echo -e " Install flex package (e.g yum install flex)." ;; - bison) - echo -e "\n Bison." + yacc) + echo -e "\n Yacc." echo -e " Required for Wanpipe Utilities." - echo -e " Install bison package (e.g yum install bison)." + echo -e " Install byacc package (e.g yum install byacc)." ;; esac @@ -1275,7 +1276,7 @@ There are two configuration files associated with WANPIPE. - defines interfaces, hardware and protocol information. - this file can be created using the 'wancfg' GUI utility or manually based on sample files located - in $WAN_CONF_DIR/samples. + in /etc/wanpipe/samples. Please read the WanpipeInstallation.(pdf/txt) manual for further information. @@ -1298,7 +1299,7 @@ function get_conf_dir () #banner if test -z $NONINTERACTIVE; then echo -e "\nPlease specify a desired location for ${DISTR_NAME} configuration files." - echo -e "\n\t(Press Enter for Default: $WAN_CONF_DIR)\n" + echo -e "\n\t(Press Enter for Default: /etc/wanpipe)\n" echo -n "" read response @@ -1334,17 +1335,17 @@ function get_bin_dir () #banner if test -z $NONINTERACTIVE; then echo -e "\nPlease specify a location for WANPIPE binary, firmware files." - echo -e "\n\t(Press Enter for Default: $WAN_CONF_DIR/firmware)\n" + echo -e "\n\t(Press Enter for Default: /etc/wanpipe/firmware)\n" echo -n "" read response if [ $response ]; then WAN_FIRMWARE_DIR=$response else - WAN_FIRMWARE_DIR=$WAN_CONF_DIR/firmware + WAN_FIRMWARE_DIR=/etc/wanpipe/firmware fi else - WAN_FIRMWARE_DIR=$WAN_CONF_DIR/firmware + WAN_FIRMWARE_DIR=/etc/wanpipe/firmware fi if [ ! -d $WAN_FIRMWARE_DIR ]; then @@ -1355,7 +1356,7 @@ function get_bin_dir () echo -e "\nERROR: Directory $WAN_FIRMWARE_DIR not found !\n" getyn "Would you like to try again?" if [ $? -ne 0 ]; then - WAN_FIRMWARE_DIR=$WAN_CONF_DIR/firmware + WAN_FIRMWARE_DIR=/etc/wanpipe/firmware else get_bin_dir fi @@ -1368,7 +1369,7 @@ function get_intr_dir () local response=no local response1 - WAN_INTR_DIR=$WAN_CONF_DIR/interfaces + WAN_INTR_DIR=/etc/wanpipe/interfaces if [ ! -d $WAN_INTR_DIR ]; then \mkdir -p $WAN_INTR_DIR @@ -1404,7 +1405,7 @@ function get_intr_dir () echo -n "" read response1 - WAN_INTR_DIR=$WAN_CONF_DIR/interfaces + WAN_INTR_DIR=/etc/wanpipe/interfaces if [ $response1 ]; then WAN_INTR_DIR=$response1 @@ -1418,7 +1419,7 @@ function get_intr_dir () echo -e "\nERROR: Directory $WAN_INTR_DIR not found !\n" getyn "Would you like to try again?" if [ $? -ne 0 ]; then - WAN_INTR_DIR=$WAN_CONF_DIR/interfaces + WAN_INTR_DIR=/etc/wanpipe/interfaces else get_intr_dir fi @@ -1440,7 +1441,7 @@ create_mataconf() elif [ -d /var/adm wanpipe1]; then LOG_FILE=/var/adm/$PROD else - LOG_FILE=$WAN_CONF_DIR/$PROD.log + LOG_FILE=/etc/wanpipe/$PROD.log fi # Select directory for the lock file. @@ -1451,20 +1452,20 @@ create_mataconf() LOCK_FILE=/var/lock/$PROD LOCK_DIR=/var/lock else - LOCK_FILE=$WAN_CONF_DIR/$PROD.lck - LOCK_DIR=$WAN_CONF_DIR + LOCK_FILE=/etc/wanpipe/$PROD.lck + LOCK_DIR=/etc/wanpipe fi - if [ -f $ROOT$WAN_CONF_DIR/wanrouter.rc ]; then - . $ROOT$WAN_CONF_DIR/wanrouter.rc + if [ -f $ROOT/etc/wanpipe/wanrouter.rc ]; then + . /etc/wanpipe/wanrouter.rc fi if [ "$WAN_DEVICES" = "" ]; then WAN_DEVICES="wanpipe1" else echo - echo "Wanpipe META config file found in $WAN_CONF_DIR directory" + echo "Wanpipe META config file found in /etc/wanpipe directory" echo echo "Wanpipe startup sequence: $WAN_DEVICES" echo @@ -1518,11 +1519,11 @@ create_mataconf() fi cat > $META_CONF << ENDOFTEXT -#!/bin/bash +#!/bin/sh # router.rc WAN router meta-configuration file. # # This file defines variables used by the router shell scripts -# and should be located in $WAN_CONF_DIR directory. These are: +# and should be located in /etc/wanpipe directory. These are: # # ROUTER_BOOT = Boot flag (YES/NO). # WAN_CONF_DIR = Where to put wanpipe config files. @@ -1553,13 +1554,13 @@ ENDOFTEXT echo "WAN_LOCK_DIR=$LOCK_DIR" >> $META_CONF echo "WAN_IP_FORWARD=$ENABLE_IP_FWD" >> $META_CONF echo "NEW_IF_TYPE=$NEW_IF_TYPE" >> $META_CONF - echo "WAN_LIB_DIR=$WAN_CONF_DIR/lib" >> $META_CONF - echo "WAN_ADSL_LIST=$WAN_CONF_DIR/wan_adsl.list" >> $META_CONF + echo "WAN_LIB_DIR=/etc/wanpipe/lib" >> $META_CONF + echo "WAN_ADSL_LIST=/etc/wanpipe/wan_adsl.list" >> $META_CONF echo "WAN_ANNEXG_LOAD=$ANNEXG_LOAD" >> $META_CONF echo "WAN_SCTP_LOAD=$SCTP_LOAD" >> $META_CONF echo "WAN_LIP_LOAD=$LIP_LOAD" >> $META_CONF echo "WAN_DYN_WANCONFIG=NO" >> $META_CONF - echo "WAN_SCRIPTS_DIR=$WAN_CONF_DIR/scripts" >> $META_CONF + echo "WAN_SCRIPTS_DIR=/etc/wanpipe/scripts" >> $META_CONF echo "WAN_FIRMWARE_DIR=$WAN_FIRMWARE_DIR" >> $META_CONF echo "WAN_DEVICES_REV_STOP_ORDER=YES" >> $META_CONF echo "WAN_DEVICES=\"$WAN_DEVICES\"" >> $META_CONF @@ -1568,19 +1569,19 @@ ENDOFTEXT } # ---------------------------------------------------------------------------- -# Install initialization scripts. +#Install initialization scripts. # ---------------------------------------------------------------------------- install_init() { - if [ "$PKG_NAME" = "wanpipe-lite" ]; then + if [ "$PKG_NAME" = "wanpipe-lite" ]; then return 0 fi if [ $NO_AUTO_START -eq 1 ]; then return 0; fi - banner + banner cat << ENDOFTEXT WANPIPE BOOTSTRAP CONFIGURATION @@ -1594,35 +1595,35 @@ i.e. By selecting this option WANPIPE will startup on system bootup and stop on system shutdown. ENDOFTEXT - - getyn "Would you like to install WANPIPE start-up scripts?" || return 0 - - cd $PROD_HOME/util/wancfg_zaptel - eval "./wancfg_zaptel.pl --silent --install_boot_script" - - if [ $? -ne 0 ]; then - echo "Failed to install boot scripts" - fi - - if [ "$TDM_PROT" = "YES" ]; then + + getyn "Would you like to install WANPIPE start-up scripts?" || return 0 + + cd $PROD_HOME/util/wancfg_zaptel + eval "./wancfg_zaptel.pl --silent --install_boot_script" + + if [ $? -ne 0 ]; then + echo "Failed to install boot scripts" + fi + + if [ "$TDM_PROT" = "YES" ]; then getyn "Would you like to auto-execute ztcfg after wanrouter start?" || return 0 - if [ ! -d $WAN_CONF_DIR/scripts ]; then - eval "\mkdir -p $WAN_CONF_DIR/scripts >/dev/null 2>/dev/null" + if [ ! -d $ROOT$WAN_CONF_DIR/scripts ]; then + eval "\mkdir -p $ROOT$WAN_CONF_DIR/scripts >/dev/null 2>/dev/null" fi - eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $WAN_CONF_DIR/scripts/start > /dev/null 2> /dev/null" - if [ ! -f $WAN_CONF_DIR/scripts/start ]; then + eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $ROOT$WAN_CONF_DIR/scripts/start > /dev/null 2> /dev/null" + if [ ! -f $ROOT$WAN_CONF_DIR/scripts/start ]; then echo "Error: Could not copy auto-ztcfg script" fi fi - cd $PROD_HOME - + cd $PROD_HOME + } + # ---------------------------------------------------------------------------- # Old Install initialization scripts. # ---------------------------------------------------------------------------- - install_init_old() { if [ "$PKG_NAME" = "wanpipe-lite" ]; then @@ -1695,8 +1696,8 @@ ENDOFTEXT getyn "Would you like to auto-execute ztcfg after wanrouter start?" || return 0 if [ ! -d $WAN_CONF_DIR/scripts ]; then eval "\mkdir -p $WAN_CONF_DIR/scripts >/dev/null 2>/dev/null" - fi - eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $WAN_CONF_DIR/scripts/start > /dev/null 2> /dev/null" + fi + eval "\cp -f $PROD_HOME/samples/wanpipe_zaptel_start $WAN_CONF_DIR/scripts/start >/dev/null 2>/dev/null" if [ ! -f $WAN_CONF_DIR/scripts/start ]; then echo "Error: Could not copy auto-ztcfg script" fi @@ -1757,11 +1758,11 @@ remove() #FIXME: Find a better way of doing this if [ "$PKG_NAME" != "wanpipe-lite" ]; then - if [ -d $WAN_CONF_DIR ]; then - rm -rf $WAN_CONF_DIR + if [ -d /etc/wanpipe ]; then + rm -rf /etc/wanpipe fi else - IFCFG_LIST=`ls $WAN_CONF_DIR/ifcfg-* 2>/dev/null` + IFCFG_LIST=`ls /etc/wanpipe/ifcfg-* 2>/dev/null` for ifcfg in $IFCFG_LIST; do [ -f "$ifcfg" ] && rm -f $ifcfg done @@ -1846,7 +1847,7 @@ WANPIPE utilities are used to: 4) debug line, protocol and driver problems. (/usr/sbin/wanpipemon) 5) aid in WANPIPE API development - ($WAN_CONF_DIR/api) + (/etc/wanpipe/api) Refer to the WanpipeInstallation.(pdf/txt) for more information. @@ -1915,6 +1916,7 @@ WARNING: The Linux source in $SOURCEDIR has not been configured. MAKEINC=$MAKEINC" ENABLE_WANPIPEMON_ZAP=YES " fi eval "make CC=$CC SYSINC=$SOURCEDIR/include WANINCDIR=$WANPIPE_INCLUDE_DIR $MAKEINC >> $CMP_LOG 2>> $CMP_LOG" + #eval "make CC=$CC SYSINC=$DRIVER_INC_DIR WANINCDIR=$WANPIPE_INCLUDE_DIR $MAKEINC >> $CMP_LOG 2>> $CMP_LOG" if [ $? -eq 0 ] then @@ -1922,6 +1924,7 @@ WARNING: The Linux source in $SOURCEDIR has not been configured. else echo echo "make CC=$CC SYSINC=$SOURCEDIR/include $MAKEINC" + echo "make CC=$CC SYSINC=$SOURCEDIR/include $MAKEINC" echo echo -e "Failed!\n" echo -e "\n\t\t!!! ${DISTR_NAME} Tools Compilation Failed !!!" @@ -1996,8 +1999,37 @@ WARNING: The Linux source in $SOURCEDIR has not been configured. if [ $superuser = "YES" ] && [ -z $ROOT ]; then eval "ldconfig > /dev/null 2> /dev/null" - fi + fi + #Default install in /usr/lib no need for additional +# if [ 0 ]; then +# if [ $superuser = "YES" ]; then +# if [ -d /etc/ld.so.conf.d ]; then +# if [ ! -e $ROOT/etc/ld.so.conf.d/ ]; then +# \mkdir -p $ROOT/etc/ld.so.conf.d/ +# fi +# \cp -f libsangoma.so.conf $ROOT/etc/ld.so.conf.d/ +# +# if [ $superuser = "YES" ]; then +# eval "ldconfig" +# fi +# elif [ -f /etc/ld.so.conf ]; then +# if [ $superuser = "YES" ]; then +# cat /etc/ld.so.conf libsangoma.so.conf > ldconf.$$ +# mv ldconf.$$ /etc/ld.so.conf +# eval "ldconfig" +# fi +# else +# echo +# echo "Warning: LD Conf files not found in /etc directory" +# echo "Please add /usr/local/lib to the LD_LIBRARY_PATH" +# echo +# eval "ldconfig" +# pause +# fi +# fi +# fi + echo echo -n "Compiling WANPIPE API Development Utilities ..." @@ -2382,7 +2414,7 @@ function build_wanec_module () local files="wanec_iface wanec_cmd wanec_utils wanec_dev $BTDIR/octapi_bt0 $LARGMATHDIR/octapi_largmath $LLMANDIR/octapi_llman $OCTAPIMIDIR/oct6100_mask_interrupts $OCTAPIDIR/oct6100_adpcm_chan $OCTAPIDIR/oct6100_channel $OCTAPIDIR/oct6100_chip_open $OCTAPIDIR/oct6100_chip_stats $OCTAPIDIR/oct6100_conf_bridge $OCTAPIDIR/oct6100_debug $OCTAPIDIR/oct6100_events $OCTAPIDIR/oct6100_interrupts $OCTAPIDIR/oct6100_memory $OCTAPIDIR/oct6100_miscellaneous $OCTAPIDIR/oct6100_mixer $OCTAPIDIR/oct6100_phasing_tsst $OCTAPIDIR/oct6100_playout_buf $OCTAPIDIR/oct6100_remote_debug $OCTAPIDIR/oct6100_tlv $OCTAPIDIR/oct6100_tone_detection $OCTAPIDIR/oct6100_tsi_cnct $OCTAPIDIR/oct6100_tsst $OCTAPIDIR/oct6100_user " - eval "make SUBDIRS=$PWD clean >> $CMP_BUILD 2>> $CMP_BUILD" + eval "make SUBDIRS=$PWD clean >> $CMP_BUILD 2>> $CMP_BUILD " if [ $KERN_VER -eq 24 ]; then if [ -e wanectmp ]; then @@ -2533,23 +2565,28 @@ function select_compilation_mode() 3. TDM Voice (Zaptel) + WAN Protocol Support -4. SMG (SS7) (Default for Asterisk/CallWeaver SMG/SS7 install) +4. SMG (SS7) (Default for Asterisk SMG/SS7 install) 5. SMG (SS7) + TDM Voice (Zaptel) - Default for: Asterisk/CallWeaver SS7 + PRI + Default for: Asterisk SS7 + PRI -6. TDM API +6. SMG (BRI) (Default for Asterisk SMG/BRI install) + +7. SMG (BRI) + TDM Voice (Zaptel) + Default for: Asterisk BRI + PRI + Analog + +8. TDM API Protocols: TDM API on AFT adapters: Default for: FreeSwitch, Yate, Sunrise Custom voice development -7. Custom Compilation Mode +9. Custom Compilation Mode Specify protocols to be added into the WANPIPE kernel drivers. ENDOFTEXT -echo -n "Please select (1,2,3,4,5,6 or 7) [Default: 1]: " +echo -n "Please select (1,2,3,4,5,6,7,8 or 9) [Default: 1]: " if test -z $NONINTERACTIVE; then @@ -2583,8 +2620,14 @@ if test -z $NONINTERACTIVE; then elif [ "$response" -eq 6 ]; then enable_protocols "AFT_TE1" + SSMG_BRI=YES elif [ "$response" -eq 7 ]; then + enable_protocols "AFT_TE1" + enable_protocols "TDM" + SSMG_BRI=YES + + elif [ "$response" -eq 9 ]; then enable_custom_protocols else select_compilation_mode @@ -3321,35 +3364,20 @@ CFLAGS="$CC -Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__LINUX__ -Dli -e s/s390x/s390/ -e s/parisc64/parisc/ \ -e s/ppc.*/powerpc/ -e s/mips.*/mips/ ) - #New way of checking REGPARM because its enabled - #by default on 2.6.20 kernel and up - if [ $SUBARCH != "" ]; then - if [ -f $SOURCEDIR/arch/$SUBARCH/Makefile ]; then - eval "grep \"CFLAGS.*=.*regparm\" $SOURCEDIR/arch/$SUBARCH/Makefile*" > /dev/null 2> /dev/null - res=$? - elif [ -d $SOURCEDIR/arch/x86 ]; then - eval "grep \"CFLAGS.*=*regparm\" $SOURCEDIR/arch/x86/Makefile*" > /dev/null 2> /dev/null - res=$? - else - echo - echo "Warning: Failed to determine regparm from Makefile defaulting to YES!" - echo - res=0 - fi - if [ $res -eq 0 ]; then - echo -e "Enabled.\n" - REGPARM_OPT=".regparm" - else - echo -e "Disabled.\n" - fi - else - echo - echo "Warning: Failed to determine ARCH: regparm defaulting to YES!" - echo - REGPARM_OPT=".regparm" - echo -e "Enabled.\n" - fi + #New way of checking REGPARM because its enabled + #by default on 2.6.20 kernel and up + if [ $SUBARCH != "" ]; then + eval "grep \"CFLAGS.*=.*-pipe.*regparm\" $SOURCEDIR/arch/$SUBARCH/Makefile" > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + echo -e "Enabled.\n" + REGPARM_OPT=".regparm" + else + echo -e "Disabled.\n" + fi + else + echo -e "Disabled.\n" + fi fi @@ -3441,7 +3469,7 @@ CFLAGS="$CC -Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__LINUX__ -Dli eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_abstr -DKBUILD_MODNAME=wanpipe_lite \ -c -o tmp/wanpipe_abstr.o wanpipe_abstr.c" eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdladrv -DKBUILD_MODNAME=wanpipe_lite \ - -c -o tmp/sdladrv.o sdladrv.c sdladrv_fe.c" + -c -o tmp/sdladrv.o sdladrv.c sdladrv_fe.c sdladrv_utils.c" eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_xilinx -DKBUILD_MODNAME=wanpipe_lite \ -c -o tmp/sdla_xilinx.o sdla_xilinx.c" eval "$CFLAGS $PROTOCOL_DEFINES -DKBUILD_BASENAME=sdla_aft_te1 -DKBUILD_MODNAME=wanpipe_lite \ @@ -3491,7 +3519,7 @@ CFLAGS="$CC -Wp,-MD,.wanpipe.o.d -nostdinc -iwithprefix include -D__LINUX__ -Dli cat < $PROD_HOME/Compile_Setup.sh -#!/bin/bash +#!/bin/sh if [ -e kdrvcmp ]; then rm -rf kdrvcmp @@ -3525,7 +3553,7 @@ ENDOFTEXT tmp=${CFLAGS/$CC/} cat < $PROD_HOME/Compile.sh -#!/bin/bash +#!/bin/sh make CFLAGS="$tmp" PROTOCOL_DEFINES="$PROTOCOL_DEFINES" @@ -3542,7 +3570,7 @@ WANPIPE_OBJS= rm -f sdladrv_src.c ln -s sdladrv.c sdladrv_src.c - build_kernel_module sdladrv "sdladrv_src sdladrv_fe" + build_kernel_module sdladrv "sdladrv_src sdladrv_fe sdladrv_utils" build_kernel_module wanrouter "wanmain wanproc waniface" @@ -3737,7 +3765,8 @@ WANPIPE_OBJS= if [ "$TDM_PROT" = "YES" ]; then \cp $DRIVER_UPDATE_DIR/src/net/sdla_tdmv.c . \cp $DRIVER_UPDATE_DIR/src/net/sdla_remora_tdmv.c . - WANPIPE_OBJS=$WANPIPE_OBJS"sdla_tdmv sdla_remora_tdmv " + \cp $DRIVER_UPDATE_DIR/src/net/sdla_bri_tdmv.c . + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_tdmv sdla_remora_tdmv sdla_bri_tdmv " WANPIPE_EXTRA_CFLAGS=$WANPIPE_EXTRA_CFLAGS"-I$ZAPTEL_SOURCE_DIR " fi @@ -3745,6 +3774,14 @@ WANPIPE_OBJS= WANPIPE_OBJS=$WANPIPE_OBJS"sdla_xilinx sdla_aft_te1 aft_a104 sdla_remora aft_analog " fi + if [ "$AFT_BRI_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_bri aft_bri " + fi + + if [ "$AFT_SERIAL_PROT" = "YES" ]; then + WANPIPE_OBJS=$WANPIPE_OBJS"sdla_serial " + fi + if [ "$AFT_TE3_PROT" = "YES" ]; then WANPIPE_OBJS=$WANPIPE_OBJS"sdla_aft_te3 " fi @@ -4159,7 +4196,7 @@ WANPIPE_OBJS= cat < $CMP_INSTALL -#!/bin/bash +#!/bin/sh mv *.ko mod/ > /dev/null 2> /dev/null @@ -4204,7 +4241,7 @@ ENDOFTEXT chmod 755 $CMP_INSTALL cat < .clean.$$ -#!/bin/bash +#!/bin/sh rm -f *.ko rm -f tmp/*.*o @@ -4371,7 +4408,7 @@ function install_chan_woomera() if [ "$install_failures" = "" ]; then echo - echo "Installatoin Complete" + echo "Installation Complete" echo else echo @@ -4389,6 +4426,63 @@ function install_chan_woomera() return 0 } +function install_ssmg_bri() +{ + + if [ $SSMG_BRI != "YES" ]; then + return 0 + fi + + SSMG="YES" + eval "install_ssmg" + if [ $? -ne 0 ]; then + echo "-------------------------------------" + echo "Error: SMG Libraries Failed to install" + echo "Please Contact Sangoma Support!" + echo "-------------------------------------" + exit 1; + fi + echo + + cd $PROD_HOME/$SSMG_DIR + cd sangoma_mgd.trunk + + echo "Installing SMG Daemon..." + echo + if [ -z $ROOT ]; then + eval "./install -noss7" + else + eval "./install -noss7 -rootdir $ROOT" + fi + if [ $? -ne 0 ]; then + echo "-------------------------------------" + echo "Error: SMG Failed to install" + echo "Please Contact Sangoma Support!" + echo "-------------------------------------" + exit 1; + fi + echo + + cd $PROD_HOME/$SSMG_DIR + cd sangoma_bri + echo + echo "Installing SMG BRI Daemon..." + eval "make INSTALLPREFIX=$ROOT install > /dev/null " + + echo + echo "----------------------------------------" + echo "Sangoma BRI Installation Complete" + echo + echo " -> To configure for BRI run:" + echo " -> /usr/bin/wancfg_smg" + echo + echo "----------------------------------------" + echo + install_smg_samples_bri + pause +} + + function install_ssmg () { if [ "$SSMG" != "YES" ]; then @@ -4399,35 +4493,16 @@ function install_ssmg () banner - echo "Installing LibSangoma Library..." - - cd libsangoma.trunk - eval "./configure; make clean; make; make install" > /dev/null - if [ $? -ne 0 ]; then - echo "FAILED" - return 1 - fi - - if [ -d /etc/ld.so.conf.d ]; then - \cp -f libsangoma.so.conf /etc/ld.so.conf.d/ - eval "ldconfig" - elif [ -f /etc/ld.so.conf ]; then - cat /etc/ld.so.conf libsangoma.so.conf > ldconf.$$ - mv ldconf.$$ /etc/ld.so.conf - eval "ldconfig" - else - echo "Warning: LD Conf files not found in /etc directory" - echo "Please add /usr/local/lib to the LD_LIBRARY_PATH" - echo - pause - fi - - echo "Installing LibSangoma Library...DONE" - echo - cd $PROD_HOME/$SSMG_DIR cd sangoma_mgd.trunk + if [ $superuser = "YES" ] && [ -z $ROOT ]; then + eval "find /usr/local/lib -name 'libteletone*' > /dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + eval "find /usr/local/lib -name 'libteletone*' | xargs rm > /dev/null 2>/dev/null" + fi + fi + echo "Installing Sangoma Media Gateway Daemon..." cd lib/libteletone/ eval "./configure --prefix=$ROOT/usr; make clean; make CC=$CC; make install " > /dev/null @@ -4435,24 +4510,29 @@ function install_ssmg () echo "FAILED" return 1 fi - if [ $superuser = "YES" ]; then eval "ldconfig" fi - cd $PROD_HOME/$SSMG_DIR - cd sangoma_mgd.trunk + if [ $SSMG_BRI != "YES" ]; then + install_smg_samples_ss7 + fi +} + +function install_smg_samples_bri() +{ getyn "Add Woomera config in Asterisk Extensions and Iax Conf" if [ $? -ne 0 ]; then return 0; fi - + cd $PROD_HOME/$SSMG_DIR + cd sangoma_mgd.trunk if [ -f $ROOT/etc/asterisk/extensions.conf ]; then - eval "grep -i woomera $ROOT/etc/asterisk/extensions.conf 2> /dev/null > /dev/null" + eval "grep -i outb-bri $ROOT/etc/asterisk/extensions.conf 2> /dev/null > /dev/null" if [ $? -ne 0 ]; then - cat $ROOT/etc/asterisk/extensions.conf ./conf/woomera_ext.conf > conf.$$ + cat $ROOT/etc/asterisk/extensions.conf ./conf_bri/woomera_ext.conf > conf.$$ mv conf.$$ $ROOT/etc/asterisk/extensions.conf echo "Asterisk extensions.conf file updated with woomera config" else @@ -4462,9 +4542,47 @@ function install_ssmg () fi if [ -f $ROOT/etc/asterisk/iax.conf ]; then - eval "grep -i ss7 $ROOT/etc/asterisk/iax.conf 2> /dev/null > /dev/null" + eval "grep -i outb-bri $ROOT/etc/asterisk/iax.conf 2> /dev/null > /dev/null" if [ $? -ne 0 ]; then - cat $ROOT/etc/asterisk/iax.conf ./conf/woomera_iax.conf > conf.$$ + cat $ROOT/etc/asterisk/iax.conf ./conf_bri/woomera_iax.conf > conf.$$ + mv conf.$$ $ROOT/etc/asterisk/iax.conf + echo "Asterisk iax.conf file updated with bri guest config" + else + echo "Asterisk iax.conf already updated" + fi + fi + + pause + + return 0 +} + + + +function install_smg_samples_ss7() +{ + cd $PROD_HOME/$SSMG_DIR + cd sangoma_mgd.trunk + getyn "Add Woomera config in Asterisk Extensions and Iax Conf" + if [ $? -ne 0 ]; then + return 0; + fi + if [ -f $ROOT/etc/asterisk/extensions.conf ]; then + eval "grep -i outb-ss7 $ROOT/etc/asterisk/extensions.conf 2> /dev/null > /dev/null" + if [ $? -ne 0 ]; then + cat $ROOT/etc/asterisk/extensions.conf ./conf_ss7/woomera_ext.conf > conf.$$ + mv conf.$$ $ROOT/etc/asterisk/extensions.conf + echo "Asterisk extensions.conf file updated with woomera config" + else + echo "Asterisk extensions.conf already updated" + + fi + fi + + if [ -f $ROOT/etc/asterisk/iax.conf ]; then + eval "grep -i outb-ss7 $ROOT/etc/asterisk/iax.conf 2> /dev/null > /dev/null" + if [ $? -ne 0 ]; then + cat $ROOT/etc/asterisk/iax.conf ./conf_ss7/woomera_iax.conf > conf.$$ mv conf.$$ $ROOT/etc/asterisk/iax.conf echo "Asterisk iax.conf file updated with ss7 guest config" else @@ -4472,7 +4590,6 @@ function install_ssmg () fi fi - pause return 0 @@ -4494,7 +4611,7 @@ function install_all () if [ "$PKG_NAME" = "wanpipe-lite" ]; then cd $PROD_HOME - \cp -rf samples $ROOT$WAN_CONF_DIR + \cp -rf samples $ROOT/etc/wanpipe install -D -m 755 $PROD_HOME/scripts/wanlite $ROOT/usr/sbin/wanlite pause return 0 @@ -4505,20 +4622,20 @@ function install_all () cd $PROD_HOME/util/misc make install WAN_VIRTUAL=$ROOT > /dev/null 2> /dev/null - echo "Installing wanrouter.rc in $ROOT$WAN_CONF_DIR" + echo "Installing wanrouter.rc in $ROOT/etc/wanpipe" cd $PROD_HOME - install -D -m 644 wanrouter.rc $ROOT$WAN_CONF_DIR/wanrouter.rc + install -D -m 644 wanrouter.rc $ROOT/etc/wanpipe/wanrouter.rc - echo "Installing wanpipe libraries in $ROOT$WAN_CONF_DIR" + echo "Installing wanpipe libraries in $ROOT/etc/wanpipe" - \mkdir -p $ROOT$WAN_CONF_DIR/lib/ - \cp -f $PROD_HOME/util/wancfg_legacy/lib/* $ROOT$WAN_CONF_DIR/lib/ + \mkdir -p $ROOT/etc/wanpipe/lib/ + \cp -f $PROD_HOME/util/wancfg_legacy/lib/* $ROOT/etc/wanpipe/lib/ - echo "Installing firmware in $ROOT$WAN_CONF_DIR/firmware" - \cp -rf firmware $ROOT$WAN_CONF_DIR/ + echo "Installing firmware in $ROOT/etc/wanpipe/firmware" + \cp -rf firmware $ROOT/etc/wanpipe/ - if [ ! -f $ROOT$WAN_CONF_DIR/interfaces ]; then - \mkdir -p $ROOT$WAN_CONF_DIR/interfaces + if [ ! -f $ROOT/etc/wanpipe/interfaces ]; then + \mkdir -p $ROOT/etc/wanpipe/interfaces fi echo "Installing documentation in $ROOT/usr/share/doc/wanpipe" @@ -4528,10 +4645,9 @@ function install_all () \cp -f doc/* $ROOT/usr/share/doc/wanpipe \cp -f README* $ROOT/usr/share/doc/wanpipe - echo "Installing sample api code in $ROOT$WAN_CONF_DIR/api" - \cp -rf api $ROOT$WAN_CONF_DIR - \cp -rf samples $ROOT$WAN_CONF_DIR - + echo "Installing sample api code in $ROOT/etc/wanpipe/api" + \cp -rf api $ROOT/etc/wanpipe + \cp -rf samples $ROOT/etc/wanpipe echo "Installing AFT Firmware update utility in $ROOT$WAN_CONF_DIR/util" \cp -rf util/wanec_apilib/ $ROOT$WAN_CONF_DIR/util @@ -4543,22 +4659,20 @@ function install_all () fi \ln -s ../util/wan_aftup wan_aftup - cd $PROD_HOME - - if [ ! -d $ROOT$WAN_CONF_DIR/scripts ]; then - \mkdir -p $ROOT$WAN_CONF_DIR/scripts + if [ ! -d $ROOT/etc/wanpipe/scripts ]; then + \mkdir -p $ROOT/etc/wanpipe/scripts fi - echo "Installing driver headers in $ROOT$WAN_CONF_DIR/api/include/linux" - if [ ! -d $ROOT$WAN_CONF_DIR/api/include/linux ]; then - \mkdir -p $ROOT$WAN_CONF_DIR/api/include/linux + echo "Installing driver headers in $ROOT/etc/wanpipe/api/include/linux" + if [ ! -d $ROOT/etc/wanpipe/api/include/linux ]; then + \mkdir -p $ROOT/etc/wanpipe/api/include/linux fi cd $PROD_HOME if [ -d wan_ec ]; then - cp -rf wan_ec $ROOT$WAN_CONF_DIR + cp -rf wan_ec $ROOT/etc/wanpipe echo "Installing Hardware Echo Cancel Utilites" cd util/wanec_client make install WAN_VIRTUAL=$ROOT > /dev/null 2> /dev/null @@ -4573,11 +4687,11 @@ function install_all () cd $PROD_HOME - if [ ! -f $ROOT$WAN_CONF_DIR/api/include/linux/ ]; then - \mkdir -p $ROOT$WAN_CONF_DIR/api/include/linux/ + if [ ! -f $ROOT/etc/wanpipe/api/include/linux/ ]; then + \mkdir -p $ROOT/etc/wanpipe/api/include/linux/ fi - \cp -f $DRIVER_UPDATE_DIR/include/*.* $ROOT$WAN_CONF_DIR/api/include/linux/ + \cp -f $DRIVER_UPDATE_DIR/include/*.* $ROOT/etc/wanpipe/api/include/linux/ pause return 0 @@ -4601,7 +4715,7 @@ function uninstall_all () cd $PROD_HOME rm -f $ROOT/usr/sbin/wp_pppconfig rm -rf $ROOT/usr/doc/wanpipe - rm -rf $ROOT/$WAN_CONF_DIR + rm -rf $ROOT/etc/wanpipe pause return 0 @@ -4857,53 +4971,48 @@ search_and_replace() } function tdmv_get_zaptel_path () { + if [ $ZAPTEL_PATH_OP != "YES" ]; then find_zap_dirs fi - if [ 0 ]; then - if [ $ZAPTEL_PATH_OP != "YES" ]; then - echo - echo -e "\nPlease specify absolute path to Zaptel source directory" - echo -e "\n[default:$ZAPTEL_SOURCE_DIR]\n" - echo -n " " - if [ ! -d $ZAPTEL_SOURCE_DIR ]; then - echo -e "Warning: $ZAPTEL_SOURCE_DIR does not exist\n" - fi - if test -z $NONINTERACTIVE; then - read response - - [ $response ] && { - ZAPTEL_SOURCE_DIR=$response - } - fi - fi - - #Check if this post Zaptel-1.4.9 - if [ -d $ZAPTEL_SOURCE_DIR/kernel ]; then - ZAPTEL_INSTALL_DIR=$ZAPTEL_SOURCE_DIR - ZAPTEL_SOURCE_DIR=$ZAPTEL_SOURCE_DIR/kernel - else - if [ -z $ZAPTEL_INSTALL_DIR ]; then - ZAPTEL_INSTALL_DIR=$ZAPTEL_SOURCE_DIR - fi +if [ 0 ]; then + if [ $ZAPTEL_PATH_OP != "YES" ]; then + echo + echo -e "\nPlease specify absolute path to Zaptel source directory" + echo -e "\n[default:$ZAPTEL_INSTALL_DIR]\n" + echo -n " " + if [ ! -d $ZAPTEL_INSTALL_DIR ]; then + echo -e "Warning: $ZAPTEL_INSTALL_DIR does not exist\n" fi - - if [ ! -f $ZAPTEL_SOURCE_DIR/zaptel.h ]; then - echo " Zaptel source not found in $ZAPTEL_INSTALL_DIR" - ZAPTEL_SOURCE_DIR="/usr/src/zaptel" - ZAPTEL_INSTALL_DIR=$ZAPTEL_SOURCE_DIR - if test $NONINTERACTIVE; then - return 1 - else - getyn " Press Y to specify another Zaptel source directory, N to exit" - if [ $? -ne 0 ]; then - exit 1; - fi - tdmv_get_zaptel_path - fi - fi - fi + if test -z $NONINTERACTIVE; then + read response + + [ $response ] && { + ZAPTEL_INSTALL_DIR=$response + if [ -d $ZAPTEL_INSTALL_DIR/kernel ]; then + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR/kernel + else + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR + fi + } + fi + fi + if [ ! -f $ZAPTEL_SOURCE_DIR/zaptel.h ]; then + echo " Zaptel source not found in $ZAPTEL_SOURCE_DIR" + ZAPTEL_SOURCE_DIR="/usr/src/zaptel" + ZAPTEL_INSTALL_DIR=$ZAPTEL_SOURCE_DIR + if test $NONINTERACTIVE; then + return 1 + else + getyn " Press Y to specify another Zaptel source directory, N to exit" + if [ $? -ne 0 ]; then + exit 1; + fi + tdmv_get_zaptel_path + fi + fi +fi #zaptel.c renamed to zaptel-base.c in zaptel v1.2.13 and later if [ -e $ZAPTEL_SOURCE_DIR/zaptel-base.c ]; then ZAPTEL_C_FILE="zaptel-base.c"; @@ -4986,8 +5095,8 @@ function tdmv_apply_zaptel_dchan_patch_old () function tdmv_apply_zaptel_chunk_patch () { lhome=`pwd` TEMP=tmp - cd $ZAPTEL_SOURCE_DIR - echo "Applying Zaptel Chunk patch..." + cd $ZAPTEL_SOURCE_DIR + echo "Applying Zaptel Chunk patch..." echo " " #modify zaptel.h eval "cat zaptel.h | sed '/^#define ZT_CHUNKSIZE/c\#define ZT_CHUNKSIZE $ZAP_CHUNK' >$TEMP 2>/dev/null" @@ -5005,7 +5114,6 @@ function tdmv_apply_zaptel_chunk_patch () { fi fi - cd $ZAPTEL_INSTALL_DIR #remove wct4xxp module from Makefile eval "cat Makefile |sed 's/wct1xxp wct4xxp wcte11xp/wct1xxp wcte11xp/g'>$TEMP 2>/dev/null " if [ $? -ne 0 ]; then @@ -5022,6 +5130,7 @@ function tdmv_apply_zaptel_chunk_patch () { fi fi + cd $ZAPTEL_INSTALL_DIR eval "cat Makefile |sed 's/^SUBDIR_MODULES:=.*//g'>$TEMP 2>/dev/null " if [ $? -ne 0 ]; then echo " Failed to remove wct4xxp from Makefile" @@ -5418,12 +5527,11 @@ function find_zap_dirs () echo echo "Looking for zaptel directory in /usr/src ..." echo "-------------------------------------------" - if [ "$zapdirs" = "" ]; then zapdirs=`find /usr/src -maxdepth 2 -name 'zaptel*' | xargs ` - if [ -d "/usr/src/zaptel" ]; then - zapdirs="/usr/src/zaptel "$zapdirs - fi + if [ -d "/usr/src/zaptel" ]; then + zapdirs="/usr/src/zaptel "$zapdirs + fi fi @@ -5432,6 +5540,7 @@ function find_zap_dirs () if [ -f $PROD_HOME/zaptel/zaptel.path ]; then zapextradir=`cat $PROD_HOME/zaptel/zaptel.path` fi + cnt=1 for dir in $zapdirs do @@ -5439,21 +5548,21 @@ function find_zap_dirs () continue fi - if [ ! -f $dir/zaptel.h ] && [ ! -f $dir/kernel/zaptel.h ];then + if [ ! -f $dir/zaptel.h ] && [ ! -f $dir/kernel/zaptel.h ]; then continue; fi - + if [ "$dir" = "/usr/src/zaptel" ] && [ $cnt -ne 1 ]; then - continue; - fi + continue; + fi + zapdir_array[$cnt]=$dir; echo "$cnt : $dir " cnt=$((cnt+1)) done - if [ $cnt -eq 1 ]; then echo echo "No zaptel dirs found in /usr/src " @@ -5468,7 +5577,7 @@ function find_zap_dirs () continue fi - if [ ! -f $dir/zaptel.h ]; then + if [ ! -f $dir/zaptel.h ] && [ ! -f $dir/kernel/zaptel.h ]; then continue; fi @@ -5487,7 +5596,6 @@ function find_zap_dirs () echo "(ctrl-c to Exit)" echo -n "Please select working zaptel directory [1-$((cnt-1))][m]: " - response=1 if [ -z $NONINTERACTIVE ] || [ $zaptel_auto_install = "YES" ]; then @@ -5503,9 +5611,9 @@ function find_zap_dirs () read response if [ "$response" = "" ]; then - ZAPTEL_SOURCE_DIR=$ZAPTEL_DFLT_INSTALL_DIR + ZAPTEL_INSTALL_DIR=$ZAPTEL_DFLT_INSTALL_DIR else - ZAPTEL_SOURCE_DIR=$response + ZAPTEL_INSTALL_DIR=$response fi zapdir_manual=1 @@ -5515,19 +5623,18 @@ function find_zap_dirs () # return 1; elif [ $response -gt 0 ] && [ $response -lt $cnt ]; then - ZAPTEL_SOURCE_DIR=${zapdir_array[$response]} + ZAPTEL_INSTALL_DIR=${zapdir_array[$response]} else find_zap_dirs_invalid "$zapdirs" fi - #Check if this post Zaptel-1.4.9 - if [ -d $ZAPTEL_SOURCE_DIR/kernel ]; then - ZAPTEL_INSTALL_DIR=$ZAPTEL_SOURCE_DIR - ZAPTEL_SOURCE_DIR=$ZAPTEL_SOURCE_DIR/kernel + #Check if this is post Zaptel-1.4.9 + if [ -d $ZAPTEL_INSTALL_DIR/kernel ]; then + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR/kernel else - ZAPTEL_INSTALL_DIR=$ZAPTEL_SOURCE_DIR + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR fi - + if [ ! -f $ZAPTEL_SOURCE_DIR/zaptel.h ]; then echo echo "Error: zaptel.h not found in $ZAPTEL_SOURCE_DIR" @@ -5540,14 +5647,14 @@ function find_zap_dirs () fi if [ $find_zap_dir_quit -eq 1 ] ; then - ZAPTEL_SOURCE_DIR=$ZAPTEL_DFLT_INSTALL_DIR + ZAPTEL_INSTALL_DIR=$ZAPTEL_DFLT_INSTALL_DIR return 1 fi if [ $zapdir_manual -eq 1 ]; then - eval "grep \"$ZAPTEL_SOURCE_DIR\" $PROD_HOME/zaptel/zaptel.path 2> /dev/null > /dev/null " + eval "grep \"$ZAPTEL_INSTALL_DIR\" $PROD_HOME/zaptel/zaptel.path 2> /dev/null > /dev/null " if [ $? -ne 0 ]; then - echo "$ZAPTEL_SOURCE_DIR" >> $PROD_HOME/zaptel/zaptel.path + echo "$ZAPTEL_INSTALL_DIR" >> $PROD_HOME/zaptel/zaptel.path fi fi @@ -5559,6 +5666,7 @@ function find_zap_dirs () if [ -e $ZAPTEL_SOURCE_DIR/zaptel-base.c ]; then ZAPTEL_C_FILE="zaptel-base.c"; fi + return 0; } @@ -5598,6 +5706,13 @@ function enable_protocols () ARG=${2:-NO} + echo "$PROTOCOL" | grep "BRI" > /dev/null + if [ $? -eq 0 ]; then + echo "Enabling the AFT BRI SMG Support" + SSMG_BRI="YES" + PROT_MATCH=YES + fi + echo "$PROTOCOL" | grep "FR" > /dev/null if [ $? -eq 0 ]; then if [ $FR_PROT != YES ]; then @@ -5838,9 +5953,11 @@ ENDOFTEXT if [ $? -eq 0 ]; then if [ $AFT_TE1_PROT != YES ]; then echo "Enabling the AFT TE1 Support" - PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_CODEC_SLINEAR_LAW" + PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_CORE -DCONFIG_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_AFT_56K -DCONFIG_PRODUCT_WANPIPE_AFT_RM -DCONFIG_PRODUCT_WANPIPE_CODEC_SLINEAR_LAW -DCONFIG_PRODUCT_WANPIPE_AFT_BRI -DCONFIG_PRODUCT_WANPIPE_AFT_SERIAL " fi AFT_TE1_PROT=YES + AFT_BRI_PROT=YES + AFT_SERIAL_PROT=YES PROT_MATCH=YES fi @@ -5873,7 +5990,7 @@ ENDOFTEXT echo "$PROTOCOL" | grep "TDM" > /dev/null if [ $? -eq 0 ]; then tdmv_get_zaptel_path - if [ $? -eq 0 ]; then + if [ $? -eq 0 ]; then ZAP_MOD_DIR=/lib/modules/$(uname -r) if [ $KERN_VER -eq 24 ]; then @@ -5915,29 +6032,25 @@ ENDOFTEXT if [ $TDM_PROT != YES ]; then echo "Enabling the TDM Voice Asterisk Support" PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE " - ASTERISK_IFLAGS="-I$ZAPTEL_SOURCE_DIR" + ASTERISK_IFLAGS="-I$ZAPTEL_INSTALL_DIR" WANCFG_ZAPTEL_CFG=YES fi - #Check for new zaptel hw hdlc option if [ -f $ZAPTEL_SOURCE_DIR/zaptel-base.c ]; then eval "grep hdlc_hard_xmit $ZAPTEL_SOURCE_DIR/zaptel-base.c > /dev/null 2> /dev/null" if [ $? -eq 0 ] ; then - echo + echo " " + echo "Zaptel HW HDLC Support Detected: Enabling DCHAN Feature" echo "Native Zaptel HW HDLC Support Detected - No patch required" - echo "Zaptel source unmodified, no zaptel re-compilation needed!" - echo - pause + echo "Zaptel source unmodified" + echo " " - echo - echo - TDM_DCHAN="(DCHAN)" PROTOCOL_DEFINES="$PROTOCOL_DEFINES -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL " fi fi - + #Check if dchan patch is already enabled if [ "$TDM_DCHAN" = "" ]; then eval "grep ZT_DCHAN_TX_V2 $ZAPTEL_SOURCE_DIR/* 2> /dev/null > /dev/null" @@ -5949,6 +6062,7 @@ ENDOFTEXT fi fi + #If DCHAN patch is not enabled give option to enable it if [ "$TDM_DCHAN" = "" ]; then echo echo @@ -5966,8 +6080,8 @@ ENDOFTEXT zaptel_modified=1 elif [ $result -eq 1 ]; then TDM_DCHAN="(DCHAN)" - echo zaptel_modified=1 + echo else echo "Zaptel Update Failed!" echo @@ -5983,7 +6097,7 @@ ENDOFTEXT fi fi if [ $ZAP_CHUNK_OP == "YES" ] ; then - tdmv_apply_zaptel_chunk_patch + tdmv_apply_zaptel_chunk_patch fi #################################################################### @@ -6062,7 +6176,6 @@ ENDOFTEXT fi fi tdmv_check_zaptel_udev - echo fi fi PROT_MATCH=YES @@ -6155,7 +6268,11 @@ PPP_PROT=NO CHDLC_PROT=NO X25_PROT=NO AFT_TE1_PROT=NO +AFT_BRI_PROT=NO +AFT_SERIAL_PROT=NO AFT_TE3_PROT=NO +SSMG=NO +SSMG_BRI=NO WAN_FRM_UPDATE_DRIVER=YES @@ -6221,6 +6338,29 @@ function detect_rpm_build_utility() fi } +function compile_aft_firmware_util() +{ + lhome=`pwd` + \cp -f $PROD_HOME/util/wan_aftup $PROD_HOME/rpmbuild/etc/wanpipe/firmware/ -r + + cd $PROD_HOME/rpmbuild/etc/wanpipe/firmware/wan_aftup + echo "Compiling firmware update utilities..." + eval "make wan_aftup" >/dev/null 2>/dev/null + if [ ! $? -eq 0 ]; then + echo "failed" + exit + else + echo "done" + fi + + + \rm -f *.c + \rm -f *.o + \rm -f *.h + \rm -f Makefile + cd $lhome +} + function usage() { if [ "$PKG_NAME" != "wanpipe-lite" ]; then @@ -6357,12 +6497,12 @@ KERNEL_UNAME=`uname -r` PKG_NAME=wanpipe DISTR_NAME="WANPIPE" PROD=wanrouter -PROD_VER=3.2.7.1 +PROD_VER=3.3.2 PROD_HOME=`pwd` -WAN_CONF_DIR=/etc/wanpipe -META_CONF=$PROD_HOME/$PROD.rc +META_CONF=$PROD_HOME/$PROD.rc WAN_INTR_DIR=$PROD_HOME/interfaces -PROD_CONF=$WAN_CONF_DIR/wanpipe1.conf +WAN_CONF_DIR=/etc/wanpipe +PROD_CONF=$PROD_HOME/wanpipe1.conf PROD_PATCH=$PROD_HOME/patches PROD_INIT=/usr/sbin/ FILELIST=$PROD_HOME/Filelist @@ -6396,6 +6536,7 @@ SSMG_DIR=ssmg WANPIPE_INCLUDE_DIR=/usr/include/wanpipe WANCFG_ZAPTEL_CFG=NO WANCFG_ZAPTEL=/usr/sbin/wancfg_zaptel +WANCFG_SMG=/usr/sbin/wancfg_smg find_zap_dir_quit=0 zaptel_auto_install="NO" @@ -6416,6 +6557,7 @@ DRIVERS_MPAPI_X25="x25_api_iface.c x25_dsp_iface.c x25_facils.c x25_iface.c x25_ DRIVER_UPDATE_DIR=$PROD_PATCH/kdrivers +DRIVER_INC_DIR=$PROD_PATCH/kdrivers/include DRIVER_TMP_DIR=$PROD_HOME/kdrvtmp DRIVERS_COMPILED=no NEW_IF_TYPE=NO @@ -6442,8 +6584,8 @@ ANNEXG_LOAD=NO SCTP_LOAD=NO ZAPTEL_DFLT_INSTALL_DIR="/usr/src/zaptel" -ZAPTEL_SOURCE_DIR=$ZAPTEL_DFLT_INSTALL_DIR #Location of Zaptel Source Files -ZAPTEL_INSTALL_DIR="" #Location of Zaptel Install Files +ZAPTEL_SOURCE_DIR=$ZAPTEL_DFLT_INSTALL_DIR +ZAPTEL_INSTALL_DIR=$ZAPTEL_DFLT_INSTALL_DIR ZAPTEL_C_FILE="zaptel.c" ASTERISK_IFLAGS= EDAC_ZAP_PATCH_FILE=ed_zaptel.patch @@ -6717,13 +6859,23 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then echo "Error invalid --zaptel-path option"; exit 1; fi - ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR + if [ ! -d "$ZAPTEL_INSTALL_DIR" ]; then + echo "Error: Zaptel source directory not found: $ZAPTEL_INSTALL_DIR"; + exit 1; + fi if [ ! -f "$ZAPTEL_INSTALL_DIR/Makefile" ]; then echo "Error: Invalid zaptel source found in $ZAPTEL_INSTALL_DIR"; exit 1; fi ZAPTEL_PATH_OP="YES"; echo "Zaptel path defined as: $ZAPTEL_INSTALL_DIR" + + if [ -d $ZAPTEL_INSTALL_DIR/kernel ]; then + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR/kernel + else + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR + fi + ;; --with-zaptel*) @@ -6732,16 +6884,27 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then echo "Error invalid --with-zaptel option"; exit 1; fi - ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR + if [ ! -d "$ZAPTEL_INSTALL_DIR" ]; then + echo "Error: Zaptel source directory not found: $ZAPTEL_INSTALL_DIR"; + exit 1; + fi if [ ! -f "$ZAPTEL_INSTALL_DIR/Makefile" ]; then echo "Error: Invalid zaptel source found in $ZAPTEL_INSTALL_DIR"; exit 1; fi ZAPTEL_PATH_OP="YES"; echo "Zaptel path defined as: $ZAPTEL_INSTALL_DIR" + + + if [ -d $ZAPTEL_INSTALL_DIR/kernel ]; then + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR/kernel + else + ZAPTEL_SOURCE_DIR=$ZAPTEL_INSTALL_DIR + fi + ;; - - --no-zaptel-compile*) + + --no-zaptel-compile*) ZAPTEL_COMPILE_DISABLE="YES"; ;; @@ -6762,7 +6925,7 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then fi export ASTBROOT=$ROOT; ASTBROOT=$ROOT; - + TMP_123=${WANPIPE_INCLUDE_DIR#/*} WANPIPE_INCLUDE_DIR=$ROOT/$TMP_123 TMP_123=${WANCFG_ZAPTEL#/*} @@ -6865,6 +7028,12 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then enable_protocols AFT_TE1 "YES" fi + echo "$PROTS" | grep "BRI" > /dev/null + if [ $? -eq 0 ]; then + enable_protocols AFT_TE1 "YES" + enable_protocols BRI "YES" + fi + enable_protocols "$PROTS" "YES" if [ $? -ne 0 ]; then exit 1 @@ -6878,6 +7047,14 @@ if [ "$PKG_NAME" != "wanpipe-lite" ]; then exit; fi + if [ "$setup_cmd" = "smgbri" ]; then + SSMG=YES + SSMG_BRI=YES + NONINTERACTIVE=1; + install_ssmg_bri; + exit; + fi + if [ "$setup_cmd" = "utility" ]; then compile_src; exit; @@ -6952,7 +7129,7 @@ following Environment variables. " if [ $TDM_PROT = "YES" ]; then -echo " 7. Zaptel Build Dir : $ZAPTEL_SOURCE_DIR " +echo " 7. Zaptel Build Dir : $ZAPTEL_INSTALL_DIR " fi echo echo @@ -6975,18 +7152,17 @@ you know what you are doing :) exit 1 fi - if [ $TDM_PROT = "YES" ]; then - $PROD_HOME/Setup install --silent --builddir=$PROD_HOME/$build_dir --with-linux=$SOURCEDIR --arch=$ARCH --protocol=$PROTS --ss7_user_id=$SS7_USER_ID --noautostart --no-zaptel-compile --zaptel-path=$ZAPTEL_SOURCE_DIR --usr-cc=$CC - else - $PROD_HOME/Setup install --silent --builddir=$PROD_HOME/$build_dir --with-linux=$SOURCEDIR --arch=$ARCH --protocol=$PROTS --ss7_user_id=$SS7_USER_ID --noautostart --usr-cc=$CC - fi + + $PROD_HOME/Setup install --silent --builddir=$PROD_HOME/$build_dir --with-linux=$SOURCEDIR --arch=$ARCH --protocol=$PROTS --ss7_user_id=$SS7_USER_ID --noautostart --no-zaptel-compile --zaptel-path=$ZAPTEL_INSTALL_DIR if [ $? -ne 0 ]; then echo "Error: WANPIPE Installation Failed!" exit 1; fi + if [ "$setup_cmd" = "buildrpm" ]; then + compile_aft_firmware_util detect_rpm_build_utility @@ -7157,11 +7333,12 @@ welcome || exit 0 prepare || exit 1 apply_patches || exit 1 compile_drivers || exit 1 -install_config || exit 1 +install_init || exit 1 +install_config || exit 1 compile_src || exit 1 install_all -install_init || exit 1 install_ssmg +install_ssmg_bri clean_up goodbye @@ -7177,7 +7354,11 @@ if [ -z $NONINTERACTIVE ] && [ "$WANCFG_ZAPTEL_CFG" = "YES" ] && [ -e $WANCFG_ZA echo "-----------------------------------------------------" getyn "Would you like to configure wanpipe devices for ZAPTEL?" if [ $? -eq 0 ]; then - eval "$WANCFG_ZAPTEL" + if [ $SSMG_BRI == "YES" ]; then + eval "$WANCFG_SMG" + else + eval "$WANCFG_ZAPTEL" + fi else echo "Wanpipe Installation Complete" echo "-----------------------------" diff --git a/api/aft/Makefile b/api/aft/Makefile index a91b46a..0e16fe4 100644 --- a/api/aft/Makefile +++ b/api/aft/Makefile @@ -16,7 +16,7 @@ SYSINC=/usr/src/linux/include endif VPATH = $(SYSINC) -DIR_EC_APILIB=../wanec_apilib +DIR_EC_APILIB=/common/wantools/wanec_apilib SRC_EC_APILIB=$(DIR_EC_APILIB)/wanec_api.c $(DIR_EC_APILIB)/wanec_api_lib.c INC_EC_APILIB=-I/usr/include/wanpipe/oct6100_api -I$(DIR_EC_APILIB) @@ -26,8 +26,7 @@ CFLAGS += -I/usr/include/wanpipe TARGETS=aft_api TARGETS+= aft_api_events -TARGETS+= aft_integrity -TARGETS+= aft_echo +TARGETS+= aft_api_repeater #TARGETS+= aft_api_ss7 #TARGETS+= aft_api_check #TARGETS+= aft_tdm_api @@ -43,6 +42,9 @@ aft_api: aft_api.c ../lib/lib_api.c aft_api_events: aft_api_events.c $(SRC_EC_APILIB) ../lib/lib_api.c $(CC) $(CFLAGS) $(INC_EC_APILIB) -o $@ $^ +aft_api_repeater: aft_api_repeater.c ../lib/lib_api.c + $(CC) $(CFLAGS) -o $@ $^ + aft_api_check: aft_api_check.c ../lib/lib_api.c $(CC) $(CFLAGS) -o $@ $^ @@ -52,11 +54,5 @@ aft_tdm_api: aft_tdm_api.c ../lib/lib_api.c aft_api_ss7: aft_api_ss7.c ../lib/lib_api.c $(CC) $(CFLAGS) -o $@ $^ -aft_integrity: aft_integrity.c ../lib/lib_api.c - $(CC) $(CFLAGS) -o $@ $^ - -aft_echo: aft_echo.c ../lib/lib_api.c - $(CC) $(CFLAGS) -o $@ $^ - clean: rm -f $(TARGETS) diff --git a/api/aft/aft_api b/api/aft/aft_api deleted file mode 100755 index 4e54e6a67fbcc5e0905257b2f32dcd6827462e03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20351 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 P^PByBgHT_*lHTxND!<;B diff --git a/api/aft/aft_api.c b/api/aft/aft_api.c index 53bc59a..a6bacd0 100644 --- a/api/aft/aft_api.c +++ b/api/aft/aft_api.c @@ -34,10 +34,10 @@ #include #include "lib_api.h" -#define MAX_TX_DATA 5000 /* Size of tx data */ +#define MAX_TX_DATA 1024*10 /* Size of tx data */ #define MAX_FRAMES 5000 /* Number of frames to transmit */ -#define MAX_RX_DATA 5000 +#define MAX_RX_DATA 1024*10 unsigned short Rx_lgth; @@ -90,8 +90,8 @@ int MakeConnection(void) printf("\nConnecting to card %s, interface %s prot %x\n", card_name, if_name,htons(PVC_PROT)); - strcpy( (char*)sa.sll_device, if_name); - strcpy( (char*)sa.sll_card, card_name); + strcpy( sa.sll_device, if_name); + strcpy( sa.sll_card, card_name); sa.sll_protocol = htons(PVC_PROT); sa.sll_family=AF_WANPIPE; @@ -543,7 +543,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage((unsigned char*)argv[0]); + usage(argv[0]); return -1; } diff --git a/api/aft/aft_api_events b/api/aft/aft_api_events deleted file mode 100755 index 0356331c95f26f23eb8de8a5d1e93bc4c583f440..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42961 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 +* +* Copyright: (c) 2003-2004 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib_api.h" + +#define MAX_TX_DATA 5000 /* Size of tx data */ +#define MAX_FRAMES 5000 /* Number of frames to transmit */ + +#define MAX_RX_DATA 5000 + +unsigned short Rx_lgth; + +unsigned char Rx_data[MAX_RX_DATA]; +unsigned char Tx_data[MAX_TX_DATA + sizeof(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) +*/ + +void print_packet(unsigned char *buf, int len) +{ + int x; + printf("{ | "); + for (x=0;xdata[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 + } + } + } + + memset(api_tx_el->api_tx_hdr.wp_api_tx_hdr_hdlc_rpt_data,tx_data+1,4); + api_tx_el->api_tx_hdr.wp_api_tx_hdr_hdlc_rpt_len=4; + + /* 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 + */ + + memset(Rx_data, 0, sizeof(Rx_data)); + +#if 1 + err = sangoma_readmsg_socket(sock, + Rx_data,16, + &Rx_data[16], MAX_RX_DATA-16, + 0); +#else + err = sangoma_read_socket(sock, Rx_data, MAX_RX_DATA, 0); +#endif + if (!read_enable){ + goto bitstrm_skip_read; + } + + + /* err indicates bytes received */ + if(err <= 0) { + printf("\nError receiving data\n"); + break; + } + + 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;iapi_rx_hdr.error_flag & (1<api_rx_hdr.error_flag,Rx_lgth); + continue; + } + + if (api_rx_el->api_rx_hdr.error_flag & (1<api_rx_hdr.error_flag,Rx_lgth); + continue; + } + + if (api_rx_el->api_rx_hdr.error_flag & (1<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; + + //printf("RECEIVE:\n"); + //print_packet(&Rx_data[16],Rx_lgth); + + if (Rx_lgth > 8) { + verbose=3; + } else { + if (verbose) { + verbose--; + } + } + + if (verbose){ + printf("Received %i Olen=%i Length = %i\n", + Rx_count, err,Rx_lgth); +#if 1 + printf("Data: "); + for(i=0;idata[i]); + } + printf("\n"); +#endif + }else{ + //putchar('R'); + } + + if (rx_cnt > 0 && Rx_count >= rx_cnt){ + break; + } +bitstrm_skip_read: +; + } + + if (FD_ISSET(sock,&write)){ + + + if (Tx_count == 0){ + //printf("SEND: Len=%i\n",Tx_length); + //print_packet(&Tx_data[16],Tx_length); + } + +#if 1 + err = sangoma_sendmsg_socket(sock, + Tx_data,16, + &Tx_data[16], Tx_length, + 0); +#else + err = sangoma_send_socket(sock,Tx_data, + Tx_length + sizeof(api_tx_hdr_t), 0); +#endif + 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 errno=%i len=%i \n",errno,Tx_length); + perror("Send: "); + break; + } + }else{ + ++Tx_count; + tx_data++; + + memset(api_tx_el->data,tx_data,Tx_length); + memset(api_tx_el->api_tx_hdr.wp_api_tx_hdr_hdlc_rpt_data,tx_data+1,4); + api_tx_el->api_tx_hdr.wp_api_tx_hdr_hdlc_rpt_len=4; + + + 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); +} + + + diff --git a/api/aft/aft_echo b/api/aft/aft_echo deleted file mode 100755 index 5ba2b469ba403fac268668f5003c82dac771ff53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17274 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 -* -* Copyright: (c) 1995-2001 Sangoma Technologies Inc. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* ============================================================================ -* Description: -* -* The chdlc_api.c utility will bind to a socket to a chdlc network -* interface, and continously tx and rx packets to an from the sockets. -* -* This example has been written for a single interface in mind, -* where the same process handles tx and rx data. -* -* A real world example, should use different processes to handle -* tx and rx spearately. -*/ - - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lib_api.h" - -#define FALSE 0 -#define TRUE 1 - -#define LGTH_CRC_BYTES 0 -#define MAX_TX_DATA 5000 /* Size of tx data */ -#define MAX_RX_DATA MAX_TX_DATA - - -#define SOCK_TIMEOUT 1 - - -/*=================================================== - * Golobal data - *==================================================*/ - -unsigned char HDLC_streaming = FALSE; -unsigned short Rx_lgth; - -unsigned char Rx_data[MAX_RX_DATA]; -unsigned char Tx_data[MAX_TX_DATA]; -int sock; - - -/*=================================================== - * Function Prototypes - *==================================================*/ -int MakeConnection(void); -void handle_socket( void); - - - - -/*=================================================== - * MakeConnection - * - * o Create a Socket - * o Bind a socket to a wanpipe network interface - * (Interface name is supplied by the user) - *==================================================*/ - -int MakeConnection(void) -{ - struct wan_sockaddr_ll sa; - - memset(&sa,0,sizeof(struct wan_sockaddr_ll)); - errno = 0; - sock = socket(AF_WANPIPE, SOCK_RAW, 0); - if( sock < 0 ) { - perror("Socket"); - return(FALSE); - } /* if */ - - printf("\nConnecting to router %s, interface %s\n", card_name, if_name); - - strcpy( (char*)sa.sll_device, if_name); - strcpy( (char*)sa.sll_card, card_name); - sa.sll_protocol = htons(PVC_PROT); - sa.sll_family=AF_WANPIPE; - - if(bind(sock, (struct sockaddr *)&sa, sizeof(struct wan_sockaddr_ll)) < 0){ - perror("bind"); - printf("Failed to bind a socket to %s interface\n",if_name); - exit(0); - } - printf("Socket bound to %s\n\n",if_name); - - return(TRUE); - -} - - -/*=========================================================== - * handle_socket - * - * o Tx/Rx data to and from the socket - * o Cast received data to an api_rx_element_t data type - * o The received packet contains 16 bytes header - * - * ------------------------------------------ - * | 16 bytes | X bytes ... - * ------------------------------------------ - * Header Data - * - * RX DATA: - * -------- - * Each rx data packet contains the 16 byte header! - * - * o Rx 16 byte data structure: - * - * typedef struct { - * unsigned char error_flag PACKED; - * unsigned short time_stamp PACKED; - * unsigned char reserved[13] PACKED; - * } api_rx_hdr_t; - * - * typedef struct { - * api_rx_hdr_t api_rx_hdr PACKED; - * void * data PACKED; - * } api_rx_element_t; - * - * error_flag: - * bit 0: incoming frame was aborted - * bit 1: incoming frame has a CRC error - * bit 2: incoming frame has an overrun eror - * - * time_stamp: - * absolute time value in ms. - * - * TX_DATA: - * -------- - * Each tx data packet MUST contain a 16 byte header! - * - * o Tx 16 byte data structure - * - * typedef struct { - * unsigned char attr PACKED; - * unsigned char reserved[15] PACKED; - * } api_tx_hdr_t; - * - * typedef struct { - * api_tx_hdr_t api_tx_hdr PACKED; - * void * data PACKED; - * } api_tx_element_t; - * - * Currently the chdlc device driver doesn't use any of - * the above fields. Thus, the user can set the 16 bytes - * to ZERO. - * - */ - -void handle_socket(void) -{ - unsigned int Rx_count,Tx_count,Tx_length; - api_tx_element_t * api_tx_el; - fd_set ready,write,oob; - int err; - struct timeval tv; - tv.tv_usec = 0; - tv.tv_sec = SOCK_TIMEOUT; - - - Rx_count = 0; - Tx_count = 0; - Tx_length = tx_size; - - printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i RxCnt=%i\n", - read_enable,write_enable,tx_cnt,tx_size,tx_delay,rx_cnt); - - /* If running HDLC_STREAMING then the received CRC bytes - * will be passed to the application as part of the - * received data. - */ - - api_tx_el = (api_tx_element_t*)&Tx_data[0]; - memset(&Tx_data[0],0,MAX_TX_DATA); - - while (1) { - err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); - printf("Interface %s state is %s (%d)\n", - if_name, - (err == 0) ? "CONNECTED" : - (err == 1) ? "DISCONNECTED" : - "CONNECTING",err); - - if (err < 0) { - printf("Error interface down %s sock disconnected! (%s)\n", - if_name,strerror(errno)); - return; - } - - if (err > 0) { - printf("Waiting for interface %s to come up!\n",if_name); - sleep(10); - } else { - break; - } - } - - for(;;) { - FD_ZERO(&ready); - FD_ZERO(&write); - FD_ZERO(&oob); - FD_SET(sock,&oob); - FD_SET(sock,&ready); - - tv.tv_usec = 0; - tv.tv_sec = SOCK_TIMEOUT; - - if (write_enable){ - FD_SET(sock,&write); - } - - fflush(stdout); - err= select(sock + 1,&ready, NULL, &oob, NULL); - - if (err < 0) { - printf("Error: inteface down: %s socket disconnected %s\n", - if_name,strerror(errno)); - break; - - } else if (err == 0) { - /* Timeout do something */ - - } else { - - if (FD_ISSET(sock,&oob)){ - - err = recv(sock, Rx_data, MAX_RX_DATA, MSG_OOB); - - if(err < 0 ) { - printf("Failed to receive OOB %i , %i\n", Rx_count, err); - err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); - printf("Sock state is %s\n", - (err == 0) ? "CONNECTED" : - (err == 1) ? "DISCONNECTED" : - "CONNECTING"); - break; - } - - printf("Got OOB exception: Link Down !\n"); - break; - } - - - if (FD_ISSET(sock,&ready)){ - - err = recv(sock, Rx_data, MAX_RX_DATA, 0); - - /* err indicates bytes received */ - if (err > 0){ - Rx_count++; - err = send(sock, Rx_data, err, 0); - Tx_count++; - printf("Rx Len=%i Rx=%i Tx=%i : Echo Ok\r", - err-sizeof(api_rx_hdr_t), Tx_count,Rx_count); - } else { - printf("\nError receiving data\n"); - break; - } - - } - } - } - - close (sock); -} - -/*************************************************************** - * Main: - * - * o Make a socket connection to the driver. - * o Call handle_socket() to read/write the socket - * - **************************************************************/ - - -int main(int argc, char* argv[]) -{ - int proceed; - - proceed=init_args(argc,argv); - if (proceed != WAN_TRUE){ - usage((unsigned char*)argv[0]); - return -1; - } - - proceed = MakeConnection(); - if(proceed == WAN_TRUE){ - handle_socket(); - return 0; - } - - return 1; -}; diff --git a/api/aft/aft_integrity b/api/aft/aft_integrity deleted file mode 100755 index de6c382df202af4dbb53b662dd158a3e57388901..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18322 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 AasU7T diff --git a/api/chdlc/Makefile b/api/chdlc/Makefile index c4a83c8..2ec2d42 100644 --- a/api/chdlc/Makefile +++ b/api/chdlc/Makefile @@ -11,8 +11,8 @@ OS_TYPE = __LINUX__ DEBUG = 2 # Project file paths. -SYSINC = /usr/src/linux/include -APIINC = /usr/src/linux/include +SYSINC = /usr/include/wanpipe +APIINC = /usr/include/wanpipe # Tools options. CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) -I$(APIINC) @@ -22,6 +22,7 @@ CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib -I$(SYSINC) all: chdlc_api \ chdlc_rts_cts \ chdlc_integrity \ + chdlc_modem_cmd \ chdlc_echo @echo "Ok." @@ -38,6 +39,9 @@ chdlc_rts_cts: chdlc_rts_cts.c chdlc_integrity: chdlc_integrity.c ../lib/lib_api.c $(CC) $(CFLAGS) -o $@ $^ +chdlc_modem_cmd: chdlc_modem_cmd.c ../lib/lib_api.c + $(CC) $(CFLAGS) -o $@ $^ + clean: rm -f chdlc_api rm -f chdlc_rts_cts diff --git a/api/chdlc/chdlc_modem_cmd b/api/chdlc/chdlc_modem_cmd new file mode 100755 index 0000000000000000000000000000000000000000..9b276cce19bca9e22137d82f695aeb0eef7613b0 GIT binary patch literal 17232 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 N*grq^!op4Be*lmb>F)pl literal 0 HcmV?d00001 diff --git a/api/aft/aft_integrity.c b/api/chdlc/chdlc_modem_cmd.c similarity index 57% rename from api/aft/aft_integrity.c rename to api/chdlc/chdlc_modem_cmd.c index 7844900..ffcd9fa 100644 --- a/api/aft/aft_integrity.c +++ b/api/chdlc/chdlc_modem_cmd.c @@ -1,9 +1,9 @@ /***************************************************************************** -* chdlc_api.c CHDLC API: Receive Module +* chdlc_modem_cmd.c CHDLC API: Modem CMD Example * -* Author(s): Gideon Hack & Nenad Corbic +* Author(s): Nenad Corbic * -* Copyright: (c) 1995-2001 Sangoma Technologies Inc. +* Copyright: (c) 1995-2008 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 @@ -37,24 +37,26 @@ #include #include #include -#include +#include #include "lib_api.h" #define FALSE 0 #define TRUE 1 -#define LGTH_CRC_BYTES 0 +#define LGTH_CRC_BYTES 2 #define MAX_TX_DATA 5000 /* Size of tx data */ #define MAX_RX_DATA MAX_TX_DATA -#define SOCK_TIMEOUT 1 +FILE *tx_fd=NULL,*rx_fd=NULL; +wan_mbox_t gmbox; /*=================================================== * Golobal data *==================================================*/ +unsigned short no_CRC_bytes_Rx; unsigned char HDLC_streaming = FALSE; unsigned short Rx_lgth; @@ -69,10 +71,6 @@ int sock; int MakeConnection(void); void handle_socket( void); -static unsigned char test_data[]={0x00,0x5A, 0xAA, 0xA5, 0xFF}; -static unsigned char tx_index=0; - - /*=================================================== * MakeConnection @@ -96,8 +94,8 @@ int MakeConnection(void) printf("\nConnecting to router %s, interface %s\n", card_name, if_name); - strcpy( (char*)sa.sll_device, if_name); - strcpy( (char*)sa.sll_card, card_name); + strcpy( sa.sll_device, if_name); + strcpy( sa.sll_card, card_name); sa.sll_protocol = htons(PVC_PROT); sa.sll_family=AF_WANPIPE; @@ -113,31 +111,90 @@ int MakeConnection(void) } -void init_tx_pattern(void) +static int exec_cmd(int fd, wan_mbox_t * mb) { - api_tx_element_t * api_tx_el; - unsigned char *data; - int i; - - memset(&Tx_data[0],0,MAX_TX_DATA); - - /* Initialize the tx packet. The 16 byte header must - * be inserted before tx data. In CHDLC protocol, - * the tx x25 header is not used, thus it can be - * set to zero */ - api_tx_el = (api_tx_element_t*)&Tx_data[0]; - data = (unsigned char *)api_tx_el->data; - - for (i=0;i= sizeof(test_data)){ - tx_index=0; - } + int err = ioctl(sock,SIOC_MBOX_CMD,mb); + if (err) { + perror("SIOC_MBOX_CMD"); + return -1; } + + switch (mb->wan_return_code) { + + case 0: + return 0; + default: + printf("Error: CMD returned 0x%0X\n", + mb->wan_return_code); + return -1; + } + + return 0; } +static unsigned char gstatus=0; +static int exec_read_modem_cmd(int fd, wan_mbox_t * mb) +{ + MODEM_STATUS_STRUCT *mstat; + int err=0; + memset(mb,0,sizeof(wan_mbox_t)); + + mb->wan_data_len = 0; + mb->wan_command = READ_MODEM_STATUS; + + err=exec_cmd(fd,mb); + if (err) { + return err; + } + mstat=(MODEM_STATUS_STRUCT*)mb->wan_data; + + if (mstat->modem_status == gstatus) { + return 0; + } + gstatus = mstat->modem_status; + + printf("MODEM CMD rc=0x%02X data_len=%i data=0x%02X\n", + mb->wan_return_code, mb->wan_data_len, mb->wan_data[0]); + + mstat=(MODEM_STATUS_STRUCT*)mb->wan_data; + + printf("MODEM STATUS (Data=0x%02X) DCD=%i CTS=%i\n", + mstat->modem_status, + (mstat->modem_status&MODEM_DCD_MASK)?1:0, + (mstat->modem_status&MODEM_CTS_MASK)?1:0); +} + +static int exec_set_modem_cmd(int fd, wan_mbox_t * mb, int dtr, int rts) +{ + MODEM_STATUS_STRUCT *mstat=(MODEM_STATUS_STRUCT*)mb->wan_data; + + int err=0; + memset(mb,0,sizeof(wan_mbox_t)); + + mb->wan_data_len = 0; + mb->wan_command = SET_MODEM_STATUS; + mb->wan_data_len = 1; + + mstat->modem_status = 0; + if (dtr) { + mstat->modem_status |= SET_MODEM_DTR_HIGH; + } + if (rts) { + mstat->modem_status |= SET_MODEM_RTS_HIGH; + } + + + err=exec_cmd(fd,mb); + if (err) { + return err; + } + + printf("MODEM CMD rc=0x%02X data_len=%i data=0x%02X (dtr=%i rts=%i)\n", + mb->wan_return_code, mb->wan_data_len, mb->wan_data[0],dtr,rts); + +} + + /*=========================================================== * handle_socket @@ -205,12 +262,16 @@ void handle_socket(void) 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; - struct timeval tv; - tv.tv_usec = 0; - tv.tv_sec = SOCK_TIMEOUT; + 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; @@ -223,33 +284,73 @@ void handle_socket(void) * received data. */ - api_tx_el = (api_tx_element_t*)&Tx_data[0]; memset(&Tx_data[0],0,MAX_TX_DATA); - init_tx_pattern(); + 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); + } - while (1) { - err = ioctl(sock,SIOC_WANPIPE_SOCK_STATE,0); - printf("Interface %s state is %s (%d)\n", - if_name, - (err == 0) ? "CONNECTED" : - (err == 1) ? "DISCONNECTED" : - "CONNECTING",err); + + if (files_used & TX_FILE_USED){ - if (err < 0) { - printf("Error interface down %s sock disconnected! (%s)\n", - if_name,strerror(errno)); + tx_fd=fopen(tx_file,"rb"); + if (!tx_fd){ + printf("Failed to open file %s\n",tx_file); + perror("File: "); return; } - if (err > 0) { - printf("Waiting for interface %s to come up!\n",if_name); - sleep(10); - } else { - break; + 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;idata[i] = (unsigned char)i; + }else{ + api_tx_el->data[i] = (unsigned char)tx_data; + } } } + if (!write_enable) { + while (1) { + exec_read_modem_cmd(sock, &gmbox); + sleep(1); + } + } + + + sleep(4); + exec_set_modem_cmd(sock, &gmbox, 0, 0); + sleep(4); + exec_set_modem_cmd(sock, &gmbox, 1, 0); + sleep(4); + exec_set_modem_cmd(sock, &gmbox, 0, 1); + sleep(4); + exec_set_modem_cmd(sock, &gmbox, 1, 1); + sleep(4); + + exit(1); + + for(;;) { FD_ZERO(&ready); FD_ZERO(&write); @@ -257,25 +358,12 @@ void handle_socket(void) FD_SET(sock,&oob); FD_SET(sock,&ready); - tv.tv_usec = 0; - tv.tv_sec = SOCK_TIMEOUT; - if (write_enable){ FD_SET(sock,&write); } fflush(stdout); - err= select(sock + 1,&ready, &write, &oob, &tv); - - if (err < 0) { - printf("Error: inteface down: %s socket disconnected %s\n", - if_name,strerror(errno)); - break; - - } else if (err == 0) { - /* Timeout do someting if you like */ - - } else { + if(select(sock + 1,&ready, &write, &oob, NULL)){ if (FD_ISSET(sock,&oob)){ @@ -300,6 +388,10 @@ void handle_socket(void) err = recv(sock, Rx_data, MAX_RX_DATA, 0); + if (!read_enable){ + goto bitstrm_skip_read; + } + /* err indicates bytes received */ if (err > 0){ @@ -310,36 +402,64 @@ void handle_socket(void) if(Rx_lgth<=0) { printf("\nShort frame received (%d)\n", Rx_lgth); - Rx_count++; - continue; + return; } - ++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); + 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; } - for (i=0;idata)[i] != - ((unsigned char*)api_tx_el->data)[i]){ - printf("Rx Error cnt=%i: Packet corruption on offset %i\n", - Rx_count,i); - break; + + + if ((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); } - } - - if (verbose) { - printf("Tx Len=%i Tx=%i Rx=%i : Data Ok\r", - Tx_length, Tx_count,Rx_count); } + + ++Rx_count; - if (Rx_count == tx_cnt){ - init_tx_pattern(); - Rx_count=0; - write_enable=1; + 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;(idata[i]); + } + printf("\n"); + } +#endif + + if (rx_cnt == Rx_count){ + printf("Rxcnt %i == RxCount=%i\n",rx_cnt,Rx_count); + break; } } else { @@ -349,12 +469,16 @@ void handle_socket(void) } +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 */ @@ -369,12 +493,31 @@ void handle_socket(void) break; } }else{ - ++Tx_count; - if (verbose && Rx_count < 1) { - printf("Tx Len=%i Tx=%i Rx=%i : Data Ok\r", - Tx_length, Tx_count,Rx_count); - } + ++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; + } + } } } @@ -382,13 +525,22 @@ void handle_socket(void) sleep(tx_delay); } - if (tx_size && Tx_count == tx_cnt){ + if (tx_size && Tx_count == tx_cnt && !(files_used & TX_FILE_USED)){ write_enable=0; - Tx_count=0; + if (!rx_cnt){ + break; + } } } } + if (tx_fd){ + fclose(tx_fd); + } + if (rx_fd){ + fclose(rx_fd); + } + close (sock); } @@ -407,7 +559,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage((unsigned char*)argv[0]); + usage(argv[0]); return -1; } diff --git a/api/fr/Makefile b/api/fr/Makefile index 74bcaba..0cf20af 100644 --- a/api/fr/Makefile +++ b/api/fr/Makefile @@ -16,13 +16,19 @@ SYSINC = /usr/src/linux/include # Tools options. CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(SYSINC) -I$(APIINC) +TARGETS = fr_api +#TARGETS += fr_api_fast + + ####### RULES ################################################################ -all: fr_api +all: $(TARGETS) @echo "Ok." fr_api: fr_api.c $(CC) $(CFLAGS) -c -o $@ $< +#fr_api_fast: fr_api_fast.c +# $(CC) $(CFLAGS) -c -o $@ $< clean: - rm -f fr_api + rm -f $(TARGETS) diff --git a/api/lib/lib_api.c b/api/lib/lib_api.c index a2f873f..f78f8cb 100644 --- a/api/lib/lib_api.c +++ b/api/lib/lib_api.c @@ -407,7 +407,7 @@ int init_args(int argc, char *argv[]) return WAN_TRUE; } -static unsigned char api_usage[]="\n" +static char api_usage[]="\n" "\n" ":\n" " -i #interface name\n" @@ -466,7 +466,7 @@ static unsigned char api_usage[]="\n" " -diagn #disconnect diagnostic (dflt=0)\n" "\n"; -void usage(unsigned char *api_name) +void usage(char *api_name) { printf ("\n\nAPI %s USAGE:\n\n%s \n\n%s\n", api_name,api_name,api_usage); diff --git a/api/lib/lib_api.h b/api/lib/lib_api.h index fc33b2e..419cba1 100644 --- a/api/lib/lib_api.h +++ b/api/lib/lib_api.h @@ -38,14 +38,14 @@ extern int cause; extern int card_cnt; extern int i_cnt; -extern char tx_file[WAN_IFNAME_SZ]; -extern char rx_file[WAN_IFNAME_SZ]; +extern char tx_file[WAN_IFNAME_SZ]; +extern char rx_file[WAN_IFNAME_SZ]; #define TX_ADDR_STR_SZ 100 -extern char daddr[TX_ADDR_STR_SZ]; -extern char saddr[TX_ADDR_STR_SZ]; -extern char udata[TX_ADDR_STR_SZ]; +extern char daddr[TX_ADDR_STR_SZ]; +extern char saddr[TX_ADDR_STR_SZ]; +extern char udata[TX_ADDR_STR_SZ]; #define TX_FILE_USED 1 @@ -55,11 +55,11 @@ extern char udata[TX_ADDR_STR_SZ]; extern int init_args(int argc, char *argv[]); -extern void usage(unsigned char *api_name); +extern void usage(char *api_name); extern void u_delay(int usec); extern char card_name[WAN_IFNAME_SZ]; extern char if_name[WAN_IFNAME_SZ]; -extern char sw_if_name[WAN_IFNAME_SZ]; -extern char sw_card_name[WAN_IFNAME_SZ]; +extern char sw_if_name[WAN_IFNAME_SZ]; +extern char sw_card_name[WAN_IFNAME_SZ]; diff --git a/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo b/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo index 1a925df..24f589c 100644 --- a/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo +++ b/api/libsangoma/.deps/libsangoma_la-libsangoma.Plo @@ -66,12 +66,16 @@ libsangoma_la-libsangoma.lo libsangoma_la-libsangoma.o: libsangoma.c \ ../../patches/kdrivers/include/linux/wanpipe_version.h \ ../../patches/kdrivers/include/linux/wanpipe_kernel.h \ /lib/modules/2.6.18-8.1.15.el5/build/include/linux/version.h \ + ../../patches/kdrivers/include/linux/wanpipe_abstr_types.h \ ../../patches/kdrivers/include/linux/wanpipe_cfg.h \ ../../patches/kdrivers/include/linux/sdla_56k.h \ ../../patches/kdrivers/include/linux/sdla_te1.h \ ../../patches/kdrivers/include/linux/sdla_te3.h \ ../../patches/kdrivers/include/linux/sdla_remora.h \ ../../patches/kdrivers/include/linux/sdla_remora_proslic.h \ + ../../patches/kdrivers/include/linux/sdla_bri.h \ + ../../patches/kdrivers/include/linux/xhfc24succ.h \ + ../../patches/kdrivers/include/linux/sdla_serial.h \ ../../patches/kdrivers/include/linux/sdla_front_end.h \ ../../patches/kdrivers/include/linux/wanpipe.h \ ../../patches/kdrivers/include/linux/wanpipe_debug.h \ @@ -82,7 +86,8 @@ libsangoma_la-libsangoma.lo libsangoma_la-libsangoma.o: libsangoma.c \ ../../patches/kdrivers/include/linux/wanpipe_includes.h \ ../../patches/kdrivers/include/linux/if_wanpipe.h \ /lib/modules/2.6.18-8.1.15.el5/build/include/linux/sockios.h \ - ../../patches/kdrivers/include/linux/wanpipe_codec_iface.h + ../../patches/kdrivers/include/linux/wanpipe_codec_iface.h \ + ../../patches/kdrivers/include/linux/wanpipe_tdm_api_iface.h libsangoma.h: @@ -302,6 +307,8 @@ libsangoma.h: /lib/modules/2.6.18-8.1.15.el5/build/include/linux/version.h: +../../patches/kdrivers/include/linux/wanpipe_abstr_types.h: + ../../patches/kdrivers/include/linux/wanpipe_cfg.h: ../../patches/kdrivers/include/linux/sdla_56k.h: @@ -314,6 +321,12 @@ libsangoma.h: ../../patches/kdrivers/include/linux/sdla_remora_proslic.h: +../../patches/kdrivers/include/linux/sdla_bri.h: + +../../patches/kdrivers/include/linux/xhfc24succ.h: + +../../patches/kdrivers/include/linux/sdla_serial.h: + ../../patches/kdrivers/include/linux/sdla_front_end.h: ../../patches/kdrivers/include/linux/wanpipe.h: @@ -335,3 +348,5 @@ libsangoma.h: /lib/modules/2.6.18-8.1.15.el5/build/include/linux/sockios.h: ../../patches/kdrivers/include/linux/wanpipe_codec_iface.h: + +../../patches/kdrivers/include/linux/wanpipe_tdm_api_iface.h: diff --git a/api/libsangoma/.deps/libsangoma_la-sangoma_pri.Plo b/api/libsangoma/.deps/libsangoma_la-sangoma_pri.Plo index e638078..9ce06a8 100644 --- a/api/libsangoma/.deps/libsangoma_la-sangoma_pri.Plo +++ b/api/libsangoma/.deps/libsangoma_la-sangoma_pri.Plo @@ -1,336 +1 @@ -libsangoma_la-sangoma_pri.lo libsangoma_la-sangoma_pri.o: sangoma_pri.c \ - ./libsangoma.h /usr/include/stdlib.h /usr/include/features.h \ - /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \ - /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h \ - /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ - /usr/include/endian.h /usr/include/bits/endian.h /usr/include/xlocale.h \ - /usr/include/sys/types.h /usr/include/bits/types.h \ - /usr/include/bits/wordsize.h /usr/include/bits/typesizes.h \ - /usr/include/time.h /usr/include/sys/select.h \ - /usr/include/bits/select.h /usr/include/bits/sigset.h \ - /usr/include/bits/time.h /usr/include/sys/sysmacros.h \ - /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h \ - /usr/include/alloca.h /usr/include/stdio.h /usr/include/libio.h \ - /usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \ - /usr/include/gconv.h \ - /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h \ - /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ - /usr/include/bits/stdio.h /usr/include/ctype.h /usr/include/unistd.h \ - /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \ - /usr/include/bits/confname.h /usr/include/getopt.h \ - /usr/include/sys/time.h /usr/include/sys/socket.h \ - /usr/include/sys/uio.h /usr/include/bits/uio.h \ - /usr/include/bits/socket.h \ - /usr/lib/gcc/i386-redhat-linux/3.4.3/include/limits.h \ - /usr/lib/gcc/i386-redhat-linux/3.4.3/include/syslimits.h \ - /usr/include/limits.h /usr/include/bits/posix1_lim.h \ - /usr/include/bits/local_lim.h /usr/src/linux/include/linux/limits.h \ - /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \ - /usr/include/bits/sockaddr.h /usr/src/linux/include/asm/socket.h \ - /usr/src/linux/include/asm/sockios.h /usr/include/netinet/in.h \ - /usr/include/stdint.h /usr/include/bits/in.h \ - /usr/include/bits/byteswap.h /usr/include/string.h \ - /usr/include/bits/string.h /usr/include/bits/string2.h \ - /usr/include/errno.h /usr/include/bits/errno.h \ - /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/errno.h \ - /usr/src/linux/include/asm-generic/errno.h \ - /usr/src/linux/include/asm-generic/errno-base.h /usr/include/fcntl.h \ - /usr/include/bits/fcntl.h /usr/include/sys/stat.h \ - /usr/include/bits/stat.h /usr/include/sys/ioctl.h \ - /usr/include/bits/ioctls.h /usr/src/linux/include/asm/ioctls.h \ - /usr/src/linux/include/asm/ioctl.h /usr/include/bits/ioctl-types.h \ - /usr/include/sys/ttydefaults.h /usr/src/linux/include/linux/if.h \ - /usr/src/linux/include/linux/types.h \ - /usr/src/linux/include/linux/posix_types.h \ - /usr/src/linux/include/linux/stddef.h \ - /usr/src/linux/include/linux/compiler.h \ - /usr/src/linux/include/asm/posix_types.h \ - /usr/src/linux/include/asm/types.h \ - /usr/src/linux/include/linux/socket.h \ - /usr/src/linux/include/linux/hdlc/ioctl.h \ - /usr/src/linux/include/linux/wanpipe_defines.h \ - /usr/src/linux/include/linux/wanpipe_version.h \ - /usr/src/linux/include/linux/wanpipe_kernel.h \ - /usr/src/linux/include/linux/version.h \ - /usr/src/linux/include/linux/wanpipe_cfg.h \ - /usr/src/linux/include/linux/sdla_56k.h \ - /usr/src/linux/include/linux/sdla_te1.h \ - /usr/src/linux/include/linux/sdla_te3.h \ - /usr/src/linux/include/linux/sdla_remora.h \ - /usr/src/linux/include/linux/sdla_remora_proslic.h \ - /usr/src/linux/include/linux/sdla_front_end.h \ - /usr/src/linux/include/linux/wanpipe.h \ - /usr/src/linux/include/linux/wanpipe_debug.h \ - /usr/src/linux/include/linux/wanpipe_common.h \ - /usr/src/linux/include/linux/wanpipe_events.h \ - /usr/src/linux/include/linux/wanrouter.h /usr/include/poll.h \ - /usr/include/sys/poll.h /usr/include/bits/poll.h \ - /usr/src/linux/include/linux/wanpipe_tdm_api.h \ - /usr/src/linux/include/linux/wanpipe_includes.h \ - /usr/src/linux/include/linux/if_wanpipe.h \ - /usr/src/linux/include/linux/sockios.h \ - /usr/src/linux/include/linux/wanpipe_codec_iface.h \ - /usr/include/signal.h /usr/include/bits/signum.h \ - /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h \ - /usr/include/bits/sigcontext.h /usr/src/linux/include/asm/sigcontext.h \ - /usr/include/bits/sigstack.h /usr/include/sys/ucontext.h \ - /usr/include/bits/sigthread.h /usr/include/sys/signal.h \ - /usr/include/sys/wait.h /usr/include/sys/resource.h \ - /usr/include/bits/resource.h ./sangoma_pri.h /usr/src/libpri/libpri.h \ - /usr/src/libpri/pri_internal.h - -./libsangoma.h: - -/usr/include/stdlib.h: - -/usr/include/features.h: - -/usr/include/sys/cdefs.h: - -/usr/include/gnu/stubs.h: - -/usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h: - -/usr/include/bits/waitflags.h: - -/usr/include/bits/waitstatus.h: - -/usr/include/endian.h: - -/usr/include/bits/endian.h: - -/usr/include/xlocale.h: - -/usr/include/sys/types.h: - -/usr/include/bits/types.h: - -/usr/include/bits/wordsize.h: - -/usr/include/bits/typesizes.h: - -/usr/include/time.h: - -/usr/include/sys/select.h: - -/usr/include/bits/select.h: - -/usr/include/bits/sigset.h: - -/usr/include/bits/time.h: - -/usr/include/sys/sysmacros.h: - -/usr/include/bits/pthreadtypes.h: - -/usr/include/bits/sched.h: - -/usr/include/alloca.h: - -/usr/include/stdio.h: - -/usr/include/libio.h: - -/usr/include/_G_config.h: - -/usr/include/wchar.h: - -/usr/include/bits/wchar.h: - -/usr/include/gconv.h: - -/usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h: - -/usr/include/bits/stdio_lim.h: - -/usr/include/bits/sys_errlist.h: - -/usr/include/bits/stdio.h: - -/usr/include/ctype.h: - -/usr/include/unistd.h: - -/usr/include/bits/posix_opt.h: - -/usr/include/bits/environments.h: - -/usr/include/bits/confname.h: - -/usr/include/getopt.h: - -/usr/include/sys/time.h: - -/usr/include/sys/socket.h: - -/usr/include/sys/uio.h: - -/usr/include/bits/uio.h: - -/usr/include/bits/socket.h: - -/usr/lib/gcc/i386-redhat-linux/3.4.3/include/limits.h: - -/usr/lib/gcc/i386-redhat-linux/3.4.3/include/syslimits.h: - -/usr/include/limits.h: - -/usr/include/bits/posix1_lim.h: - -/usr/include/bits/local_lim.h: - -/usr/src/linux/include/linux/limits.h: - -/usr/include/bits/posix2_lim.h: - -/usr/include/bits/xopen_lim.h: - -/usr/include/bits/sockaddr.h: - -/usr/src/linux/include/asm/socket.h: - -/usr/src/linux/include/asm/sockios.h: - -/usr/include/netinet/in.h: - -/usr/include/stdint.h: - -/usr/include/bits/in.h: - -/usr/include/bits/byteswap.h: - -/usr/include/string.h: - -/usr/include/bits/string.h: - -/usr/include/bits/string2.h: - -/usr/include/errno.h: - -/usr/include/bits/errno.h: - -/usr/src/linux/include/linux/errno.h: - -/usr/src/linux/include/asm/errno.h: - -/usr/src/linux/include/asm-generic/errno.h: - -/usr/src/linux/include/asm-generic/errno-base.h: - -/usr/include/fcntl.h: - -/usr/include/bits/fcntl.h: - -/usr/include/sys/stat.h: - -/usr/include/bits/stat.h: - -/usr/include/sys/ioctl.h: - -/usr/include/bits/ioctls.h: - -/usr/src/linux/include/asm/ioctls.h: - -/usr/src/linux/include/asm/ioctl.h: - -/usr/include/bits/ioctl-types.h: - -/usr/include/sys/ttydefaults.h: - -/usr/src/linux/include/linux/if.h: - -/usr/src/linux/include/linux/types.h: - -/usr/src/linux/include/linux/posix_types.h: - -/usr/src/linux/include/linux/stddef.h: - -/usr/src/linux/include/linux/compiler.h: - -/usr/src/linux/include/asm/posix_types.h: - -/usr/src/linux/include/asm/types.h: - -/usr/src/linux/include/linux/socket.h: - -/usr/src/linux/include/linux/hdlc/ioctl.h: - -/usr/src/linux/include/linux/wanpipe_defines.h: - -/usr/src/linux/include/linux/wanpipe_version.h: - -/usr/src/linux/include/linux/wanpipe_kernel.h: - -/usr/src/linux/include/linux/version.h: - -/usr/src/linux/include/linux/wanpipe_cfg.h: - -/usr/src/linux/include/linux/sdla_56k.h: - -/usr/src/linux/include/linux/sdla_te1.h: - -/usr/src/linux/include/linux/sdla_te3.h: - -/usr/src/linux/include/linux/sdla_remora.h: - -/usr/src/linux/include/linux/sdla_remora_proslic.h: - -/usr/src/linux/include/linux/sdla_front_end.h: - -/usr/src/linux/include/linux/wanpipe.h: - -/usr/src/linux/include/linux/wanpipe_debug.h: - -/usr/src/linux/include/linux/wanpipe_common.h: - -/usr/src/linux/include/linux/wanpipe_events.h: - -/usr/src/linux/include/linux/wanrouter.h: - -/usr/include/poll.h: - -/usr/include/sys/poll.h: - -/usr/include/bits/poll.h: - -/usr/src/linux/include/linux/wanpipe_tdm_api.h: - -/usr/src/linux/include/linux/wanpipe_includes.h: - -/usr/src/linux/include/linux/if_wanpipe.h: - -/usr/src/linux/include/linux/sockios.h: - -/usr/src/linux/include/linux/wanpipe_codec_iface.h: - -/usr/include/signal.h: - -/usr/include/bits/signum.h: - -/usr/include/bits/siginfo.h: - -/usr/include/bits/sigaction.h: - -/usr/include/bits/sigcontext.h: - -/usr/src/linux/include/asm/sigcontext.h: - -/usr/include/bits/sigstack.h: - -/usr/include/sys/ucontext.h: - -/usr/include/bits/sigthread.h: - -/usr/include/sys/signal.h: - -/usr/include/sys/wait.h: - -/usr/include/sys/resource.h: - -/usr/include/bits/resource.h: - -./sangoma_pri.h: - -/usr/src/libpri/libpri.h: - -/usr/src/libpri/pri_internal.h: +# dummy diff --git a/api/libsangoma/.svn/all-wcprops b/api/libsangoma/.svn/all-wcprops new file mode 100644 index 0000000..9481f6c --- /dev/null +++ b/api/libsangoma/.svn/all-wcprops @@ -0,0 +1,215 @@ +K 25 +svn:wc:ra_dav:version-url +V 32 +/svn/libsangoma/!svn/ver/1/trunk +END +configure +K 25 +svn:wc:ra_dav:version-url +V 42 +/svn/libsangoma/!svn/ver/1/trunk/configure +END +Makefile.in +K 25 +svn:wc:ra_dav:version-url +V 44 +/svn/libsangoma/!svn/ver/1/trunk/Makefile.in +END +config.log +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/libsangoma/!svn/ver/1/trunk/config.log +END +AUTHORS +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/AUTHORS +END +depcomp +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/depcomp +END +compile +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/compile +END +config.guess +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/libsangoma/!svn/ver/1/trunk/config.guess +END +svn-commit.2.tmp +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/libsangoma/!svn/ver/1/trunk/svn-commit.2.tmp +END +ltmain.sh +K 25 +svn:wc:ra_dav:version-url +V 42 +/svn/libsangoma/!svn/ver/1/trunk/ltmain.sh +END +config.sub +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/libsangoma/!svn/ver/1/trunk/config.sub +END +libsangoma.c +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/libsangoma/!svn/ver/1/trunk/libsangoma.c +END +libsangoma.dsp +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/libsangoma/!svn/ver/1/trunk/libsangoma.dsp +END +libsangoma.h +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/libsangoma/!svn/ver/1/trunk/libsangoma.h +END +g711.h +K 25 +svn:wc:ra_dav:version-url +V 39 +/svn/libsangoma/!svn/ver/1/trunk/g711.h +END +INSTALL +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/INSTALL +END +libsangoma.dsw +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/libsangoma/!svn/ver/1/trunk/libsangoma.dsw +END +COPYING +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/COPYING +END +NEWS +K 25 +svn:wc:ra_dav:version-url +V 37 +/svn/libsangoma/!svn/ver/1/trunk/NEWS +END +Makefile +K 25 +svn:wc:ra_dav:version-url +V 41 +/svn/libsangoma/!svn/ver/1/trunk/Makefile +END +sangoma_pri.c +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/libsangoma/!svn/ver/1/trunk/sangoma_pri.c +END +libsangoma.so.conf +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/libsangoma/!svn/ver/1/trunk/libsangoma.so.conf +END +win_api_common.h +K 25 +svn:wc:ra_dav:version-url +V 49 +/svn/libsangoma/!svn/ver/1/trunk/win_api_common.h +END +sangoma_pri.h +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/libsangoma/!svn/ver/1/trunk/sangoma_pri.h +END +version +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/version +END +configure.in +K 25 +svn:wc:ra_dav:version-url +V 45 +/svn/libsangoma/!svn/ver/1/trunk/configure.in +END +ChangeLog +K 25 +svn:wc:ra_dav:version-url +V 42 +/svn/libsangoma/!svn/ver/1/trunk/ChangeLog +END +config.status +K 25 +svn:wc:ra_dav:version-url +V 46 +/svn/libsangoma/!svn/ver/1/trunk/config.status +END +svn-commit.tmp +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/libsangoma/!svn/ver/1/trunk/svn-commit.tmp +END +README +K 25 +svn:wc:ra_dav:version-url +V 39 +/svn/libsangoma/!svn/ver/1/trunk/README +END +config.h.in +K 25 +svn:wc:ra_dav:version-url +V 44 +/svn/libsangoma/!svn/ver/1/trunk/config.h.in +END +libtool +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/libtool +END +missing +K 25 +svn:wc:ra_dav:version-url +V 40 +/svn/libsangoma/!svn/ver/1/trunk/missing +END +Makefile.am +K 25 +svn:wc:ra_dav:version-url +V 44 +/svn/libsangoma/!svn/ver/1/trunk/Makefile.am +END +install-sh +K 25 +svn:wc:ra_dav:version-url +V 43 +/svn/libsangoma/!svn/ver/1/trunk/install-sh +END +libsangoma.vcproj +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/libsangoma/!svn/ver/1/trunk/libsangoma.vcproj +END diff --git a/api/libsangoma/.svn/entries b/api/libsangoma/.svn/entries index 79f3175..af1aa24 100644 --- a/api/libsangoma/.svn/entries +++ b/api/libsangoma/.svn/entries @@ -1,15 +1,15 @@ 8 dir -237 -svn://sangoma.freeswitch.org/libsangoma/trunk -svn://sangoma.freeswitch.org +1 +https://www.sangomapbx.com/svn/libsangoma/trunk +https://www.sangomapbx.com/svn/libsangoma -2007-07-24T23:10:36.931930Z -231 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root svn:special svn:externals svn:needs-lock @@ -24,7 +24,7 @@ svn:special svn:externals svn:needs-lock -2028fedf-720c-0410-83b8-d54a3e729fb0 +8fe45b59-3c47-0410-bdf9-e5d932a076a6 configure file @@ -32,11 +32,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z cdcb22cae8ad2d0de88542d1adf5b13d -2007-02-07T19:00:12.109961Z -166 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root has-props Makefile.in @@ -45,11 +45,23 @@ file -2007-07-24T22:45:02.000000Z +2008-02-28T19:04:34.000000Z 1c05e844314274f082a74abf3f446239 -2007-05-29T18:03:36.038276Z -206 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root + +config.log +file + + + + +2008-02-28T19:04:34.000000Z +1584c0969324cd96c0864b8e43ee0b0f +2008-02-28T18:51:53.196120Z +1 +root AUTHORS file @@ -57,11 +69,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z d41d8cd98f00b204e9800998ecf8427e -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root depcomp file @@ -69,11 +81,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z e181e2c8720c60522c4c4c981108e367 -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root has-props compile @@ -82,11 +94,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z a7ecc032b527a0d578545f19d3418073 -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root has-props config.guess @@ -95,11 +107,48 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 9ae396244b8f138c76514a6b7531e696 -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root +has-props + +svn-commit.2.tmp +file + + + + +2008-02-28T19:04:34.000000Z +9bf5427f205140ba936f4feb06d54cac +2008-02-28T18:51:53.196120Z +1 +root + +ltmain.sh +file + + + + +2008-02-28T19:04:34.000000Z +c8215e3aa0858d700783015614f53b79 +2008-02-28T18:51:53.196120Z +1 +root + +config.sub +file + + + + +2008-02-28T19:04:34.000000Z +3d36962d51070d30b7554203b0d7c01c +2008-02-28T18:51:53.196120Z +1 +root has-props libsangoma.c @@ -108,36 +157,11 @@ file -2007-07-24T23:09:55.000000Z -cb02ecd239d3d3d37cf6d5e704a0dc39 -2007-07-24T23:10:36.931930Z -231 -ncorbic - -ltmain.sh -file - - - - -2007-05-17T23:49:20.000000Z -c8215e3aa0858d700783015614f53b79 -2006-02-10T16:20:41.709688Z +2008-02-28T19:04:34.000000Z +20fa69ba4181e245e810703d4c1787bd +2008-02-28T18:51:53.196120Z 1 -anthm - -config.sub -file - - - - -2007-05-17T23:49:20.000000Z -3d36962d51070d30b7554203b0d7c01c -2006-02-10T16:20:41.709688Z -1 -anthm -has-props +root libsangoma.dsp file @@ -145,11 +169,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z f934aab66c529599725686f321d182e6 -2006-12-04T20:48:10.874618Z -156 -anthm +2008-02-28T18:51:53.196120Z +1 +root libsangoma.h file @@ -157,11 +181,11 @@ file -2007-07-24T22:47:49.000000Z -19c2545ffa4e1a11f2a1b5f4850a10bd -2007-07-24T22:47:39.060265Z -230 -ncorbic +2008-02-28T19:04:34.000000Z +3a381ddb82700688b9ea1dcdb1f10d6a +2008-02-28T18:51:53.196120Z +1 +root g711.h file @@ -169,11 +193,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 0f725f95ced42af15dcaef21f3a1722b -2006-11-06T23:11:15.401413Z -119 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root INSTALL file @@ -181,23 +205,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 40539bd3eff06e4b82f380103145415b -2006-08-08T19:52:23.727343Z -94 -ncorbic - -libsangoma.dsw -file - - - - -2007-05-17T23:49:20.000000Z -f13496d2105bae2add104c36a1d656f6 -2006-12-04T20:48:10.874618Z -156 -anthm +2008-02-28T18:51:53.196120Z +1 +root COPYING file @@ -205,11 +217,47 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z d41d8cd98f00b204e9800998ecf8427e -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root + +libsangoma.dsw +file + + + + +2008-02-28T19:04:34.000000Z +f13496d2105bae2add104c36a1d656f6 +2008-02-28T18:51:53.196120Z +1 +root + +diff +file +2 + + + + + + + + + + + + + + + + + + + +deleted NEWS file @@ -217,11 +265,23 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z d41d8cd98f00b204e9800998ecf8427e -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root + +Makefile +file + + + + +2008-02-28T19:04:34.000000Z +c4406ae0adf00115003a0530d2e2c5d0 +2008-02-28T18:51:53.196120Z +1 +root libsangoma.so.conf file @@ -229,11 +289,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z bcdcb23c5d5fb460cee2ce315ef7bd32 -2006-10-19T19:27:09.335085Z -101 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root sangoma_pri.c file @@ -241,11 +301,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z e2a6c68fadfefb2d2b16c52534e85675 -2006-12-04T20:47:20.283144Z -155 -anthm +2008-02-28T18:51:53.196120Z +1 +root win_api_common.h file @@ -253,11 +313,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z b6be170d18fa90b79f7264cf8b0f7348 -2006-12-04T22:21:07.339224Z -157 -mikej +2008-02-28T18:51:53.196120Z +1 +root version file @@ -265,11 +325,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 35f672d1fb01b542f667952c9dbb26fe -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root sangoma_pri.h file @@ -277,11 +337,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z f24c6cf396aeaa6df2747f7f6b32969d -2006-03-24T14:19:31.976520Z -28 -anthm +2008-02-28T18:51:53.196120Z +1 +root configure.in file @@ -289,11 +349,24 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 5b9888fc365c4ebffdbb55656c091a2f -2007-02-07T19:00:12.109961Z -166 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root + +config.status +file + + + + +2008-02-28T19:04:34.000000Z +75ac9809637055fcbd3f4be64fab529f +2008-02-28T18:51:53.196120Z +1 +root +has-props ChangeLog file @@ -301,11 +374,23 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z d41d8cd98f00b204e9800998ecf8427e -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root + +svn-commit.tmp +file + + + + +2008-02-28T19:04:34.000000Z +4ac38b24bcff9c3975171af8ccbcfa36 +2008-02-28T18:51:53.196120Z +1 +root README file @@ -313,11 +398,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z e8a0abce86211364eb60bbe6e07d4b05 -2006-02-14T19:06:52.853886Z -6 -nenad +2008-02-28T18:51:53.196120Z +1 +root config.h.in file @@ -325,23 +410,24 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 5c51918deee8d041af37226bd4b4271e -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root -Makefile.am +libtool file -2007-07-24T22:45:02.000000Z -061d814c4cf9a1066e4ff2501fa0a100 -2007-05-29T18:03:36.038276Z -206 -ncorbic +2008-02-28T19:04:34.000000Z +898515184ba0d7df32a1913b7f3ee099 +2008-02-28T18:51:53.196120Z +1 +root +has-props missing file @@ -349,24 +435,27 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z fd5dd60aa8cefab9462677280ea74a61 -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root has-props -aclocal.m4 +Makefile.am file -2007-05-17T23:49:20.000000Z -dd02d76e53ac83f5112d68797e8f52e3 -2007-02-07T19:00:12.109961Z -166 -ncorbic +2008-02-28T19:04:34.000000Z +061d814c4cf9a1066e4ff2501fa0a100 +2008-02-28T18:51:53.196120Z +1 +root + +examples +dir install-sh file @@ -374,25 +463,22 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 92067666ddce97609bd0ec67d36460cd -2006-02-10T16:20:41.709688Z +2008-02-28T18:51:53.196120Z 1 -anthm +root has-props -examples -dir - libsangoma.vcproj file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z a09711e3b6aac93dd48d8e9b3014955f -2006-12-04T22:24:41.715361Z -158 -mikej +2008-02-28T18:51:53.196120Z +1 +root diff --git a/api/libsangoma/.svn/prop-base/config.status.svn-base b/api/libsangoma/.svn/prop-base/config.status.svn-base new file mode 100644 index 0000000..a669705 --- /dev/null +++ b/api/libsangoma/.svn/prop-base/config.status.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 0 + +END diff --git a/api/libsangoma/.svn/prop-base/libtool.svn-base b/api/libsangoma/.svn/prop-base/libtool.svn-base new file mode 100644 index 0000000..a669705 --- /dev/null +++ b/api/libsangoma/.svn/prop-base/libtool.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 0 + +END diff --git a/api/libsangoma/.svn/text-base/Makefile.svn-base b/api/libsangoma/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..ac4db0c --- /dev/null +++ b/api/libsangoma/.svn/text-base/Makefile.svn-base @@ -0,0 +1,679 @@ +# Makefile.in generated by automake 1.9.2 from Makefile.am. +# Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + +SOURCES = $(libsangoma_a_SOURCES) $(libsangoma_la_SOURCES) + +srcdir = . +top_srcdir = . + +pkgdatadir = $(datadir)/libsangoma +pkglibdir = $(libdir)/libsangoma +pkgincludedir = $(includedir)/libsangoma +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = /usr/bin/install -c +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +#am__append_1 = sangoma_pri.c sangoma_pri.h +#am__append_2 = sangoma_pri.h +#am__append_3 = -I$(libpripath) +#am__append_4 = -L$(libpripath) -lpri +DIST_COMMON = README $(am__configure_deps) \ + $(am__library_include_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ + ChangeLog INSTALL NEWS compile config.guess config.sub depcomp \ + install-sh ltmain.sh missing +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libdir)" \ + "$(DESTDIR)$(library_includedir)" +libLIBRARIES_INSTALL = $(INSTALL_DATA) +LIBRARIES = $(lib_LIBRARIES) +ARFLAGS = cru +libsangoma_a_AR = $(AR) $(ARFLAGS) +libsangoma_a_LIBADD = +am_libsangoma_a_OBJECTS = +libsangoma_a_OBJECTS = $(am_libsangoma_a_OBJECTS) +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +libsangoma_la_LIBADD = +am__libsangoma_la_SOURCES_DIST = libsangoma.c libsangoma.h \ + sangoma_pri.c sangoma_pri.h +#am__objects_1 = libsangoma_la-sangoma_pri.lo +am__objects_2 = libsangoma_la-libsangoma.lo $(am__objects_1) +am_libsangoma_la_OBJECTS = $(am__objects_2) +libsangoma_la_OBJECTS = $(am_libsangoma_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link --tag=CC $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libsangoma_a_SOURCES) $(libsangoma_la_SOURCES) +DIST_SOURCES = $(libsangoma_a_SOURCES) \ + $(am__libsangoma_la_SOURCES_DIST) +am__library_include_HEADERS_DIST = libsangoma.h sangoma_pri.h +library_includeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(library_include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = ${SHELL} /usr/src/libsangoma/trunk/missing --run aclocal-1.9 +AMDEP_FALSE = # +AMDEP_TRUE = +AMTAR = ${SHELL} /usr/src/libsangoma/trunk/missing --run tar +AR = ar +AUTOCONF = ${SHELL} /usr/src/libsangoma/trunk/missing --run autoconf +AUTOHEADER = ${SHELL} /usr/src/libsangoma/trunk/missing --run autoheader +AUTOMAKE = ${SHELL} /usr/src/libsangoma/trunk/missing --run automake-1.9 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CPP = gcc -E +CPPFLAGS = +CXX = g++ +CXXCPP = g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -g -O2 +CYGPATH_W = echo +DEFS = -DPACKAGE_NAME=\"libsangoma\" -DPACKAGE_TARNAME=\"libsangoma\" -DPACKAGE_VERSION=\"1.0.0\" -DPACKAGE_STRING=\"libsangoma\ 1.0.0\" -DPACKAGE_BUGREPORT=\"anthmct@yahoo.com\" -DPACKAGE=\"libsangoma\" -DVERSION=\"1.0.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DHAVE_FCNTL_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MATH_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_SOCKET_H=1 -DSELECT_TYPE_ARG1=int -DSELECT_TYPE_ARG234=\(fd_set\ \*\) -DSELECT_TYPE_ARG5=\(struct\ timeval\ \*\) -DHAVE_GETTIMEOFDAY=1 -DHAVE_MEMSET=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 +DEPDIR = .deps +ECHO = echo +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = grep -E +EXEEXT = +F77 = g77 +FFLAGS = -g -O2 +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s +LDFLAGS = +LIBOBJS = +LIBPRI_FALSE = +LIBPRI_TRUE = # +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /usr/src/libsangoma/trunk/missing --run makeinfo +OBJEXT = o +PACKAGE = libsangoma +PACKAGE_BUGREPORT = anthmct@yahoo.com +PACKAGE_NAME = libsangoma +PACKAGE_STRING = libsangoma 1.0.0 +PACKAGE_TARNAME = libsangoma +PACKAGE_VERSION = 1.0.0 +PATH_SEPARATOR = : +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +VERSION = 1.0.0 +ac_ct_AR = ar +ac_ct_CC = gcc +ac_ct_CXX = g++ +ac_ct_F77 = g77 +ac_ct_RANLIB = ranlib +ac_ct_STRIP = strip +am__fastdepCC_FALSE = # +am__fastdepCC_TRUE = +am__fastdepCXX_FALSE = # +am__fastdepCXX_TRUE = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = i686-pc-linux-gnu +build_alias = +build_cpu = i686 +build_os = linux-gnu +build_vendor = pc +datadir = ${prefix}/share +exec_prefix = ${prefix} +host = i686-pc-linux-gnu +host_alias = +host_cpu = i686 +host_os = linux-gnu +host_vendor = pc +includedir = ${prefix}/include +infodir = ${prefix}/info +install_sh = /usr/src/libsangoma/trunk/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +libpripath = +localstatedir = ${prefix}/var +mandir = ${prefix}/man +mkdir_p = mkdir -p -- +oldincludedir = /usr/include +prefix = /usr/local +program_transform_name = s,x,x, +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +sysconfdir = ${prefix}/etc +target_alias = +KINC = /lib/modules/$(shell uname -r)/build +WINC = ../../patches/kdrivers/include +AM_CFLAGS = -fPIC -Wall -Wstrict-prototypes -Wmissing-prototypes -g -I$(WINC) -I$(KINC)/include -I. \ + -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O2 -D_DEBUG_=2 -D_GNUC_ -I../lib -I$(KINC)/include + +LIB_SOURCES = libsangoma.c libsangoma.h $(am__append_1) +library_includedir = $(includedir) +library_include_HEADERS = libsangoma.h $(am__append_2) +lib_LTLIBRARIES = libsangoma.la +libsangoma_la_CFLAGS = $(AM_CFLAGS) $(am__append_3) +libsangoma_la_LDFLAGS = -version-info 1:0:0 $(am__append_4) +libsangoma_la_SOURCES = $(LIB_SOURCES) +lib_LIBRARIES = libsangoma.a +libsangoma_a_CFLAGS = $(AM_CFLAGS) +libsangoma_a_SOURCES = $(LIB_SOUCES) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + p=$(am__strip_dir) \ + echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \ + $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) +libsangoma.a: $(libsangoma_a_OBJECTS) $(libsangoma_a_DEPENDENCIES) + -rm -f libsangoma.a + $(libsangoma_a_AR) libsangoma.a $(libsangoma_a_OBJECTS) $(libsangoma_a_LIBADD) + $(RANLIB) libsangoma.a +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libsangoma.la: $(libsangoma_la_OBJECTS) $(libsangoma_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libsangoma_la_LDFLAGS) $(libsangoma_la_OBJECTS) $(libsangoma_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/libsangoma_la-libsangoma.Plo +include ./$(DEPDIR)/libsangoma_la-sangoma_pri.Plo + +.c.o: + if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c $< + +.c.obj: + if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: + if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ + then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +# source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(LTCOMPILE) -c -o $@ $< + +libsangoma_la-libsangoma.lo: libsangoma.c + if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-libsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c; \ + then mv -f "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" "$(DEPDIR)/libsangoma_la-libsangoma.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libsangoma.Tpo"; exit 1; fi +# source='libsangoma.c' object='libsangoma_la-libsangoma.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c + +libsangoma_la-sangoma_pri.lo: sangoma_pri.c + if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-sangoma_pri.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c; \ + then mv -f "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" "$(DEPDIR)/libsangoma_la-sangoma_pri.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo"; exit 1; fi +# source='sangoma_pri.c' object='libsangoma_la-sangoma_pri.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-library_includeHEADERS: $(library_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(library_includedir)" || $(mkdir_p) "$(DESTDIR)$(library_includedir)" + @list='$(library_include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(library_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(library_includedir)/$$f'"; \ + $(library_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(library_includedir)/$$f"; \ + done + +uninstall-library_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(library_include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(library_includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(library_includedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(library_includedir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES clean-libLTLIBRARIES \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-library_includeHEADERS + +install-exec-am: install-libLIBRARIES install-libLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-libLIBRARIES \ + uninstall-libLTLIBRARIES uninstall-library_includeHEADERS + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ + clean-generic clean-libLIBRARIES clean-libLTLIBRARIES \ + clean-libtool ctags dist dist-all dist-bzip2 dist-gzip \ + dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-libLIBRARIES \ + install-libLTLIBRARIES install-library_includeHEADERS \ + install-man install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am uninstall-libLIBRARIES \ + uninstall-libLTLIBRARIES uninstall-library_includeHEADERS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/api/libsangoma/.svn/text-base/aclocal.m4.svn-base b/api/libsangoma/.svn/text-base/aclocal.m4.svn-base deleted file mode 100644 index 8a90c6a..0000000 --- a/api/libsangoma/.svn/text-base/aclocal.m4.svn-base +++ /dev/null @@ -1,6945 +0,0 @@ -# generated automatically by aclocal 1.9.2 -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- - -# serial 47 AC_PROG_LIBTOOL - - -# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) -# ----------------------------------------------------------- -# If this macro is not defined by Autoconf, define it here. -m4_ifdef([AC_PROVIDE_IFELSE], - [], - [m4_define([AC_PROVIDE_IFELSE], - [m4_ifdef([AC_PROVIDE_$1], - [$2], [$3])])]) - - -# AC_PROG_LIBTOOL -# --------------- -AC_DEFUN([AC_PROG_LIBTOOL], -[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl -dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX -dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. - AC_PROVIDE_IFELSE([AC_PROG_CXX], - [AC_LIBTOOL_CXX], - [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX - ])]) -dnl And a similar setup for Fortran 77 support - AC_PROVIDE_IFELSE([AC_PROG_F77], - [AC_LIBTOOL_F77], - [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 -])]) - -dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. -dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run -dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. - AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [ifdef([AC_PROG_GCJ], - [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) - ifdef([A][M_PROG_GCJ], - [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) - ifdef([LT_AC_PROG_GCJ], - [define([LT_AC_PROG_GCJ], - defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) -])])# AC_PROG_LIBTOOL - - -# _AC_PROG_LIBTOOL -# ---------------- -AC_DEFUN([_AC_PROG_LIBTOOL], -[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl -AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl -AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl -AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -# Prevent multiple expansion -define([AC_PROG_LIBTOOL], []) -])# _AC_PROG_LIBTOOL - - -# AC_LIBTOOL_SETUP -# ---------------- -AC_DEFUN([AC_LIBTOOL_SETUP], -[AC_PREREQ(2.50)dnl -AC_REQUIRE([AC_ENABLE_SHARED])dnl -AC_REQUIRE([AC_ENABLE_STATIC])dnl -AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_LD])dnl -AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl -AC_REQUIRE([AC_PROG_NM])dnl - -AC_REQUIRE([AC_PROG_LN_S])dnl -AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl -# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! -AC_REQUIRE([AC_OBJEXT])dnl -AC_REQUIRE([AC_EXEEXT])dnl -dnl - -AC_LIBTOOL_SYS_MAX_CMD_LEN -AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -AC_LIBTOOL_OBJDIR - -AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl -_LT_AC_PROG_ECHO_BACKSLASH - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' -[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] - -# Same as above, but do not quote variable references. -[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" - -AC_CHECK_TOOL(AR, ar, false) -AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_CHECK_TOOL(STRIP, strip, :) - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$SED" && SED=sed -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" - ;; - *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - AC_PATH_MAGIC - fi - ;; -esac - -AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) -AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], -enable_win32_dll=yes, enable_win32_dll=no) - -AC_ARG_ENABLE([libtool-lock], - [AC_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -AC_ARG_WITH([pic], - [AC_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) -test -z "$pic_mode" && pic_mode=default - -# Use C for the default configuration in the libtool script -tagname= -AC_LIBTOOL_LANG_C_CONFIG -_LT_AC_TAGCONFIG -])# AC_LIBTOOL_SETUP - - -# _LT_AC_SYS_COMPILER -# ------------------- -AC_DEFUN([_LT_AC_SYS_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_AC_SYS_COMPILER - - -# _LT_AC_SYS_LIBPATH_AIX -# ---------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], -[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi -])# _LT_AC_SYS_LIBPATH_AIX - - -# _LT_AC_SHELL_INIT(ARG) -# ---------------------- -AC_DEFUN([_LT_AC_SHELL_INIT], -[ifdef([AC_DIVERSION_NOTICE], - [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -$1 -AC_DIVERT_POP -])# _LT_AC_SHELL_INIT - - -# _LT_AC_PROG_ECHO_BACKSLASH -# -------------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], -[_LT_AC_SHELL_INIT([ -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -echo=${ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null && - echo_test_string="`eval $cmd`" && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(ECHO) -])])# _LT_AC_PROG_ECHO_BACKSLASH - - -# _LT_AC_LOCK -# ----------- -AC_DEFUN([_LT_AC_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AC_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case "`/usr/bin/file conftest.o`" in - *32-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], -[*-*-cygwin* | *-*-mingw* | *-*-pw32*) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; - ]) -esac - -need_locks="$enable_libtool_lock" - -])# _LT_AC_LOCK - - -# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], -[AC_REQUIRE([LT_AC_PROG_SED]) -AC_CACHE_CHECK([$1], [$2], - [$2=no - ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then - $2=yes - fi - fi - $rm conftest* -]) - -if test x"[$]$2" = xyes; then - ifelse([$5], , :, [$5]) -else - ifelse([$6], , :, [$6]) -fi -])# AC_LIBTOOL_COMPILER_OPTION - - -# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ------------------------------------------------------------ -# Check whether the given compiler option works -AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], -[AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - printf "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - else - $2=yes - fi - fi - $rm conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - ifelse([$4], , :, [$4]) -else - ifelse([$5], , :, [$5]) -fi -])# AC_LIBTOOL_LINKER_OPTION - - -# AC_LIBTOOL_SYS_MAX_CMD_LEN -# -------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], -[# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ - = "XX$teststring") >/dev/null 2>&1 && - new_result=`expr "X$teststring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - teststring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -])# AC_LIBTOOL_SYS_MAX_CMD_LEN - - -# _LT_AC_CHECK_DLFCN -# -------------------- -AC_DEFUN([_LT_AC_CHECK_DLFCN], -[AC_CHECK_HEADERS(dlfcn.h)dnl -])# _LT_AC_CHECK_DLFCN - - -# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ------------------------------------------------------------------ -AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], -[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -}] -EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_unknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_AC_TRY_DLOPEN_SELF - - -# AC_LIBTOOL_DLOPEN_SELF -# ------------------- -AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], -[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -])# AC_LIBTOOL_DLOPEN_SELF - - -# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) -# --------------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler -AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s out/conftest.err; then - _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* -]) -])# AC_LIBTOOL_PROG_CC_C_O - - -# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) -# ----------------------------------------- -# Check to see if we can do hard links to lock some files if needed -AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], -[AC_REQUIRE([_LT_AC_LOCK])dnl - -hard_links="nottested" -if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS - - -# AC_LIBTOOL_OBJDIR -# ----------------- -AC_DEFUN([AC_LIBTOOL_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -])# AC_LIBTOOL_OBJDIR - - -# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) -# ---------------------------------------------- -# Check hardcoding attributes. -AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_AC_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ - test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \ - test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then - - # We can hardcode non-existant directories. - if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_AC_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_AC_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_AC_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH - - -# AC_LIBTOOL_SYS_LIB_STRIP -# ------------------------ -AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], -[striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) -fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -])# AC_LIBTOOL_SYS_LIB_STRIP - - -# AC_LIBTOOL_SYS_DYNAMIC_LINKER -# ----------------------------- -# PORTME Fill in your ld.so characteristics -AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], -[AC_MSG_CHECKING([dynamic linker characteristics]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case "$host_cpu" in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # find out which ABI we are using - libsuff= - case "$host_cpu" in - x86_64*|s390x*|powerpc64*) - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *64-bit*) - libsuff=64 - sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" - ;; - esac - fi - rm -rf conftest* - ;; - esac - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`$SED -e 's/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g' /etc/ld.so.conf | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - need_version=yes - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no -])# AC_LIBTOOL_SYS_DYNAMIC_LINKER - - -# _LT_AC_TAGCONFIG -# ---------------- -AC_DEFUN([_LT_AC_TAGCONFIG], -[AC_ARG_WITH([tags], - [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], - [include additional configurations @<:@automatic@:>@])], - [tagnames="$withval"]) - -if test -f "$ltmain" && test -n "$tagnames"; then - if test ! -f "${ofile}"; then - AC_MSG_WARN([output file `$ofile' does not exist]) - fi - - if test -z "$LTCC"; then - eval "`$SHELL ${ofile} --config | grep '^LTCC='`" - if test -z "$LTCC"; then - AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) - else - AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) - fi - fi - - # Extract list of available tagged configurations in $ofile. - # Note that this assumes the entire list is on one line. - available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` - - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for tagname in $tagnames; do - IFS="$lt_save_ifs" - # Check whether tagname contains only valid characters - case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in - "") ;; - *) AC_MSG_ERROR([invalid tag name: $tagname]) - ;; - esac - - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null - then - AC_MSG_ERROR([tag name \"$tagname\" already exists]) - fi - - # Update the list of available tags. - if test -n "$tagname"; then - echo appending configuration tag \"$tagname\" to $ofile - - case $tagname in - CXX) - if test -n "$CXX" && test "X$CXX" != "Xno"; then - AC_LIBTOOL_LANG_CXX_CONFIG - else - tagname="" - fi - ;; - - F77) - if test -n "$F77" && test "X$F77" != "Xno"; then - AC_LIBTOOL_LANG_F77_CONFIG - else - tagname="" - fi - ;; - - GCJ) - if test -n "$GCJ" && test "X$GCJ" != "Xno"; then - AC_LIBTOOL_LANG_GCJ_CONFIG - else - tagname="" - fi - ;; - - RC) - AC_LIBTOOL_LANG_RC_CONFIG - ;; - - *) - AC_MSG_ERROR([Unsupported tag name: $tagname]) - ;; - esac - - # Append the new tag name to the list of available tags. - if test -n "$tagname" ; then - available_tags="$available_tags $tagname" - fi - fi - done - IFS="$lt_save_ifs" - - # Now substitute the updated list of available tags. - if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then - mv "${ofile}T" "$ofile" - chmod +x "$ofile" - else - rm -f "${ofile}T" - AC_MSG_ERROR([unable to update list of available tagged configurations.]) - fi -fi -])# _LT_AC_TAGCONFIG - - -# AC_LIBTOOL_DLOPEN -# ----------------- -# enable checks for dlopen support -AC_DEFUN([AC_LIBTOOL_DLOPEN], - [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) -])# AC_LIBTOOL_DLOPEN - - -# AC_LIBTOOL_WIN32_DLL -# -------------------- -# declare package support for building win32 dll's -AC_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) -])# AC_LIBTOOL_WIN32_DLL - - -# AC_ENABLE_SHARED([DEFAULT]) -# --------------------------- -# implement the --enable-shared flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_SHARED], -[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([shared], - [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]AC_ENABLE_SHARED_DEFAULT) -])# AC_ENABLE_SHARED - - -# AC_DISABLE_SHARED -# ----------------- -#- set the default shared flag to --disable-shared -AC_DEFUN([AC_DISABLE_SHARED], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_SHARED(no) -])# AC_DISABLE_SHARED - - -# AC_ENABLE_STATIC([DEFAULT]) -# --------------------------- -# implement the --enable-static flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_STATIC], -[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([static], - [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]AC_ENABLE_STATIC_DEFAULT) -])# AC_ENABLE_STATIC - - -# AC_DISABLE_STATIC -# ----------------- -# set the default static flag to --disable-static -AC_DEFUN([AC_DISABLE_STATIC], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_STATIC(no) -])# AC_DISABLE_STATIC - - -# AC_ENABLE_FAST_INSTALL([DEFAULT]) -# --------------------------------- -# implement the --enable-fast-install flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_FAST_INSTALL], -[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([fast-install], - [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) -])# AC_ENABLE_FAST_INSTALL - - -# AC_DISABLE_FAST_INSTALL -# ----------------------- -# set the default to --disable-fast-install -AC_DEFUN([AC_DISABLE_FAST_INSTALL], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_FAST_INSTALL(no) -])# AC_DISABLE_FAST_INSTALL - - -# AC_LIBTOOL_PICMODE([MODE]) -# -------------------------- -# implement the --with-pic flag -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -AC_DEFUN([AC_LIBTOOL_PICMODE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -pic_mode=ifelse($#,1,$1,default) -])# AC_LIBTOOL_PICMODE - - -# AC_PROG_EGREP -# ------------- -# This is predefined starting with Autoconf 2.54, so this conditional -# definition can be removed once we require Autoconf 2.54 or later. -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], -[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], - [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' - fi]) - EGREP=$ac_cv_prog_egrep - AC_SUBST([EGREP]) -])]) - - -# AC_PATH_TOOL_PREFIX -# ------------------- -# find a file program which can recognise shared library -AC_DEFUN([AC_PATH_TOOL_PREFIX], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="ifelse([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -])# AC_PATH_TOOL_PREFIX - - -# AC_PATH_MAGIC -# ------------- -# find a file program which can recognise a shared library -AC_DEFUN([AC_PATH_MAGIC], -[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# AC_PATH_MAGIC - - -# AC_PROG_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([AC_PROG_LD], -[AC_ARG_WITH([gnu-ld], - [AC_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no]) -AC_REQUIRE([LT_AC_PROG_SED])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case "$host_cpu" in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux*) - case $host_cpu in - alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*|x86_64*) - lt_cv_deplibs_check_method=pass_all ;; - *) - # glibc up to 2.1.1 does not perform some relocations on ARM - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; - esac - lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -nto-qnx*) - lt_cv_deplibs_check_method=unknown - ;; - -openbsd*) - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' - else - lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown -])# AC_DEPLIBS_CHECK_METHOD - - -# AC_PROG_NM -# ---------- -# find the pathname to a BSD-compatible name lister -AC_DEFUN([AC_PROG_NM], -[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - esac - fi - done - IFS="$lt_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi]) -NM="$lt_cv_path_NM" -])# AC_PROG_NM - - -# AC_CHECK_LIBM -# ------------- -# check for math library -AC_DEFUN([AC_CHECK_LIBM], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -])# AC_CHECK_LIBM - - -# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) -# ----------------------------------- -# sets LIBLTDL to the link flags for the libltdl convenience library and -# LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL -# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If -# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will -# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. -AC_DEFUN([AC_LIBLTDL_CONVENIENCE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - case $enable_ltdl_convenience in - no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; - "") enable_ltdl_convenience=yes - ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; - esac - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -])# AC_LIBLTDL_CONVENIENCE - - -# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) -# ----------------------------------- -# sets LIBLTDL to the link flags for the libltdl installable library and -# LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-install to the configure arguments. Note that LIBLTDL -# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If -# DIRECTORY is not provided and an installed libltdl is not found, it is -# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' -# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single -# quotes!). If your package is not flat and you're not using automake, -# define top_builddir and top_srcdir appropriately in the Makefiles. -# In the future, this macro may have to be called after AC_PROG_LIBTOOL. -AC_DEFUN([AC_LIBLTDL_INSTALLABLE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - AC_CHECK_LIB(ltdl, lt_dlinit, - [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], - [if test x"$enable_ltdl_install" = xno; then - AC_MSG_WARN([libltdl not installed, but installation disabled]) - else - enable_ltdl_install=yes - fi - ]) - if test x"$enable_ltdl_install" = x"yes"; then - ac_configure_args="$ac_configure_args --enable-ltdl-install" - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - else - ac_configure_args="$ac_configure_args --enable-ltdl-install=no" - LIBLTDL="-lltdl" - LTDLINCL= - fi - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -])# AC_LIBLTDL_INSTALLABLE - - -# AC_LIBTOOL_CXX -# -------------- -# enable support for C++ libraries -AC_DEFUN([AC_LIBTOOL_CXX], -[AC_REQUIRE([_LT_AC_LANG_CXX]) -])# AC_LIBTOOL_CXX - - -# _LT_AC_LANG_CXX -# --------------- -AC_DEFUN([_LT_AC_LANG_CXX], -[AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([AC_PROG_CXXCPP]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) -])# _LT_AC_LANG_CXX - - -# AC_LIBTOOL_F77 -# -------------- -# enable support for Fortran 77 libraries -AC_DEFUN([AC_LIBTOOL_F77], -[AC_REQUIRE([_LT_AC_LANG_F77]) -])# AC_LIBTOOL_F77 - - -# _LT_AC_LANG_F77 -# --------------- -AC_DEFUN([_LT_AC_LANG_F77], -[AC_REQUIRE([AC_PROG_F77]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) -])# _LT_AC_LANG_F77 - - -# AC_LIBTOOL_GCJ -# -------------- -# enable support for GCJ libraries -AC_DEFUN([AC_LIBTOOL_GCJ], -[AC_REQUIRE([_LT_AC_LANG_GCJ]) -])# AC_LIBTOOL_GCJ - - -# _LT_AC_LANG_GCJ -# --------------- -AC_DEFUN([_LT_AC_LANG_GCJ], -[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], - [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], - [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], - [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], - [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) -])# _LT_AC_LANG_GCJ - - -# AC_LIBTOOL_RC -# -------------- -# enable support for Windows resource files -AC_DEFUN([AC_LIBTOOL_RC], -[AC_REQUIRE([LT_AC_PROG_RC]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) -])# AC_LIBTOOL_RC - - -# AC_LIBTOOL_LANG_C_CONFIG -# ------------------------ -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) -AC_DEFUN([_LT_AC_LANG_C_CONFIG], -[lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' - -_LT_AC_SYS_COMPILER - -# -# Check for any special shared library compilation flags. -# -_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' - ;; - esac -fi -if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then - AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) - if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : - else - AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) - _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), - $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), - [], - [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) - - -AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) - -# Report which librarie types wil actually be built -AC_MSG_CHECKING([if libtool supports shared libraries]) -AC_MSG_RESULT([$can_build_shared]) - -AC_MSG_CHECKING([whether to build shared libraries]) -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case "$host_os" in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4* | aix5*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - darwin* | rhapsody*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case "$host_os" in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; -esac -AC_MSG_RESULT([$enable_shared]) - -AC_MSG_CHECKING([whether to build static libraries]) -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -AC_MSG_RESULT([$enable_static]) - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_POP -CC="$lt_save_CC" -])# AC_LIBTOOL_LANG_C_CONFIG - - -# AC_LIBTOOL_LANG_CXX_CONFIG -# -------------------------- -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) -AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], -[AC_LANG_PUSH(C++) -AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([AC_PROG_CXXCPP]) - -_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_AC_TAGVAR(allow_undefined_flag, $1)= -_LT_AC_TAGVAR(always_export_symbols, $1)=no -_LT_AC_TAGVAR(archive_expsym_cmds, $1)= -_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_direct, $1)=no -_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= -_LT_AC_TAGVAR(hardcode_minus_L, $1)=no -_LT_AC_TAGVAR(hardcode_automatic, $1)=no -_LT_AC_TAGVAR(module_cmds, $1)= -_LT_AC_TAGVAR(module_expsym_cmds, $1)= -_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown -_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_AC_TAGVAR(no_undefined_flag, $1)= -_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= -_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Dependencies to place before and after the object being linked: -_LT_AC_TAGVAR(predep_objects, $1)= -_LT_AC_TAGVAR(postdep_objects, $1)= -_LT_AC_TAGVAR(predeps, $1)= -_LT_AC_TAGVAR(postdeps, $1)= -_LT_AC_TAGVAR(compiler_lib_search_path, $1)= - -# Source file extension for C++ test sources. -ac_ext=cc - -# Object file extension for compiled C++ test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_AC_SYS_COMPILER - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_LD=$LD -lt_save_GCC=$GCC -GCC=$GXX -lt_save_with_gnu_ld=$with_gnu_ld -lt_save_path_LD=$lt_cv_path_LD -if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx -else - unset lt_cv_prog_gnu_ld -fi -if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX -else - unset lt_cv_path_LD -fi -test -z "${LDCXX+set}" || LD=$LDCXX -CC=${CXX-"c++"} -compiler=$CC -_LT_AC_TAGVAR(compiler, $1)=$CC -cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` - -# We don't want -fno-exception wen compiling C++ code, so set the -# no_builtin_flag separately -if test "$GXX" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' -else - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= -fi - -if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - AC_PROG_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ - grep 'no-whole-archive' > /dev/null; then - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - -else - GXX=no - with_gnu_ld=no - wlarc= -fi - -# PORTME: fill in a description of your system's C++ link characteristics -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -_LT_AC_TAGVAR(ld_shlibs, $1)=yes -case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_AC_TAGVAR(archive_cmds, $1)='' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GXX" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - else - # We have old collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds it's shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - darwin* | rhapsody*) - if test "$GXX" = yes; then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case "$host_os" in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - dgux*) - case $cc_basename in - ec++) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - freebsd[12]*) - # C++ shared libraries reported to be fairly broken before switch to ELF - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - freebsd-elf*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - freebsd* | kfreebsd*-gnu) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - ;; - gnu*) - ;; - hpux9*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aCC) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - case "$host_cpu" in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - ;; - *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case "$host_cpu" in - hppa*64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - *) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aCC) - case "$host_cpu" in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case "$host_cpu" in - ia64*|hppa*64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - irix5* | irix6*) - case $cc_basename in - CC) - # SGI C++ - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' - fi - fi - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - linux*) - case $cc_basename in - KCC) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc) - # Intel C++ - with_gnu_ld=yes - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - cxx) - # Compaq C++ - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - esac - ;; - lynxos*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - m88k*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - mvs*) - case $cc_basename in - cxx) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - osf3*) - case $cc_basename in - KCC) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - - ;; - RCC) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - cxx) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - osf4* | osf5*) - case $cc_basename in - KCC) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' - ;; - RCC) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - cxx) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ - $rm $lib.exp' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - psos*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - sco*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - lcc) - # Lucid - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - solaris*) - case $cc_basename in - CC) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | grep -v '^2\.7' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - fi - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - fi - ;; - esac - ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - tandem*) - case $cc_basename in - NCC) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - vxworks*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; -esac -AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_AC_TAGVAR(GCC, $1)="$GXX" -_LT_AC_TAGVAR(LD, $1)="$LD" - -AC_LIBTOOL_POSTDEP_PREDEP($1) -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_POP -CC=$lt_save_CC -LDCXX=$LD -LD=$lt_save_LD -GCC=$lt_save_GCC -with_gnu_ldcxx=$with_gnu_ld -with_gnu_ld=$lt_save_with_gnu_ld -lt_cv_path_LDCXX=$lt_cv_path_LD -lt_cv_path_LD=$lt_save_path_LD -lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld -lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -])# AC_LIBTOOL_LANG_CXX_CONFIG - -# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) -# ------------------------ -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" -ifelse([$1], [], -[#! $SHELL - -# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# -# This file is part of GNU Libtool: -# Originally by Gordon Matzigkeit , 1996 -# -# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="$SED -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -# The names of the tagged configurations supported by this script. -available_tags= - -# ### BEGIN LIBTOOL CONFIG], -[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) - -# Is the compiler the GNU C compiler? -with_gcc=$_LT_AC_TAGVAR(GCC, $1) - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_[]_LT_AC_TAGVAR(LD, $1) - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) - -# Commands used to build and install a shared archive. -archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) -archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) -module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" - -# Set to yes if exported symbols are required. -always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) - -# The commands to list exported symbols. -export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) - -# Symbols that must always be exported. -include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) - -ifelse([$1],[], -[# ### END LIBTOOL CONFIG], -[# ### END LIBTOOL TAG CONFIG: $tagname]) - -__EOF__ - -ifelse([$1],[], [ - case $host_os in - aix3*) - cat <<\EOF >> "$cfgfile" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || \ - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -]) -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi -])# AC_LIBTOOL_CONFIG - - -# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------------------- -AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl - -_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - - AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI - - -# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -# --------------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], -[AC_REQUIRE([AC_CANONICAL_HOST]) -AC_REQUIRE([AC_PROG_NM]) -AC_REQUIRE([AC_OBJEXT]) -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) # Its linker distinguishes data from code symbols - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris* | sysv5*) - symcode='[[BDRT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Write the raw and C identifiers. - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if grep ' nm_test_var$' "$nlist" >/dev/null; then - if grep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' - - cat <> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[[]] = -{ -EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi -]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE - - -# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) -# --------------------------------------- -AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], -[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= - -AC_MSG_CHECKING([for $compiler option to produce PIC]) - ifelse([$1],[CXX],[ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | os2* | pw32*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix4* | aix5*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68) - # Green Hills C++ Compiler - # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | kfreebsd*-gnu) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - if test "$host_cpu" != ia64; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux*) - case $cc_basename in - KCC) - # KAI C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - icpc) - # Intel C++ - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - cxx) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC) - # Rational C++ 2.4.1 - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx) - # Digital/Compaq C++ - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - sco*) - case $cc_basename in - CC) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - *) - ;; - esac - ;; - solaris*) - case $cc_basename in - CC) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC) - # Sun C++ 4.x - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc) - # Lucid - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC) - # NonStop-UX NCC 3.20 - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - unixware*) - ;; - vxworks*) - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case "$host_cpu" in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - newsos6) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - linux*) - case $CC in - icc* | ecc*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - ccc*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' - ;; - - solaris*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sunos4*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - uts4*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then - AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), - [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -case "$host_os" in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" - ;; -esac -]) - - -# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) -# ------------------------------------ -# See if the linker supports building shared libraries. -AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], -[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -ifelse([$1],[CXX],[ - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix4* | aix5*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - else - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' - ;; - *) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -],[ - runpath_var= - _LT_AC_TAGVAR(allow_undefined_flag, $1)= - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)= - _LT_AC_TAGVAR(archive_expsym_cmds, $1)= - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= - _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown - _LT_AC_TAGVAR(hardcode_automatic, $1)=no - _LT_AC_TAGVAR(module_cmds, $1)= - _LT_AC_TAGVAR(module_expsym_cmds, $1)= - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_AC_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_AC_TAGVAR(ld_shlibs, $1)=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - ld_shlibs=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - _LT_AC_TAGVAR(ld_shlibs, $1)=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sunos4*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds" - fi - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then - runpath_var=LD_RUN_PATH - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - else - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_AC_TAGVAR(archive_cmds, $1)='' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - else - # We have old collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds it's shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - # see comment about different semantics on the GNU ld section - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - bsdi4*) - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - darwin* | rhapsody*) - if test "$GXX" = yes ; then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case "$host_os" in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - dgux*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case "$host_cpu" in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - ;; - *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - sco3.2v5*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; - esac - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4.2uw2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv5*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - fi -]) -AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_AC_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) - _LT_AC_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) - then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - else - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) - ;; - esac - fi - ;; -esac -])# AC_LIBTOOL_PROG_LD_SHLIBS - - -# _LT_AC_FILE_LTDLL_C -# ------------------- -# Be careful that the start marker always follows a newline. -AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ -# /* ltdll.c starts here */ -# #define WIN32_LEAN_AND_MEAN -# #include -# #undef WIN32_LEAN_AND_MEAN -# #include -# -# #ifndef __CYGWIN__ -# # ifdef __CYGWIN32__ -# # define __CYGWIN__ __CYGWIN32__ -# # endif -# #endif -# -# #ifdef __cplusplus -# extern "C" { -# #endif -# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); -# #ifdef __cplusplus -# } -# #endif -# -# #ifdef __CYGWIN__ -# #include -# DECLARE_CYGWIN_DLL( DllMain ); -# #endif -# HINSTANCE __hDllInstance_base; -# -# BOOL APIENTRY -# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) -# { -# __hDllInstance_base = hInst; -# return TRUE; -# } -# /* ltdll.c ends here */ -])# _LT_AC_FILE_LTDLL_C - - -# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) -# --------------------------------- -AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) - - -# old names -AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) -AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) -AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) -AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) -AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) - -# This is just to silence aclocal about the macro not being used -ifelse([AC_DISABLE_FAST_INSTALL]) - -AC_DEFUN([LT_AC_PROG_GCJ], -[AC_CHECK_TOOL(GCJ, gcj, no) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS) -]) - -AC_DEFUN([LT_AC_PROG_RC], -[AC_CHECK_TOOL(RC, windres, no) -]) - -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -# LT_AC_PROG_SED -# -------------- -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -AC_DEFUN([LT_AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && break - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -SED=$lt_cv_path_SED -]) -AC_MSG_RESULT([$SED]) -]) - -# -*- Autoconf -*- -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. -# Generated from amversion.in; do not edit by hand. - -# 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., 59 Temple Place - Suite 330, Boston, MA - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION so it can be traced. -# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.2])]) - -# AM_AUX_DIR_EXPAND - -# Copyright (C) 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 6 - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE]) -AC_SUBST([$1_FALSE]) -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# serial 7 -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH]) -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -#serial 2 - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # So let's grep whole file. - if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# This macro actually does too much some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 11 - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.58])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -# test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && - test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) -AM_PROG_INSTALL_SH -AM_PROG_INSTALL_STRIP -AC_REQUIRE([AM_PROG_MKDIR_P])dnl -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl -]) -]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $1 | $1:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. - -# Copyright (C) 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -install_sh=${install_sh-"$am_aux_dir/install-sh"} -AC_SUBST(install_sh)]) - -# -*- Autoconf -*- -# Copyright (C) 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 1 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 2 - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# -*- Autoconf -*- - - -# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) -fi -]) - -# AM_PROG_MKDIR_P -# --------------- -# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. - -# Copyright (C) 2003, 2004 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories -# created by `make install' are always world readable, even if the -# installer happens to have an overly restrictive umask (e.g. 077). -# This was a mistake. There are at least two reasons why we must not -# use `-m 0755': -# - it causes special bits like SGID to be ignored, -# - it may be too restrictive (some setups expect 775 directories). -# -# Do not use -m 0755 and let people choose whatever they expect by -# setting umask. -# -# We cannot accept any implementation of `mkdir' that recognizes `-p'. -# Some implementations (such as Solaris 8's) are not thread-safe: if a -# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' -# concurrently, both version can detect that a/ is missing, but only -# one can create it and the other will error out. Consequently we -# restrict ourselves to GNU make (using the --version option ensures -# this.) -AC_DEFUN([AM_PROG_MKDIR_P], -[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in - # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' -else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - for d in ./-p ./--version; - do - test -d $d && rmdir $d - done - # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. - if test -f "$ac_aux_dir/mkinstalldirs"; then - mkdir_p='$(mkinstalldirs)' - else - mkdir_p='$(install_sh) -d' - fi -fi -AC_SUBST([mkdir_p])]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 2 - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# ------------------------------ -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) - -# _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# -# Check to make sure that the build environment is sane. -# - -# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT(yes)]) - -# AM_PROG_INSTALL_STRIP - -# Copyright (C) 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# One issue with vendor `install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 1 - - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - diff --git a/api/libsangoma/.svn/text-base/config.log.svn-base b/api/libsangoma/.svn/text-base/config.log.svn-base new file mode 100644 index 0000000..02c7292 --- /dev/null +++ b/api/libsangoma/.svn/text-base/config.log.svn-base @@ -0,0 +1,1053 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libsangoma configure 1.0.0, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ ./configure --no-create --no-recursion + +## --------- ## +## Platform. ## +## --------- ## + +hostname = sangoma_mantis +uname -m = i686 +uname -r = 2.6.9-22.EL +uname -s = Linux +uname -v = #1 Sat Oct 8 17:48:27 CDT 2005 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = i686 +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /usr/kerberos/sbin +PATH: /usr/kerberos/bin +PATH: /usr/local/sbin +PATH: /usr/local/bin +PATH: /sbin +PATH: /bin +PATH: /usr/sbin +PATH: /usr/bin +PATH: /usr/X11R6/bin +PATH: /root/bin + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:1551: checking for a BSD-compatible install +configure:1606: result: /usr/bin/install -c +configure:1617: checking whether build environment is sane +configure:1660: result: yes +configure:1725: checking for gawk +configure:1741: found /bin/gawk +configure:1751: result: gawk +configure:1761: checking whether make sets $(MAKE) +configure:1781: result: yes +configure:1996: checking for gcc +configure:2012: found /usr/bin/gcc +configure:2022: result: gcc +configure:2266: checking for C compiler version +configure:2269: gcc --version &5 +gcc (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2) +Copyright (C) 2004 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:2272: $? = 0 +configure:2274: gcc -v &5 +Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.4/specs +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux +Thread model: posix +gcc version 3.4.4 20050721 (Red Hat 3.4.4-2) +configure:2277: $? = 0 +configure:2279: gcc -V &5 +gcc: `-V' option must have argument +configure:2282: $? = 1 +configure:2305: checking for C compiler default output file name +configure:2308: gcc conftest.c >&5 +configure:2311: $? = 0 +configure:2357: result: a.out +configure:2362: checking whether the C compiler works +configure:2368: ./a.out +configure:2371: $? = 0 +configure:2388: result: yes +configure:2395: checking whether we are cross compiling +configure:2397: result: no +configure:2400: checking for suffix of executables +configure:2402: gcc -o conftest conftest.c >&5 +configure:2405: $? = 0 +configure:2430: result: +configure:2436: checking for suffix of object files +configure:2457: gcc -c conftest.c >&5 +configure:2460: $? = 0 +configure:2482: result: o +configure:2486: checking whether we are using the GNU C compiler +configure:2510: gcc -c conftest.c >&5 +configure:2516: $? = 0 +configure:2520: test -z + || test ! -s conftest.err +configure:2523: $? = 0 +configure:2526: test -s conftest.o +configure:2529: $? = 0 +configure:2542: result: yes +configure:2548: checking whether gcc accepts -g +configure:2569: gcc -c -g conftest.c >&5 +configure:2575: $? = 0 +configure:2579: test -z + || test ! -s conftest.err +configure:2582: $? = 0 +configure:2585: test -s conftest.o +configure:2588: $? = 0 +configure:2599: result: yes +configure:2616: checking for gcc option to accept ANSI C +configure:2686: gcc -c -g -O2 conftest.c >&5 +configure:2692: $? = 0 +configure:2696: test -z + || test ! -s conftest.err +configure:2699: $? = 0 +configure:2702: test -s conftest.o +configure:2705: $? = 0 +configure:2723: result: none needed +configure:2741: gcc -c -g -O2 conftest.c >&5 +conftest.c:2: error: syntax error before "me" +configure:2747: $? = 1 +configure: failed program was: +| #ifndef __cplusplus +| choke me +| #endif +configure:2891: checking for style of include used by make +configure:2919: result: GNU +configure:2947: checking dependency style of gcc +configure:3037: result: gcc3 +configure:3132: checking build system type +configure:3150: result: i686-pc-linux-gnu +configure:3158: checking host system type +configure:3172: result: i686-pc-linux-gnu +configure:3180: checking for a sed that does not truncate output +configure:3234: result: /bin/sed +configure:3237: checking for egrep +configure:3247: result: grep -E +configure:3263: checking for ld used by gcc +configure:3330: result: /usr/bin/ld +configure:3339: checking if the linker (/usr/bin/ld) is GNU ld +configure:3354: result: yes +configure:3359: checking for /usr/bin/ld option to reload object files +configure:3366: result: -r +configure:3375: checking for BSD-compatible nm +configure:3417: result: /usr/bin/nm -B +configure:3421: checking whether ln -s works +configure:3425: result: yes +configure:3432: checking how to recognise dependent libraries +configure:3615: result: pass_all +configure:3829: checking how to run the C preprocessor +configure:3864: gcc -E conftest.c +configure:3870: $? = 0 +configure:3902: gcc -E conftest.c +conftest.c:11:28: ac_nonexistent.h: No such file or directory +configure:3908: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "libsangoma" +| #define PACKAGE_TARNAME "libsangoma" +| #define PACKAGE_VERSION "1.0.0" +| #define PACKAGE_STRING "libsangoma 1.0.0" +| #define PACKAGE_BUGREPORT "anthmct@yahoo.com" +| #define PACKAGE "libsangoma" +| #define VERSION "1.0.0" +| /* end confdefs.h. */ +| #include +configure:3947: result: gcc -E +configure:3971: gcc -E conftest.c +configure:3977: $? = 0 +configure:4009: gcc -E conftest.c +conftest.c:11:28: ac_nonexistent.h: No such file or directory +configure:4015: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "libsangoma" +| #define PACKAGE_TARNAME "libsangoma" +| #define PACKAGE_VERSION "1.0.0" +| #define PACKAGE_STRING "libsangoma 1.0.0" +| #define PACKAGE_BUGREPORT "anthmct@yahoo.com" +| #define PACKAGE "libsangoma" +| #define VERSION "1.0.0" +| /* end confdefs.h. */ +| #include +configure:4059: checking for ANSI C header files +configure:4084: gcc -c -g -O2 conftest.c >&5 +configure:4090: $? = 0 +configure:4094: test -z + || test ! -s conftest.err +configure:4097: $? = 0 +configure:4100: test -s conftest.o +configure:4103: $? = 0 +configure:4192: gcc -o conftest -g -O2 conftest.c >&5 +configure:4195: $? = 0 +configure:4197: ./conftest +configure:4200: $? = 0 +configure:4215: result: yes +configure:4239: checking for sys/types.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for sys/stat.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for stdlib.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for string.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for memory.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for strings.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for inttypes.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for stdint.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4239: checking for unistd.h +configure:4255: gcc -c -g -O2 conftest.c >&5 +configure:4261: $? = 0 +configure:4265: test -z + || test ! -s conftest.err +configure:4268: $? = 0 +configure:4271: test -s conftest.o +configure:4274: $? = 0 +configure:4285: result: yes +configure:4311: checking dlfcn.h usability +configure:4323: gcc -c -g -O2 conftest.c >&5 +configure:4329: $? = 0 +configure:4333: test -z + || test ! -s conftest.err +configure:4336: $? = 0 +configure:4339: test -s conftest.o +configure:4342: $? = 0 +configure:4352: result: yes +configure:4356: checking dlfcn.h presence +configure:4366: gcc -E conftest.c +configure:4372: $? = 0 +configure:4392: result: yes +configure:4427: checking for dlfcn.h +configure:4434: result: yes +configure:4499: checking for g++ +configure:4515: found /usr/bin/g++ +configure:4525: result: g++ +configure:4541: checking for C++ compiler version +configure:4544: g++ --version &5 +g++ (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2) +Copyright (C) 2004 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:4547: $? = 0 +configure:4549: g++ -v &5 +Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.4/specs +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux +Thread model: posix +gcc version 3.4.4 20050721 (Red Hat 3.4.4-2) +configure:4552: $? = 0 +configure:4554: g++ -V &5 +g++: `-V' option must have argument +configure:4557: $? = 1 +configure:4560: checking whether we are using the GNU C++ compiler +configure:4584: g++ -c conftest.cc >&5 +configure:4590: $? = 0 +configure:4594: test -z + || test ! -s conftest.err +configure:4597: $? = 0 +configure:4600: test -s conftest.o +configure:4603: $? = 0 +configure:4616: result: yes +configure:4622: checking whether g++ accepts -g +configure:4643: g++ -c -g conftest.cc >&5 +configure:4649: $? = 0 +configure:4653: test -z + || test ! -s conftest.err +configure:4656: $? = 0 +configure:4659: test -s conftest.o +configure:4662: $? = 0 +configure:4673: result: yes +configure:4715: g++ -c -g -O2 conftest.cc >&5 +configure:4721: $? = 0 +configure:4725: test -z + || test ! -s conftest.err +configure:4728: $? = 0 +configure:4731: test -s conftest.o +configure:4734: $? = 0 +configure:4760: g++ -c -g -O2 conftest.cc >&5 +conftest.cc: In function `int main()': +conftest.cc:26: error: `exit' undeclared (first use this function) +conftest.cc:26: error: (Each undeclared identifier is reported only once for each function it appears in.) +configure:4766: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "libsangoma" +| #define PACKAGE_TARNAME "libsangoma" +| #define PACKAGE_VERSION "1.0.0" +| #define PACKAGE_STRING "libsangoma 1.0.0" +| #define PACKAGE_BUGREPORT "anthmct@yahoo.com" +| #define PACKAGE "libsangoma" +| #define VERSION "1.0.0" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| /* end confdefs.h. */ +| +| int +| main () +| { +| exit (42); +| ; +| return 0; +| } +configure:4715: g++ -c -g -O2 conftest.cc >&5 +configure:4721: $? = 0 +configure:4725: test -z + || test ! -s conftest.err +configure:4728: $? = 0 +configure:4731: test -s conftest.o +configure:4734: $? = 0 +configure:4760: g++ -c -g -O2 conftest.cc >&5 +configure:4766: $? = 0 +configure:4770: test -z + || test ! -s conftest.err +configure:4773: $? = 0 +configure:4776: test -s conftest.o +configure:4779: $? = 0 +configure:4804: checking dependency style of g++ +configure:4894: result: gcc3 +configure:4916: checking how to run the C++ preprocessor +configure:4947: g++ -E conftest.cc +configure:4953: $? = 0 +configure:4985: g++ -E conftest.cc +conftest.cc:25:28: ac_nonexistent.h: No such file or directory +configure:4991: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "libsangoma" +| #define PACKAGE_TARNAME "libsangoma" +| #define PACKAGE_VERSION "1.0.0" +| #define PACKAGE_STRING "libsangoma 1.0.0" +| #define PACKAGE_BUGREPORT "anthmct@yahoo.com" +| #define PACKAGE "libsangoma" +| #define VERSION "1.0.0" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| /* end confdefs.h. */ +| #include +configure:5030: result: g++ -E +configure:5054: g++ -E conftest.cc +configure:5060: $? = 0 +configure:5092: g++ -E conftest.cc +conftest.cc:25:28: ac_nonexistent.h: No such file or directory +configure:5098: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| +| #define PACKAGE_NAME "libsangoma" +| #define PACKAGE_TARNAME "libsangoma" +| #define PACKAGE_VERSION "1.0.0" +| #define PACKAGE_STRING "libsangoma 1.0.0" +| #define PACKAGE_BUGREPORT "anthmct@yahoo.com" +| #define PACKAGE "libsangoma" +| #define VERSION "1.0.0" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #ifdef __cplusplus +| extern "C" void std::exit (int) throw (); using std::exit; +| #endif +| /* end confdefs.h. */ +| #include +configure:5193: checking for g77 +configure:5209: found /usr/bin/g77 +configure:5219: result: g77 +configure:5234: checking for Fortran 77 compiler version +configure:5237: g77 --version &5 +GNU Fortran (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2) +Copyright (C) 2004 Free Software Foundation, Inc. + +GNU Fortran comes with NO WARRANTY, to the extent permitted by law. +You may redistribute copies of GNU Fortran +under the terms of the GNU General Public License. +For more information about these matters, see the file named COPYING +or type the command `info -f g77 Copying'. +configure:5240: $? = 0 +configure:5242: g77 -v &5 +Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.4/specs +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux +Thread model: posix +gcc version 3.4.4 20050721 (Red Hat 3.4.4-2) +configure:5245: $? = 0 +configure:5247: g77 -V &5 +g77: `-V' option must have argument +configure:5250: $? = 1 +configure:5258: checking whether we are using the GNU Fortran 77 compiler +configure:5272: g77 -c conftest.F >&5 +configure:5278: $? = 0 +configure:5282: test -z + || test ! -s conftest.err +configure:5285: $? = 0 +configure:5288: test -s conftest.o +configure:5291: $? = 0 +configure:5304: result: yes +configure:5310: checking whether g77 accepts -g +configure:5322: g77 -c -g conftest.f >&5 +configure:5328: $? = 0 +configure:5332: test -z + || test ! -s conftest.err +configure:5335: $? = 0 +configure:5338: test -s conftest.o +configure:5341: $? = 0 +configure:5353: result: yes +configure:5383: checking the maximum length of command line arguments +configure:5448: result: 32768 +configure:5459: checking command to parse /usr/bin/nm -B output from gcc object +configure:5548: gcc -c -g -O2 conftest.c >&5 +configure:5551: $? = 0 +configure:5555: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' \> conftest.nm +configure:5558: $? = 0 +configure:5610: gcc -o conftest -g -O2 conftest.c conftstm.o >&5 +configure:5613: $? = 0 +configure:5651: result: ok +configure:5655: checking for objdir +configure:5670: result: .libs +configure:5760: checking for ar +configure:5776: found /usr/bin/ar +configure:5787: result: ar +configure:5840: checking for ranlib +configure:5856: found /usr/bin/ranlib +configure:5867: result: ranlib +configure:5920: checking for strip +configure:5936: found /usr/bin/strip +configure:5947: result: strip +configure:6209: checking if gcc static flag works +configure:6232: result: yes +configure:6250: checking if gcc supports -fno-rtti -fno-exceptions +configure:6268: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 +cc1: warning: command line option "-fno-rtti" is valid for C++/ObjC++ but not for C +configure:6272: $? = 0 +configure:6283: result: no +configure:6298: checking for gcc option to produce PIC +configure:6475: result: -fPIC +configure:6483: checking if gcc PIC flag -fPIC works +configure:6501: gcc -c -g -O2 -fPIC -DPIC conftest.c >&5 +configure:6505: $? = 0 +configure:6516: result: yes +configure:6540: checking if gcc supports -c -o file.o +configure:6561: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 +configure:6565: $? = 0 +configure:6585: result: yes +configure:6611: checking whether the gcc linker (/usr/bin/ld) supports shared libraries +configure:7459: result: yes +configure:7485: checking whether -lc should be explicitly linked in +configure:7490: gcc -c -g -O2 conftest.c >&5 +configure:7493: $? = 0 +configure:7507: gcc -shared conftest.o -v -Wl,-soname -Wl,conftest -o conftest 2\>\&1 \| grep -lc \>/dev/null 2\>\&1 +configure:7510: $? = 0 +configure:7522: result: no +configure:7530: checking dynamic linker characteristics +configure:8091: result: GNU/Linux ld.so +configure:8095: checking how to hardcode library paths into programs +configure:8120: result: immediate +configure:8134: checking whether stripping libraries is possible +configure:8139: result: yes +configure:8969: checking if libtool supports shared libraries +configure:8971: result: yes +configure:8974: checking whether to build shared libraries +configure:9032: result: yes +configure:9035: checking whether to build static libraries +configure:9039: result: yes +configure:9131: creating libtool +configure:9678: checking for ld used by g++ +configure:9745: result: /usr/bin/ld +configure:9754: checking if the linker (/usr/bin/ld) is GNU ld +configure:9769: result: yes +configure:9820: checking whether the g++ linker (/usr/bin/ld) supports shared libraries +configure:10648: result: yes +configure:10666: g++ -c -g -O2 conftest.cc >&5 +configure:10669: $? = 0 +configure:10765: checking for g++ option to produce PIC +configure:11017: result: -fPIC +configure:11025: checking if g++ PIC flag -fPIC works +configure:11043: g++ -c -g -O2 -fPIC -DPIC conftest.cc >&5 +configure:11047: $? = 0 +configure:11058: result: yes +configure:11082: checking if g++ supports -c -o file.o +configure:11103: g++ -c -g -O2 -o out/conftest2.o conftest.cc >&5 +configure:11107: $? = 0 +configure:11127: result: yes +configure:11153: checking whether the g++ linker (/usr/bin/ld) supports shared libraries +configure:11178: result: yes +configure:11249: checking dynamic linker characteristics +configure:11810: result: GNU/Linux ld.so +configure:11814: checking how to hardcode library paths into programs +configure:11839: result: immediate +configure:11853: checking whether stripping libraries is possible +configure:11858: result: yes +configure:13165: checking if libtool supports shared libraries +configure:13167: result: yes +configure:13170: checking whether to build shared libraries +configure:13188: result: yes +configure:13191: checking whether to build static libraries +configure:13195: result: yes +configure:13207: checking for g77 option to produce PIC +configure:13384: result: -fPIC +configure:13392: checking if g77 PIC flag -fPIC works +configure:13410: g77 -c -g -O2 -fPIC conftest.f >&5 +configure:13414: $? = 0 +configure:13425: result: yes +configure:13449: checking if g77 supports -c -o file.o +configure:13470: g77 -c -g -O2 -o out/conftest2.o conftest.f >&5 +configure:13474: $? = 0 +configure:13494: result: yes +configure:13520: checking whether the g77 linker (/usr/bin/ld) supports shared libraries +configure:14348: result: yes +configure:14419: checking dynamic linker characteristics +configure:14980: result: GNU/Linux ld.so +configure:14984: checking how to hardcode library paths into programs +configure:15009: result: immediate +configure:15023: checking whether stripping libraries is possible +configure:15028: result: yes +configure:19176: checking for ranlib +configure:19203: result: ranlib +configure:19239: checking fcntl.h usability +configure:19251: gcc -c -g -O2 conftest.c >&5 +configure:19257: $? = 0 +configure:19261: test -z + || test ! -s conftest.err +configure:19264: $? = 0 +configure:19267: test -s conftest.o +configure:19270: $? = 0 +configure:19280: result: yes +configure:19284: checking fcntl.h presence +configure:19294: gcc -E conftest.c +configure:19300: $? = 0 +configure:19320: result: yes +configure:19355: checking for fcntl.h +configure:19362: result: yes +configure:19239: checking netinet/in.h usability +configure:19251: gcc -c -g -O2 conftest.c >&5 +configure:19257: $? = 0 +configure:19261: test -z + || test ! -s conftest.err +configure:19264: $? = 0 +configure:19267: test -s conftest.o +configure:19270: $? = 0 +configure:19280: result: yes +configure:19284: checking netinet/in.h presence +configure:19294: gcc -E conftest.c +configure:19300: $? = 0 +configure:19320: result: yes +configure:19355: checking for netinet/in.h +configure:19362: result: yes +configure:19230: checking for stdlib.h +configure:19235: result: yes +configure:19230: checking for string.h +configure:19235: result: yes +configure:19239: checking sys/ioctl.h usability +configure:19251: gcc -c -g -O2 conftest.c >&5 +configure:19257: $? = 0 +configure:19261: test -z + || test ! -s conftest.err +configure:19264: $? = 0 +configure:19267: test -s conftest.o +configure:19270: $? = 0 +configure:19280: result: yes +configure:19284: checking sys/ioctl.h presence +configure:19294: gcc -E conftest.c +configure:19300: $? = 0 +configure:19320: result: yes +configure:19355: checking for sys/ioctl.h +configure:19362: result: yes +configure:19239: checking sys/socket.h usability +configure:19251: gcc -c -g -O2 conftest.c >&5 +configure:19257: $? = 0 +configure:19261: test -z + || test ! -s conftest.err +configure:19264: $? = 0 +configure:19267: test -s conftest.o +configure:19270: $? = 0 +configure:19280: result: yes +configure:19284: checking sys/socket.h presence +configure:19294: gcc -E conftest.c +configure:19300: $? = 0 +configure:19320: result: yes +configure:19355: checking for sys/socket.h +configure:19362: result: yes +configure:19239: checking sys/time.h usability +configure:19251: gcc -c -g -O2 conftest.c >&5 +configure:19257: $? = 0 +configure:19261: test -z + || test ! -s conftest.err +configure:19264: $? = 0 +configure:19267: test -s conftest.o +configure:19270: $? = 0 +configure:19280: result: yes +configure:19284: checking sys/time.h presence +configure:19294: gcc -E conftest.c +configure:19300: $? = 0 +configure:19320: result: yes +configure:19355: checking for sys/time.h +configure:19362: result: yes +configure:19230: checking for unistd.h +configure:19235: result: yes +configure:19239: checking math.h usability +configure:19251: gcc -c -g -O2 conftest.c >&5 +configure:19257: $? = 0 +configure:19261: test -z + || test ! -s conftest.err +configure:19264: $? = 0 +configure:19267: test -s conftest.o +configure:19270: $? = 0 +configure:19280: result: yes +configure:19284: checking math.h presence +configure:19294: gcc -E conftest.c +configure:19300: $? = 0 +configure:19320: result: yes +configure:19355: checking for math.h +configure:19362: result: yes +configure:19396: checking whether time.h and sys/time.h may both be included +configure:19421: gcc -c -g -O2 conftest.c >&5 +configure:19427: $? = 0 +configure:19431: test -z + || test ! -s conftest.err +configure:19434: $? = 0 +configure:19437: test -s conftest.o +configure:19440: $? = 0 +configure:19451: result: yes +configure:19478: checking sys/select.h usability +configure:19490: gcc -c -g -O2 conftest.c >&5 +configure:19496: $? = 0 +configure:19500: test -z + || test ! -s conftest.err +configure:19503: $? = 0 +configure:19506: test -s conftest.o +configure:19509: $? = 0 +configure:19519: result: yes +configure:19523: checking sys/select.h presence +configure:19533: gcc -E conftest.c +configure:19539: $? = 0 +configure:19559: result: yes +configure:19594: checking for sys/select.h +configure:19601: result: yes +configure:19469: checking for sys/socket.h +configure:19474: result: yes +configure:19614: checking types of arguments for select +configure:19647: gcc -c -g -O2 conftest.c >&5 +configure:19653: $? = 0 +configure:19657: test -z + || test ! -s conftest.err +configure:19660: $? = 0 +configure:19663: test -s conftest.o +configure:19666: $? = 0 +configure:19682: result: int,fd_set *,struct timeval * +configure:19712: checking for gettimeofday +configure:19769: gcc -o conftest -g -O2 conftest.c >&5 +configure:19775: $? = 0 +configure:19779: test -z + || test ! -s conftest.err +configure:19782: $? = 0 +configure:19785: test -s conftest +configure:19788: $? = 0 +configure:19800: result: yes +configure:19712: checking for memset +configure:19769: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:65: warning: conflicting types for built-in function 'memset' +configure:19775: $? = 0 +configure:19779: test -z + || test ! -s conftest.err +configure:19782: $? = 0 +configure:19785: test -s conftest +configure:19788: $? = 0 +configure:19800: result: yes +configure:19712: checking for select +configure:19769: gcc -o conftest -g -O2 conftest.c >&5 +configure:19775: $? = 0 +configure:19779: test -z + || test ! -s conftest.err +configure:19782: $? = 0 +configure:19785: test -s conftest +configure:19788: $? = 0 +configure:19800: result: yes +configure:19712: checking for socket +configure:19769: gcc -o conftest -g -O2 conftest.c >&5 +configure:19775: $? = 0 +configure:19779: test -z + || test ! -s conftest.err +configure:19782: $? = 0 +configure:19785: test -s conftest +configure:19788: $? = 0 +configure:19800: result: yes +configure:19966: creating ./config.status + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_build=i686-pc-linux-gnu +ac_cv_build_alias=i686-pc-linux-gnu +ac_cv_c_compiler_gnu=yes +ac_cv_cxx_compiler_gnu=yes +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_CXXCPP_set= +ac_cv_env_CXXCPP_value= +ac_cv_env_CXXFLAGS_set= +ac_cv_env_CXXFLAGS_value= +ac_cv_env_CXX_set= +ac_cv_env_CXX_value= +ac_cv_env_F77_set= +ac_cv_env_F77_value= +ac_cv_env_FFLAGS_set= +ac_cv_env_FFLAGS_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_exeext= +ac_cv_f77_compiler_gnu=yes +ac_cv_func_gettimeofday=yes +ac_cv_func_memset=yes +ac_cv_func_select=yes +ac_cv_func_select_args='int,fd_set *,struct timeval *' +ac_cv_func_socket=yes +ac_cv_header_dlfcn_h=yes +ac_cv_header_fcntl_h=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_math_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_netinet_in_h=yes +ac_cv_header_stdc=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_ioctl_h=yes +ac_cv_header_sys_select_h=yes +ac_cv_header_sys_socket_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_time_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_time=yes +ac_cv_header_unistd_h=yes +ac_cv_host=i686-pc-linux-gnu +ac_cv_host_alias=i686-pc-linux-gnu +ac_cv_objext=o +ac_cv_path_install='/usr/bin/install -c' +ac_cv_prog_AWK=gawk +ac_cv_prog_CPP='gcc -E' +ac_cv_prog_CXXCPP='g++ -E' +ac_cv_prog_ac_ct_AR=ar +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_ac_ct_CXX=g++ +ac_cv_prog_ac_ct_F77=g77 +ac_cv_prog_ac_ct_RANLIB=ranlib +ac_cv_prog_ac_ct_STRIP=strip +ac_cv_prog_cc_g=yes +ac_cv_prog_cc_stdc= +ac_cv_prog_cxx_g=yes +ac_cv_prog_egrep='grep -E' +ac_cv_prog_f77_g=yes +ac_cv_prog_make_make_set=yes +am_cv_CC_dependencies_compiler_type=gcc3 +am_cv_CXX_dependencies_compiler_type=gcc3 +lt_cv_deplibs_check_method=pass_all +lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file='/lib/libc.so.6 /lib/libc-2.3.4.so' +lt_cv_ld_reload_flag=-r +lt_cv_objdir=.libs +lt_cv_path_LD=/usr/bin/ld +lt_cv_path_LDCXX=/usr/bin/ld +lt_cv_path_NM='/usr/bin/nm -B' +lt_cv_path_SED=/bin/sed +lt_cv_prog_compiler_c_o=yes +lt_cv_prog_compiler_c_o_CXX=yes +lt_cv_prog_compiler_c_o_F77=yes +lt_cv_prog_compiler_rtti_exceptions=no +lt_cv_prog_gnu_ld=yes +lt_cv_prog_gnu_ldcxx=yes +lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p'\''' +lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr) \&\2},/p'\''' +lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^. .* \(.*\)$/extern int \1;/p'\''' +lt_cv_sys_max_cmd_len=32768 +lt_lt_cv_prog_compiler_c_o='"yes"' +lt_lt_cv_prog_compiler_c_o_CXX='"yes"' +lt_lt_cv_prog_compiler_c_o_F77='"yes"' +lt_lt_cv_sys_global_symbol_pipe='"sed -n -e '\''s/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'\''"' +lt_lt_cv_sys_global_symbol_to_c_name_address='"sed -n -e '\''s/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'\''"' +lt_lt_cv_sys_global_symbol_to_cdecl='"sed -n -e '\''s/^. .* \\(.*\\)\$/extern int \\1;/p'\''"' + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +ACLOCAL='${SHELL} /usr/src/libsangoma/trunk/missing --run aclocal-1.9' +AMDEPBACKSLASH='\' +AMDEP_FALSE='#' +AMDEP_TRUE='' +AMTAR='${SHELL} /usr/src/libsangoma/trunk/missing --run tar' +AR='ar' +AUTOCONF='${SHELL} /usr/src/libsangoma/trunk/missing --run autoconf' +AUTOHEADER='${SHELL} /usr/src/libsangoma/trunk/missing --run autoheader' +AUTOMAKE='${SHELL} /usr/src/libsangoma/trunk/missing --run automake-1.9' +AWK='gawk' +CC='gcc' +CCDEPMODE='depmode=gcc3' +CFLAGS='-g -O2' +CPP='gcc -E' +CPPFLAGS='' +CXX='g++' +CXXCPP='g++ -E' +CXXDEPMODE='depmode=gcc3' +CXXFLAGS='-g -O2' +CYGPATH_W='echo' +DEFS='-DPACKAGE_NAME=\"libsangoma\" -DPACKAGE_TARNAME=\"libsangoma\" -DPACKAGE_VERSION=\"1.0.0\" -DPACKAGE_STRING=\"libsangoma\ 1.0.0\" -DPACKAGE_BUGREPORT=\"anthmct@yahoo.com\" -DPACKAGE=\"libsangoma\" -DVERSION=\"1.0.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DHAVE_FCNTL_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MATH_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_SOCKET_H=1 -DSELECT_TYPE_ARG1=int -DSELECT_TYPE_ARG234=\(fd_set\ \*\) -DSELECT_TYPE_ARG5=\(struct\ timeval\ \*\) -DHAVE_GETTIMEOFDAY=1 -DHAVE_MEMSET=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 ' +DEPDIR='.deps' +ECHO='echo' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='grep -E' +EXEEXT='' +F77='g77' +FFLAGS='-g -O2' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +INSTALL_STRIP_PROGRAM='${SHELL} $(install_sh) -c -s' +LDFLAGS='' +LIBOBJS='' +LIBPRI_FALSE='' +LIBPRI_TRUE='#' +LIBS='' +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +LN_S='ln -s' +LTLIBOBJS='' +MAKEINFO='${SHELL} /usr/src/libsangoma/trunk/missing --run makeinfo' +OBJEXT='o' +PACKAGE='libsangoma' +PACKAGE_BUGREPORT='anthmct@yahoo.com' +PACKAGE_NAME='libsangoma' +PACKAGE_STRING='libsangoma 1.0.0' +PACKAGE_TARNAME='libsangoma' +PACKAGE_VERSION='1.0.0' +PATH_SEPARATOR=':' +RANLIB='ranlib' +SET_MAKE='' +SHELL='/bin/sh' +STRIP='strip' +VERSION='1.0.0' +ac_ct_AR='ar' +ac_ct_CC='gcc' +ac_ct_CXX='g++' +ac_ct_F77='g77' +ac_ct_RANLIB='ranlib' +ac_ct_STRIP='strip' +am__fastdepCC_FALSE='#' +am__fastdepCC_TRUE='' +am__fastdepCXX_FALSE='#' +am__fastdepCXX_TRUE='' +am__include='include' +am__leading_dot='.' +am__quote='' +am__tar='${AMTAR} chof - "$$tardir"' +am__untar='${AMTAR} xf -' +bindir='${exec_prefix}/bin' +build='i686-pc-linux-gnu' +build_alias='' +build_cpu='i686' +build_os='linux-gnu' +build_vendor='pc' +datadir='${prefix}/share' +exec_prefix='${prefix}' +host='i686-pc-linux-gnu' +host_alias='' +host_cpu='i686' +host_os='linux-gnu' +host_vendor='pc' +includedir='${prefix}/include' +infodir='${prefix}/info' +install_sh='/usr/src/libsangoma/trunk/install-sh' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +libpripath='' +localstatedir='${prefix}/var' +mandir='${prefix}/man' +mkdir_p='mkdir -p --' +oldincludedir='/usr/include' +prefix='/usr/local' +program_transform_name='s,x,x,' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define HAVE_DLFCN_H 1 +#define HAVE_FCNTL_H 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_MEMSET 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_SELECT 1 +#define HAVE_SOCKET 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_IOCTL_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_UNISTD_H 1 +#define PACKAGE "libsangoma" +#define PACKAGE_BUGREPORT "anthmct@yahoo.com" +#define PACKAGE_NAME "libsangoma" +#define PACKAGE_STRING "libsangoma 1.0.0" +#define PACKAGE_TARNAME "libsangoma" +#define PACKAGE_VERSION "1.0.0" +#define SELECT_TYPE_ARG1 int +#define SELECT_TYPE_ARG234 (fd_set *) +#define SELECT_TYPE_ARG5 (struct timeval *) +#define STDC_HEADERS 1 +#define TIME_WITH_SYS_TIME 1 +#define VERSION "1.0.0" +#endif +#ifdef __cplusplus +extern "C" void std::exit (int) throw (); using std::exit; + +configure: exit 0 + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by libsangoma config.status 1.0.0, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on sangoma_mantis + +config.status:709: creating Makefile +config.status:892: executing depfiles commands diff --git a/api/libsangoma/.svn/text-base/config.status.svn-base b/api/libsangoma/.svn/text-base/config.status.svn-base new file mode 100644 index 0000000..310587a --- /dev/null +++ b/api/libsangoma/.svn/text-base/config.status.svn-base @@ -0,0 +1,983 @@ +#! /bin/sh +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=${CONFIG_SHELL-/bin/sh} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by libsangoma $as_me 1.0.0, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +config_files=" Makefile" +config_commands=" depfiles" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to ." +ac_cs_version="\ +libsangoma config.status 1.0.0 +configured by ./configure, generated by GNU Autoconf 2.59, + with options \"\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=. +INSTALL="/usr/bin/install -c" +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + echo "running /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 + exec /bin/sh ./configure $ac_configure_extra_args --no-create --no-recursion +fi + +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="" ac_aux_dir="." + +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF +s,@SHELL@,/bin/sh,;t t +s,@PATH_SEPARATOR@,:,;t t +s,@PACKAGE_NAME@,libsangoma,;t t +s,@PACKAGE_TARNAME@,libsangoma,;t t +s,@PACKAGE_VERSION@,1.0.0,;t t +s,@PACKAGE_STRING@,libsangoma 1.0.0,;t t +s,@PACKAGE_BUGREPORT@,anthmct@yahoo.com,;t t +s,@exec_prefix@,${prefix},;t t +s,@prefix@,/usr/local,;t t +s,@program_transform_name@,s,x,x,,;t t +s,@bindir@,${exec_prefix}/bin,;t t +s,@sbindir@,${exec_prefix}/sbin,;t t +s,@libexecdir@,${exec_prefix}/libexec,;t t +s,@datadir@,${prefix}/share,;t t +s,@sysconfdir@,${prefix}/etc,;t t +s,@sharedstatedir@,${prefix}/com,;t t +s,@localstatedir@,${prefix}/var,;t t +s,@libdir@,${exec_prefix}/lib,;t t +s,@includedir@,${prefix}/include,;t t +s,@oldincludedir@,/usr/include,;t t +s,@infodir@,${prefix}/info,;t t +s,@mandir@,${prefix}/man,;t t +s,@build_alias@,,;t t +s,@host_alias@,,;t t +s,@target_alias@,,;t t +s,@DEFS@,-DPACKAGE_NAME=\"libsangoma\" -DPACKAGE_TARNAME=\"libsangoma\" -DPACKAGE_VERSION=\"1.0.0\" -DPACKAGE_STRING=\"libsangoma\ 1.0.0\" -DPACKAGE_BUGREPORT=\"anthmct@yahoo.com\" -DPACKAGE=\"libsangoma\" -DVERSION=\"1.0.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DHAVE_FCNTL_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_UNISTD_H=1 -DHAVE_MATH_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_SOCKET_H=1 -DSELECT_TYPE_ARG1=int -DSELECT_TYPE_ARG234=\(fd_set\ \*\) -DSELECT_TYPE_ARG5=\(struct\ timeval\ \*\) -DHAVE_GETTIMEOFDAY=1 -DHAVE_MEMSET=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 ,;t t +s,@ECHO_C@,,;t t +s,@ECHO_N@,-n,;t t +s,@ECHO_T@,,;t t +s,@LIBS@,,;t t +s,@INSTALL_PROGRAM@,${INSTALL},;t t +s,@INSTALL_SCRIPT@,${INSTALL},;t t +s,@INSTALL_DATA@,${INSTALL} -m 644,;t t +s,@CYGPATH_W@,echo,;t t +s,@PACKAGE@,libsangoma,;t t +s,@VERSION@,1.0.0,;t t +s,@ACLOCAL@,${SHELL} /usr/src/libsangoma/trunk/missing --run aclocal-1.9,;t t +s,@AUTOCONF@,${SHELL} /usr/src/libsangoma/trunk/missing --run autoconf,;t t +s,@AUTOMAKE@,${SHELL} /usr/src/libsangoma/trunk/missing --run automake-1.9,;t t +s,@AUTOHEADER@,${SHELL} /usr/src/libsangoma/trunk/missing --run autoheader,;t t +s,@MAKEINFO@,${SHELL} /usr/src/libsangoma/trunk/missing --run makeinfo,;t t +s,@install_sh@,/usr/src/libsangoma/trunk/install-sh,;t t +s,@STRIP@,strip,;t t +s,@ac_ct_STRIP@,strip,;t t +s,@INSTALL_STRIP_PROGRAM@,${SHELL} $(install_sh) -c -s,;t t +s,@mkdir_p@,mkdir -p --,;t t +s,@AWK@,gawk,;t t +s,@SET_MAKE@,,;t t +s,@am__leading_dot@,.,;t t +s,@AMTAR@,${SHELL} /usr/src/libsangoma/trunk/missing --run tar,;t t +s,@am__tar@,${AMTAR} chof - "$$tardir",;t t +s,@am__untar@,${AMTAR} xf -,;t t +s,@CC@,gcc,;t t +s,@CFLAGS@,-g -O2,;t t +s,@LDFLAGS@,,;t t +s,@CPPFLAGS@,,;t t +s,@ac_ct_CC@,gcc,;t t +s,@EXEEXT@,,;t t +s,@OBJEXT@,o,;t t +s,@DEPDIR@,.deps,;t t +s,@am__include@,include,;t t +s,@am__quote@,,;t t +s,@AMDEP_TRUE@,,;t t +s,@AMDEP_FALSE@,#,;t t +s,@AMDEPBACKSLASH@,\,;t t +s,@CCDEPMODE@,depmode=gcc3,;t t +s,@am__fastdepCC_TRUE@,,;t t +s,@am__fastdepCC_FALSE@,#,;t t +s,@build@,i686-pc-linux-gnu,;t t +s,@build_cpu@,i686,;t t +s,@build_vendor@,pc,;t t +s,@build_os@,linux-gnu,;t t +s,@host@,i686-pc-linux-gnu,;t t +s,@host_cpu@,i686,;t t +s,@host_vendor@,pc,;t t +s,@host_os@,linux-gnu,;t t +s,@EGREP@,grep -E,;t t +s,@LN_S@,ln -s,;t t +s,@ECHO@,echo,;t t +s,@AR@,ar,;t t +s,@ac_ct_AR@,ar,;t t +s,@RANLIB@,ranlib,;t t +s,@ac_ct_RANLIB@,ranlib,;t t +s,@CPP@,gcc -E,;t t +s,@CXX@,g++,;t t +s,@CXXFLAGS@,-g -O2,;t t +s,@ac_ct_CXX@,g++,;t t +s,@CXXDEPMODE@,depmode=gcc3,;t t +s,@am__fastdepCXX_TRUE@,,;t t +s,@am__fastdepCXX_FALSE@,#,;t t +s,@CXXCPP@,g++ -E,;t t +s,@F77@,g77,;t t +s,@FFLAGS@,-g -O2,;t t +s,@ac_ct_F77@,g77,;t t +s,@LIBTOOL@,$(SHELL) $(top_builddir)/libtool,;t t +s,@LIBPRI_TRUE@,#,;t t +s,@LIBPRI_FALSE@,,;t t +s,@libpripath@,,;t t +s,@LIBOBJS@,,;t t +s,@LTLIBOBJS@,,;t t +CEOF + + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done + +{ (exit 0); exit 0; } diff --git a/api/libsangoma/.svn/text-base/libsangoma.c.svn-base b/api/libsangoma/.svn/text-base/libsangoma.c.svn-base index 1fea515..aaea8a8 100644 --- a/api/libsangoma/.svn/text-base/libsangoma.c.svn-base +++ b/api/libsangoma/.svn/text-base/libsangoma.c.svn-base @@ -22,16 +22,17 @@ #include "libsangoma.h" #define DFT_CARD "wanpipe1" - -#ifndef WP_TDM_EVENT_FE_ALARM +#ifndef WP_TDM_FEATURE_FE_ALARM #warning "Warning: TDM FE ALARM not supported by driver" #endif - -#ifndef WP_TDMAPI_EVENT_DTMF -#warning "Warning: TDM EVENTS not supported by driver" +#ifndef WP_TDM_FEATURE_DTMF_EVENTS +#warning "Warning: TDM DTMF not supported by driver" #endif +#ifndef WP_TDM_FEATURE_EVENTS +#warning "Warning: TDM EVENTS not supported by driver" +#endif #if defined(WIN32) @@ -520,7 +521,7 @@ int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_tdm_cmd.usr_mtu_mru); printf("\tidle flag:\t0x%02X\n",tdm_api->wp_tdm_cmd.idle_flag); -#ifdef WP_TDM_EVENT_FE_ALARM +#ifdef WP_TDM_FEATURE_FE_ALARM printf("\tfe alarms:\t0x%02X\n",tdm_api->wp_tdm_cmd.fe_alarms); #endif @@ -765,7 +766,7 @@ int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { -#ifdef WP_TDM_EVENT_TDM_API_EVENTS +#ifdef WP_TDM_FEATURE_EVENTS wp_tdm_api_event_t *rx_event; @@ -793,7 +794,8 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) } break; - + +#ifdef WP_TDM_FEATURE_DTMF_EVENTS case WP_TDMAPI_EVENT_DTMF: printf("%d: GOT DTMF EVENT\n",(int)fd); if (tdm_api->wp_tdm_event.wp_dtmf_event) { @@ -803,6 +805,7 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) rx_event->wp_tdm_api_event_dtmf_port); } break; +#endif case WP_TDMAPI_EVENT_RXHOOK: printf("%d: GOT RXHOOK EVENT\n",(int)fd); @@ -828,13 +831,13 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) } break; -#ifdef WP_TDM_EVENT_FE_ALARM - case WP_TDMAPI_EVENT_FE_ALARM: +#ifdef WP_TDM_FEATURE_FE_ALARM + case WP_TDMAPI_EVENT_ALARM: printf("%d: GOT FE ALARMS EVENT %i\n",(int)fd, - rx_event->wp_tdm_api_event_fe_alarm); + rx_event->wp_tdm_api_event_alarm); if (tdm_api->wp_tdm_event.wp_fe_alarm_event) { tdm_api->wp_tdm_event.wp_fe_alarm_event(fd, - rx_event->wp_tdm_api_event_fe_alarm); + rx_event->wp_tdm_api_event_alarm); } #endif @@ -845,13 +848,12 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; #else - return -EINVAL; + printf("Error: Read Event not supported!\n"); + return -1; #endif } - -#ifdef WP_TDMAPI_EVENT_DTMF - +#ifdef WP_TDM_FEATURE_DTMF_EVENTS int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -911,6 +913,7 @@ int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; } +#endif int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { @@ -927,33 +930,6 @@ int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; } -int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) -{ - int err; - - tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_HWEC; - err=sangoma_tdm_cmd_exec(fd,tdm_api); - if (err){ - return err; - } - - return 0; -} - -int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) -{ - int err; - - tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_HWEC; - err=sangoma_tdm_cmd_exec(fd,tdm_api); - if (err){ - return err; - } - - return 0; -} - - int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -1156,13 +1132,39 @@ int sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { return tdm_api->wp_tdm_cmd.rbs_poll; } -#endif + +int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_HWEC; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + +int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_HWEC; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } + + return 0; +} + /*======================================================== * GET Front End Alarms * */ -#ifdef WP_TDM_EVENT_FE_ALARM +#ifdef WP_TDM_FEATURE_FE_ALARM int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -1178,4 +1180,26 @@ int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) } #endif +/* get current Line Connection state - Connected/Disconnected */ +int sangoma_tdm_get_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char *current_status) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FE_STATUS; + err = sangoma_tdm_cmd_exec(fd, tdm_api); + *current_status = tdm_api->wp_tdm_cmd.fe_status; + + return err; +} + + +/* set current Line Connection state - Connected/Disconnected. valid only for ISDN BRI */ +int sangoma_tdm_set_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char new_status) +{ + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_FE_STATUS; + tdm_api->wp_tdm_cmd.fe_status = new_status; + + return sangoma_tdm_cmd_exec(fd, tdm_api); +} + #endif /* WANPIPE_TDM_API */ diff --git a/api/libsangoma/.svn/text-base/libsangoma.h.svn-base b/api/libsangoma/.svn/text-base/libsangoma.h.svn-base index 438307a..fab9646 100644 --- a/api/libsangoma/.svn/text-base/libsangoma.h.svn-base +++ b/api/libsangoma/.svn/text-base/libsangoma.h.svn-base @@ -50,6 +50,7 @@ typedef unsigned __int32 u_int32_t; typedef HANDLE sng_fd_t; #else +/* L I N U X */ #include #include #include @@ -76,6 +77,7 @@ typedef HANDLE sng_fd_t; #ifdef WANPIPE_TDM_API # include #endif + #endif #define FNAME_LEN 50 @@ -176,15 +178,20 @@ int sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); -int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); -int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); - - int sangoma_tdm_txsig_onhook(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_txsig_offhook(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_txsig_start(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_txsig_kewl(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); +int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); +int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); + +/* get current Line Connection state - Connected/Disconnected */ +int sangoma_tdm_get_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char *current_status); +/* set current Line Connection state - Connected/Disconnected. valid only for ISDN BRI */ +int sangoma_tdm_set_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char new_status); + + #ifndef LIBSANGOMA_GET_HWCODING #define LIBSANGOMA_GET_HWCODING 1 #endif @@ -193,3 +200,4 @@ int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api); #endif /* WANPIPE_TDM_API */ #endif + diff --git a/api/libsangoma/.svn/text-base/libtool.svn-base b/api/libsangoma/.svn/text-base/libtool.svn-base new file mode 100644 index 0000000..ff4763a --- /dev/null +++ b/api/libsangoma/.svn/text-base/libtool.svn-base @@ -0,0 +1,7340 @@ +#! /bin/sh + +# libtoolT - Provide generalized library-building support services. +# Generated automatically by (GNU libsangoma 1.0.0) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED="/bin/sed" + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="/bin/sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# The names of the tagged configurations supported by this script. +available_tags=" CXX F77" + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host sangoma_mantis: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-pc-linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# A language-specific compiler. +CC="gcc" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +# An ERE matcher. +EGREP="grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=32768 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation ? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" +old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ +cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ +\$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects="" + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="" + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec=" /usr/lib/gcc/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../i386-redhat-linux/lib/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../ /lib/i386-redhat-linux/3.4.4/ /lib/ /usr/lib/i386-redhat-linux/3.4.4/ /usr/lib/" + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/lib /usr/lib include ld.so.conf.d/*.conf " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL CONFIG + +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.10 +TIMESTAMP=" (1.1220.2.130 2004/09/19 12:13:49)" + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes. +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () { + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` + if test "X$win32_nmres" = "Ximport" ; then + win32_libid_type="x86 archive import" + else + win32_libid_type="x86 archive static" + fi + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () { + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () { + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xdir="$my_gentop/$my_xlib" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$my_xdir"; then + exit $status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename $darwin_archive` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + # Remove the table of contents from the thin files. + $AR -d "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" __.SYMDEF 2>/dev/null || true + $AR -d "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" __.SYMDEF\ SORTED 2>/dev/null || true + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $AR -xo "${darwin_base_archive}" + rm "${darwin_base_archive}" + cd "$darwin_curdir" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f | xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + rm -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + (cd $my_xdir && $AR x $my_xabs) || exit $? + fi # $darwin_arches + fi # $run + ;; + *) + # We will extract separately just the conflicting names and we will + # no longer touch any unique names. It is faster to leave these + # extract automatically by $AR in one run. + $show "(cd $my_xdir && $AR x $my_xabs)" + $run eval "(cd \$my_xdir && $AR x \$my_xabs)" || exit $? + if ($AR t "$my_xabs" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; renaming object files" 1>&2 + $echo "$modename: warning: to ensure that they will not overwrite" 1>&2 + $AR t "$my_xabs" | sort | uniq -cd | while read -r count name + do + i=1 + while test "$i" -le "$count" + do + # Put our $i before any first dot (extension) + # Never overwrite any file + name_to="$name" + while test "X$name_to" = "X$name" || test -f "$my_xdir/$name_to" + do + name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"` + done + $show "(cd $my_xdir && $AR xN $i $my_xabs '$name' && $mv '$name' '$name_to')" + $run eval "(cd \$my_xdir && $AR xN $i \$my_xabs '$name' && $mv '$name' '$name_to')" || exit $? + i=`expr $i + 1` + done + done + fi + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2003 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $EXIT_SUCCESS + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $EXIT_SUCCESS + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $EXIT_SUCCESS + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) prevopt="--tag" prev=tag ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case "$arg_mode" in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit $EXIT_FAILURE + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # gcc -m* arguments should be passed to the linker via $compiler_flags + # in order to pass architecture information to the linker + # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo + # but this is not reliable with gcc because gcc may use -mfoo to + # select a different linker, different libraries, etc, while + # -Wl,-mfoo simply passes -mfoo to the linker. + -m*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + if test "$with_gcc" = "yes" ; then + compiler_flags="$compiler_flags $arg" + fi + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test "$status" -ne 0 && test ! -d "$output_objdir"; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5* ) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$save_output-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$save_output-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$save_output-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadale object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$save_output-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + cwrappersource=`$echo ${objdir}/lt-${output}.c` + cwrapper=`$echo ${output}.exe` + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +#define HAVE_DOS_BASED_FILE_SYSTEM +#ifndef DIR_SEPARATOR_2 +#define DIR_SEPARATOR_2 '\\' +#endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +char * basename (const char *name); +char * fnqualify(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup ((char *) basename (argv[0])); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = fnqualify(argv[0]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +char * +basename (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha (name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return (char *) base; +} + +char * +fnqualify(const char *path) +{ + size_t size; + char *p; + char tmp[LT_PATHMAX + 1]; + + assert(path != NULL); + + /* Is it qualified already? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha (path[0]) && path[1] == ':') + return xstrdup (path); +#endif + if (IS_DIR_SEPARATOR (path[0])) + return xstrdup (path); + + /* prepend the current directory */ + /* doesn't handle '~' */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ + p = XMALLOC(char, size); + sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); + return p; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + # GNU ar 2.10+ was changed to match POSIX; thus no paths are + # encoded into archives. This makes 'ar r' malfunction in + # this piecewise linking case whenever conflicting object + # names appear in distinct ar calls; check, warn and compensate. + if (for obj in $save_oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2 + $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2 + AR_FLAGS=cq + fi + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + save_umask=`umask` + umask 0077 + if $mkdir "$tmpdir"; then + umask $save_umask + else + umask $save_umask + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "----------------------------------------------------------------------" + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "----------------------------------------------------------------------" + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test "$mode" = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $EXIT_SUCCESS + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# Libtool was configured on host sangoma_mantis: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-pc-linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# A language-specific compiler. +CC="g++" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +# An ERE matcher. +EGREP="grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=32768 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation ? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" +old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects="/usr/lib/gcc/i386-redhat-linux/3.4.4/../../../crti.o /usr/lib/gcc/i386-redhat-linux/3.4.4/crtbeginS.o" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects="/usr/lib/gcc/i386-redhat-linux/3.4.4/crtendS.o /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../crtn.o" + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="-L/usr/lib/gcc/i386-redhat-linux/3.4.4 -L/usr/lib/gcc/i386-redhat-linux/3.4.4 -L/usr/lib/gcc/i386-redhat-linux/3.4.4/../../.." + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var= + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec=" /usr/lib/gcc/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../i386-redhat-linux/lib/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../ /lib/i386-redhat-linux/3.4.4/ /lib/ /usr/lib/i386-redhat-linux/3.4.4/ /usr/lib/" + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/lib /usr/lib include ld.so.conf.d/*.conf " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL TAG CONFIG: CXX + +# ### BEGIN LIBTOOL TAG CONFIG: F77 + +# Libtool was configured on host sangoma_mantis: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-pc-linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# A language-specific compiler. +CC="g77" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +# An ERE matcher. +EGREP="grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=32768 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation ? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag="" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" +old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ +cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ +\$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects="" + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="" + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec=" /usr/lib/gcc/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../i386-redhat-linux/lib/i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../i386-redhat-linux/3.4.4/ /usr/lib/gcc/i386-redhat-linux/3.4.4/../../../ /lib/i386-redhat-linux/3.4.4/ /lib/ /usr/lib/i386-redhat-linux/3.4.4/ /usr/lib/" + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/lib /usr/lib include ld.so.conf.d/*.conf " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL TAG CONFIG: F77 + diff --git a/api/libsangoma/.svn/text-base/svn-commit.2.tmp.svn-base b/api/libsangoma/.svn/text-base/svn-commit.2.tmp.svn-base new file mode 100644 index 0000000..48940b9 --- /dev/null +++ b/api/libsangoma/.svn/text-base/svn-commit.2.tmp.svn-base @@ -0,0 +1,5 @@ +Added new event support +--This line, and those below, will be ignored-- + +M libsangoma.c +M libsangoma.h diff --git a/api/libsangoma/.svn/text-base/svn-commit.tmp.svn-base b/api/libsangoma/.svn/text-base/svn-commit.tmp.svn-base new file mode 100644 index 0000000..4965420 --- /dev/null +++ b/api/libsangoma/.svn/text-base/svn-commit.tmp.svn-base @@ -0,0 +1,5 @@ +Added new event features +--This line, and those below, will be ignored-- + +M libsangoma.c +M libsangoma.h diff --git a/api/libsangoma/Makefile b/api/libsangoma/Makefile index fce2039..6d7b323 100644 --- a/api/libsangoma/Makefile +++ b/api/libsangoma/Makefile @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.2 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,8 +16,6 @@ -SOURCES = $(libsangoma_a_SOURCES) $(libsangoma_la_SOURCES) - srcdir = . top_srcdir = . @@ -87,11 +85,11 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) \ +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link --tag=CC $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libsangoma_a_SOURCES) $(libsangoma_la_SOURCES) DIST_SOURCES = $(libsangoma_a_SOURCES) \ @@ -112,14 +110,14 @@ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print -ACLOCAL = ${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run aclocal-1.9 +ACLOCAL = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run aclocal-1.9 AMDEP_FALSE = # AMDEP_TRUE = -AMTAR = ${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run tar +AMTAR = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run tar AR = ar -AUTOCONF = ${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run autoconf -AUTOHEADER = ${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run autoheader -AUTOMAKE = ${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run automake-1.9 +AUTOCONF = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run autoconf +AUTOHEADER = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run autoheader +AUTOMAKE = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run automake-1.9 AWK = gawk CC = gcc CCDEPMODE = depmode=gcc3 @@ -153,7 +151,7 @@ LIBS = LIBTOOL = $(SHELL) $(top_builddir)/libtool LN_S = ln -s LTLIBOBJS = -MAKEINFO = ${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run makeinfo +MAKEINFO = ${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run makeinfo OBJEXT = o PACKAGE = libsangoma PACKAGE_BUGREPORT = anthmct@yahoo.com @@ -163,6 +161,7 @@ PACKAGE_TARNAME = libsangoma PACKAGE_VERSION = 1.0.0 PATH_SEPARATOR = : RANLIB = ranlib +SED = /bin/sed SET_MAKE = SHELL = /bin/sh STRIP = strip @@ -197,7 +196,7 @@ host_os = linux-gnu host_vendor = pc includedir = ${prefix}/include infodir = ${prefix}/info -install_sh = /root/3.2/wanpipe/api/libsangoma/install-sh +install_sh = /root/3.3/wanpipe/api/libsangoma/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec libpripath = @@ -357,18 +356,18 @@ include ./$(DEPDIR)/libsangoma_la-sangoma_pri.Plo # $(LTCOMPILE) -c -o $@ $< libsangoma_la-libsangoma.lo: libsangoma.c - if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-libsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c; \ + if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-libsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c; \ then mv -f "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" "$(DEPDIR)/libsangoma_la-libsangoma.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libsangoma.Tpo"; exit 1; fi # source='libsangoma.c' object='libsangoma_la-libsangoma.lo' libtool=yes \ # DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c +# $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c libsangoma_la-sangoma_pri.lo: sangoma_pri.c - if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-sangoma_pri.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c; \ + if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-sangoma_pri.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c; \ then mv -f "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" "$(DEPDIR)/libsangoma_la-sangoma_pri.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo"; exit 1; fi # source='sangoma_pri.c' object='libsangoma_la-sangoma_pri.lo' libtool=yes \ # DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c +# $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c mostlyclean-libtool: -rm -f *.lo diff --git a/api/libsangoma/Makefile.in b/api/libsangoma/Makefile.in index 41ebb2c..251a1de 100644 --- a/api/libsangoma/Makefile.in +++ b/api/libsangoma/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.2 from Makefile.am. +# Makefile.in generated by automake 1.9.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,8 +16,6 @@ -SOURCES = $(libsangoma_a_SOURCES) $(libsangoma_la_SOURCES) - srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -87,11 +85,11 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) \ +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link --tag=CC $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(libsangoma_a_SOURCES) $(libsangoma_la_SOURCES) DIST_SOURCES = $(libsangoma_a_SOURCES) \ @@ -163,6 +161,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -357,18 +356,18 @@ distclean-compile: @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libsangoma_la-libsangoma.lo: libsangoma.c -@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-libsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c; \ +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-libsangoma.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsangoma_la-libsangoma.Tpo" "$(DEPDIR)/libsangoma_la-libsangoma.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-libsangoma.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libsangoma.c' object='libsangoma_la-libsangoma.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-libsangoma.lo `test -f 'libsangoma.c' || echo '$(srcdir)/'`libsangoma.c libsangoma_la-sangoma_pri.lo: sangoma_pri.c -@am__fastdepCC_TRUE@ if $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-sangoma_pri.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c; \ +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -MT libsangoma_la-sangoma_pri.lo -MD -MP -MF "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo" "$(DEPDIR)/libsangoma_la-sangoma_pri.Plo"; else rm -f "$(DEPDIR)/libsangoma_la-sangoma_pri.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sangoma_pri.c' object='libsangoma_la-sangoma_pri.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsangoma_la_CFLAGS) $(CFLAGS) -c -o libsangoma_la-sangoma_pri.lo `test -f 'sangoma_pri.c' || echo '$(srcdir)/'`sangoma_pri.c mostlyclean-libtool: -rm -f *.lo diff --git a/api/libsangoma/aclocal.m4 b/api/libsangoma/aclocal.m4 index 8a90c6a..b9e32cf 100644 --- a/api/libsangoma/aclocal.m4 +++ b/api/libsangoma/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.9.2 -*- Autoconf -*- +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -13,7 +13,7 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# serial 47 AC_PROG_LIBTOOL +# serial 48 AC_PROG_LIBTOOL # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) @@ -123,7 +123,7 @@ esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' +Xsed='sed -e 1s/^X//' [sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] # Same as above, but do not quote variable references. @@ -143,7 +143,7 @@ rm="rm -f" default_ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except M$VC, +# All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" @@ -163,6 +163,7 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" @@ -182,15 +183,17 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi +_LT_CC_BASENAME([$compiler]) + # Only perform the check for file, if the check method requires it case $deplibs_check_method in file_magic*) @@ -231,11 +234,56 @@ AC_DEFUN([_LT_AC_SYS_COMPILER], # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_AC_SYS_COMPILER +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_LINKER_BOILERPLATE + + # _LT_AC_SYS_LIBPATH_AIX # ---------------------- # Links a minimal program and checks the executable @@ -308,15 +356,15 @@ fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. -if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string="`eval $cmd`") 2>/dev/null && - echo_test_string="`eval $cmd`" && + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break @@ -485,7 +533,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case "`/usr/bin/file conftest.o`" in + case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*linux*) @@ -536,6 +584,22 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) CFLAGS="$SAVE_CFLAGS" fi ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], [*-*-cygwin* | *-*-mingw* | *-*-pw32*) AC_CHECK_TOOL(DLLTOOL, dlltool, false) @@ -567,7 +631,7 @@ AC_CACHE_CHECK([$1], [$2], # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) @@ -577,8 +641,10 @@ AC_CACHE_CHECK([$1], [$2], echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi @@ -604,11 +670,16 @@ AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], LDFLAGS="$LDFLAGS $3" printf "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The compiler can only warn and ignore the option if not recognized + # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi else $2=yes fi @@ -667,11 +738,55 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - *) + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && new_result=`expr "X$teststring" : ".*" 2>&1` && lt_cv_sys_max_cmd_len=$new_result && @@ -697,7 +812,7 @@ fi # _LT_AC_CHECK_DLFCN -# -------------------- +# ------------------ AC_DEFUN([_LT_AC_CHECK_DLFCN], [AC_CHECK_HEADERS(dlfcn.h)dnl ])# _LT_AC_CHECK_DLFCN @@ -705,7 +820,7 @@ AC_DEFUN([_LT_AC_CHECK_DLFCN], # _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ------------------------------------------------------------------ +# --------------------------------------------------------------------- AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "$cross_compiling" = yes; then : @@ -771,17 +886,19 @@ int main () else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } + else + puts (dlerror ()); exit (status); }] EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; - x$lt_unknown|x*) $3 ;; + x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed @@ -793,7 +910,7 @@ rm -fr conftest* # AC_LIBTOOL_DLOPEN_SELF -# ------------------- +# ---------------------- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "x$enable_dlopen" != xyes; then @@ -864,7 +981,7 @@ else test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" @@ -877,7 +994,7 @@ else ]) if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_AC_TRY_DLOPEN_SELF( @@ -925,7 +1042,7 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) @@ -937,11 +1054,13 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - if test ! -s out/conftest.err; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi - chmod u+w . + chmod u+w . 2>&AS_MESSAGE_LOG_FD $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -1005,8 +1124,8 @@ AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_AC_TAGVAR(hardcode_action, $1)= if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ - test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \ - test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existant directories. if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && @@ -1173,7 +1292,7 @@ beos*) shlibpath_var=LIBRARY_PATH ;; -bsdi4*) +bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -1201,7 +1320,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -1231,7 +1351,7 @@ cygwin* | mingw* | pw32*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac ;; @@ -1254,7 +1374,7 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` @@ -1289,8 +1409,17 @@ kfreebsd*-gnu) dynamic_linker='GNU ld.so' ;; -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -1308,14 +1437,19 @@ freebsd*) freebsd2*) shlibpath_overrides_runpath=yes ;; - freebsd3.[01]* | freebsdelf3.[01]*) + freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -1335,7 +1469,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -1375,6 +1509,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -1451,7 +1597,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`$SED -e 's/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g' /etc/ld.so.conf | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" fi @@ -1513,8 +1659,13 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no - need_version=yes + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH @@ -1552,13 +1703,6 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - solaris*) version_type=linux need_lib_prefix=no @@ -1584,7 +1728,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -1617,6 +1761,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -1630,6 +1797,11 @@ uts4*) esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi ])# AC_LIBTOOL_SYS_DYNAMIC_LINKER @@ -1654,6 +1826,9 @@ if test -f "$ltmain" && test -n "$tagnames"; then AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) fi fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. @@ -1680,7 +1855,9 @@ if test -f "$ltmain" && test -n "$tagnames"; then case $tagname in CXX) - if test -n "$CXX" && test "X$CXX" != "Xno"; then + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then AC_LIBTOOL_LANG_CXX_CONFIG else tagname="" @@ -1742,7 +1919,7 @@ AC_DEFUN([AC_LIBTOOL_DLOPEN], # AC_LIBTOOL_WIN32_DLL # -------------------- -# declare package support for building win32 dll's +# declare package support for building win32 DLLs AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) ])# AC_LIBTOOL_WIN32_DLL @@ -1780,7 +1957,7 @@ AC_ARG_ENABLE([shared], # AC_DISABLE_SHARED # ----------------- -#- set the default shared flag to --disable-shared +# set the default shared flag to --disable-shared AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_SHARED(no) @@ -1916,7 +2093,7 @@ dnl not every word. This closes a longstanding sh security hole. if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then @@ -2026,7 +2203,7 @@ AC_CACHE_VAL(lt_cv_path_LD, if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. + # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; @@ -2163,7 +2349,7 @@ gnu*) hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file - case "$host_cpu" in + case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so @@ -2179,6 +2365,11 @@ hpux10.20* | hpux11*) esac ;; +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; @@ -2191,15 +2382,6 @@ irix5* | irix6* | nonstopux*) # This must be Linux ELF. linux*) - case $host_cpu in - alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*|x86_64*) - lt_cv_deplibs_check_method=pass_all ;; - *) - # glibc up to 2.1.1 does not perform some relocations on ARM - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; - esac - lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` lt_cv_deplibs_check_method=pass_all ;; @@ -2222,12 +2404,10 @@ nto-qnx*) ;; openbsd*) - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else - lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; @@ -2235,15 +2415,11 @@ osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - solaris*) lt_cv_deplibs_check_method=pass_all ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' @@ -2264,10 +2440,13 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) siemens) lt_cv_deplibs_check_method=pass_all ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; esac ;; -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac @@ -2287,36 +2466,43 @@ AC_DEFUN([AC_PROG_NM], # Let the user override the test. lt_cv_path_NM="$NM" else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" break ;; *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac ;; esac - esac - fi + fi + done + IFS="$lt_save_ifs" done - IFS="$lt_save_ifs" test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi]) NM="$lt_cv_path_NM" @@ -2348,13 +2534,13 @@ esac # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL -# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If -# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will -# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# it is assumed to be `libltdl'. LIBLTDL will be prefixed with +# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' +# (note the single quotes!). If your package is not flat and you're not +# using automake, define top_builddir and top_srcdir appropriately in +# the Makefiles. AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl case $enable_ltdl_convenience in @@ -2373,13 +2559,13 @@ AC_DEFUN([AC_LIBLTDL_CONVENIENCE], # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl installable library and # LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-install to the configure arguments. Note that LIBLTDL -# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If -# DIRECTORY is not provided and an installed libltdl is not found, it is -# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' -# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single -# quotes!). If your package is not flat and you're not using automake, -# define top_builddir and top_srcdir appropriately in the Makefiles. +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# and an installed libltdl is not found, it is assumed to be `libltdl'. +# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and top_srcdir +# appropriately in the Makefiles. # In the future, this macro may have to be called after AC_PROG_LIBTOOL. AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl @@ -2417,10 +2603,21 @@ AC_DEFUN([AC_LIBTOOL_CXX], # --------------- AC_DEFUN([_LT_AC_LANG_CXX], [AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([AC_PROG_CXXCPP]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) ])# _LT_AC_LANG_CXX +# _LT_AC_PROG_CXXCPP +# ------------------ +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP # AC_LIBTOOL_F77 # -------------- @@ -2460,7 +2657,7 @@ _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) # AC_LIBTOOL_RC -# -------------- +# ------------- # enable support for Windows resource files AC_DEFUN([AC_LIBTOOL_RC], [AC_REQUIRE([LT_AC_PROG_RC]) @@ -2493,36 +2690,9 @@ lt_simple_link_test_code='int main(){return(0);}\n' _LT_AC_SYS_COMPILER -# -# Check for any special shared library compilation flags. -# -_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' - ;; - esac -fi -if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then - AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) - if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : - else - AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) - _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), - $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), - [], - [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) - +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) AC_LIBTOOL_PROG_COMPILER_PIC($1) @@ -2532,9 +2702,9 @@ AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) +AC_LIBTOOL_DLOPEN_SELF -# Report which librarie types wil actually be built +# Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) @@ -2543,7 +2713,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -2555,43 +2725,6 @@ aix3*) aix4* | aix5*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no - fi - ;; - darwin* | rhapsody*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case "$host_os" in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; esac @@ -2618,7 +2751,7 @@ AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], [AC_LANG_PUSH(C++) AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([AC_PROG_CXXCPP]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(allow_undefined_flag, $1)= @@ -2630,6 +2763,7 @@ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= _LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(hardcode_automatic, $1)=no _LT_AC_TAGVAR(module_cmds, $1)= _LT_AC_TAGVAR(module_expsym_cmds, $1)= @@ -2647,7 +2781,7 @@ _LT_AC_TAGVAR(postdeps, $1)= _LT_AC_TAGVAR(compiler_lib_search_path, $1)= # Source file extension for C++ test sources. -ac_ext=cc +ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o @@ -2657,11 +2791,15 @@ _LT_AC_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD @@ -2672,18 +2810,18 @@ lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else - unset lt_cv_prog_gnu_ld + $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else - unset lt_cv_path_LD + $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_AC_TAGVAR(compiler, $1)=$CC -cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` +_LT_CC_BASENAME([$compiler]) # We don't want -fno-exception wen compiling C++ code, so set the # no_builtin_flag separately @@ -2772,6 +2910,7 @@ case $host_os in ;; esac done + ;; esac exp_sym_flag='-bexport' @@ -2790,7 +2929,7 @@ case $host_os in _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GXX" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) + case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` @@ -2809,8 +2948,12 @@ case $host_os in _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi + ;; esac shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi else # not using gcc if test "$host_cpu" = ia64; then @@ -2837,12 +2980,12 @@ case $host_os in _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX @@ -2851,16 +2994,26 @@ case $host_os in # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds it's shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + chorus*) case $cc_basename in *) @@ -2879,7 +3032,7 @@ case $host_os in _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -2888,70 +3041,81 @@ case $host_os in echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; - - darwin* | rhapsody*) - if test "$GXX" = yes; then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case "$host_os" in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' - ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; dgux*) case $cc_basename in - ec++) + ec++*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - ghcx) + ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no @@ -2962,14 +3126,14 @@ case $host_os in ;; esac ;; - freebsd[12]*) + freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before switch to ELF _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_AC_TAGVAR(ld_shlibs, $1)=yes @@ -2986,11 +3150,11 @@ case $host_os in # location of the library. case $cc_basename in - CC) + CC*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - aCC) + aCC*) _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when @@ -3000,7 +3164,7 @@ case $host_os in # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then @@ -3014,34 +3178,23 @@ case $host_os in ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then - case "$host_cpu" in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi - case "$host_cpu" in - hppa*64*) + case $host_cpu in + hppa*64*|ia64*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - ia64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; *) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, @@ -3051,14 +3204,17 @@ case $host_os in esac case $cc_basename in - CC) + CC*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - aCC) - case "$host_cpu" in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -3077,9 +3233,12 @@ case $host_os in *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then - case "$host_cpu" in - ia64*|hppa*64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -3093,11 +3252,25 @@ case $host_os in ;; esac ;; + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; irix5* | irix6*) case $cc_basename in - CC) + CC*) # SGI C++ - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is @@ -3108,7 +3281,7 @@ case $host_os in *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' fi @@ -3121,7 +3294,7 @@ case $host_os in ;; linux*) case $cc_basename in - KCC) + KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file @@ -3146,17 +3319,41 @@ case $host_os in # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - icpc) + icpc*) # Intel C++ with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; - cxx) + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) # Compaq C++ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' @@ -3187,7 +3384,7 @@ case $host_os in ;; mvs*) case $cc_basename in - cxx) + cxx*) # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; @@ -3208,9 +3405,25 @@ case $host_os in # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; osf3*) case $cc_basename in - KCC) + KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file @@ -3226,14 +3439,14 @@ case $host_os in _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - RCC) + RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - cxx) + cxx*) _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: @@ -3251,7 +3464,7 @@ case $host_os in *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: @@ -3270,7 +3483,7 @@ case $host_os in ;; osf4* | osf5*) case $cc_basename in - KCC) + KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file @@ -3285,17 +3498,17 @@ case $host_os in # the KAI C++ compiler. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - RCC) + RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - cxx) + cxx*) _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ $rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -3314,7 +3527,7 @@ case $host_os in *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: @@ -3335,27 +3548,14 @@ case $host_os in # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - sco*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; sunos4*) case $cc_basename in - CC) + CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - lcc) + lcc*) # Lucid # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no @@ -3368,36 +3568,33 @@ case $host_os in ;; solaris*) case $cc_basename in - CC) + CC*) # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The C++ compiler is used as linker so we must use $wl # flag to pass the commands to the underlying system - # linker. + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is @@ -3405,7 +3602,7 @@ case $host_os in # in the archive. _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; - gcx) + gcx*) # Green Hills C++ Compiler _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' @@ -3443,12 +3640,63 @@ case $host_os in ;; esac ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac ;; tandem*) case $cc_basename in - NCC) + NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no @@ -3481,8 +3729,6 @@ AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) AC_LIBTOOL_CONFIG($1) @@ -3500,7 +3746,7 @@ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ])# AC_LIBTOOL_LANG_CXX_CONFIG # AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) -# ------------------------ +# ------------------------------------ # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary @@ -3554,7 +3800,7 @@ if AC_TRY_EVAL(ac_compile); then # The `*' in the case matches for architectures that use `case' in # $output_verbose_cmd can trigger glob expansion during the loop # eval without this substitution. - output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`" + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` for p in `eval $output_verbose_link_cmd`; do case $p in @@ -3630,13 +3876,37 @@ fi $rm -f confest.$objext +# PORTME: override above test on systems where it is broken +ifelse([$1],[CXX], +[case $host_os in +interix3*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_AC_TAGVAR(predep_objects,$1)= + _LT_AC_TAGVAR(postdep_objects,$1)= + _LT_AC_TAGVAR(postdeps,$1)= + ;; + +solaris*) + case $cc_basename in + CC*) + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun' + ;; + esac + ;; +esac +]) + case " $_LT_AC_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac ])# AC_LIBTOOL_POSTDEP_PREDEP # AC_LIBTOOL_LANG_F77_CONFIG -# ------------------------ +# -------------------------- # Ensure that the configuration vars for the C compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. @@ -3680,12 +3950,16 @@ lt_simple_link_test_code=" program t\n end\n" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${F77-"f77"} compiler=$CC _LT_AC_TAGVAR(compiler, $1)=$CC -cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` +_LT_CC_BASENAME([$compiler]) AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) @@ -3695,7 +3969,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -3704,7 +3978,9 @@ aix3*) fi ;; aix4* | aix5*) - test "$enable_shared" = yes && enable_static=no + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi ;; esac AC_MSG_RESULT([$enable_shared]) @@ -3714,8 +3990,6 @@ AC_MSG_CHECKING([whether to build static libraries]) test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - _LT_AC_TAGVAR(GCC, $1)="$G77" _LT_AC_TAGVAR(LD, $1)="$LD" @@ -3725,8 +3999,6 @@ AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP - AC_LIBTOOL_CONFIG($1) @@ -3755,20 +4027,27 @@ _LT_AC_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code="class foo {}\n" # Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${GCJ-"gcj"} compiler=$CC _LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) AC_LIBTOOL_PROG_COMPILER_PIC($1) AC_LIBTOOL_PROG_CC_C_O($1) @@ -3776,8 +4055,6 @@ AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) AC_LIBTOOL_CONFIG($1) @@ -3787,7 +4064,7 @@ CC="$lt_save_CC" # AC_LIBTOOL_LANG_RC_CONFIG -# -------------------------- +# ------------------------- # Ensure that the configuration vars for the Windows resource compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. @@ -3811,11 +4088,16 @@ lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${RC-"windres"} compiler=$CC _LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes AC_LIBTOOL_CONFIG($1) @@ -3845,7 +4127,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -3951,7 +4233,7 @@ ifelse([$1], [], # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -3962,11 +4244,11 @@ ifelse([$1], [], SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="$SED -e s/^X//" +Xsed="$SED -e 1s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # The names of the tagged configurations supported by this script. available_tags= @@ -3997,6 +4279,12 @@ fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo @@ -4008,12 +4296,18 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) # Is the compiler the GNU C compiler? with_gcc=$_LT_AC_TAGVAR(GCC, $1) +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + # An ERE matcher. EGREP=$lt_EGREP @@ -4073,7 +4367,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? @@ -4147,11 +4441,11 @@ striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) +predep_objects=\`echo $lt_[]_LT_AC_TAGVAR(predep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) +postdep_objects=\`echo $lt_[]_LT_AC_TAGVAR(postdep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place before the objects being linked to create a # shared library. @@ -4163,7 +4457,7 @@ postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) +compiler_lib_search_path=\`echo $lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method @@ -4243,7 +4537,7 @@ variables_saved_for_relink="$variables_saved_for_relink" link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) # Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec @@ -4347,9 +4641,6 @@ symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - # Transform an extracted symbol line into a proper C declaration lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" @@ -4371,15 +4662,31 @@ hpux*) # Its linker distinguishes data from code symbols lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; -solaris* | sysv5*) +solaris*) symcode='[[BDRT]]' ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; sysv4) symcode='[[DFNSTU]]' ;; @@ -4402,8 +4709,11 @@ esac # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + # Write the raw and C identifiers. - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no @@ -4559,6 +4869,10 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) # DJGPP does not support shared libraries at all _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic @@ -4567,7 +4881,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) ;; *) @@ -4592,18 +4906,28 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; chorus*) case $cc_basename in - cxch68) + cxch68*) # Green Hills C++ Compiler # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; dgux*) case $cc_basename in - ec++) + ec++*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; - ghcx) + ghcx*) # Green Hills C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; @@ -4611,22 +4935,22 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in - CC) + CC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; - aCC) + aCC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case "$host_cpu" in + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -4639,9 +4963,13 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; irix5* | irix6* | nonstopux*) case $cc_basename in - CC) + CC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. @@ -4652,18 +4980,24 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; linux*) case $cc_basename in - KCC) + KCC*) # KAI C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; - icpc) + icpc* | ecpc*) # Intel C++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; - cxx) + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. @@ -4680,7 +5014,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; mvs*) case $cc_basename in - cxx) + cxx*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) @@ -4691,14 +5025,14 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; osf3* | osf4* | osf5*) case $cc_basename in - KCC) + KCC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; - RCC) + RCC*) # Rational C++ 2.4.1 _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; - cxx) + cxx*) # Digital/Compaq C++ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha @@ -4712,24 +5046,15 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; psos*) ;; - sco*) - case $cc_basename in - CC) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - *) - ;; - esac - ;; solaris*) case $cc_basename in - CC) + CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; - gcx) + gcx*) # Green Hills C++ Compiler _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; @@ -4739,12 +5064,12 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; sunos4*) case $cc_basename in - CC) + CC*) # Sun C++ 4.x _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; - lcc) + lcc*) # Lucid _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; @@ -4754,7 +5079,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; tandem*) case $cc_basename in - NCC) + NCC*) # NonStop-UX NCC 3.20 _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; @@ -4762,7 +5087,14 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; - unixware*) + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac ;; vxworks*) ;; @@ -4809,6 +5141,11 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -4825,7 +5162,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -4851,6 +5188,16 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being @@ -4862,7 +5209,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -4886,12 +5233,19 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; linux*) - case $CC in + case $cc_basename in icc* | ecc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; ccc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. @@ -4906,15 +5260,15 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' - ;; - solaris*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac ;; sunos4*) @@ -4923,7 +5277,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' @@ -4936,6 +5290,17 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + uts4*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' @@ -4963,7 +5328,7 @@ if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= @@ -4972,6 +5337,16 @@ case "$host_os" in _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" ;; esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) ]) @@ -4996,7 +5371,7 @@ ifelse([$1],[CXX],[ _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' ;; *) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' @@ -5039,7 +5414,8 @@ ifelse([$1],[CXX],[ # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= - + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) case $host_os in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time @@ -5049,6 +5425,10 @@ ifelse([$1],[CXX],[ with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -5059,6 +5439,27 @@ ifelse([$1],[CXX],[ # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) @@ -5109,10 +5510,10 @@ EOF _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -5121,9 +5522,55 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else - ld_shlibs=no + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; @@ -5137,7 +5584,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <&2 @@ -5158,6 +5605,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + sunos4*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -5165,31 +5639,6 @@ EOF _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds" - fi - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' @@ -5200,16 +5649,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ ;; esac - if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then - runpath_var=LD_RUN_PATH - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) @@ -5221,7 +5665,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported @@ -5255,6 +5699,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ break fi done + ;; esac exp_sym_flag='-bexport' @@ -5273,7 +5718,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) + case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` @@ -5292,8 +5737,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi + ;; esac shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi else # not using gcc if test "$host_cpu" = ia64; then @@ -5301,11 +5750,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -5319,12 +5768,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX @@ -5333,13 +5782,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds it's shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -5352,7 +5799,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - bsdi4*) + bsdi[[45]]*) _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; @@ -5373,57 +5820,57 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) - if test "$GXX" = yes ; then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case "$host_os" in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup' - ;; - esac - fi - ;; + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else - _LT_AC_TAGVAR(ld_shlibs, $1)=no + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac fi ;; @@ -5457,7 +5904,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes @@ -5480,47 +5927,62 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' @@ -5568,6 +6030,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else @@ -5613,7 +6076,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -5621,21 +6084,15 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; - sco3.2v5*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' if test "$GCC" = yes; then + wlarc='${wl}' _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else + wlarc='' _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' @@ -5644,8 +6101,18 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; @@ -5702,36 +6169,45 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ fi ;; - sysv4.2uw2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - sysv5*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -5749,11 +6225,6 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -5781,6 +6252,7 @@ x|xyes) libobjs=conftest.$ac_objext deplibs= wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= @@ -5901,12 +6373,13 @@ do done done done +IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && break + test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in @@ -5931,28 +6404,17 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do fi done done -SED=$lt_cv_path_SED ]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ]) -# -*- Autoconf -*- -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. -# Generated from amversion.in; do not edit by hand. - -# 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., 59 Temple Place - Suite 330, Boston, MA +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- @@ -5965,26 +6427,15 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.2])]) + [AM_AUTOMAKE_VERSION([1.9.6])]) -# AM_AUX_DIR_EXPAND +# AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to @@ -6031,26 +6482,16 @@ AC_PREREQ([2.50])dnl am_aux_dir=`cd $ac_aux_dir && pwd` ]) -# AM_CONDITIONAL -*- Autoconf -*- +# AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 6 +# serial 7 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- @@ -6074,26 +6515,15 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# serial 7 -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - +# serial 8 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, @@ -6102,7 +6532,6 @@ fi])]) # CC etc. in the Makefile, will ask for an AC_PROG_CC use... - # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. @@ -6242,27 +6671,16 @@ AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) -# Generate code to set up dependency tracking. -*- Autoconf -*- +# Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 -# Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -#serial 2 +#serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ @@ -6321,30 +6739,19 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) -# Do all the work for Automake. -*- Autoconf -*- +# Do all the work for Automake. -*- Autoconf -*- -# This macro actually does too much some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is 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. +# serial 12 -# 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 11 +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) @@ -6446,51 +6853,27 @@ for _am_header in $config_headers :; do done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. - -# Copyright (C) 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) -# -*- Autoconf -*- -# Copyright (C) 2003 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 1 +# serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. @@ -6505,26 +6888,15 @@ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) -# Check to see how 'make' treats includes. -*- Autoconf -*- +# Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 2 +# serial 3 # AM_MAKE_INCLUDE() # ----------------- @@ -6568,27 +6940,16 @@ AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# -*- Autoconf -*- +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 +# serial 4 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ @@ -6614,27 +6975,16 @@ else fi ]) +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. - -# Copyright (C) 2003, 2004 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - +# # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). @@ -6688,26 +7038,15 @@ else fi AC_SUBST([mkdir_p])]) -# Helper functions for option handling. -*- Autoconf -*- +# Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# This program is 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 2 +# serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- @@ -6732,28 +7071,16 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. # -# Check to make sure that the build environment is sane. -# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. -# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 3 +# serial 4 # AM_SANITY_CHECK # --------------- @@ -6796,25 +7123,14 @@ Check your system clock]) fi AC_MSG_RESULT(yes)]) +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + # AM_PROG_INSTALL_STRIP - -# Copyright (C) 2001, 2003 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - +# --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip @@ -6837,25 +7153,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004 Free Software Foundation, 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -# serial 1 +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- diff --git a/api/libsangoma/autom4te.cache/output.0 b/api/libsangoma/autom4te.cache/output.0 new file mode 100644 index 0000000..2b3e017 --- /dev/null +++ b/api/libsangoma/autom4te.cache/output.0 @@ -0,0 +1,20518 @@ +@%:@! /bin/sh +@%:@ Guess values for system-dependent variables and create Makefiles. +@%:@ Generated by GNU Autoconf 2.59 for libsangoma 1.0.0. +@%:@ +@%:@ Report bugs to . +@%:@ +@%:@ Copyright (C) 2003 Free Software Foundation, Inc. +@%:@ This configure script is free software; the Free Software Foundation +@%:@ gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +tagnames=${tagnames+${tagnames},}CXX + +tagnames=${tagnames+${tagnames},}F77 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='libsangoma' +PACKAGE_TARNAME='libsangoma' +PACKAGE_VERSION='1.0.0' +PACKAGE_STRING='libsangoma 1.0.0' +PACKAGE_BUGREPORT='anthmct@yahoo.com' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBPRI_TRUE LIBPRI_FALSE libpripath LIB@&t@OBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP +ac_env_CXX_set=${CXX+set} +ac_env_CXX_value=$CXX +ac_cv_env_CXX_set=${CXX+set} +ac_cv_env_CXX_value=$CXX +ac_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_env_CXXFLAGS_value=$CXXFLAGS +ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_cv_env_CXXFLAGS_value=$CXXFLAGS +ac_env_CXXCPP_set=${CXXCPP+set} +ac_env_CXXCPP_value=$CXXCPP +ac_cv_env_CXXCPP_set=${CXXCPP+set} +ac_cv_env_CXXCPP_value=$CXXCPP +ac_env_F77_set=${F77+set} +ac_env_F77_value=$F77 +ac_cv_env_F77_set=${F77+set} +ac_cv_env_F77_value=$F77 +ac_env_FFLAGS_set=${FFLAGS+set} +ac_env_FFLAGS_value=$FFLAGS +ac_cv_env_FFLAGS_set=${FFLAGS+set} +ac_cv_env_FFLAGS_value=$FFLAGS + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures libsangoma 1.0.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libsangoma 1.0.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared@<:@=PKGS@:>@ + build shared libraries @<:@default=yes@:>@ + --enable-static@<:@=PKGS@:>@ + build static libraries @<:@default=yes@:>@ + --enable-fast-install@<:@=PKGS@:>@ + optimize for fast installation @<:@default=yes@:>@ + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld @<:@default=no@:>@ + --with-pic try to use only PIC/non-PIC objects @<:@default=use + both@:>@ + --with-tags@<:@=TAGS@:>@ + include additional configurations @<:@automatic@:>@ + --with-libpri= enable pri support + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + F77 Fortran 77 compiler command + FFLAGS Fortran 77 compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +libsangoma configure 1.0.0 +generated by GNU Autoconf 2.59 + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libsangoma $as_me 1.0.0, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +@%:@@%:@ --------- @%:@@%:@ +@%:@@%:@ Platform. @%:@@%:@ +@%:@@%:@ --------- @%:@@%:@ + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +@%:@@%:@ ----------- @%:@@%:@ +@%:@@%:@ Core tests. @%:@@%:@ +@%:@@%:@ ----------- @%:@@%:@ + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +@%:@@%:@ ---------------- @%:@@%:@ +@%:@@%:@ Cache variables. @%:@@%:@ +@%:@@%:@ ---------------- @%:@@%:@ +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +@%:@@%:@ ----------------- @%:@@%:@ +@%:@@%:@ Output variables. @%:@@%:@ +@%:@@%:@ ----------------- @%:@@%:@ +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +@%:@@%:@ ------------- @%:@@%:@ +@%:@@%:@ Output files. @%:@@%:@ +@%:@@%:@ ------------- @%:@@%:@ +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +@%:@@%:@ ----------- @%:@@%:@ +@%:@@%:@ confdefs.h. @%:@@%:@ +@%:@@%:@ ----------- @%:@@%:@ +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + +am__api_version="1.9" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=libsangoma + VERSION=1.0.0 + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $@%:@ != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +@%:@ifndef __cplusplus + choke me +@%:@endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +@%:@include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi; + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi; + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi; + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done + +fi + +SED=$lt_cv_path_SED + +echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6 + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + +echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi +echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 +echo "${ECHO_T}$lt_cv_path_NM" >&6 +NM="$lt_cv_path_NM" + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 +echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump'. + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | kfreebsd*-gnu | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +lt_cv_cc_needs_belf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + + +esac + +need_locks="$enable_libtool_lock" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +@%:@define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +@%:@@%:@ -------------------------------- @%:@@%:@ +@%:@@%:@ Report this to anthmct@yahoo.com @%:@@%:@ +@%:@@%:@ -------------------------------- @%:@@%:@ +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CXX" && break +done +test -n "$ac_ct_CXX" || ac_ct_CXX="g++" + + CXX=$ac_ct_CXX +fi + + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cxx_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +@%:@include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +echo "$as_me:$LINENO: result: $CXXCPP" >&5 +echo "${ECHO_T}$CXXCPP" >&6 +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +fi + + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$F77"; then + ac_cv_prog_F77="$F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_F77="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +F77=$ac_cv_prog_F77 +if test -n "$F77"; then + echo "$as_me:$LINENO: result: $F77" >&5 +echo "${ECHO_T}$F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$F77" && break + done +fi +if test -z "$F77"; then + ac_ct_F77=$F77 + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_F77"; then + ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_F77="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_F77=$ac_cv_prog_ac_ct_F77 +if test -n "$ac_ct_F77"; then + echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 +echo "${ECHO_T}$ac_ct_F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_F77" && break +done + + F77=$ac_ct_F77 +fi + + +# Provide some information about the compiler. +echo "$as_me:__oline__:" \ + "checking for Fortran 77 compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +rm -f a.out + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. (Note that this only needs to work for GNU compilers.) +ac_save_ext=$ac_ext +ac_ext=F +echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 +if test "${ac_cv_f77_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_f77_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 +ac_ext=$ac_save_ext +ac_test_FFLAGS=${FFLAGS+set} +ac_save_FFLAGS=$FFLAGS +FFLAGS= +echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 +echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_f77_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + FFLAGS=-g +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_f77_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_f77_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 +if test "$ac_test_FFLAGS" = set; then + FFLAGS=$ac_save_FFLAGS +elif test $ac_cv_prog_f77_g = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-g -O2" + else + FFLAGS="-g" + fi +else + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-O2" + else + FFLAGS= + fi +fi + +G77=`test $ac_compiler_gnu = yes && echo yes` +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# find the maximum length of command line arguments +echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 +else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +fi + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 +echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDGIRSTW]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 +else + echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6 +fi + +echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6 +if test "${lt_cv_objdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 +echo "${ECHO_T}$lt_cv_objdir" >&6 +objdir=$lt_cv_objdir + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + AR=$ac_ct_AR +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +enable_dlopen=no +enable_win32_dll=no + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi; +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic='-qnocommon' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 + +if test x"$lt_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works=yes + fi + else + lt_prog_compiler_static_works=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 + +if test x"$lt_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag= + enable_shared_with_static_runtimes=no + archive_cmds= + archive_expsym_cmds= + old_archive_From_new_cmds= + old_archive_from_expsyms_cmds= + export_dynamic_flag_spec= + whole_archive_flag_spec= + thread_safe_flag_spec= + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_direct=no + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + link_all_deplibs=unknown + hardcode_automatic=no + module_cmds= + module_expsym_cmds= + always_export_symbols=no + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix3*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld='-rpath $libdir' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6 +test "$ld_shlibs" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 +echo "${ECHO_T}$archive_cmds_need_lc" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var" || \ + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + ;; + *) + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +char (*f) () = shl_load; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != shl_load; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +char (*f) () = dlopen; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != dlopen; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# Report which library types will actually be built +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler \ + CC \ + LD \ + lt_prog_compiler_wl \ + lt_prog_compiler_pic \ + lt_prog_compiler_static \ + lt_prog_compiler_no_builtin_flag \ + export_dynamic_flag_spec \ + thread_safe_flag_spec \ + whole_archive_flag_spec \ + enable_shared_with_static_runtimes \ + old_archive_cmds \ + old_archive_from_new_cmds \ + predep_objects \ + postdep_objects \ + predeps \ + postdeps \ + compiler_lib_search_path \ + archive_cmds \ + archive_expsym_cmds \ + postinstall_cmds \ + postuninstall_cmds \ + old_archive_from_expsyms_cmds \ + allow_undefined_flag \ + no_undefined_flag \ + export_symbols_cmds \ + hardcode_libdir_flag_spec \ + hardcode_libdir_flag_spec_ld \ + hardcode_libdir_separator \ + hardcode_automatic \ + module_cmds \ + module_expsym_cmds \ + lt_cv_prog_compiler_c_o \ + exclude_expsyms \ + include_expsyms; do + + case $var in + old_archive_cmds | \ + old_archive_from_new_cmds | \ + archive_cmds | \ + archive_expsym_cmds | \ + module_cmds | \ + module_expsym_cmds | \ + old_archive_from_expsyms_cmds | \ + export_symbols_cmds | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + { echo "$as_me:$LINENO: creating $ofile" >&5 +echo "$as_me: creating $ofile" >&6;} + + cat <<__EOF__ >> "$cfgfile" +#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + +# Check whether --with-tags or --without-tags was given. +if test "${with_tags+set}" = set; then + withval="$with_tags" + tagnames="$withval" +fi; + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} + else + { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 +echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in + "") ;; + *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 +echo "$as_me: error: invalid tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 +echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} + { (exit 1); exit 1; }; } + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +compiler_CXX=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' +else + lt_prog_compiler_no_builtin_flag_CXX= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 +ld_shlibs_CXX=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_CXX=yes + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_CXX=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + ld_shlibs_CXX=no + ;; + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + gnu*) + ;; + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_CXX='+b $libdir' + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + interix3*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + ;; + linux*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + openbsd*) + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; +esac +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +GCC_CXX="$GXX" +LD_CXX="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... + +cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$rm -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix3*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +solaris*) + case $cc_basename in + CC*) + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + postdeps_CXX='-lCstd -lCrun' + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + +lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_CXX='-qnocommon' + lt_prog_compiler_wl_CXX='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_CXX=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 + +if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_CXX=yes + fi + else + lt_prog_compiler_static_works_CXX=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6 + +if test x"$lt_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || \ + test -n "$runpath_var_CXX" || \ + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 +echo "${ECHO_T}$hardcode_action_CXX" >&6 + +if test "$hardcode_action_CXX" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_CXX \ + CC_CXX \ + LD_CXX \ + lt_prog_compiler_wl_CXX \ + lt_prog_compiler_pic_CXX \ + lt_prog_compiler_static_CXX \ + lt_prog_compiler_no_builtin_flag_CXX \ + export_dynamic_flag_spec_CXX \ + thread_safe_flag_spec_CXX \ + whole_archive_flag_spec_CXX \ + enable_shared_with_static_runtimes_CXX \ + old_archive_cmds_CXX \ + old_archive_from_new_cmds_CXX \ + predep_objects_CXX \ + postdep_objects_CXX \ + predeps_CXX \ + postdeps_CXX \ + compiler_lib_search_path_CXX \ + archive_cmds_CXX \ + archive_expsym_cmds_CXX \ + postinstall_cmds_CXX \ + postuninstall_cmds_CXX \ + old_archive_from_expsyms_cmds_CXX \ + allow_undefined_flag_CXX \ + no_undefined_flag_CXX \ + export_symbols_cmds_CXX \ + hardcode_libdir_flag_spec_CXX \ + hardcode_libdir_flag_spec_ld_CXX \ + hardcode_libdir_separator_CXX \ + hardcode_automatic_CXX \ + module_cmds_CXX \ + module_expsym_cmds_CXX \ + lt_cv_prog_compiler_c_o_CXX \ + exclude_expsyms_CXX \ + include_expsyms_CXX; do + + case $var in + old_archive_cmds_CXX | \ + old_archive_from_new_cmds_CXX | \ + archive_cmds_CXX | \ + archive_expsym_cmds_CXX | \ + module_cmds_CXX | \ + module_expsym_cmds_CXX | \ + old_archive_from_expsyms_cmds_CXX | \ + export_symbols_cmds_CXX | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_CXX + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_CXX +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_CXX" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld + + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + + +archive_cmds_need_lc_F77=no +allow_undefined_flag_F77= +always_export_symbols_F77=no +archive_expsym_cmds_F77= +export_dynamic_flag_spec_F77= +hardcode_direct_F77=no +hardcode_libdir_flag_spec_F77= +hardcode_libdir_flag_spec_ld_F77= +hardcode_libdir_separator_F77= +hardcode_minus_L_F77=no +hardcode_automatic_F77=no +module_cmds_F77= +module_expsym_cmds_F77= +link_all_deplibs_F77=unknown +old_archive_cmds_F77=$old_archive_cmds +no_undefined_flag_F77= +whole_archive_flag_spec_F77= +enable_shared_with_static_runtimes_F77=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +objext_F77=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code=" subroutine t\n return\n end\n" + +# Code to be used in simple link tests +lt_simple_link_test_code=" program t\n end\n" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +compiler_F77=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +GCC_F77="$G77" +LD_F77="$LD" + +lt_prog_compiler_wl_F77= +lt_prog_compiler_pic_F77= +lt_prog_compiler_static_F77= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_static_F77='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_F77='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_F77=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_F77=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_F77='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + else + lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_F77='-qnocommon' + lt_prog_compiler_wl_F77='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_F77='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_F77='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-fpic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_F77='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_F77='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_F77='-Qoption ld ';; + *) + lt_prog_compiler_wl_F77='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_F77='-Qoption ld ' + lt_prog_compiler_pic_F77='-PIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_F77='-Kconform_pic' + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_can_build_shared_F77=no + ;; + + uts4*) + lt_prog_compiler_pic_F77='-pic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_F77"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_F77=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_F77" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_F77=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 + +if test x"$lt_prog_compiler_pic_works_F77" = xyes; then + case $lt_prog_compiler_pic_F77 in + "" | " "*) ;; + *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; + esac +else + lt_prog_compiler_pic_F77= + lt_prog_compiler_can_build_shared_F77=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_F77= + ;; + *) + lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_F77=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_F77=yes + fi + else + lt_prog_compiler_static_works_F77=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6 + +if test x"$lt_prog_compiler_static_works_F77" = xyes; then + : +else + lt_prog_compiler_static_F77= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_F77=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_F77=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_F77= + enable_shared_with_static_runtimes_F77=no + archive_cmds_F77= + archive_expsym_cmds_F77= + old_archive_From_new_cmds_F77= + old_archive_from_expsyms_cmds_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + thread_safe_flag_spec_F77= + hardcode_libdir_flag_spec_F77= + hardcode_libdir_flag_spec_ld_F77= + hardcode_libdir_separator_F77= + hardcode_direct_F77=no + hardcode_minus_L_F77=no + hardcode_shlibpath_var_F77=unsupported + link_all_deplibs_F77=unknown + hardcode_automatic_F77=no + module_cmds_F77= + module_expsym_cmds_F77= + always_export_symbols_F77=no + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_F77= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_F77=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_F77='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_F77= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_F77=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_F77=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_F77='-L$libdir' + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=no + enable_shared_with_static_runtimes_F77=yes + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_F77=no + fi + ;; + + interix3*) + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_F77=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_F77=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + + if test "$ld_shlibs_F77" = no; then + runpath_var= + hardcode_libdir_flag_spec_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=yes + archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_F77=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_F77=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_F77='' + hardcode_direct_F77=yes + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_F77=yes + else + # We have old collect2 + hardcode_direct_F77=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_F77=yes + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_libdir_separator_F77= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_F77=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_F77='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_F77="-z nodefs" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_F77=' ${wl}-bernotok' + allow_undefined_flag_F77=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_F77='$convenience' + archive_cmds_need_lc_F77=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_F77=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_F77=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_F77=' ' + allow_undefined_flag_F77=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_F77='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_F77='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_F77=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_F77=no + hardcode_direct_F77=no + hardcode_automatic_F77=yes + hardcode_shlibpath_var_F77=unsupported + whole_archive_flag_spec_F77='' + link_all_deplibs_F77=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_F77=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + freebsd1*) + ld_shlibs_F77=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + ;; + *) + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + link_all_deplibs_F77=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + newsos6) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_shlibpath_var_F77=no + ;; + + openbsd*) + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + ;; + *) + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + allow_undefined_flag_F77=unsupported + archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_F77='-rpath $libdir' + fi + hardcode_libdir_separator_F77=: + ;; + + solaris*) + no_undefined_flag_F77=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_shlibpath_var_F77=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs_F77=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_F77='$CC -r -o $output$reload_objs' + hardcode_direct_F77=no + ;; + motorola) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_F77=no + ;; + + sysv4.3*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + export_dynamic_flag_spec_F77='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_F77=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_F77='${wl}-z,text' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_F77='${wl}-z,text' + allow_undefined_flag_F77='${wl}-z,nodefs' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + export_dynamic_flag_spec_F77='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + *) + ld_shlibs_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 +echo "${ECHO_T}$ld_shlibs_F77" >&6 +test "$ld_shlibs_F77" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_F77" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_F77=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_F77 in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_F77 + pic_flag=$lt_prog_compiler_pic_F77 + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_F77 + allow_undefined_flag_F77= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_F77=no + else + archive_cmds_need_lc_F77=yes + fi + allow_undefined_flag_F77=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_F77= +if test -n "$hardcode_libdir_flag_spec_F77" || \ + test -n "$runpath_var_F77" || \ + test "X$hardcode_automatic_F77" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_F77" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && + test "$hardcode_minus_L_F77" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_F77=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_F77=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_F77=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 +echo "${ECHO_T}$hardcode_action_F77" >&6 + +if test "$hardcode_action_F77" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_F77 \ + CC_F77 \ + LD_F77 \ + lt_prog_compiler_wl_F77 \ + lt_prog_compiler_pic_F77 \ + lt_prog_compiler_static_F77 \ + lt_prog_compiler_no_builtin_flag_F77 \ + export_dynamic_flag_spec_F77 \ + thread_safe_flag_spec_F77 \ + whole_archive_flag_spec_F77 \ + enable_shared_with_static_runtimes_F77 \ + old_archive_cmds_F77 \ + old_archive_from_new_cmds_F77 \ + predep_objects_F77 \ + postdep_objects_F77 \ + predeps_F77 \ + postdeps_F77 \ + compiler_lib_search_path_F77 \ + archive_cmds_F77 \ + archive_expsym_cmds_F77 \ + postinstall_cmds_F77 \ + postuninstall_cmds_F77 \ + old_archive_from_expsyms_cmds_F77 \ + allow_undefined_flag_F77 \ + no_undefined_flag_F77 \ + export_symbols_cmds_F77 \ + hardcode_libdir_flag_spec_F77 \ + hardcode_libdir_flag_spec_ld_F77 \ + hardcode_libdir_separator_F77 \ + hardcode_automatic_F77 \ + module_cmds_F77 \ + module_expsym_cmds_F77 \ + lt_cv_prog_compiler_c_o_F77 \ + exclude_expsyms_F77 \ + include_expsyms_F77; do + + case $var in + old_archive_cmds_F77 | \ + old_archive_from_new_cmds_F77 | \ + archive_cmds_F77 | \ + archive_expsym_cmds_F77 | \ + module_cmds_F77 | \ + module_expsym_cmds_F77 | \ + old_archive_from_expsyms_cmds_F77 | \ + export_symbols_cmds_F77 | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_F77 + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_F77 + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_F77 + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_F77 + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_F77 + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_F77 +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_F77 + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_F77 +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_F77 +archive_expsym_cmds=$lt_archive_expsym_cmds_F77 +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_F77 +module_expsym_cmds=$lt_module_expsym_cmds_F77 + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_F77 + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_F77 + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_F77 + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_F77 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_F77 + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_F77 + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_F77 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_F77 + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_F77" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_F77 + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_F77 + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_F77 + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_F77 + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + + + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +objext_GCJ=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +compiler_GCJ=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +archive_cmds_need_lc_GCJ=no + +old_archive_cmds_GCJ=$old_archive_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... + +lt_prog_compiler_no_builtin_flag_GCJ= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl_GCJ= +lt_prog_compiler_pic_GCJ= +lt_prog_compiler_static_GCJ= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_static_GCJ='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_GCJ='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_GCJ=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_GCJ=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_GCJ='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + else + lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_GCJ='-qnocommon' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-fpic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_GCJ='-Qoption ld ';; + *) + lt_prog_compiler_wl_GCJ='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_GCJ='-Qoption ld ' + lt_prog_compiler_pic_GCJ='-PIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_GCJ='-Kconform_pic' + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_can_build_shared_GCJ=no + ;; + + uts4*) + lt_prog_compiler_pic_GCJ='-pic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_GCJ"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_GCJ=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_GCJ" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_GCJ=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 + +if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then + case $lt_prog_compiler_pic_GCJ in + "" | " "*) ;; + *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; + esac +else + lt_prog_compiler_pic_GCJ= + lt_prog_compiler_can_build_shared_GCJ=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_GCJ= + ;; + *) + lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_GCJ=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_GCJ=yes + fi + else + lt_prog_compiler_static_works_GCJ=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6 + +if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then + : +else + lt_prog_compiler_static_GCJ= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_GCJ=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_GCJ=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_GCJ= + enable_shared_with_static_runtimes_GCJ=no + archive_cmds_GCJ= + archive_expsym_cmds_GCJ= + old_archive_From_new_cmds_GCJ= + old_archive_from_expsyms_cmds_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + thread_safe_flag_spec_GCJ= + hardcode_libdir_flag_spec_GCJ= + hardcode_libdir_flag_spec_ld_GCJ= + hardcode_libdir_separator_GCJ= + hardcode_direct_GCJ=no + hardcode_minus_L_GCJ=no + hardcode_shlibpath_var_GCJ=unsupported + link_all_deplibs_GCJ=unknown + hardcode_automatic_GCJ=no + module_cmds_GCJ= + module_expsym_cmds_GCJ= + always_export_symbols_GCJ=no + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_GCJ= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_GCJ=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_GCJ= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_GCJ=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_GCJ=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_GCJ='-L$libdir' + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=no + enable_shared_with_static_runtimes_GCJ=yes + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + interix3*) + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_GCJ=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_GCJ=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + + if test "$ld_shlibs_GCJ" = no; then + runpath_var= + hardcode_libdir_flag_spec_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=yes + archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_GCJ=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_GCJ=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_GCJ='' + hardcode_direct_GCJ=yes + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_GCJ=yes + else + # We have old collect2 + hardcode_direct_GCJ=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_GCJ=yes + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_libdir_separator_GCJ= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_GCJ=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_GCJ='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_GCJ="-z nodefs" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_GCJ=' ${wl}-bernotok' + allow_undefined_flag_GCJ=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_GCJ='$convenience' + archive_cmds_need_lc_GCJ=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_GCJ=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_GCJ=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_GCJ=' ' + allow_undefined_flag_GCJ=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_GCJ='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_GCJ=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_GCJ=no + hardcode_direct_GCJ=no + hardcode_automatic_GCJ=yes + hardcode_shlibpath_var_GCJ=unsupported + whole_archive_flag_spec_GCJ='' + link_all_deplibs_GCJ=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_GCJ=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + freebsd1*) + ld_shlibs_GCJ=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + ;; + *) + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + link_all_deplibs_GCJ=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + newsos6) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_shlibpath_var_GCJ=no + ;; + + openbsd*) + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + ;; + *) + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + allow_undefined_flag_GCJ=unsupported + archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_GCJ='-rpath $libdir' + fi + hardcode_libdir_separator_GCJ=: + ;; + + solaris*) + no_undefined_flag_GCJ=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_shlibpath_var_GCJ=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs_GCJ=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_GCJ='$CC -r -o $output$reload_objs' + hardcode_direct_GCJ=no + ;; + motorola) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4.3*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + export_dynamic_flag_spec_GCJ='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_GCJ=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_GCJ='${wl}-z,text' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_GCJ='${wl}-z,text' + allow_undefined_flag_GCJ='${wl}-z,nodefs' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + *) + ld_shlibs_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 +echo "${ECHO_T}$ld_shlibs_GCJ" >&6 +test "$ld_shlibs_GCJ" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_GCJ" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_GCJ=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_GCJ in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_GCJ + pic_flag=$lt_prog_compiler_pic_GCJ + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ + allow_undefined_flag_GCJ= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_GCJ=no + else + archive_cmds_need_lc_GCJ=yes + fi + allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_GCJ= +if test -n "$hardcode_libdir_flag_spec_GCJ" || \ + test -n "$runpath_var_GCJ" || \ + test "X$hardcode_automatic_GCJ" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_GCJ" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && + test "$hardcode_minus_L_GCJ" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_GCJ=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_GCJ=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_GCJ=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 +echo "${ECHO_T}$hardcode_action_GCJ" >&6 + +if test "$hardcode_action_GCJ" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_GCJ \ + CC_GCJ \ + LD_GCJ \ + lt_prog_compiler_wl_GCJ \ + lt_prog_compiler_pic_GCJ \ + lt_prog_compiler_static_GCJ \ + lt_prog_compiler_no_builtin_flag_GCJ \ + export_dynamic_flag_spec_GCJ \ + thread_safe_flag_spec_GCJ \ + whole_archive_flag_spec_GCJ \ + enable_shared_with_static_runtimes_GCJ \ + old_archive_cmds_GCJ \ + old_archive_from_new_cmds_GCJ \ + predep_objects_GCJ \ + postdep_objects_GCJ \ + predeps_GCJ \ + postdeps_GCJ \ + compiler_lib_search_path_GCJ \ + archive_cmds_GCJ \ + archive_expsym_cmds_GCJ \ + postinstall_cmds_GCJ \ + postuninstall_cmds_GCJ \ + old_archive_from_expsyms_cmds_GCJ \ + allow_undefined_flag_GCJ \ + no_undefined_flag_GCJ \ + export_symbols_cmds_GCJ \ + hardcode_libdir_flag_spec_GCJ \ + hardcode_libdir_flag_spec_ld_GCJ \ + hardcode_libdir_separator_GCJ \ + hardcode_automatic_GCJ \ + module_cmds_GCJ \ + module_expsym_cmds_GCJ \ + lt_cv_prog_compiler_c_o_GCJ \ + exclude_expsyms_GCJ \ + include_expsyms_GCJ; do + + case $var in + old_archive_cmds_GCJ | \ + old_archive_from_new_cmds_GCJ | \ + archive_cmds_GCJ | \ + archive_expsym_cmds_GCJ | \ + module_cmds_GCJ | \ + module_expsym_cmds_GCJ | \ + old_archive_from_expsyms_cmds_GCJ | \ + export_symbols_cmds_GCJ | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_GCJ + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_GCJ + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_GCJ + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_GCJ + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_GCJ + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_GCJ +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_GCJ + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_GCJ +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_GCJ +archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_GCJ +module_expsym_cmds=$lt_module_expsym_cmds_GCJ + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_GCJ + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_GCJ + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_GCJ + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_GCJ + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_GCJ + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_GCJ + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_GCJ + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_GCJ + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_GCJ" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_GCJ + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_GCJ + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_GCJ + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_GCJ + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + RC) + + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +compiler_RC=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + +lt_cv_prog_compiler_c_o_RC=yes + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_RC \ + CC_RC \ + LD_RC \ + lt_prog_compiler_wl_RC \ + lt_prog_compiler_pic_RC \ + lt_prog_compiler_static_RC \ + lt_prog_compiler_no_builtin_flag_RC \ + export_dynamic_flag_spec_RC \ + thread_safe_flag_spec_RC \ + whole_archive_flag_spec_RC \ + enable_shared_with_static_runtimes_RC \ + old_archive_cmds_RC \ + old_archive_from_new_cmds_RC \ + predep_objects_RC \ + postdep_objects_RC \ + predeps_RC \ + postdeps_RC \ + compiler_lib_search_path_RC \ + archive_cmds_RC \ + archive_expsym_cmds_RC \ + postinstall_cmds_RC \ + postuninstall_cmds_RC \ + old_archive_from_expsyms_cmds_RC \ + allow_undefined_flag_RC \ + no_undefined_flag_RC \ + export_symbols_cmds_RC \ + hardcode_libdir_flag_spec_RC \ + hardcode_libdir_flag_spec_ld_RC \ + hardcode_libdir_separator_RC \ + hardcode_automatic_RC \ + module_cmds_RC \ + module_expsym_cmds_RC \ + lt_cv_prog_compiler_c_o_RC \ + exclude_expsyms_RC \ + include_expsyms_RC; do + + case $var in + old_archive_cmds_RC | \ + old_archive_from_new_cmds_RC | \ + archive_cmds_RC | \ + archive_expsym_cmds_RC | \ + module_cmds_RC | \ + module_expsym_cmds_RC | \ + old_archive_from_expsyms_cmds_RC | \ + export_symbols_cmds_RC | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_RC + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_RC + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_RC +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_RC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_RC + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_RC + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_RC" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + ;; + + *) + { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 +echo "$as_me: error: Unsupported tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 +echo "$as_me: error: unable to update list of available tagged configurations." >&2;} + { (exit 1); exit 1; }; } + fi +fi + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +# Checks for libraries. + + + + + + + + + + +for ac_header in fcntl.h netinet/in.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h math.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +@%:@@%:@ -------------------------------- @%:@@%:@ +@%:@@%:@ Report this to anthmct@yahoo.com @%:@@%:@ +@%:@@%:@ -------------------------------- @%:@@%:@ +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +# Check whether --with-libpri or --without-libpri was given. +if test "${with_libpri+set}" = set; then + withval="$with_libpri" + libpripath="$withval" +fi; + + + +if test -d "$libpripath" ; then + LIBPRI_TRUE= + LIBPRI_FALSE='#' +else + LIBPRI_TRUE='#' + LIBPRI_FALSE= +fi + + + +# Checks for typedefs, structures, and compiler characteristics. +echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_time=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +@%:@define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + + +# Checks for library functions. + + +for ac_header in sys/select.h sys/socket.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +@%:@@%:@ -------------------------------- @%:@@%:@ +@%:@@%:@ Report this to anthmct@yahoo.com @%:@@%:@ +@%:@@%:@ -------------------------------- @%:@@%:@ +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +echo "$as_me:$LINENO: checking types of arguments for select" >&5 +echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6 +if test "${ac_cv_func_select_args+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + for ac_arg234 in 'fd_set *' 'int *' 'void *'; do + for ac_arg1 in 'int' 'size_t' 'unsigned long' 'unsigned'; do + for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#if HAVE_SYS_SELECT_H +# include +#endif +#if HAVE_SYS_SOCKET_H +# include +#endif + +int +main () +{ +extern int select ($ac_arg1, + $ac_arg234, $ac_arg234, $ac_arg234, + $ac_arg5); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done + done +done +# Provide a safe default value. +: ${ac_cv_func_select_args='int,int *,struct timeval *'} + +fi +echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 +echo "${ECHO_T}$ac_cv_func_select_args" >&6 +ac_save_IFS=$IFS; IFS=',' +set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` +IFS=$ac_save_IFS +shift + +cat >>confdefs.h <<_ACEOF +@%:@define SELECT_TYPE_ARG1 $1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define SELECT_TYPE_ARG234 ($2) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define SELECT_TYPE_ARG5 ($3) +_ACEOF + +rm -f conftest* + + + + + +for ac_func in gettimeofday memset select socket +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIB@&t@OBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIB@&t@OBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${LIBPRI_TRUE}" && test -z "${LIBPRI_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"LIBPRI\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"LIBPRI\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX +@%:@@%:@ Running $as_me. @%:@@%:@ +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by libsangoma $as_me 1.0.0, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +libsangoma config.status 1.0.0 +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@mkdir_p@,$mkdir_p,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@am__leading_dot@,$am__leading_dot,;t t +s,@AMTAR@,$AMTAR,;t t +s,@am__tar@,$am__tar,;t t +s,@am__untar@,$am__untar,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@SED@,$SED,;t t +s,@EGREP@,$EGREP,;t t +s,@LN_S@,$LN_S,;t t +s,@ECHO@,$ECHO,;t t +s,@AR@,$AR,;t t +s,@ac_ct_AR@,$ac_ct_AR,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@CXX@,$CXX,;t t +s,@CXXFLAGS@,$CXXFLAGS,;t t +s,@ac_ct_CXX@,$ac_ct_CXX,;t t +s,@CXXDEPMODE@,$CXXDEPMODE,;t t +s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t +s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t +s,@CXXCPP@,$CXXCPP,;t t +s,@F77@,$F77,;t t +s,@FFLAGS@,$FFLAGS,;t t +s,@ac_ct_F77@,$ac_ct_F77,;t t +s,@LIBTOOL@,$LIBTOOL,;t t +s,@LIBPRI_TRUE@,$LIBPRI_TRUE,;t t +s,@LIBPRI_FALSE@,$LIBPRI_FALSE,;t t +s,@libpripath@,$libpripath,;t t +s,@LIB@&t@OBJS@,$LIB@&t@OBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/api/libsangoma/autom4te.cache/output.1 b/api/libsangoma/autom4te.cache/output.1 new file mode 100644 index 0000000..a949c8a --- /dev/null +++ b/api/libsangoma/autom4te.cache/output.1 @@ -0,0 +1,20506 @@ +@%:@! /bin/sh +@%:@ Guess values for system-dependent variables and create Makefiles. +@%:@ Generated by GNU Autoconf 2.59 for libsangoma 1.0.0. +@%:@ +@%:@ Report bugs to . +@%:@ +@%:@ Copyright (C) 2003 Free Software Foundation, Inc. +@%:@ This configure script is free software; the Free Software Foundation +@%:@ gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +tagnames=${tagnames+${tagnames},}CXX + +tagnames=${tagnames+${tagnames},}F77 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='libsangoma' +PACKAGE_TARNAME='libsangoma' +PACKAGE_VERSION='1.0.0' +PACKAGE_STRING='libsangoma 1.0.0' +PACKAGE_BUGREPORT='anthmct@yahoo.com' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBPRI_TRUE LIBPRI_FALSE libpripath LIB@&t@OBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP +ac_env_CXX_set=${CXX+set} +ac_env_CXX_value=$CXX +ac_cv_env_CXX_set=${CXX+set} +ac_cv_env_CXX_value=$CXX +ac_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_env_CXXFLAGS_value=$CXXFLAGS +ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_cv_env_CXXFLAGS_value=$CXXFLAGS +ac_env_CXXCPP_set=${CXXCPP+set} +ac_env_CXXCPP_value=$CXXCPP +ac_cv_env_CXXCPP_set=${CXXCPP+set} +ac_cv_env_CXXCPP_value=$CXXCPP +ac_env_F77_set=${F77+set} +ac_env_F77_value=$F77 +ac_cv_env_F77_set=${F77+set} +ac_cv_env_F77_value=$F77 +ac_env_FFLAGS_set=${FFLAGS+set} +ac_env_FFLAGS_value=$FFLAGS +ac_cv_env_FFLAGS_set=${FFLAGS+set} +ac_cv_env_FFLAGS_value=$FFLAGS + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures libsangoma 1.0.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libsangoma 1.0.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared@<:@=PKGS@:>@ + build shared libraries @<:@default=yes@:>@ + --enable-static@<:@=PKGS@:>@ + build static libraries @<:@default=yes@:>@ + --enable-fast-install@<:@=PKGS@:>@ + optimize for fast installation @<:@default=yes@:>@ + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld @<:@default=no@:>@ + --with-pic try to use only PIC/non-PIC objects @<:@default=use + both@:>@ + --with-tags@<:@=TAGS@:>@ + include additional configurations @<:@automatic@:>@ + --with-libpri= enable pri support + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + F77 Fortran 77 compiler command + FFLAGS Fortran 77 compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +libsangoma configure 1.0.0 +generated by GNU Autoconf 2.59 + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libsangoma $as_me 1.0.0, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +@%:@@%:@ --------- @%:@@%:@ +@%:@@%:@ Platform. @%:@@%:@ +@%:@@%:@ --------- @%:@@%:@ + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +@%:@@%:@ ----------- @%:@@%:@ +@%:@@%:@ Core tests. @%:@@%:@ +@%:@@%:@ ----------- @%:@@%:@ + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +@%:@@%:@ ---------------- @%:@@%:@ +@%:@@%:@ Cache variables. @%:@@%:@ +@%:@@%:@ ---------------- @%:@@%:@ +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +@%:@@%:@ ----------------- @%:@@%:@ +@%:@@%:@ Output variables. @%:@@%:@ +@%:@@%:@ ----------------- @%:@@%:@ +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +@%:@@%:@ ------------- @%:@@%:@ +@%:@@%:@ Output files. @%:@@%:@ +@%:@@%:@ ------------- @%:@@%:@ +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +@%:@@%:@ ----------- @%:@@%:@ +@%:@@%:@ confdefs.h. @%:@@%:@ +@%:@@%:@ ----------- @%:@@%:@ +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + +am__api_version="1.9" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=libsangoma + VERSION=1.0.0 + + +cat >>confdefs.h <<_ACEOF +@%:@define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $@%:@ != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +@%:@ifndef __cplusplus + choke me +@%:@endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +@%:@include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi; + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi; + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi; + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done + +fi + +SED=$lt_cv_path_SED + +echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6 + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + +echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi +echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 +echo "${ECHO_T}$lt_cv_path_NM" >&6 +NM="$lt_cv_path_NM" + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 +echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump'. + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | kfreebsd*-gnu | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +lt_cv_cc_needs_belf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + + +esac + +need_locks="$enable_libtool_lock" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +@%:@define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +@%:@@%:@ -------------------------------- @%:@@%:@ +@%:@@%:@ Report this to anthmct@yahoo.com @%:@@%:@ +@%:@@%:@ -------------------------------- @%:@@%:@ +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CXX" && break +done +test -n "$ac_ct_CXX" || ac_ct_CXX="g++" + + CXX=$ac_ct_CXX +fi + + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cxx_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +@%:@include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6 +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +echo "$as_me:$LINENO: result: $CXXCPP" >&5 +echo "${ECHO_T}$CXXCPP" >&6 +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@ifdef __STDC__ +@%:@ include +@%:@else +@%:@ include +@%:@endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +fi + + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$F77"; then + ac_cv_prog_F77="$F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_F77="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +F77=$ac_cv_prog_F77 +if test -n "$F77"; then + echo "$as_me:$LINENO: result: $F77" >&5 +echo "${ECHO_T}$F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$F77" && break + done +fi +if test -z "$F77"; then + ac_ct_F77=$F77 + for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_F77"; then + ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_F77="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_F77=$ac_cv_prog_ac_ct_F77 +if test -n "$ac_ct_F77"; then + echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 +echo "${ECHO_T}$ac_ct_F77" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_F77" && break +done + + F77=$ac_ct_F77 +fi + + +# Provide some information about the compiler. +echo "$as_me:__oline__:" \ + "checking for Fortran 77 compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +rm -f a.out + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. (Note that this only needs to work for GNU compilers.) +ac_save_ext=$ac_ext +ac_ext=F +echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 +if test "${ac_cv_f77_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_f77_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 +ac_ext=$ac_save_ext +ac_test_FFLAGS=${FFLAGS+set} +ac_save_FFLAGS=$FFLAGS +FFLAGS= +echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 +echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_f77_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + FFLAGS=-g +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_f77_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_f77_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 +if test "$ac_test_FFLAGS" = set; then + FFLAGS=$ac_save_FFLAGS +elif test $ac_cv_prog_f77_g = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-g -O2" + else + FFLAGS="-g" + fi +else + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-O2" + else + FFLAGS= + fi +fi + +G77=`test $ac_compiler_gnu = yes && echo yes` +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# find the maximum length of command line arguments +echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6 +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6 +else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +fi + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 +echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6 +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDGIRSTW]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 +else + echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6 +fi + +echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6 +if test "${lt_cv_objdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 +echo "${ECHO_T}$lt_cv_objdir" >&6 +objdir=$lt_cv_objdir + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false" +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + AR=$ac_ct_AR +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +enable_dlopen=no +enable_win32_dll=no + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + +fi; +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi; +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic='-qnocommon' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6 + +if test x"$lt_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works=yes + fi + else + lt_prog_compiler_static_works=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 + +if test x"$lt_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag= + enable_shared_with_static_runtimes=no + archive_cmds= + archive_expsym_cmds= + old_archive_From_new_cmds= + old_archive_from_expsyms_cmds= + export_dynamic_flag_spec= + whole_archive_flag_spec= + thread_safe_flag_spec= + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_direct=no + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + link_all_deplibs=unknown + hardcode_automatic=no + module_cmds= + module_expsym_cmds= + always_export_symbols=no + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix3*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld='-rpath $libdir' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6 +test "$ld_shlibs" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 +echo "${ECHO_T}$archive_cmds_need_lc" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var" || \ + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + ;; + *) + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +char (*f) () = shl_load; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != shl_load; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load (); +int +main () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +char (*f) () = dlopen; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != dlopen; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# Report which library types will actually be built +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler \ + CC \ + LD \ + lt_prog_compiler_wl \ + lt_prog_compiler_pic \ + lt_prog_compiler_static \ + lt_prog_compiler_no_builtin_flag \ + export_dynamic_flag_spec \ + thread_safe_flag_spec \ + whole_archive_flag_spec \ + enable_shared_with_static_runtimes \ + old_archive_cmds \ + old_archive_from_new_cmds \ + predep_objects \ + postdep_objects \ + predeps \ + postdeps \ + compiler_lib_search_path \ + archive_cmds \ + archive_expsym_cmds \ + postinstall_cmds \ + postuninstall_cmds \ + old_archive_from_expsyms_cmds \ + allow_undefined_flag \ + no_undefined_flag \ + export_symbols_cmds \ + hardcode_libdir_flag_spec \ + hardcode_libdir_flag_spec_ld \ + hardcode_libdir_separator \ + hardcode_automatic \ + module_cmds \ + module_expsym_cmds \ + lt_cv_prog_compiler_c_o \ + exclude_expsyms \ + include_expsyms; do + + case $var in + old_archive_cmds | \ + old_archive_from_new_cmds | \ + archive_cmds | \ + archive_expsym_cmds | \ + module_cmds | \ + module_expsym_cmds | \ + old_archive_from_expsyms_cmds | \ + export_symbols_cmds | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + { echo "$as_me:$LINENO: creating $ofile" >&5 +echo "$as_me: creating $ofile" >&6;} + + cat <<__EOF__ >> "$cfgfile" +#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + +# Check whether --with-tags or --without-tags was given. +if test "${with_tags+set}" = set; then + withval="$with_tags" + tagnames="$withval" +fi; + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} + else + { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 +echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in + "") ;; + *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 +echo "$as_me: error: invalid tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 +echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} + { (exit 1); exit 1; }; } + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +compiler_CXX=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' +else + lt_prog_compiler_no_builtin_flag_CXX= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 +ld_shlibs_CXX=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_CXX=yes + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_CXX=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + ld_shlibs_CXX=no + ;; + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + gnu*) + ;; + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_CXX='+b $libdir' + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + interix3*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + ;; + linux*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + openbsd*) + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; +esac +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +GCC_CXX="$GXX" +LD_CXX="$LD" + + +cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$rm -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix3*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +solaris*) + case $cc_basename in + CC*) + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + postdeps_CXX='-lCstd -lCrun' + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + +lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_CXX='-qnocommon' + lt_prog_compiler_wl_CXX='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_CXX=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6 + +if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_CXX=yes + fi + else + lt_prog_compiler_static_works_CXX=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6 + +if test x"$lt_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6 +test "$ld_shlibs_CXX" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || \ + test -n "$runpath_var_CXX" || \ + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 +echo "${ECHO_T}$hardcode_action_CXX" >&6 + +if test "$hardcode_action_CXX" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_CXX \ + CC_CXX \ + LD_CXX \ + lt_prog_compiler_wl_CXX \ + lt_prog_compiler_pic_CXX \ + lt_prog_compiler_static_CXX \ + lt_prog_compiler_no_builtin_flag_CXX \ + export_dynamic_flag_spec_CXX \ + thread_safe_flag_spec_CXX \ + whole_archive_flag_spec_CXX \ + enable_shared_with_static_runtimes_CXX \ + old_archive_cmds_CXX \ + old_archive_from_new_cmds_CXX \ + predep_objects_CXX \ + postdep_objects_CXX \ + predeps_CXX \ + postdeps_CXX \ + compiler_lib_search_path_CXX \ + archive_cmds_CXX \ + archive_expsym_cmds_CXX \ + postinstall_cmds_CXX \ + postuninstall_cmds_CXX \ + old_archive_from_expsyms_cmds_CXX \ + allow_undefined_flag_CXX \ + no_undefined_flag_CXX \ + export_symbols_cmds_CXX \ + hardcode_libdir_flag_spec_CXX \ + hardcode_libdir_flag_spec_ld_CXX \ + hardcode_libdir_separator_CXX \ + hardcode_automatic_CXX \ + module_cmds_CXX \ + module_expsym_cmds_CXX \ + lt_cv_prog_compiler_c_o_CXX \ + exclude_expsyms_CXX \ + include_expsyms_CXX; do + + case $var in + old_archive_cmds_CXX | \ + old_archive_from_new_cmds_CXX | \ + archive_cmds_CXX | \ + archive_expsym_cmds_CXX | \ + module_cmds_CXX | \ + module_expsym_cmds_CXX | \ + old_archive_from_expsyms_cmds_CXX | \ + export_symbols_cmds_CXX | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_CXX + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_CXX +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_CXX" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld + + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + + +archive_cmds_need_lc_F77=no +allow_undefined_flag_F77= +always_export_symbols_F77=no +archive_expsym_cmds_F77= +export_dynamic_flag_spec_F77= +hardcode_direct_F77=no +hardcode_libdir_flag_spec_F77= +hardcode_libdir_flag_spec_ld_F77= +hardcode_libdir_separator_F77= +hardcode_minus_L_F77=no +hardcode_automatic_F77=no +module_cmds_F77= +module_expsym_cmds_F77= +link_all_deplibs_F77=unknown +old_archive_cmds_F77=$old_archive_cmds +no_undefined_flag_F77= +whole_archive_flag_spec_F77= +enable_shared_with_static_runtimes_F77=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +objext_F77=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code=" subroutine t\n return\n end\n" + +# Code to be used in simple link tests +lt_simple_link_test_code=" program t\n end\n" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +compiler_F77=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6 + +GCC_F77="$G77" +LD_F77="$LD" + +lt_prog_compiler_wl_F77= +lt_prog_compiler_pic_F77= +lt_prog_compiler_static_F77= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_static_F77='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_F77='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_F77=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_F77=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_F77='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + else + lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_F77='-qnocommon' + lt_prog_compiler_wl_F77='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_F77='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_F77='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-fpic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_F77='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_F77='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_F77='-Qoption ld ';; + *) + lt_prog_compiler_wl_F77='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_F77='-Qoption ld ' + lt_prog_compiler_pic_F77='-PIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_F77='-Kconform_pic' + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_can_build_shared_F77=no + ;; + + uts4*) + lt_prog_compiler_pic_F77='-pic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_F77"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_F77=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_F77" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_F77=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6 + +if test x"$lt_prog_compiler_pic_works_F77" = xyes; then + case $lt_prog_compiler_pic_F77 in + "" | " "*) ;; + *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; + esac +else + lt_prog_compiler_pic_F77= + lt_prog_compiler_can_build_shared_F77=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_F77= + ;; + *) + lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_F77=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_F77=yes + fi + else + lt_prog_compiler_static_works_F77=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6 + +if test x"$lt_prog_compiler_static_works_F77" = xyes; then + : +else + lt_prog_compiler_static_F77= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_F77=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_F77=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_F77= + enable_shared_with_static_runtimes_F77=no + archive_cmds_F77= + archive_expsym_cmds_F77= + old_archive_From_new_cmds_F77= + old_archive_from_expsyms_cmds_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + thread_safe_flag_spec_F77= + hardcode_libdir_flag_spec_F77= + hardcode_libdir_flag_spec_ld_F77= + hardcode_libdir_separator_F77= + hardcode_direct_F77=no + hardcode_minus_L_F77=no + hardcode_shlibpath_var_F77=unsupported + link_all_deplibs_F77=unknown + hardcode_automatic_F77=no + module_cmds_F77= + module_expsym_cmds_F77= + always_export_symbols_F77=no + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_F77= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_F77=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_F77='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_F77= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_F77=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_F77=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_F77='-L$libdir' + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=no + enable_shared_with_static_runtimes_F77=yes + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_F77=no + fi + ;; + + interix3*) + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_F77=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_F77=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + + if test "$ld_shlibs_F77" = no; then + runpath_var= + hardcode_libdir_flag_spec_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=yes + archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_F77=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_F77=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_F77='' + hardcode_direct_F77=yes + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_F77=yes + else + # We have old collect2 + hardcode_direct_F77=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_F77=yes + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_libdir_separator_F77= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_F77=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_F77='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_F77="-z nodefs" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_F77=' ${wl}-bernotok' + allow_undefined_flag_F77=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_F77='$convenience' + archive_cmds_need_lc_F77=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_F77=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_F77=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_F77=' ' + allow_undefined_flag_F77=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_F77='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_F77='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_F77=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_F77=no + hardcode_direct_F77=no + hardcode_automatic_F77=yes + hardcode_shlibpath_var_F77=unsupported + whole_archive_flag_spec_F77='' + link_all_deplibs_F77=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_F77=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + freebsd1*) + ld_shlibs_F77=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + ;; + *) + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + link_all_deplibs_F77=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + newsos6) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_shlibpath_var_F77=no + ;; + + openbsd*) + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + ;; + *) + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + allow_undefined_flag_F77=unsupported + archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_F77='-rpath $libdir' + fi + hardcode_libdir_separator_F77=: + ;; + + solaris*) + no_undefined_flag_F77=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_shlibpath_var_F77=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs_F77=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_F77='$CC -r -o $output$reload_objs' + hardcode_direct_F77=no + ;; + motorola) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_F77=no + ;; + + sysv4.3*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + export_dynamic_flag_spec_F77='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_F77=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_F77='${wl}-z,text' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_F77='${wl}-z,text' + allow_undefined_flag_F77='${wl}-z,nodefs' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + export_dynamic_flag_spec_F77='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + *) + ld_shlibs_F77=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 +echo "${ECHO_T}$ld_shlibs_F77" >&6 +test "$ld_shlibs_F77" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_F77" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_F77=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_F77 in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_F77 + pic_flag=$lt_prog_compiler_pic_F77 + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_F77 + allow_undefined_flag_F77= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_F77=no + else + archive_cmds_need_lc_F77=yes + fi + allow_undefined_flag_F77=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_F77= +if test -n "$hardcode_libdir_flag_spec_F77" || \ + test -n "$runpath_var_F77" || \ + test "X$hardcode_automatic_F77" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_F77" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && + test "$hardcode_minus_L_F77" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_F77=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_F77=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_F77=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 +echo "${ECHO_T}$hardcode_action_F77" >&6 + +if test "$hardcode_action_F77" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_F77 \ + CC_F77 \ + LD_F77 \ + lt_prog_compiler_wl_F77 \ + lt_prog_compiler_pic_F77 \ + lt_prog_compiler_static_F77 \ + lt_prog_compiler_no_builtin_flag_F77 \ + export_dynamic_flag_spec_F77 \ + thread_safe_flag_spec_F77 \ + whole_archive_flag_spec_F77 \ + enable_shared_with_static_runtimes_F77 \ + old_archive_cmds_F77 \ + old_archive_from_new_cmds_F77 \ + predep_objects_F77 \ + postdep_objects_F77 \ + predeps_F77 \ + postdeps_F77 \ + compiler_lib_search_path_F77 \ + archive_cmds_F77 \ + archive_expsym_cmds_F77 \ + postinstall_cmds_F77 \ + postuninstall_cmds_F77 \ + old_archive_from_expsyms_cmds_F77 \ + allow_undefined_flag_F77 \ + no_undefined_flag_F77 \ + export_symbols_cmds_F77 \ + hardcode_libdir_flag_spec_F77 \ + hardcode_libdir_flag_spec_ld_F77 \ + hardcode_libdir_separator_F77 \ + hardcode_automatic_F77 \ + module_cmds_F77 \ + module_expsym_cmds_F77 \ + lt_cv_prog_compiler_c_o_F77 \ + exclude_expsyms_F77 \ + include_expsyms_F77; do + + case $var in + old_archive_cmds_F77 | \ + old_archive_from_new_cmds_F77 | \ + archive_cmds_F77 | \ + archive_expsym_cmds_F77 | \ + module_cmds_F77 | \ + module_expsym_cmds_F77 | \ + old_archive_from_expsyms_cmds_F77 | \ + export_symbols_cmds_F77 | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_F77 + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_F77 + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_F77 + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_F77 + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_F77 + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_F77 +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_F77 + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_F77 +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_F77 +archive_expsym_cmds=$lt_archive_expsym_cmds_F77 +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_F77 +module_expsym_cmds=$lt_module_expsym_cmds_F77 + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_F77 + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_F77 + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_F77 + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_F77 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_F77 + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_F77 + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_F77 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_F77 + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_F77" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_F77 + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_F77 + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_F77 + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_F77 + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + + + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +objext_GCJ=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +compiler_GCJ=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +archive_cmds_need_lc_GCJ=no + +old_archive_cmds_GCJ=$old_archive_cmds + + +lt_prog_compiler_no_builtin_flag_GCJ= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' + + +echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6 + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl_GCJ= +lt_prog_compiler_pic_GCJ= +lt_prog_compiler_static_GCJ= + +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 + + if test "$GCC" = yes; then + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_static_GCJ='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_GCJ='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_GCJ=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_GCJ=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_GCJ='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + else + lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_GCJ='-qnocommon' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-fpic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_GCJ='-Qoption ld ';; + *) + lt_prog_compiler_wl_GCJ='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_GCJ='-Qoption ld ' + lt_prog_compiler_pic_GCJ='-PIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_GCJ='-Kconform_pic' + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_can_build_shared_GCJ=no + ;; + + uts4*) + lt_prog_compiler_pic_GCJ='-pic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6 + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_GCJ"; then + +echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6 +if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_GCJ=no + ac_outfile=conftest.$ac_objext + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_GCJ" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_GCJ=yes + fi + fi + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6 + +if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then + case $lt_prog_compiler_pic_GCJ in + "" | " "*) ;; + *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; + esac +else + lt_prog_compiler_pic_GCJ= + lt_prog_compiler_can_build_shared_GCJ=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_GCJ= + ;; + *) + lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_GCJ=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_GCJ=yes + fi + else + lt_prog_compiler_static_works_GCJ=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6 + +if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then + : +else + lt_prog_compiler_static_GCJ= +fi + + +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_GCJ=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:__oline__: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_GCJ=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6 + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6 + + runpath_var= + allow_undefined_flag_GCJ= + enable_shared_with_static_runtimes_GCJ=no + archive_cmds_GCJ= + archive_expsym_cmds_GCJ= + old_archive_From_new_cmds_GCJ= + old_archive_from_expsyms_cmds_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + thread_safe_flag_spec_GCJ= + hardcode_libdir_flag_spec_GCJ= + hardcode_libdir_flag_spec_ld_GCJ= + hardcode_libdir_separator_GCJ= + hardcode_direct_GCJ=no + hardcode_minus_L_GCJ=no + hardcode_shlibpath_var_GCJ=unsupported + link_all_deplibs_GCJ=unknown + hardcode_automatic_GCJ=no + module_cmds_GCJ= + module_expsym_cmds_GCJ= + always_export_symbols_GCJ=no + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_GCJ= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_GCJ=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_GCJ= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_GCJ=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_GCJ=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_GCJ='-L$libdir' + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=no + enable_shared_with_static_runtimes_GCJ=yes + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + interix3*) + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_GCJ=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_GCJ=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + + if test "$ld_shlibs_GCJ" = no; then + runpath_var= + hardcode_libdir_flag_spec_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=yes + archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_GCJ=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_GCJ=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_GCJ='' + hardcode_direct_GCJ=yes + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct_GCJ=yes + else + # We have old collect2 + hardcode_direct_GCJ=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_GCJ=yes + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_libdir_separator_GCJ= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_GCJ=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_GCJ='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_GCJ="-z nodefs" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_GCJ=' ${wl}-bernotok' + allow_undefined_flag_GCJ=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_GCJ='$convenience' + archive_cmds_need_lc_GCJ=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_GCJ=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_GCJ=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_GCJ=' ' + allow_undefined_flag_GCJ=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_GCJ='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_GCJ=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_GCJ=no + hardcode_direct_GCJ=no + hardcode_automatic_GCJ=yes + hardcode_shlibpath_var_GCJ=unsupported + whole_archive_flag_spec_GCJ='' + link_all_deplibs_GCJ=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_GCJ=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + freebsd1*) + ld_shlibs_GCJ=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + ;; + *) + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + link_all_deplibs_GCJ=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + newsos6) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_shlibpath_var_GCJ=no + ;; + + openbsd*) + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + ;; + *) + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + allow_undefined_flag_GCJ=unsupported + archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_GCJ='-rpath $libdir' + fi + hardcode_libdir_separator_GCJ=: + ;; + + solaris*) + no_undefined_flag_GCJ=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_shlibpath_var_GCJ=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + link_all_deplibs_GCJ=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_GCJ='$CC -r -o $output$reload_objs' + hardcode_direct_GCJ=no + ;; + motorola) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4.3*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + export_dynamic_flag_spec_GCJ='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_GCJ=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_GCJ='${wl}-z,text' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_GCJ='${wl}-z,text' + allow_undefined_flag_GCJ='${wl}-z,nodefs' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + *) + ld_shlibs_GCJ=no + ;; + esac + fi + +echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 +echo "${ECHO_T}$ld_shlibs_GCJ" >&6 +test "$ld_shlibs_GCJ" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_GCJ" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_GCJ=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_GCJ in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_GCJ + pic_flag=$lt_prog_compiler_pic_GCJ + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ + allow_undefined_flag_GCJ= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_GCJ=no + else + archive_cmds_need_lc_GCJ=yes + fi + allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6 + ;; + esac + fi + ;; +esac + +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '#line __oline__ "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 +hardcode_action_GCJ= +if test -n "$hardcode_libdir_flag_spec_GCJ" || \ + test -n "$runpath_var_GCJ" || \ + test "X$hardcode_automatic_GCJ" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_GCJ" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && + test "$hardcode_minus_L_GCJ" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_GCJ=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_GCJ=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_GCJ=unsupported +fi +echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 +echo "${ECHO_T}$hardcode_action_GCJ" >&6 + +if test "$hardcode_action_GCJ" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_GCJ \ + CC_GCJ \ + LD_GCJ \ + lt_prog_compiler_wl_GCJ \ + lt_prog_compiler_pic_GCJ \ + lt_prog_compiler_static_GCJ \ + lt_prog_compiler_no_builtin_flag_GCJ \ + export_dynamic_flag_spec_GCJ \ + thread_safe_flag_spec_GCJ \ + whole_archive_flag_spec_GCJ \ + enable_shared_with_static_runtimes_GCJ \ + old_archive_cmds_GCJ \ + old_archive_from_new_cmds_GCJ \ + predep_objects_GCJ \ + postdep_objects_GCJ \ + predeps_GCJ \ + postdeps_GCJ \ + compiler_lib_search_path_GCJ \ + archive_cmds_GCJ \ + archive_expsym_cmds_GCJ \ + postinstall_cmds_GCJ \ + postuninstall_cmds_GCJ \ + old_archive_from_expsyms_cmds_GCJ \ + allow_undefined_flag_GCJ \ + no_undefined_flag_GCJ \ + export_symbols_cmds_GCJ \ + hardcode_libdir_flag_spec_GCJ \ + hardcode_libdir_flag_spec_ld_GCJ \ + hardcode_libdir_separator_GCJ \ + hardcode_automatic_GCJ \ + module_cmds_GCJ \ + module_expsym_cmds_GCJ \ + lt_cv_prog_compiler_c_o_GCJ \ + exclude_expsyms_GCJ \ + include_expsyms_GCJ; do + + case $var in + old_archive_cmds_GCJ | \ + old_archive_from_new_cmds_GCJ | \ + archive_cmds_GCJ | \ + archive_expsym_cmds_GCJ | \ + module_cmds_GCJ | \ + module_expsym_cmds_GCJ | \ + old_archive_from_expsyms_cmds_GCJ | \ + export_symbols_cmds_GCJ | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_GCJ + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_GCJ + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_GCJ + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_GCJ + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_GCJ + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_GCJ +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_GCJ + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_GCJ +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_GCJ +archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_GCJ +module_expsym_cmds=$lt_module_expsym_cmds_GCJ + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_GCJ + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_GCJ + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_GCJ + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_GCJ + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_GCJ + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_GCJ + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_GCJ + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_GCJ + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_GCJ" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_GCJ + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_GCJ + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_GCJ + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_GCJ + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + RC) + + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +compiler_RC=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + +lt_cv_prog_compiler_c_o_RC=yes + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_RC \ + CC_RC \ + LD_RC \ + lt_prog_compiler_wl_RC \ + lt_prog_compiler_pic_RC \ + lt_prog_compiler_static_RC \ + lt_prog_compiler_no_builtin_flag_RC \ + export_dynamic_flag_spec_RC \ + thread_safe_flag_spec_RC \ + whole_archive_flag_spec_RC \ + enable_shared_with_static_runtimes_RC \ + old_archive_cmds_RC \ + old_archive_from_new_cmds_RC \ + predep_objects_RC \ + postdep_objects_RC \ + predeps_RC \ + postdeps_RC \ + compiler_lib_search_path_RC \ + archive_cmds_RC \ + archive_expsym_cmds_RC \ + postinstall_cmds_RC \ + postuninstall_cmds_RC \ + old_archive_from_expsyms_cmds_RC \ + allow_undefined_flag_RC \ + no_undefined_flag_RC \ + export_symbols_cmds_RC \ + hardcode_libdir_flag_spec_RC \ + hardcode_libdir_flag_spec_ld_RC \ + hardcode_libdir_separator_RC \ + hardcode_automatic_RC \ + module_cmds_RC \ + module_expsym_cmds_RC \ + lt_cv_prog_compiler_c_o_RC \ + exclude_expsyms_RC \ + include_expsyms_RC; do + + case $var in + old_archive_cmds_RC | \ + old_archive_from_new_cmds_RC | \ + archive_cmds_RC | \ + archive_expsym_cmds_RC | \ + module_cmds_RC | \ + module_expsym_cmds_RC | \ + old_archive_from_expsyms_cmds_RC | \ + export_symbols_cmds_RC | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_RC + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_RC + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_RC +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_predep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_postdep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_RC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_RC + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_RC + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path_RC" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + ;; + + *) + { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 +echo "$as_me: error: Unsupported tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 +echo "$as_me: error: unable to update list of available tagged configurations." >&2;} + { (exit 1); exit 1; }; } + fi +fi + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +# Checks for libraries. + + + + + + + + + + +for ac_header in fcntl.h netinet/in.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h math.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +@%:@@%:@ -------------------------------- @%:@@%:@ +@%:@@%:@ Report this to anthmct@yahoo.com @%:@@%:@ +@%:@@%:@ -------------------------------- @%:@@%:@ +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +# Check whether --with-libpri or --without-libpri was given. +if test "${with_libpri+set}" = set; then + withval="$with_libpri" + libpripath="$withval" +fi; + + + +if test -d "$libpripath" ; then + LIBPRI_TRUE= + LIBPRI_FALSE='#' +else + LIBPRI_TRUE='#' + LIBPRI_FALSE= +fi + + + +# Checks for typedefs, structures, and compiler characteristics. +echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_time=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +@%:@define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + + +# Checks for library functions. + + +for ac_header in sys/select.h sys/socket.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +@%:@include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +@%:@include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +@%:@@%:@ -------------------------------- @%:@@%:@ +@%:@@%:@ Report this to anthmct@yahoo.com @%:@@%:@ +@%:@@%:@ -------------------------------- @%:@@%:@ +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +echo "$as_me:$LINENO: checking types of arguments for select" >&5 +echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6 +if test "${ac_cv_func_select_args+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + for ac_arg234 in 'fd_set *' 'int *' 'void *'; do + for ac_arg1 in 'int' 'size_t' 'unsigned long' 'unsigned'; do + for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#if HAVE_SYS_SELECT_H +# include +#endif +#if HAVE_SYS_SOCKET_H +# include +#endif + +int +main () +{ +extern int select ($ac_arg1, + $ac_arg234, $ac_arg234, $ac_arg234, + $ac_arg5); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + done + done +done +# Provide a safe default value. +: ${ac_cv_func_select_args='int,int *,struct timeval *'} + +fi +echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 +echo "${ECHO_T}$ac_cv_func_select_args" >&6 +ac_save_IFS=$IFS; IFS=',' +set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` +IFS=$ac_save_IFS +shift + +cat >>confdefs.h <<_ACEOF +@%:@define SELECT_TYPE_ARG1 $1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define SELECT_TYPE_ARG234 ($2) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +@%:@define SELECT_TYPE_ARG5 ($3) +_ACEOF + +rm -f conftest* + + + + + +for ac_func in gettimeofday memset select socket +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +@%:@define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\_ACEOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIB@&t@OBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIB@&t@OBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${LIBPRI_TRUE}" && test -z "${LIBPRI_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"LIBPRI\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"LIBPRI\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX +@%:@@%:@ Running $as_me. @%:@@%:@ +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by libsangoma $as_me 1.0.0, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +libsangoma config.status 1.0.0 +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@mkdir_p@,$mkdir_p,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@am__leading_dot@,$am__leading_dot,;t t +s,@AMTAR@,$AMTAR,;t t +s,@am__tar@,$am__tar,;t t +s,@am__untar@,$am__untar,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@SED@,$SED,;t t +s,@EGREP@,$EGREP,;t t +s,@LN_S@,$LN_S,;t t +s,@ECHO@,$ECHO,;t t +s,@AR@,$AR,;t t +s,@ac_ct_AR@,$ac_ct_AR,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@CXX@,$CXX,;t t +s,@CXXFLAGS@,$CXXFLAGS,;t t +s,@ac_ct_CXX@,$ac_ct_CXX,;t t +s,@CXXDEPMODE@,$CXXDEPMODE,;t t +s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t +s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t +s,@CXXCPP@,$CXXCPP,;t t +s,@F77@,$F77,;t t +s,@FFLAGS@,$FFLAGS,;t t +s,@ac_ct_F77@,$ac_ct_F77,;t t +s,@LIBTOOL@,$LIBTOOL,;t t +s,@LIBPRI_TRUE@,$LIBPRI_TRUE,;t t +s,@LIBPRI_FALSE@,$LIBPRI_FALSE,;t t +s,@libpripath@,$libpripath,;t t +s,@LIB@&t@OBJS@,$LIB@&t@OBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/api/libsangoma/autom4te.cache/requests b/api/libsangoma/autom4te.cache/requests new file mode 100644 index 0000000..12a5597 --- /dev/null +++ b/api/libsangoma/autom4te.cache/requests @@ -0,0 +1,350 @@ +# This file was generated. +# It contains the lists of macros which have been traced. +# It can be safely removed. + +@request = ( + bless( [ + '0', + 1, + [ + '/usr/share/autoconf' + ], + [ + '/usr/share/autoconf/autoconf/autoconf.m4f', + '/usr/share/aclocal/libtool.m4', + '/usr/share/aclocal-1.9/amversion.m4', + '/usr/share/aclocal-1.9/auxdir.m4', + '/usr/share/aclocal-1.9/cond.m4', + '/usr/share/aclocal-1.9/depend.m4', + '/usr/share/aclocal-1.9/depout.m4', + '/usr/share/aclocal-1.9/init.m4', + '/usr/share/aclocal-1.9/install-sh.m4', + '/usr/share/aclocal-1.9/lead-dot.m4', + '/usr/share/aclocal-1.9/make.m4', + '/usr/share/aclocal-1.9/missing.m4', + '/usr/share/aclocal-1.9/mkdirp.m4', + '/usr/share/aclocal-1.9/options.m4', + '/usr/share/aclocal-1.9/runlog.m4', + '/usr/share/aclocal-1.9/sanity.m4', + '/usr/share/aclocal-1.9/strip.m4', + '/usr/share/aclocal-1.9/tar.m4', + 'configure.in' + ], + { + 'AM_ENABLE_STATIC' => 1, + 'AC_LIBTOOL_LANG_RC_CONFIG' => 1, + 'AC_TYPE_OFF_T' => 1, + 'AC_C_VOLATILE' => 1, + 'AC_FUNC_CLOSEDIR_VOID' => 1, + '_LT_AC_SHELL_INIT' => 1, + 'AC_REPLACE_FNMATCH' => 1, + 'AC_DEFUN' => 1, + '_LT_AC_LANG_CXX_CONFIG' => 1, + 'AC_PROG_LIBTOOL' => 1, + 'AC_FUNC_STAT' => 1, + 'AM_PROG_MKDIR_P' => 1, + 'AC_FUNC_WAIT3' => 1, + 'AC_STRUCT_TM' => 1, + 'AC_FUNC_LSTAT' => 1, + 'AM_AUTOMAKE_VERSION' => 1, + 'AC_FUNC_STRTOD' => 1, + 'AC_CHECK_HEADERS' => 1, + 'AM_MISSING_PROG' => 1, + 'AC_FUNC_STRNLEN' => 1, + 'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1, + 'AC_PROG_CXX' => 1, + '_LT_AC_LANG_C_CONFIG' => 1, + 'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1, + 'AM_PROG_INSTALL_STRIP' => 1, + 'AC_PROG_AWK' => 1, + '_m4_warn' => 1, + 'AC_LIBTOOL_OBJDIR' => 1, + 'AC_HEADER_MAJOR' => 1, + 'AM_SANITY_CHECK' => 1, + 'AC_LIBTOOL_PROG_COMPILER_PIC' => 1, + 'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1, + '_LT_AC_CHECK_DLFCN' => 1, + 'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1, + '_AM_PROG_TAR' => 1, + 'AC_LIBTOOL_GCJ' => 1, + 'AC_PROG_GCC_TRADITIONAL' => 1, + 'AC_LIBSOURCE' => 1, + 'AC_STRUCT_ST_BLOCKS' => 1, + 'AC_LIBTOOL_CONFIG' => 1, + '_LT_AC_LANG_F77' => 1, + 'AC_CONFIG_AUX_DIR' => 1, + 'AC_PROG_MAKE_SET' => 1, + 'sinclude' => 1, + 'AM_DISABLE_SHARED' => 1, + 'AM_PROG_LIBTOOL' => 1, + '_LT_AC_LANG_CXX' => 1, + 'AM_PROG_LD' => 1, + '_LT_AC_FILE_LTDLL_C' => 1, + 'AC_FUNC_STRERROR_R' => 1, + 'AC_FUNC_FORK' => 1, + 'AC_DECL_SYS_SIGLIST' => 1, + 'AC_FUNC_VPRINTF' => 1, + 'AU_DEFUN' => 1, + 'AC_PROG_NM' => 1, + 'AC_LIBTOOL_DLOPEN' => 1, + 'AC_PROG_LD' => 1, + 'AC_PROG_LD_GNU' => 1, + 'AC_ENABLE_FAST_INSTALL' => 1, + 'AC_INIT' => 1, + 'AC_STRUCT_TIMEZONE' => 1, + 'AC_SUBST' => 1, + 'AC_FUNC_ALLOCA' => 1, + '_AM_SET_OPTION' => 1, + 'AC_CANONICAL_HOST' => 1, + '_LT_LINKER_BOILERPLATE' => 1, + 'AC_PROG_RANLIB' => 1, + 'AC_LIBTOOL_LANG_CXX_CONFIG' => 1, + 'AC_LIBTOOL_PROG_CC_C_O' => 1, + 'AC_FUNC_SETPGRP' => 1, + 'AC_CONFIG_SUBDIRS' => 1, + 'AC_FUNC_MMAP' => 1, + 'AC_TYPE_SIZE_T' => 1, + 'AC_CHECK_TYPES' => 1, + 'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, + 'AC_CHECK_MEMBERS' => 1, + 'AC_DEFUN_ONCE' => 1, + 'AC_FUNC_UTIME_NULL' => 1, + 'AC_FUNC_SELECT_ARGTYPES' => 1, + '_LT_AC_LANG_GCJ' => 1, + 'AC_HEADER_STAT' => 1, + 'AC_FUNC_STRFTIME' => 1, + 'AC_C_INLINE' => 1, + 'AC_LIBTOOL_RC' => 1, + 'AC_DISABLE_FAST_INSTALL' => 1, + '_LT_AC_PROG_ECHO_BACKSLASH' => 1, + 'AC_CONFIG_FILES' => 1, + 'include' => 1, + '_LT_AC_SYS_LIBPATH_AIX' => 1, + '_LT_AC_TRY_DLOPEN_SELF' => 1, + 'LT_AC_PROG_SED' => 1, + 'AM_ENABLE_SHARED' => 1, + 'AM_GNU_GETTEXT' => 1, + '_LT_AC_LANG_GCJ_CONFIG' => 1, + 'AC_FUNC_OBSTACK' => 1, + 'AC_CHECK_LIB' => 1, + 'AC_ENABLE_SHARED' => 1, + 'AC_FUNC_MALLOC' => 1, + 'AC_FUNC_GETGROUPS' => 1, + 'AC_FUNC_GETLOADAVG' => 1, + 'AC_FUNC_FSEEKO' => 1, + 'AC_ENABLE_STATIC' => 1, + 'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1, + 'AM_PROG_CC_C_O' => 1, + '_LT_AC_TAGVAR' => 1, + 'AC_LIBTOOL_LANG_F77_CONFIG' => 1, + 'AC_FUNC_MKTIME' => 1, + 'AM_CONDITIONAL' => 1, + 'AC_HEADER_SYS_WAIT' => 1, + 'AC_PROG_LN_S' => 1, + 'AC_FUNC_MEMCMP' => 1, + 'm4_include' => 1, + 'AM_PROG_INSTALL_SH' => 1, + 'AC_HEADER_DIRENT' => 1, + 'AC_PROG_EGREP' => 1, + '_AC_AM_CONFIG_HEADER_HOOK' => 1, + 'AC_PATH_MAGIC' => 1, + 'AM_MAKE_INCLUDE' => 1, + '_LT_AC_TAGCONFIG' => 1, + 'm4_pattern_forbid' => 1, + 'AC_CONFIG_LIBOBJ_DIR' => 1, + 'AC_LIBTOOL_COMPILER_OPTION' => 1, + 'AC_DISABLE_SHARED' => 1, + '_LT_COMPILER_BOILERPLATE' => 1, + 'AC_LIBTOOL_SETUP' => 1, + 'AC_LIBTOOL_WIN32_DLL' => 1, + 'AC_PROG_LD_RELOAD_FLAG' => 1, + 'AC_HEADER_TIME' => 1, + 'AC_TYPE_MODE_T' => 1, + 'AC_FUNC_GETMNTENT' => 1, + 'AM_MISSING_HAS_RUN' => 1, + 'm4_sinclude' => 1, + 'AC_LIBTOOL_DLOPEN_SELF' => 1, + 'AC_PATH_X' => 1, + 'AC_LIBTOOL_PROG_LD_SHLIBS' => 1, + 'AC_HEADER_STDC' => 1, + 'AC_LIBTOOL_LINKER_OPTION' => 1, + 'AC_LIBTOOL_CXX' => 1, + 'LT_AC_PROG_RC' => 1, + 'LT_AC_PROG_GCJ' => 1, + 'AC_FUNC_ERROR_AT_LINE' => 1, + 'AM_DEP_TRACK' => 1, + '_LT_AC_PROG_CXXCPP' => 1, + 'AM_DISABLE_STATIC' => 1, + 'AC_FUNC_MBRTOWC' => 1, + '_AC_PROG_LIBTOOL' => 1, + 'AC_TYPE_SIGNAL' => 1, + 'AC_TYPE_UID_T' => 1, + '_AM_IF_OPTION' => 1, + 'AC_PATH_TOOL_PREFIX' => 1, + 'AC_LIBTOOL_F77' => 1, + 'm4_pattern_allow' => 1, + 'AM_SET_LEADING_DOT' => 1, + 'AC_DEFINE_TRACE_LITERAL' => 1, + '_AM_DEPENDENCIES' => 1, + 'AC_LIBTOOL_LANG_C_CONFIG' => 1, + 'AC_PROG_CC' => 1, + '_LT_AC_SYS_COMPILER' => 1, + 'AM_PROG_NM' => 1, + 'AC_FUNC_STRCOLL' => 1, + 'AC_PROG_YACC' => 1, + 'AC_LIBLTDL_CONVENIENCE' => 1, + 'AC_DEPLIBS_CHECK_METHOD' => 1, + 'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1, + 'AC_LIBLTDL_INSTALLABLE' => 1, + 'AC_FUNC_CHOWN' => 1, + 'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1, + 'AC_FUNC_GETPGRP' => 1, + 'AM_INIT_AUTOMAKE' => 1, + 'AC_FUNC_REALLOC' => 1, + 'AC_DISABLE_STATIC' => 1, + 'AC_CONFIG_LINKS' => 1, + 'AM_MAINTAINER_MODE' => 1, + '_LT_AC_LOCK' => 1, + '_LT_AC_LANG_RC_CONFIG' => 1, + 'AC_PROG_CPP' => 1, + 'AC_TYPE_PID_T' => 1, + 'AC_PROG_LEX' => 1, + 'AC_C_CONST' => 1, + 'AC_LIBTOOL_POSTDEP_PREDEP' => 1, + 'AC_FUNC_SETVBUF_REVERSED' => 1, + 'AC_PROG_INSTALL' => 1, + 'AM_AUX_DIR_EXPAND' => 1, + 'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1, + '_LT_AC_LANG_F77_CONFIG' => 1, + '_AM_SET_OPTIONS' => 1, + 'AM_RUN_LOG' => 1, + '_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1, + 'AC_LIBTOOL_PICMODE' => 1, + 'AH_OUTPUT' => 1, + 'AC_CHECK_LIBM' => 1, + 'AC_LIBTOOL_SYS_LIB_STRIP' => 1, + '_AM_MANGLE_OPTION' => 1, + 'AC_CANONICAL_SYSTEM' => 1, + 'AC_CONFIG_HEADERS' => 1, + 'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1, + 'AM_SET_DEPDIR' => 1, + '_LT_CC_BASENAME' => 1, + 'AC_CHECK_FUNCS' => 1 + } + ], 'Autom4te::Request' ), + bless( [ + '1', + 1, + [ + '/usr/share/autoconf' + ], + [ + '/usr/share/autoconf/autoconf/autoconf.m4f', + 'aclocal.m4', + 'configure.in' + ], + { + '_LT_AC_TAGCONFIG' => 1, + 'm4_pattern_forbid' => 1, + 'AC_CANONICAL_TARGET' => 1, + 'AC_CONFIG_LIBOBJ_DIR' => 1, + 'AC_C_VOLATILE' => 1, + 'AC_TYPE_OFF_T' => 1, + 'AC_FUNC_CLOSEDIR_VOID' => 1, + 'AC_REPLACE_FNMATCH' => 1, + 'AC_PROG_LIBTOOL' => 1, + 'AC_FUNC_STAT' => 1, + 'AC_FUNC_WAIT3' => 1, + 'AC_HEADER_TIME' => 1, + 'AM_AUTOMAKE_VERSION' => 1, + 'AC_FUNC_LSTAT' => 1, + 'AC_STRUCT_TM' => 1, + 'AC_FUNC_GETMNTENT' => 1, + 'AC_TYPE_MODE_T' => 1, + 'AC_CHECK_HEADERS' => 1, + 'AC_FUNC_STRTOD' => 1, + 'AC_FUNC_STRNLEN' => 1, + 'm4_sinclude' => 1, + 'AC_PROG_CXX' => 1, + 'AC_PATH_X' => 1, + 'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1, + 'AC_PROG_AWK' => 1, + '_m4_warn' => 1, + 'AC_HEADER_STDC' => 1, + 'AC_HEADER_MAJOR' => 1, + 'AC_FUNC_ERROR_AT_LINE' => 1, + 'AC_PROG_GCC_TRADITIONAL' => 1, + 'AC_LIBSOURCE' => 1, + 'AC_FUNC_MBRTOWC' => 1, + 'AC_STRUCT_ST_BLOCKS' => 1, + 'AC_CANONICAL_BUILD' => 1, + 'AC_TYPE_SIGNAL' => 1, + 'AC_TYPE_UID_T' => 1, + 'AC_CONFIG_AUX_DIR' => 1, + 'AC_PROG_MAKE_SET' => 1, + 'm4_pattern_allow' => 1, + 'sinclude' => 1, + 'AC_DEFINE_TRACE_LITERAL' => 1, + 'AC_FUNC_STRERROR_R' => 1, + 'AC_PROG_CC' => 1, + 'AC_DECL_SYS_SIGLIST' => 1, + 'AC_FUNC_FORK' => 1, + 'AC_FUNC_STRCOLL' => 1, + 'AC_FUNC_VPRINTF' => 1, + 'AC_PROG_YACC' => 1, + 'AC_STRUCT_TIMEZONE' => 1, + 'AC_INIT' => 1, + 'AC_FUNC_CHOWN' => 1, + 'AC_SUBST' => 1, + 'AC_FUNC_ALLOCA' => 1, + 'AC_CANONICAL_HOST' => 1, + 'AC_FUNC_GETPGRP' => 1, + 'AC_PROG_RANLIB' => 1, + 'AM_INIT_AUTOMAKE' => 1, + 'AC_FUNC_SETPGRP' => 1, + 'AC_CONFIG_SUBDIRS' => 1, + 'AC_FUNC_MMAP' => 1, + 'AC_FUNC_REALLOC' => 1, + 'AC_TYPE_SIZE_T' => 1, + 'AC_CONFIG_LINKS' => 1, + 'AC_CHECK_TYPES' => 1, + 'LT_SUPPORTED_TAG' => 1, + 'AC_CHECK_MEMBERS' => 1, + 'AM_MAINTAINER_MODE' => 1, + 'AC_FUNC_UTIME_NULL' => 1, + 'AC_FUNC_SELECT_ARGTYPES' => 1, + 'AC_FUNC_STRFTIME' => 1, + 'AC_HEADER_STAT' => 1, + 'AC_C_INLINE' => 1, + 'AC_PROG_CPP' => 1, + 'AM_ENABLE_MULTILIB' => 1, + 'AC_C_CONST' => 1, + 'AC_PROG_LEX' => 1, + 'AC_TYPE_PID_T' => 1, + 'AC_CONFIG_FILES' => 1, + 'include' => 1, + 'AC_FUNC_SETVBUF_REVERSED' => 1, + 'AC_PROG_INSTALL' => 1, + 'AM_GNU_GETTEXT' => 1, + 'AC_FUNC_OBSTACK' => 1, + 'AC_CHECK_LIB' => 1, + 'AC_FUNC_MALLOC' => 1, + 'AC_FUNC_GETGROUPS' => 1, + 'AC_FUNC_GETLOADAVG' => 1, + 'AH_OUTPUT' => 1, + 'AC_FUNC_FSEEKO' => 1, + 'AM_PROG_CC_C_O' => 1, + 'AC_FUNC_MKTIME' => 1, + 'AM_CONDITIONAL' => 1, + 'AC_CANONICAL_SYSTEM' => 1, + 'AC_CONFIG_HEADERS' => 1, + 'AC_HEADER_SYS_WAIT' => 1, + 'AC_FUNC_MEMCMP' => 1, + 'AC_PROG_LN_S' => 1, + 'm4_include' => 1, + 'AC_HEADER_DIRENT' => 1, + 'AC_CHECK_FUNCS' => 1 + } + ], 'Autom4te::Request' ) + ); + diff --git a/api/libsangoma/autom4te.cache/traces.0 b/api/libsangoma/autom4te.cache/traces.0 new file mode 100644 index 0000000..9ead66f --- /dev/null +++ b/api/libsangoma/autom4te.cache/traces.0 @@ -0,0 +1,9212 @@ +m4trace:/usr/share/aclocal/libtool.m4:55: -1- AC_DEFUN([AC_PROG_LIBTOOL], [AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote AM_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or AM_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])]) +m4trace:/usr/share/aclocal/libtool.m4:75: -1- AC_DEFUN([_AC_PROG_LIBTOOL], [AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) +m4trace:/usr/share/aclocal/libtool.m4:220: -1- AC_DEFUN([AC_LIBTOOL_SETUP], [AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +]) +m4trace:/usr/share/aclocal/libtool.m4:236: -1- AC_DEFUN([_LT_AC_SYS_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +]) +m4trace:/usr/share/aclocal/libtool.m4:252: -1- AC_DEFUN([_LT_CC_BASENAME], [for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) +m4trace:/usr/share/aclocal/libtool.m4:265: -1- AC_DEFUN([_LT_COMPILER_BOILERPLATE], [ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +]) +m4trace:/usr/share/aclocal/libtool.m4:278: -1- AC_DEFUN([_LT_LINKER_BOILERPLATE], [ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +]) +m4trace:/usr/share/aclocal/libtool.m4:297: -1- AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], [AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +]) +m4trace:/usr/share/aclocal/libtool.m4:308: -1- AC_DEFUN([_LT_AC_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +]) +m4trace:/usr/share/aclocal/libtool.m4:464: -1- AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], [_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])]) +m4trace:/usr/share/aclocal/libtool.m4:608: -1- AC_DEFUN([_LT_AC_LOCK], [AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +]) +m4trace:/usr/share/aclocal/libtool.m4:653: -1- AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:690: -1- AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:805: -1- AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:812: -1- AC_DEFUN([_LT_AC_CHECK_DLFCN], [AC_CHECK_HEADERS(dlfcn.h)dnl +]) +m4trace:/usr/share/aclocal/libtool.m4:903: -1- AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +]) +m4trace:/usr/share/aclocal/libtool.m4:1016: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:1067: -1- AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], [AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +]) +m4trace:/usr/share/aclocal/libtool.m4:1094: -1- AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:1111: -1- AC_DEFUN([AC_LIBTOOL_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +]) +m4trace:/usr/share/aclocal/libtool.m4:1152: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:1181: -1- AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], [striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:1799: -1- AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # find out which ABI we are using + libsuff= + case "$host_cpu" in + x86_64*|s390x*|powerpc64*) + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *64-bit*) + libsuff=64 + sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}" + ;; + esac + fi + rm -rf conftest* + ;; + esac + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:1903: -1- AC_DEFUN([_LT_AC_TAGCONFIG], [AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:1911: -1- AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +]) +m4trace:/usr/share/aclocal/libtool.m4:1919: -1- AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +]) +m4trace:/usr/share/aclocal/libtool.m4:1949: -1- AC_DEFUN([AC_ENABLE_SHARED], [define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +]) +m4trace:/usr/share/aclocal/libtool.m4:1958: -1- AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +]) +m4trace:/usr/share/aclocal/libtool.m4:1988: -1- AC_DEFUN([AC_ENABLE_STATIC], [define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +]) +m4trace:/usr/share/aclocal/libtool.m4:1997: -1- AC_DEFUN([AC_DISABLE_STATIC], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +]) +m4trace:/usr/share/aclocal/libtool.m4:2027: -1- AC_DEFUN([AC_ENABLE_FAST_INSTALL], [define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +]) +m4trace:/usr/share/aclocal/libtool.m4:2036: -1- AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +]) +m4trace:/usr/share/aclocal/libtool.m4:2046: -1- AC_DEFUN([AC_LIBTOOL_PICMODE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +]) +m4trace:/usr/share/aclocal/libtool.m4:2124: -1- AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:2139: -1- AC_DEFUN([AC_PATH_MAGIC], [AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:2224: -1- AC_DEFUN([AC_PROG_LD], [AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +]) +m4trace:/usr/share/aclocal/libtool.m4:2503: -1- AC_DEFUN([AC_PROG_NM], [AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +]) +m4trace:/usr/share/aclocal/libtool.m4:2524: -1- AC_DEFUN([AC_CHECK_LIBM], [AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +]) +m4trace:/usr/share/aclocal/libtool.m4:2549: -1- AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) +m4trace:/usr/share/aclocal/libtool.m4:2585: -1- AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) +m4trace:/usr/share/aclocal/libtool.m4:2593: -1- AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_LT_AC_LANG_CXX]) +]) +m4trace:/usr/share/aclocal/libtool.m4:2602: -1- AC_DEFUN([_LT_AC_LANG_CXX], [AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +]) +m4trace:/usr/share/aclocal/libtool.m4:2614: -1- AC_DEFUN([_LT_AC_PROG_CXXCPP], [ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:2621: -1- AC_DEFUN([AC_LIBTOOL_F77], [AC_REQUIRE([_LT_AC_LANG_F77]) +]) +m4trace:/usr/share/aclocal/libtool.m4:2629: -1- AC_DEFUN([_LT_AC_LANG_F77], [AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +]) +m4trace:/usr/share/aclocal/libtool.m4:2637: -1- AC_DEFUN([AC_LIBTOOL_GCJ], [AC_REQUIRE([_LT_AC_LANG_GCJ]) +]) +m4trace:/usr/share/aclocal/libtool.m4:2650: -1- AC_DEFUN([_LT_AC_LANG_GCJ], [AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +]) +m4trace:/usr/share/aclocal/libtool.m4:2659: -1- AC_DEFUN([AC_LIBTOOL_RC], [AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +]) +m4trace:/usr/share/aclocal/libtool.m4:2667: -1- AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +m4trace:/usr/share/aclocal/libtool.m4:2740: -1- AC_DEFUN([_LT_AC_LANG_C_CONFIG], [lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF + +# Report which library types will actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +]) +m4trace:/usr/share/aclocal/libtool.m4:2748: -1- AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +m4trace:/usr/share/aclocal/libtool.m4:3748: -1- AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], [AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + ;; + *) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +]) +m4trace:/usr/share/aclocal/libtool.m4:3908: -1- AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP], [ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=\`echo $lt_[]_LT_AC_TAGVAR(predep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=\`echo $lt_[]_LT_AC_TAGVAR(postdep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=\`echo $lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:4628: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:4830: -1- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) +m4trace:/usr/share/aclocal/libtool.m4:5356: -1- AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], [_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) +]) +m4trace:/usr/share/aclocal/libtool.m4:6286: -1- AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +]) +m4trace:/usr/share/aclocal/libtool.m4:6326: -1- AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +]) +m4trace:/usr/share/aclocal/libtool.m4:6331: -1- AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) +m4trace:/usr/share/aclocal/libtool.m4:6335: -1- AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +m4trace:/usr/share/aclocal/libtool.m4:6336: -1- AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +m4trace:/usr/share/aclocal/libtool.m4:6337: -1- AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +m4trace:/usr/share/aclocal/libtool.m4:6338: -1- AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +m4trace:/usr/share/aclocal/libtool.m4:6339: -1- AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +m4trace:/usr/share/aclocal/libtool.m4:6340: -1- AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +m4trace:/usr/share/aclocal/libtool.m4:6341: -1- AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) +m4trace:/usr/share/aclocal/libtool.m4:6350: -1- AC_DEFUN([LT_AC_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) +m4trace:/usr/share/aclocal/libtool.m4:6354: -1- AC_DEFUN([LT_AC_PROG_RC], [AC_CHECK_TOOL(RC, windres, no) +]) +m4trace:/usr/share/aclocal/libtool.m4:6419: -1- AC_DEFUN([LT_AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +]) +m4trace:/usr/share/aclocal-1.9/amversion.m4:13: -1- AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) +m4trace:/usr/share/aclocal-1.9/amversion.m4:20: -1- AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.9.6])]) +m4trace:/usr/share/aclocal-1.9/auxdir.m4:52: -1- AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) +m4trace:/usr/share/aclocal-1.9/cond.m4:32: -1- AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) +m4trace:/usr/share/aclocal-1.9/depend.m4:131: -1- AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) +m4trace:/usr/share/aclocal-1.9/depend.m4:141: -1- AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) +m4trace:/usr/share/aclocal-1.9/depend.m4:156: -1- AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) +m4trace:/usr/share/aclocal-1.9/depout.m4:53: -1- AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +]) +m4trace:/usr/share/aclocal-1.9/depout.m4:67: -1- AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) +m4trace:/usr/share/aclocal-1.9/init.m4:92: -1- AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) +m4trace:/usr/share/aclocal-1.9/init.m4:113: -1- AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) +m4trace:/usr/share/aclocal-1.9/install-sh.m4:14: -1- AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) +m4trace:/usr/share/aclocal-1.9/lead-dot.m4:21: -1- AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) +m4trace:/usr/share/aclocal-1.9/make.m4:51: -1- AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) +m4trace:/usr/share/aclocal-1.9/missing.m4:17: -1- AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) +m4trace:/usr/share/aclocal-1.9/missing.m4:34: -1- AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) +m4trace:/usr/share/aclocal-1.9/mkdirp.m4:63: -1- AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) +m4trace:/usr/share/aclocal-1.9/options.m4:14: -1- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) +m4trace:/usr/share/aclocal-1.9/options.m4:20: -1- AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) +m4trace:/usr/share/aclocal-1.9/options.m4:26: -1- AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) +m4trace:/usr/share/aclocal-1.9/options.m4:32: -1- AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +m4trace:/usr/share/aclocal-1.9/runlog.m4:17: -1- AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) +m4trace:/usr/share/aclocal-1.9/sanity.m4:51: -1- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) +m4trace:/usr/share/aclocal-1.9/strip.m4:28: -1- AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) +m4trace:/usr/share/aclocal-1.9/tar.m4:95: -1- AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) +m4trace:configure.in:5: -1- AC_INIT([libsangoma], [1.0.0], [anthmct@yahoo.com]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^_?A[CHUM]_]) +m4trace:configure.in:5: -1- m4_pattern_forbid([_AC_]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) +m4trace:configure.in:5: -1- m4_pattern_allow([^AS_FLAGS$]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^_?m4_]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^dnl$]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^_?AS_]) +m4trace:configure.in:5: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}]) +m4trace:configure.in:5: -1- AC_SUBST([PATH_SEPARATOR]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])]) +m4trace:configure.in:5: -1- AC_SUBST([exec_prefix], [NONE]) +m4trace:configure.in:5: -1- AC_SUBST([prefix], [NONE]) +m4trace:configure.in:5: -1- AC_SUBST([program_transform_name], [s,x,x,]) +m4trace:configure.in:5: -1- AC_SUBST([bindir], ['${exec_prefix}/bin']) +m4trace:configure.in:5: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin']) +m4trace:configure.in:5: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec']) +m4trace:configure.in:5: -1- AC_SUBST([datadir], ['${prefix}/share']) +m4trace:configure.in:5: -1- AC_SUBST([sysconfdir], ['${prefix}/etc']) +m4trace:configure.in:5: -1- AC_SUBST([sharedstatedir], ['${prefix}/com']) +m4trace:configure.in:5: -1- AC_SUBST([localstatedir], ['${prefix}/var']) +m4trace:configure.in:5: -1- AC_SUBST([libdir], ['${exec_prefix}/lib']) +m4trace:configure.in:5: -1- AC_SUBST([includedir], ['${prefix}/include']) +m4trace:configure.in:5: -1- AC_SUBST([oldincludedir], ['/usr/include']) +m4trace:configure.in:5: -1- AC_SUBST([infodir], ['${prefix}/info']) +m4trace:configure.in:5: -1- AC_SUBST([mandir], ['${prefix}/man']) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */ +#undef PACKAGE_NAME]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */ +#undef PACKAGE_VERSION]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT]) +m4trace:configure.in:5: -1- AC_SUBST([build_alias]) +m4trace:configure.in:5: -1- AC_SUBST([host_alias]) +m4trace:configure.in:5: -1- AC_SUBST([target_alias]) +m4trace:configure.in:5: -1- AC_SUBST([DEFS]) +m4trace:configure.in:5: -1- AC_SUBST([ECHO_C]) +m4trace:configure.in:5: -1- AC_SUBST([ECHO_N]) +m4trace:configure.in:5: -1- AC_SUBST([ECHO_T]) +m4trace:configure.in:5: -1- AC_SUBST([LIBS]) +m4trace:configure.in:6: -1- AM_INIT_AUTOMAKE([libsangoma], [1.0.0]) +m4trace:configure.in:6: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) +m4trace:configure.in:6: -1- AM_SET_CURRENT_AUTOMAKE_VERSION +m4trace:configure.in:6: -1- AM_AUTOMAKE_VERSION([1.9.6]) +m4trace:configure.in:6: -1- AC_PROG_INSTALL +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_PROGRAM]) +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_SCRIPT]) +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_DATA]) +m4trace:configure.in:6: -1- AC_SUBST([CYGPATH_W]) +m4trace:configure.in:6: -1- AC_SUBST([PACKAGE], [libsangoma]) +m4trace:configure.in:6: -1- AC_SUBST([VERSION], [1.0.0]) +m4trace:configure.in:6: -1- _AM_IF_OPTION([no-define], [], [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])]) +m4trace:configure.in:6: -2- _AM_MANGLE_OPTION([no-define]) +m4trace:configure.in:6: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE]) +m4trace:configure.in:6: -1- AH_OUTPUT([PACKAGE], [/* Name of package */ +#undef PACKAGE]) +m4trace:configure.in:6: -1- AC_DEFINE_TRACE_LITERAL([VERSION]) +m4trace:configure.in:6: -1- AH_OUTPUT([VERSION], [/* Version number of package */ +#undef VERSION]) +m4trace:configure.in:6: -1- AM_SANITY_CHECK +m4trace:configure.in:6: -1- AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +m4trace:configure.in:6: -1- AM_MISSING_HAS_RUN +m4trace:configure.in:6: -1- AM_AUX_DIR_EXPAND +m4trace:configure.in:6: -1- AC_SUBST([ACLOCAL]) +m4trace:configure.in:6: -1- AM_MISSING_PROG([AUTOCONF], [autoconf]) +m4trace:configure.in:6: -1- AC_SUBST([AUTOCONF]) +m4trace:configure.in:6: -1- AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +m4trace:configure.in:6: -1- AC_SUBST([AUTOMAKE]) +m4trace:configure.in:6: -1- AM_MISSING_PROG([AUTOHEADER], [autoheader]) +m4trace:configure.in:6: -1- AC_SUBST([AUTOHEADER]) +m4trace:configure.in:6: -1- AM_MISSING_PROG([MAKEINFO], [makeinfo]) +m4trace:configure.in:6: -1- AC_SUBST([MAKEINFO]) +m4trace:configure.in:6: -1- AM_PROG_INSTALL_SH +m4trace:configure.in:6: -1- AC_SUBST([install_sh]) +m4trace:configure.in:6: -1- AM_PROG_INSTALL_STRIP +m4trace:configure.in:6: -1- AC_SUBST([STRIP]) +m4trace:configure.in:6: -1- AC_SUBST([ac_ct_STRIP]) +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_STRIP_PROGRAM]) +m4trace:configure.in:6: -1- AM_PROG_MKDIR_P +m4trace:configure.in:6: -1- AC_SUBST([mkdir_p]) +m4trace:configure.in:6: -1- AC_PROG_AWK +m4trace:configure.in:6: -1- AC_SUBST([AWK]) +m4trace:configure.in:6: -1- AC_PROG_MAKE_SET +m4trace:configure.in:6: -1- AC_SUBST([SET_MAKE]) +m4trace:configure.in:6: -1- AM_SET_LEADING_DOT +m4trace:configure.in:6: -1- AC_SUBST([am__leading_dot]) +m4trace:configure.in:6: -1- _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +m4trace:configure.in:6: -2- _AM_MANGLE_OPTION([tar-ustar]) +m4trace:configure.in:6: -1- _AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])]) +m4trace:configure.in:6: -2- _AM_MANGLE_OPTION([tar-pax]) +m4trace:configure.in:6: -1- _AM_PROG_TAR([v7]) +m4trace:configure.in:6: -1- AM_MISSING_PROG([AMTAR], [tar]) +m4trace:configure.in:6: -1- AC_SUBST([AMTAR]) +m4trace:configure.in:6: -1- AC_SUBST([am__tar]) +m4trace:configure.in:6: -1- AC_SUBST([am__untar]) +m4trace:configure.in:6: -1- _AM_IF_OPTION([no-dependencies], [], [AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +m4trace:configure.in:6: -2- _AM_MANGLE_OPTION([no-dependencies]) +m4trace:configure.in:8: -1- AC_PROG_CC +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([CFLAGS]) +m4trace:configure.in:8: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.in:8: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:8: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) +m4trace:configure.in:8: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) +m4trace:configure.in:8: -1- _AM_DEPENDENCIES([CC]) +m4trace:configure.in:8: -1- AM_SET_DEPDIR +m4trace:configure.in:8: -1- AC_SUBST([DEPDIR], ["${am__leading_dot}deps"]) +m4trace:configure.in:8: -1- AM_OUTPUT_DEPENDENCY_COMMANDS +m4trace:configure.in:8: -1- AM_MAKE_INCLUDE +m4trace:configure.in:8: -1- AC_SUBST([am__include]) +m4trace:configure.in:8: -1- AC_SUBST([am__quote]) +m4trace:configure.in:8: -1- AM_DEP_TRACK +m4trace:configure.in:8: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +m4trace:configure.in:8: -1- AC_SUBST([AMDEP_TRUE]) +m4trace:configure.in:8: -1- AC_SUBST([AMDEP_FALSE]) +m4trace:configure.in:8: -1- AC_SUBST([AMDEPBACKSLASH]) +m4trace:configure.in:8: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) +m4trace:configure.in:8: -1- AM_CONDITIONAL([am__fastdepCC], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) +m4trace:configure.in:8: -1- AC_SUBST([am__fastdepCC_TRUE]) +m4trace:configure.in:8: -1- AC_SUBST([am__fastdepCC_FALSE]) +m4trace:configure.in:9: -1- AC_PROG_LIBTOOL +m4trace:configure.in:9: -1- _AC_PROG_LIBTOOL +m4trace:configure.in:9: -1- AC_LIBTOOL_SETUP +m4trace:configure.in:9: -1- AC_ENABLE_SHARED +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +/usr/share/aclocal/libtool.m4:1949: AC_ENABLE_SHARED is expanded from... +configure.in:9: AC_ENABLE_SHARED is required by... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_ENABLE_STATIC +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +/usr/share/aclocal/libtool.m4:1988: AC_ENABLE_STATIC is expanded from... +configure.in:9: AC_ENABLE_STATIC is required by... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_ENABLE_FAST_INSTALL +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +/usr/share/aclocal/libtool.m4:2027: AC_ENABLE_FAST_INSTALL is expanded from... +configure.in:9: AC_ENABLE_FAST_INSTALL is required by... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_CANONICAL_HOST +m4trace:configure.in:9: -1- AC_SUBST([build], [$ac_cv_build]) +m4trace:configure.in:9: -1- AC_SUBST([build_cpu], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) +m4trace:configure.in:9: -1- AC_SUBST([build_vendor], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) +m4trace:configure.in:9: -1- AC_SUBST([build_os], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) +m4trace:configure.in:9: -1- AC_SUBST([host], [$ac_cv_host]) +m4trace:configure.in:9: -1- AC_SUBST([host_cpu], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) +m4trace:configure.in:9: -1- AC_SUBST([host_vendor], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) +m4trace:configure.in:9: -1- AC_SUBST([host_os], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) +m4trace:configure.in:9: -1- AC_PROG_LD +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1331: AC_ARG_WITH is expanded from... +/usr/share/aclocal/libtool.m4:2224: AC_PROG_LD is expanded from... +configure.in:9: AC_PROG_LD is required by... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- LT_AC_PROG_SED +m4trace:configure.in:9: -1- AC_SUBST([SED]) +m4trace:configure.in:9: -1- AC_PROG_LD_GNU +m4trace:configure.in:9: -1- AC_PROG_EGREP +m4trace:configure.in:9: -1- AC_SUBST([EGREP]) +m4trace:configure.in:9: -1- AC_PROG_LD_RELOAD_FLAG +m4trace:configure.in:9: -1- AC_PROG_NM +m4trace:configure.in:9: -1- AC_PROG_LN_S +m4trace:configure.in:9: -1- AC_SUBST([LN_S], [$as_ln_s]) +m4trace:configure.in:9: -1- AC_DEPLIBS_CHECK_METHOD +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_MAX_CMD_LEN +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_OBJDIR +m4trace:configure.in:9: -1- _LT_AC_SYS_COMPILER +m4trace:configure.in:9: -1- _LT_AC_PROG_ECHO_BACKSLASH +m4trace:configure.in:9: -1- _LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +]) +m4trace:configure.in:9: -1- AC_SUBST([ECHO]) +m4trace:configure.in:9: -1- AC_SUBST([AR]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_AR]) +m4trace:configure.in:9: -1- AC_SUBST([RANLIB]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_RANLIB]) +m4trace:configure.in:9: -1- AC_SUBST([STRIP]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_STRIP]) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- AC_PATH_MAGIC +m4trace:configure.in:9: -1- AC_PATH_TOOL_PREFIX([${ac_tool_prefix}file], [/usr/bin$PATH_SEPARATOR$PATH]) +m4trace:configure.in:9: -1- AC_PATH_TOOL_PREFIX([file], [/usr/bin$PATH_SEPARATOR$PATH]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1331: AC_ARG_WITH is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LANG_C_CONFIG +m4trace:configure.in:9: -1- _LT_AC_LANG_C_CONFIG +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([objext], []) +m4trace:configure.in:9: -1- _LT_AC_SYS_COMPILER +m4trace:configure.in:9: -1- _LT_COMPILER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_LINKER_BOILERPLATE +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_COMPILER_NO_RTTI([]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], [lt_cv_prog_compiler_rtti_exceptions], [-fno-rtti -fno-exceptions], [], [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, )="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, ) -fno-rtti -fno-exceptions"]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_COMPILER_PIC([]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_pic_works], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, ) works], [lt_prog_compiler_pic_works], [$_LT_AC_TAGVAR(lt_prog_compiler_pic, )ifelse([],[],[ -DPIC],[ifelse([],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, ) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, )=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, )" ;; + esac], [_LT_AC_TAGVAR(lt_prog_compiler_pic, )= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, )=no]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_static_works], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_prog_compiler_static_works], [$lt_tmp_static_flag], [], [_LT_AC_TAGVAR(lt_prog_compiler_static, )=]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_CC_C_O([]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_HARD_LINK_LOCKS([]) +m4trace:configure.in:9: -1- _LT_AC_LOCK +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. +You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... +autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... +autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... +/usr/share/aclocal/libtool.m4:608: _LT_AC_LOCK is expanded from... +configure.in:9: _LT_AC_LOCK is required by... +/usr/share/aclocal/libtool.m4:1094: AC_LIBTOOL_SYS_HARD_LINK_LOCKS is expanded from... +/usr/share/aclocal/libtool.m4:2740: _LT_AC_LANG_C_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:2667: AC_LIBTOOL_LANG_C_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_SHLIBS([]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], []) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([reload_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_DYNAMIC_LINKER([]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([runpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_LIB_STRIP +m4trace:configure.in:9: -1- AC_LIBTOOL_DLOPEN_SELF +m4trace:configure.in:9: -1- _LT_AC_CHECK_DLFCN +m4trace:configure.in:9: -1- AC_CHECK_HEADERS([dlfcn.h]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H]) +m4trace:configure.in:9: -1- AC_HEADER_STDC +m4trace:configure.in:9: -1- AC_PROG_CPP +m4trace:configure.in:9: -1- AC_SUBST([CPP]) +m4trace:configure.in:9: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CPP]) +m4trace:configure.in:9: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) +m4trace:configure.in:9: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS]) +m4trace:configure.in:9: -1- AC_CHECK_HEADERS([sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h], [], [], [$ac_includes_default]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) +m4trace:configure.in:9: -1- _LT_AC_TRY_DLOPEN_SELF([lt_cv_dlopen_self=yes], [lt_cv_dlopen_self=yes], [lt_cv_dlopen_self=no], [lt_cv_dlopen_self=cross]) +m4trace:configure.in:9: -1- _LT_AC_TRY_DLOPEN_SELF([lt_cv_dlopen_self_static=yes], [lt_cv_dlopen_self_static=yes], [lt_cv_dlopen_self_static=no], [lt_cv_dlopen_self_static=cross]) +m4trace:configure.in:9: -1- AC_LIBTOOL_CONFIG([]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([CC], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postinstall_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postuninstall_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([GCC], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], []) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], []) +m4trace:configure.in:9: -1- _LT_AC_TAGCONFIG +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1331: AC_ARG_WITH is expanded from... +/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [back quotes and double quotes must not be escaped in: $as_me:$LINENO: error: tag name \"$tagname\" already exists], [/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [back quotes and double quotes must not be escaped in: $as_me: error: tag name \"$tagname\" already exists], [/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LANG_CXX_CONFIG +m4trace:configure.in:9: -1- _LT_AC_LANG_CXX_CONFIG([CXX]) +m4trace:configure.in:9: -1- AC_PROG_CXX +m4trace:configure.in:9: -1- AC_SUBST([CXX]) +m4trace:configure.in:9: -1- AC_SUBST([CXXFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CXX]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_CXX]) +m4trace:configure.in:9: -1- _AM_DEPENDENCIES([CXX]) +m4trace:configure.in:9: -1- AC_SUBST([CXXDEPMODE], [depmode=$am_cv_CXX_dependencies_compiler_type]) +m4trace:configure.in:9: -1- AM_CONDITIONAL([am__fastdepCXX], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3]) +m4trace:configure.in:9: -1- AC_SUBST([am__fastdepCXX_TRUE]) +m4trace:configure.in:9: -1- AC_SUBST([am__fastdepCXX_FALSE]) +m4trace:configure.in:9: -1- _LT_AC_PROG_CXXCPP +m4trace:configure.in:9: -1- AC_SUBST([CXXCPP]) +m4trace:configure.in:9: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CXXCPP]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([objext], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_SYS_COMPILER +m4trace:configure.in:9: -1- _LT_COMPILER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_LINKER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [CXX]) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [CXX]) +m4trace:configure.in:9: -1- AC_PROG_LD +m4trace:configure.in:9: -1- AC_PROG_LD_GNU +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([GCC], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_POSTDEP_PREDEP([CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_COMPILER_PIC([CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_pic_works], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, CXX) works], [lt_prog_compiler_pic_works_CXX], [$_LT_AC_TAGVAR(lt_prog_compiler_pic, CXX)ifelse([CXX],[],[ -DPIC],[ifelse([CXX],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, CXX) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, CXX)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, CXX)" ;; + esac], [_LT_AC_TAGVAR(lt_prog_compiler_pic, CXX)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, CXX)=no]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_static_works], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_prog_compiler_static_works_CXX], [$lt_tmp_static_flag], [], [_LT_AC_TAGVAR(lt_prog_compiler_static, CXX)=]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_CC_C_O([CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_HARD_LINK_LOCKS([CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_SHLIBS([CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_DYNAMIC_LINKER([CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([runpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_CONFIG([CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([CC], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postinstall_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postuninstall_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([GCC], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [CXX]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LANG_F77_CONFIG +m4trace:configure.in:9: -1- _LT_AC_LANG_F77_CONFIG([F77]) +m4trace:configure.in:9: -1- AC_SUBST([F77]) +m4trace:configure.in:9: -1- AC_SUBST([FFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([F77]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([objext], [F77]) +m4trace:configure.in:9: -1- _LT_AC_SYS_COMPILER +m4trace:configure.in:9: -1- _LT_COMPILER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_LINKER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [F77]) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([GCC], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_COMPILER_PIC([F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_pic_works], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, F77) works], [lt_prog_compiler_pic_works_F77], [$_LT_AC_TAGVAR(lt_prog_compiler_pic, F77)ifelse([F77],[],[ -DPIC],[ifelse([F77],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, F77) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, F77)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, F77)" ;; + esac], [_LT_AC_TAGVAR(lt_prog_compiler_pic, F77)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, F77)=no]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_static_works], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_prog_compiler_static_works_F77], [$lt_tmp_static_flag], [], [_LT_AC_TAGVAR(lt_prog_compiler_static, F77)=]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_CC_C_O([F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_HARD_LINK_LOCKS([F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_SHLIBS([F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [F77]) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([reload_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_DYNAMIC_LINKER([F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([runpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_CONFIG([F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([CC], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postinstall_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postuninstall_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([GCC], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [F77]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [F77]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LANG_GCJ_CONFIG +m4trace:configure.in:9: -1- _LT_AC_LANG_GCJ_CONFIG([GCJ]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_SAVE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +/usr/share/aclocal/libtool.m4:4069: _LT_AC_LANG_GCJ_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:4017: AC_LIBTOOL_LANG_GCJ_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [instead of using `AC_LANG', `AC_LANG_SAVE', +and `AC_LANG_RESTORE', you should use `AC_LANG_PUSH' and `AC_LANG_POP'.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +/usr/share/aclocal/libtool.m4:4069: _LT_AC_LANG_GCJ_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:4017: AC_LIBTOOL_LANG_GCJ_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([objext], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_SYS_COMPILER +m4trace:configure.in:9: -1- _LT_COMPILER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_LINKER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [GCJ]) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_COMPILER_NO_RTTI([GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], [lt_cv_prog_compiler_rtti_exceptions], [-fno-rtti -fno-exceptions], [], [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, GCJ)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, GCJ) -fno-rtti -fno-exceptions"]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_COMPILER_PIC([GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_pic_works], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, GCJ) works], [lt_prog_compiler_pic_works_GCJ], [$_LT_AC_TAGVAR(lt_prog_compiler_pic, GCJ)ifelse([GCJ],[],[ -DPIC],[ifelse([GCJ],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, GCJ) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, GCJ)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, GCJ)" ;; + esac], [_LT_AC_TAGVAR(lt_prog_compiler_pic, GCJ)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, GCJ)=no]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_can_build_shared], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([lt_prog_compiler_static_works], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], [lt_prog_compiler_static_works_GCJ], [$lt_tmp_static_flag], [], [_LT_AC_TAGVAR(lt_prog_compiler_static, GCJ)=]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_CC_C_O([GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_HARD_LINK_LOCKS([GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_SHLIBS([GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [GCJ]) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_SYS_LIBPATH_AIX +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_From_new_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([reload_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([ld_shlibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -2- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_SYS_DYNAMIC_LINKER([GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([runpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- AC_LIBTOOL_CONFIG([GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([CC], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postinstall_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postuninstall_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([GCC], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [GCJ]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [GCJ]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_RESTORE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:172: AC_LANG_RESTORE is expanded from... +/usr/share/aclocal/libtool.m4:4069: _LT_AC_LANG_GCJ_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:4017: AC_LIBTOOL_LANG_GCJ_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_LIBTOOL_LANG_RC_CONFIG +m4trace:configure.in:9: -1- _LT_AC_LANG_RC_CONFIG([RC]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_SAVE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +/usr/share/aclocal/libtool.m4:4113: _LT_AC_LANG_RC_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:4077: AC_LIBTOOL_LANG_RC_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [instead of using `AC_LANG', `AC_LANG_SAVE', +and `AC_LANG_RESTORE', you should use `AC_LANG_PUSH' and `AC_LANG_POP'.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +/usr/share/aclocal/libtool.m4:4113: _LT_AC_LANG_RC_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:4077: AC_LIBTOOL_LANG_RC_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([objext], [RC]) +m4trace:configure.in:9: -1- _LT_AC_SYS_COMPILER +m4trace:configure.in:9: -1- _LT_COMPILER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_LINKER_BOILERPLATE +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [RC]) +m4trace:configure.in:9: -1- _LT_CC_BASENAME([$compiler]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [RC]) +m4trace:configure.in:9: -1- AC_LIBTOOL_CONFIG([RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([CC], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postinstall_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postuninstall_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds_need_lc], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([enable_shared_with_static_runtimes], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([GCC], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([LD], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_wl], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_pic], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_cv_prog_compiler_c_o], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_static], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([lt_prog_compiler_no_builtin_flag], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_dynamic_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([whole_archive_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([thread_safe_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_new_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([old_archive_from_expsyms_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([archive_expsym_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([module_expsym_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predep_objects], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdep_objects], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([predeps], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([postdeps], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([compiler_lib_search_path], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([allow_undefined_flag], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([no_undefined_flag], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_action], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_flag_spec_ld], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_libdir_separator], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_direct], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_minus_L], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_shlibpath_var], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([hardcode_automatic], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([link_all_deplibs], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([fix_srcfile_path], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([always_export_symbols], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([export_symbols_cmds], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([exclude_expsyms], [RC]) +m4trace:configure.in:9: -1- _LT_AC_TAGVAR([include_expsyms], [RC]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_RESTORE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:172: AC_LANG_RESTORE is expanded from... +/usr/share/aclocal/libtool.m4:4113: _LT_AC_LANG_RC_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:4077: AC_LIBTOOL_LANG_RC_CONFIG is expanded from... +/usr/share/aclocal/libtool.m4:1903: _LT_AC_TAGCONFIG is expanded from... +/usr/share/aclocal/libtool.m4:220: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +/usr/share/aclocal/libtool.m4:75: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +/usr/share/aclocal/libtool.m4:55: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_SUBST([LIBTOOL]) +m4trace:configure.in:9: -1- AC_LIBTOOL_CXX +m4trace:configure.in:9: -1- _LT_AC_LANG_CXX +m4trace:configure.in:9: -1- _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +m4trace:configure.in:9: -1- AC_LIBTOOL_F77 +m4trace:configure.in:9: -1- _LT_AC_LANG_F77 +m4trace:configure.in:9: -1- _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +m4trace:configure.in:10: -1- AC_PROG_RANLIB +m4trace:configure.in:10: -1- AC_SUBST([RANLIB]) +m4trace:configure.in:10: -1- AC_SUBST([ac_ct_RANLIB]) +m4trace:configure.in:13: -1- AC_CHECK_HEADERS([fcntl.h netinet/in.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h math.h]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_FCNTL_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_NETINET_IN_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_SYS_IOCTL_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_SYS_SOCKET_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_SYS_TIME_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_MATH_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_MATH_H]) +m4trace:configure.in:18: -1- AM_CONDITIONAL([LIBPRI], [test -d "$libpripath" ]) +m4trace:configure.in:18: -1- AC_SUBST([LIBPRI_TRUE]) +m4trace:configure.in:18: -1- AC_SUBST([LIBPRI_FALSE]) +m4trace:configure.in:19: -1- AC_SUBST([libpripath]) +m4trace:configure.in:22: -1- AC_HEADER_TIME +m4trace:configure.in:22: -1- AC_DEFINE_TRACE_LITERAL([TIME_WITH_SYS_TIME]) +m4trace:configure.in:22: -1- AH_OUTPUT([TIME_WITH_SYS_TIME], [/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME]) +m4trace:configure.in:25: -1- AC_FUNC_SELECT_ARGTYPES +m4trace:configure.in:25: -1- AC_CHECK_HEADERS([sys/select.h sys/socket.h]) +m4trace:configure.in:25: -1- AH_OUTPUT([HAVE_SYS_SELECT_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H]) +m4trace:configure.in:25: -1- AH_OUTPUT([HAVE_SYS_SOCKET_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H]) +m4trace:configure.in:25: -1- AC_DEFINE_TRACE_LITERAL([SELECT_TYPE_ARG1]) +m4trace:configure.in:25: -1- AH_OUTPUT([SELECT_TYPE_ARG1], [/* Define to the type of arg 1 for `select\'. */ +#undef SELECT_TYPE_ARG1]) +m4trace:configure.in:25: -1- AC_DEFINE_TRACE_LITERAL([SELECT_TYPE_ARG234]) +m4trace:configure.in:25: -1- AH_OUTPUT([SELECT_TYPE_ARG234], [/* Define to the type of args 2, 3 and 4 for `select\'. */ +#undef SELECT_TYPE_ARG234]) +m4trace:configure.in:25: -1- AC_DEFINE_TRACE_LITERAL([SELECT_TYPE_ARG5]) +m4trace:configure.in:25: -1- AH_OUTPUT([SELECT_TYPE_ARG5], [/* Define to the type of arg 5 for `select\'. */ +#undef SELECT_TYPE_ARG5]) +m4trace:configure.in:26: -1- AC_CHECK_FUNCS([gettimeofday memset select socket]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_GETTIMEOFDAY], [/* Define to 1 if you have the `gettimeofday\' function. */ +#undef HAVE_GETTIMEOFDAY]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_MEMSET], [/* Define to 1 if you have the `memset\' function. */ +#undef HAVE_MEMSET]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_SELECT], [/* Define to 1 if you have the `select\' function. */ +#undef HAVE_SELECT]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_SOCKET], [/* Define to 1 if you have the `socket\' function. */ +#undef HAVE_SOCKET]) +m4trace:configure.in:27: -1- AC_CONFIG_FILES([Makefile]) +m4trace:configure.in:28: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) +m4trace:configure.in:28: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) +m4trace:configure.in:28: -1- _AM_OUTPUT_DEPENDENCY_COMMANDS diff --git a/api/libsangoma/autom4te.cache/traces.1 b/api/libsangoma/autom4te.cache/traces.1 new file mode 100644 index 0000000..75a4030 --- /dev/null +++ b/api/libsangoma/autom4te.cache/traces.1 @@ -0,0 +1,441 @@ +m4trace:configure.in:5: -1- AC_INIT([libsangoma], [1.0.0], [anthmct@yahoo.com]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^_?A[CHUM]_]) +m4trace:configure.in:5: -1- m4_pattern_forbid([_AC_]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS']) +m4trace:configure.in:5: -1- m4_pattern_allow([^AS_FLAGS$]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^_?m4_]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^dnl$]) +m4trace:configure.in:5: -1- m4_pattern_forbid([^_?AS_]) +m4trace:configure.in:5: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}]) +m4trace:configure.in:5: -1- AC_SUBST([PATH_SEPARATOR]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])]) +m4trace:configure.in:5: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])]) +m4trace:configure.in:5: -1- AC_SUBST([exec_prefix], [NONE]) +m4trace:configure.in:5: -1- AC_SUBST([prefix], [NONE]) +m4trace:configure.in:5: -1- AC_SUBST([program_transform_name], [s,x,x,]) +m4trace:configure.in:5: -1- AC_SUBST([bindir], ['${exec_prefix}/bin']) +m4trace:configure.in:5: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin']) +m4trace:configure.in:5: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec']) +m4trace:configure.in:5: -1- AC_SUBST([datadir], ['${prefix}/share']) +m4trace:configure.in:5: -1- AC_SUBST([sysconfdir], ['${prefix}/etc']) +m4trace:configure.in:5: -1- AC_SUBST([sharedstatedir], ['${prefix}/com']) +m4trace:configure.in:5: -1- AC_SUBST([localstatedir], ['${prefix}/var']) +m4trace:configure.in:5: -1- AC_SUBST([libdir], ['${exec_prefix}/lib']) +m4trace:configure.in:5: -1- AC_SUBST([includedir], ['${prefix}/include']) +m4trace:configure.in:5: -1- AC_SUBST([oldincludedir], ['/usr/include']) +m4trace:configure.in:5: -1- AC_SUBST([infodir], ['${prefix}/info']) +m4trace:configure.in:5: -1- AC_SUBST([mandir], ['${prefix}/man']) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */ +#undef PACKAGE_NAME]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */ +#undef PACKAGE_VERSION]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING]) +m4trace:configure.in:5: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT]) +m4trace:configure.in:5: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT]) +m4trace:configure.in:5: -1- AC_SUBST([build_alias]) +m4trace:configure.in:5: -1- AC_SUBST([host_alias]) +m4trace:configure.in:5: -1- AC_SUBST([target_alias]) +m4trace:configure.in:5: -1- AC_SUBST([DEFS]) +m4trace:configure.in:5: -1- AC_SUBST([ECHO_C]) +m4trace:configure.in:5: -1- AC_SUBST([ECHO_N]) +m4trace:configure.in:5: -1- AC_SUBST([ECHO_T]) +m4trace:configure.in:5: -1- AC_SUBST([LIBS]) +m4trace:configure.in:6: -1- AM_INIT_AUTOMAKE([libsangoma], [1.0.0]) +m4trace:configure.in:6: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$]) +m4trace:configure.in:6: -1- AM_AUTOMAKE_VERSION([1.9.6]) +m4trace:configure.in:6: -1- AC_PROG_INSTALL +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_PROGRAM]) +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_SCRIPT]) +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_DATA]) +m4trace:configure.in:6: -1- AC_SUBST([CYGPATH_W]) +m4trace:configure.in:6: -1- AC_SUBST([PACKAGE], [libsangoma]) +m4trace:configure.in:6: -1- AC_SUBST([VERSION], [1.0.0]) +m4trace:configure.in:6: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE]) +m4trace:configure.in:6: -1- AH_OUTPUT([PACKAGE], [/* Name of package */ +#undef PACKAGE]) +m4trace:configure.in:6: -1- AC_DEFINE_TRACE_LITERAL([VERSION]) +m4trace:configure.in:6: -1- AH_OUTPUT([VERSION], [/* Version number of package */ +#undef VERSION]) +m4trace:configure.in:6: -1- AC_SUBST([ACLOCAL]) +m4trace:configure.in:6: -1- AC_SUBST([AUTOCONF]) +m4trace:configure.in:6: -1- AC_SUBST([AUTOMAKE]) +m4trace:configure.in:6: -1- AC_SUBST([AUTOHEADER]) +m4trace:configure.in:6: -1- AC_SUBST([MAKEINFO]) +m4trace:configure.in:6: -1- AC_SUBST([install_sh]) +m4trace:configure.in:6: -1- AC_SUBST([STRIP]) +m4trace:configure.in:6: -1- AC_SUBST([ac_ct_STRIP]) +m4trace:configure.in:6: -1- AC_SUBST([INSTALL_STRIP_PROGRAM]) +m4trace:configure.in:6: -1- AC_SUBST([mkdir_p]) +m4trace:configure.in:6: -1- AC_PROG_AWK +m4trace:configure.in:6: -1- AC_SUBST([AWK]) +m4trace:configure.in:6: -1- AC_PROG_MAKE_SET +m4trace:configure.in:6: -1- AC_SUBST([SET_MAKE]) +m4trace:configure.in:6: -1- AC_SUBST([am__leading_dot]) +m4trace:configure.in:6: -1- AC_SUBST([AMTAR]) +m4trace:configure.in:6: -1- AC_SUBST([am__tar]) +m4trace:configure.in:6: -1- AC_SUBST([am__untar]) +m4trace:configure.in:8: -1- AC_PROG_CC +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([CFLAGS]) +m4trace:configure.in:8: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.in:8: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([CC]) +m4trace:configure.in:8: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:8: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) +m4trace:configure.in:8: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) +m4trace:configure.in:8: -1- AC_SUBST([DEPDIR], ["${am__leading_dot}deps"]) +m4trace:configure.in:8: -1- AC_SUBST([am__include]) +m4trace:configure.in:8: -1- AC_SUBST([am__quote]) +m4trace:configure.in:8: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +m4trace:configure.in:8: -1- AC_SUBST([AMDEP_TRUE]) +m4trace:configure.in:8: -1- AC_SUBST([AMDEP_FALSE]) +m4trace:configure.in:8: -1- AC_SUBST([AMDEPBACKSLASH]) +m4trace:configure.in:8: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type]) +m4trace:configure.in:8: -1- AM_CONDITIONAL([am__fastdepCC], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3]) +m4trace:configure.in:8: -1- AC_SUBST([am__fastdepCC_TRUE]) +m4trace:configure.in:8: -1- AC_SUBST([am__fastdepCC_FALSE]) +m4trace:configure.in:9: -1- AC_PROG_LIBTOOL +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +aclocal.m4:1955: AC_ENABLE_SHARED is expanded from... +configure.in:9: AC_ENABLE_SHARED is required by... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +aclocal.m4:1994: AC_ENABLE_STATIC is expanded from... +configure.in:9: AC_ENABLE_STATIC is required by... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +aclocal.m4:2033: AC_ENABLE_FAST_INSTALL is expanded from... +configure.in:9: AC_ENABLE_FAST_INSTALL is required by... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_CANONICAL_HOST +m4trace:configure.in:9: -1- AC_CANONICAL_BUILD +m4trace:configure.in:9: -1- AC_SUBST([build], [$ac_cv_build]) +m4trace:configure.in:9: -1- AC_SUBST([build_cpu], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) +m4trace:configure.in:9: -1- AC_SUBST([build_vendor], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) +m4trace:configure.in:9: -1- AC_SUBST([build_os], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) +m4trace:configure.in:9: -1- AC_SUBST([host], [$ac_cv_host]) +m4trace:configure.in:9: -1- AC_SUBST([host_cpu], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) +m4trace:configure.in:9: -1- AC_SUBST([host_vendor], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) +m4trace:configure.in:9: -1- AC_SUBST([host_os], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1331: AC_ARG_WITH is expanded from... +aclocal.m4:2230: AC_PROG_LD is expanded from... +configure.in:9: AC_PROG_LD is required by... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_SUBST([SED]) +m4trace:configure.in:9: -1- AC_SUBST([EGREP]) +m4trace:configure.in:9: -1- AC_PROG_LN_S +m4trace:configure.in:9: -1- AC_SUBST([LN_S], [$as_ln_s]) +m4trace:configure.in:9: -1- AC_SUBST([ECHO]) +m4trace:configure.in:9: -1- AC_SUBST([AR]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_AR]) +m4trace:configure.in:9: -1- AC_SUBST([RANLIB]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_RANLIB]) +m4trace:configure.in:9: -1- AC_SUBST([STRIP]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_STRIP]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1303: AC_ARG_ENABLE is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1331: AC_ARG_WITH is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. +You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... +autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... +autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... +aclocal.m4:614: _LT_AC_LOCK is expanded from... +configure.in:9: _LT_AC_LOCK is required by... +aclocal.m4:1100: AC_LIBTOOL_SYS_HARD_LINK_LOCKS is expanded from... +aclocal.m4:2742: _LT_AC_LANG_C_CONFIG is expanded from... +aclocal.m4:2673: AC_LIBTOOL_LANG_C_CONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_CHECK_HEADERS([dlfcn.h]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H]) +m4trace:configure.in:9: -1- AC_HEADER_STDC +m4trace:configure.in:9: -1- AC_PROG_CPP +m4trace:configure.in:9: -1- AC_SUBST([CPP]) +m4trace:configure.in:9: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CPP]) +m4trace:configure.in:9: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) +m4trace:configure.in:9: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS]) +m4trace:configure.in:9: -1- AC_CHECK_HEADERS([sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h], [], [], [$ac_includes_default]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H]) +m4trace:configure.in:9: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) +m4trace:configure.in:9: -1- AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) +m4trace:configure.in:9: -1- _LT_AC_TAGCONFIG +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. +You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... +autoconf/general.m4:1331: AC_ARG_WITH is expanded from... +aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [back quotes and double quotes must not be escaped in: $as_me:$LINENO: error: tag name \"$tagname\" already exists], [aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [back quotes and double quotes must not be escaped in: $as_me: error: tag name \"$tagname\" already exists], [aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_PROG_CXX +m4trace:configure.in:9: -1- AC_SUBST([CXX]) +m4trace:configure.in:9: -1- AC_SUBST([CXXFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CXX]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_CXX]) +m4trace:configure.in:9: -1- AC_SUBST([CXXDEPMODE], [depmode=$am_cv_CXX_dependencies_compiler_type]) +m4trace:configure.in:9: -1- AM_CONDITIONAL([am__fastdepCXX], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3]) +m4trace:configure.in:9: -1- AC_SUBST([am__fastdepCXX_TRUE]) +m4trace:configure.in:9: -1- AC_SUBST([am__fastdepCXX_FALSE]) +m4trace:configure.in:9: -1- AC_SUBST([CXXCPP]) +m4trace:configure.in:9: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([CXXCPP]) +m4trace:configure.in:9: -1- AC_SUBST([F77]) +m4trace:configure.in:9: -1- AC_SUBST([FFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.in:9: -1- AC_SUBST([F77]) +m4trace:configure.in:9: -1- AC_SUBST([ac_ct_F77]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_SAVE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +aclocal.m4:4063: _LT_AC_LANG_GCJ_CONFIG is expanded from... +aclocal.m4:4015: AC_LIBTOOL_LANG_GCJ_CONFIG is expanded from... +aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [instead of using `AC_LANG', `AC_LANG_SAVE', +and `AC_LANG_RESTORE', you should use `AC_LANG_PUSH' and `AC_LANG_POP'.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +aclocal.m4:4063: _LT_AC_LANG_GCJ_CONFIG is expanded from... +aclocal.m4:4015: AC_LIBTOOL_LANG_GCJ_CONFIG is expanded from... +aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_RESTORE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:172: AC_LANG_RESTORE is expanded from... +aclocal.m4:4063: _LT_AC_LANG_GCJ_CONFIG is expanded from... +aclocal.m4:4015: AC_LIBTOOL_LANG_GCJ_CONFIG is expanded from... +aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_SAVE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +aclocal.m4:4107: _LT_AC_LANG_RC_CONFIG is expanded from... +aclocal.m4:4071: AC_LIBTOOL_LANG_RC_CONFIG is expanded from... +aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [instead of using `AC_LANG', `AC_LANG_SAVE', +and `AC_LANG_RESTORE', you should use `AC_LANG_PUSH' and `AC_LANG_POP'.], [autoconf/lang.m4:166: AC_LANG_SAVE is expanded from... +aclocal.m4:4107: _LT_AC_LANG_RC_CONFIG is expanded from... +aclocal.m4:4071: AC_LIBTOOL_LANG_RC_CONFIG is expanded from... +aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- _m4_warn([obsolete], [The macro `AC_LANG_RESTORE' is obsolete. +You should run autoupdate.], [autoconf/lang.m4:172: AC_LANG_RESTORE is expanded from... +aclocal.m4:4107: _LT_AC_LANG_RC_CONFIG is expanded from... +aclocal.m4:4071: AC_LIBTOOL_LANG_RC_CONFIG is expanded from... +aclocal.m4:1909: _LT_AC_TAGCONFIG is expanded from... +aclocal.m4:226: AC_LIBTOOL_SETUP is expanded from... +configure.in:9: AC_LIBTOOL_SETUP is required by... +aclocal.m4:81: _AC_PROG_LIBTOOL is expanded from... +configure.in:9: _AC_PROG_LIBTOOL is required by... +aclocal.m4:61: AC_PROG_LIBTOOL is expanded from... +configure.in:9: the top level]) +m4trace:configure.in:9: -1- AC_SUBST([LIBTOOL]) +m4trace:configure.in:10: -1- AC_PROG_RANLIB +m4trace:configure.in:10: -1- AC_SUBST([RANLIB]) +m4trace:configure.in:10: -1- AC_SUBST([ac_ct_RANLIB]) +m4trace:configure.in:13: -1- AC_CHECK_HEADERS([fcntl.h netinet/in.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h math.h]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_FCNTL_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_NETINET_IN_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_SYS_IOCTL_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_SYS_SOCKET_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_SYS_TIME_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H]) +m4trace:configure.in:13: -1- AH_OUTPUT([HAVE_MATH_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_MATH_H]) +m4trace:configure.in:18: -1- AM_CONDITIONAL([LIBPRI], [test -d "$libpripath" ]) +m4trace:configure.in:18: -1- AC_SUBST([LIBPRI_TRUE]) +m4trace:configure.in:18: -1- AC_SUBST([LIBPRI_FALSE]) +m4trace:configure.in:19: -1- AC_SUBST([libpripath]) +m4trace:configure.in:22: -1- AC_HEADER_TIME +m4trace:configure.in:22: -1- AC_DEFINE_TRACE_LITERAL([TIME_WITH_SYS_TIME]) +m4trace:configure.in:22: -1- AH_OUTPUT([TIME_WITH_SYS_TIME], [/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME]) +m4trace:configure.in:25: -1- AC_FUNC_SELECT_ARGTYPES +m4trace:configure.in:25: -1- AC_CHECK_HEADERS([sys/select.h sys/socket.h]) +m4trace:configure.in:25: -1- AH_OUTPUT([HAVE_SYS_SELECT_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H]) +m4trace:configure.in:25: -1- AH_OUTPUT([HAVE_SYS_SOCKET_H], [/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H]) +m4trace:configure.in:25: -1- AC_DEFINE_TRACE_LITERAL([SELECT_TYPE_ARG1]) +m4trace:configure.in:25: -1- AH_OUTPUT([SELECT_TYPE_ARG1], [/* Define to the type of arg 1 for `select\'. */ +#undef SELECT_TYPE_ARG1]) +m4trace:configure.in:25: -1- AC_DEFINE_TRACE_LITERAL([SELECT_TYPE_ARG234]) +m4trace:configure.in:25: -1- AH_OUTPUT([SELECT_TYPE_ARG234], [/* Define to the type of args 2, 3 and 4 for `select\'. */ +#undef SELECT_TYPE_ARG234]) +m4trace:configure.in:25: -1- AC_DEFINE_TRACE_LITERAL([SELECT_TYPE_ARG5]) +m4trace:configure.in:25: -1- AH_OUTPUT([SELECT_TYPE_ARG5], [/* Define to the type of arg 5 for `select\'. */ +#undef SELECT_TYPE_ARG5]) +m4trace:configure.in:26: -1- AC_CHECK_FUNCS([gettimeofday memset select socket]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_GETTIMEOFDAY], [/* Define to 1 if you have the `gettimeofday\' function. */ +#undef HAVE_GETTIMEOFDAY]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_MEMSET], [/* Define to 1 if you have the `memset\' function. */ +#undef HAVE_MEMSET]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_SELECT], [/* Define to 1 if you have the `select\' function. */ +#undef HAVE_SELECT]) +m4trace:configure.in:26: -1- AH_OUTPUT([HAVE_SOCKET], [/* Define to 1 if you have the `socket\' function. */ +#undef HAVE_SOCKET]) +m4trace:configure.in:27: -1- AC_CONFIG_FILES([Makefile]) +m4trace:configure.in:28: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs]) +m4trace:configure.in:28: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs]) diff --git a/api/libsangoma/config.log b/api/libsangoma/config.log index 5a17b0e..676ae3e 100644 --- a/api/libsangoma/config.log +++ b/api/libsangoma/config.log @@ -140,27 +140,27 @@ configure:3150: result: i686-pc-linux-gnu configure:3158: checking host system type configure:3172: result: i686-pc-linux-gnu configure:3180: checking for a sed that does not truncate output -configure:3234: result: /bin/sed -configure:3237: checking for egrep -configure:3247: result: grep -E -configure:3263: checking for ld used by gcc -configure:3330: result: /usr/bin/ld -configure:3339: checking if the linker (/usr/bin/ld) is GNU ld -configure:3354: result: yes -configure:3359: checking for /usr/bin/ld option to reload object files -configure:3366: result: -r -configure:3375: checking for BSD-compatible nm -configure:3417: result: /usr/bin/nm -B -configure:3421: checking whether ln -s works -configure:3425: result: yes -configure:3432: checking how to recognise dependent libraries -configure:3615: result: pass_all -configure:3829: checking how to run the C preprocessor -configure:3864: gcc -E conftest.c -configure:3870: $? = 0 -configure:3902: gcc -E conftest.c +configure:3236: result: /bin/sed +configure:3239: checking for egrep +configure:3249: result: grep -E +configure:3265: checking for ld used by gcc +configure:3332: result: /usr/bin/ld +configure:3341: checking if the linker (/usr/bin/ld) is GNU ld +configure:3356: result: yes +configure:3361: checking for /usr/bin/ld option to reload object files +configure:3368: result: -r +configure:3386: checking for BSD-compatible nm +configure:3435: result: /usr/bin/nm -B +configure:3439: checking whether ln -s works +configure:3443: result: yes +configure:3450: checking how to recognise dependent libraries +configure:3626: result: pass_all +configure:3863: checking how to run the C preprocessor +configure:3898: gcc -E conftest.c +configure:3904: $? = 0 +configure:3936: gcc -E conftest.c conftest.c:11:28: error: ac_nonexistent.h: No such file or directory -configure:3908: $? = 1 +configure:3942: $? = 1 configure: failed program was: | /* confdefs.h. */ | @@ -173,12 +173,12 @@ configure: failed program was: | #define VERSION "1.0.0" | /* end confdefs.h. */ | #include -configure:3947: result: gcc -E -configure:3971: gcc -E conftest.c -configure:3977: $? = 0 -configure:4009: gcc -E conftest.c +configure:3981: result: gcc -E +configure:4005: gcc -E conftest.c +configure:4011: $? = 0 +configure:4043: gcc -E conftest.c conftest.c:11:28: error: ac_nonexistent.h: No such file or directory -configure:4015: $? = 1 +configure:4049: $? = 1 configure: failed program was: | /* confdefs.h. */ | @@ -191,167 +191,167 @@ configure: failed program was: | #define VERSION "1.0.0" | /* end confdefs.h. */ | #include -configure:4059: checking for ANSI C header files -configure:4084: gcc -c -g -O2 conftest.c >&5 -configure:4090: $? = 0 -configure:4094: test -z +configure:4093: checking for ANSI C header files +configure:4118: gcc -c -g -O2 conftest.c >&5 +configure:4124: $? = 0 +configure:4128: test -z || test ! -s conftest.err -configure:4097: $? = 0 -configure:4100: test -s conftest.o -configure:4103: $? = 0 -configure:4192: gcc -o conftest -g -O2 conftest.c >&5 +configure:4131: $? = 0 +configure:4134: test -s conftest.o +configure:4137: $? = 0 +configure:4226: gcc -o conftest -g -O2 conftest.c >&5 conftest.c: In function 'main': conftest.c:28: warning: incompatible implicit declaration of built-in function 'exit' -configure:4195: $? = 0 -configure:4197: ./conftest -configure:4200: $? = 0 -configure:4215: result: yes -configure:4239: checking for sys/types.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4229: $? = 0 +configure:4231: ./conftest +configure:4234: $? = 0 +configure:4249: result: yes +configure:4273: checking for sys/types.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for sys/stat.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for sys/stat.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for stdlib.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for stdlib.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for string.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for string.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for memory.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for memory.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for strings.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for strings.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for inttypes.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for inttypes.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for stdint.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for stdint.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4239: checking for unistd.h -configure:4255: gcc -c -g -O2 conftest.c >&5 -configure:4261: $? = 0 -configure:4265: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4273: checking for unistd.h +configure:4289: gcc -c -g -O2 conftest.c >&5 +configure:4295: $? = 0 +configure:4299: test -z || test ! -s conftest.err -configure:4268: $? = 0 -configure:4271: test -s conftest.o -configure:4274: $? = 0 -configure:4285: result: yes -configure:4311: checking dlfcn.h usability -configure:4323: gcc -c -g -O2 conftest.c >&5 -configure:4329: $? = 0 -configure:4333: test -z +configure:4302: $? = 0 +configure:4305: test -s conftest.o +configure:4308: $? = 0 +configure:4319: result: yes +configure:4345: checking dlfcn.h usability +configure:4357: gcc -c -g -O2 conftest.c >&5 +configure:4363: $? = 0 +configure:4367: test -z || test ! -s conftest.err -configure:4336: $? = 0 -configure:4339: test -s conftest.o -configure:4342: $? = 0 -configure:4352: result: yes -configure:4356: checking dlfcn.h presence -configure:4366: gcc -E conftest.c -configure:4372: $? = 0 -configure:4392: result: yes -configure:4427: checking for dlfcn.h -configure:4434: result: yes -configure:4499: checking for g++ -configure:4515: found /usr/bin/g++ -configure:4525: result: g++ -configure:4541: checking for C++ compiler version -configure:4544: g++ --version &5 +configure:4370: $? = 0 +configure:4373: test -s conftest.o +configure:4376: $? = 0 +configure:4386: result: yes +configure:4390: checking dlfcn.h presence +configure:4400: gcc -E conftest.c +configure:4406: $? = 0 +configure:4426: result: yes +configure:4461: checking for dlfcn.h +configure:4468: result: yes +configure:4533: checking for g++ +configure:4549: found /usr/bin/g++ +configure:4559: result: g++ +configure:4575: checking for C++ compiler version +configure:4578: g++ --version &5 g++ (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -configure:4547: $? = 0 -configure:4549: g++ -v &5 +configure:4581: $? = 0 +configure:4583: g++ -v &5 Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.1 20070105 (Red Hat 4.1.1-52) -configure:4552: $? = 0 -configure:4554: g++ -V &5 +configure:4586: $? = 0 +configure:4588: g++ -V &5 g++: '-V' option must have argument -configure:4557: $? = 1 -configure:4560: checking whether we are using the GNU C++ compiler -configure:4584: g++ -c conftest.cc >&5 -configure:4590: $? = 0 -configure:4594: test -z +configure:4591: $? = 1 +configure:4594: checking whether we are using the GNU C++ compiler +configure:4618: g++ -c conftest.cc >&5 +configure:4624: $? = 0 +configure:4628: test -z || test ! -s conftest.err -configure:4597: $? = 0 -configure:4600: test -s conftest.o -configure:4603: $? = 0 -configure:4616: result: yes -configure:4622: checking whether g++ accepts -g -configure:4643: g++ -c -g conftest.cc >&5 -configure:4649: $? = 0 -configure:4653: test -z +configure:4631: $? = 0 +configure:4634: test -s conftest.o +configure:4637: $? = 0 +configure:4650: result: yes +configure:4656: checking whether g++ accepts -g +configure:4677: g++ -c -g conftest.cc >&5 +configure:4683: $? = 0 +configure:4687: test -z || test ! -s conftest.err -configure:4656: $? = 0 -configure:4659: test -s conftest.o -configure:4662: $? = 0 -configure:4673: result: yes -configure:4715: g++ -c -g -O2 conftest.cc >&5 -configure:4721: $? = 0 -configure:4725: test -z +configure:4690: $? = 0 +configure:4693: test -s conftest.o +configure:4696: $? = 0 +configure:4707: result: yes +configure:4749: g++ -c -g -O2 conftest.cc >&5 +configure:4755: $? = 0 +configure:4759: test -z || test ! -s conftest.err -configure:4728: $? = 0 -configure:4731: test -s conftest.o -configure:4734: $? = 0 -configure:4760: g++ -c -g -O2 conftest.cc >&5 +configure:4762: $? = 0 +configure:4765: test -s conftest.o +configure:4768: $? = 0 +configure:4794: g++ -c -g -O2 conftest.cc >&5 conftest.cc: In function 'int main()': conftest.cc:26: error: 'exit' was not declared in this scope -configure:4766: $? = 1 +configure:4800: $? = 1 configure: failed program was: | /* confdefs.h. */ | @@ -382,28 +382,28 @@ configure: failed program was: | ; | return 0; | } -configure:4715: g++ -c -g -O2 conftest.cc >&5 -configure:4721: $? = 0 -configure:4725: test -z +configure:4749: g++ -c -g -O2 conftest.cc >&5 +configure:4755: $? = 0 +configure:4759: test -z || test ! -s conftest.err -configure:4728: $? = 0 -configure:4731: test -s conftest.o -configure:4734: $? = 0 -configure:4760: g++ -c -g -O2 conftest.cc >&5 -configure:4766: $? = 0 -configure:4770: test -z +configure:4762: $? = 0 +configure:4765: test -s conftest.o +configure:4768: $? = 0 +configure:4794: g++ -c -g -O2 conftest.cc >&5 +configure:4800: $? = 0 +configure:4804: test -z || test ! -s conftest.err -configure:4773: $? = 0 -configure:4776: test -s conftest.o -configure:4779: $? = 0 -configure:4804: checking dependency style of g++ -configure:4894: result: gcc3 -configure:4916: checking how to run the C++ preprocessor -configure:4947: g++ -E conftest.cc -configure:4953: $? = 0 -configure:4985: g++ -E conftest.cc +configure:4807: $? = 0 +configure:4810: test -s conftest.o +configure:4813: $? = 0 +configure:4838: checking dependency style of g++ +configure:4928: result: gcc3 +configure:4955: checking how to run the C++ preprocessor +configure:4986: g++ -E conftest.cc +configure:4992: $? = 0 +configure:5024: g++ -E conftest.cc conftest.cc:25:28: error: ac_nonexistent.h: No such file or directory -configure:4991: $? = 1 +configure:5030: $? = 1 configure: failed program was: | /* confdefs.h. */ | @@ -430,12 +430,12 @@ configure: failed program was: | #endif | /* end confdefs.h. */ | #include -configure:5030: result: g++ -E -configure:5054: g++ -E conftest.cc -configure:5060: $? = 0 -configure:5092: g++ -E conftest.cc +configure:5069: result: g++ -E +configure:5093: g++ -E conftest.cc +configure:5099: $? = 0 +configure:5131: g++ -E conftest.cc conftest.cc:25:28: error: ac_nonexistent.h: No such file or directory -configure:5098: $? = 1 +configure:5137: $? = 1 configure: failed program was: | /* confdefs.h. */ | @@ -462,35 +462,35 @@ configure: failed program was: | #endif | /* end confdefs.h. */ | #include -configure:5193: checking for g77 -configure:5222: result: no -configure:5193: checking for f77 -configure:5222: result: no -configure:5193: checking for xlf -configure:5222: result: no -configure:5193: checking for frt -configure:5222: result: no -configure:5193: checking for pgf77 -configure:5222: result: no -configure:5193: checking for fort77 -configure:5222: result: no -configure:5193: checking for fl32 -configure:5222: result: no -configure:5193: checking for af77 -configure:5222: result: no -configure:5193: checking for f90 -configure:5222: result: no -configure:5193: checking for xlf90 -configure:5222: result: no -configure:5193: checking for pgf90 -configure:5222: result: no -configure:5193: checking for epcf90 -configure:5222: result: no -configure:5193: checking for f95 -configure:5209: found /usr/bin/f95 -configure:5219: result: f95 -configure:5234: checking for Fortran 77 compiler version -configure:5237: f95 --version &5 +configure:5234: checking for g77 +configure:5263: result: no +configure:5234: checking for f77 +configure:5263: result: no +configure:5234: checking for xlf +configure:5263: result: no +configure:5234: checking for frt +configure:5263: result: no +configure:5234: checking for pgf77 +configure:5263: result: no +configure:5234: checking for fort77 +configure:5263: result: no +configure:5234: checking for fl32 +configure:5263: result: no +configure:5234: checking for af77 +configure:5263: result: no +configure:5234: checking for f90 +configure:5263: result: no +configure:5234: checking for xlf90 +configure:5263: result: no +configure:5234: checking for pgf90 +configure:5263: result: no +configure:5234: checking for epcf90 +configure:5263: result: no +configure:5234: checking for f95 +configure:5250: found /usr/bin/f95 +configure:5260: result: f95 +configure:5275: checking for Fortran 77 compiler version +configure:5278: f95 --version &5 GNU Fortran 95 (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52) Copyright (C) 2006 Free Software Foundation, Inc. @@ -499,315 +499,315 @@ You may redistribute copies of GNU Fortran under the terms of the GNU General Public License. For more information about these matters, see the file named COPYING -configure:5240: $? = 0 -configure:5242: f95 -v &5 +configure:5281: $? = 0 +configure:5283: f95 -v &5 Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.1 20070105 (Red Hat 4.1.1-52) -configure:5245: $? = 0 -configure:5247: f95 -V &5 +configure:5286: $? = 0 +configure:5288: f95 -V &5 f95: '-V' option must have argument -configure:5250: $? = 1 -configure:5258: checking whether we are using the GNU Fortran 77 compiler -configure:5272: f95 -c conftest.F >&5 -configure:5278: $? = 0 -configure:5282: test -z +configure:5291: $? = 1 +configure:5299: checking whether we are using the GNU Fortran 77 compiler +configure:5313: f95 -c conftest.F >&5 +configure:5319: $? = 0 +configure:5323: test -z || test ! -s conftest.err -configure:5285: $? = 0 -configure:5288: test -s conftest.o -configure:5291: $? = 0 -configure:5304: result: yes -configure:5310: checking whether f95 accepts -g -configure:5322: f95 -c -g conftest.f >&5 -configure:5328: $? = 0 -configure:5332: test -z +configure:5326: $? = 0 +configure:5329: test -s conftest.o +configure:5332: $? = 0 +configure:5345: result: yes +configure:5351: checking whether f95 accepts -g +configure:5363: f95 -c -g conftest.f >&5 +configure:5369: $? = 0 +configure:5373: test -z || test ! -s conftest.err -configure:5335: $? = 0 -configure:5338: test -s conftest.o -configure:5341: $? = 0 -configure:5353: result: yes -configure:5383: checking the maximum length of command line arguments -configure:5448: result: 32768 -configure:5459: checking command to parse /usr/bin/nm -B output from gcc object -configure:5548: gcc -c -g -O2 conftest.c >&5 -configure:5551: $? = 0 -configure:5555: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' \> conftest.nm -configure:5558: $? = 0 -configure:5610: gcc -o conftest -g -O2 conftest.c conftstm.o >&5 -configure:5613: $? = 0 -configure:5651: result: ok -configure:5655: checking for objdir -configure:5670: result: .libs -configure:5760: checking for ar -configure:5776: found /usr/bin/ar -configure:5787: result: ar -configure:5840: checking for ranlib -configure:5856: found /usr/bin/ranlib -configure:5867: result: ranlib -configure:5920: checking for strip -configure:5936: found /usr/bin/strip -configure:5947: result: strip -configure:6209: checking if gcc static flag works -configure:6232: result: yes -configure:6250: checking if gcc supports -fno-rtti -fno-exceptions -configure:6268: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 +configure:5376: $? = 0 +configure:5379: test -s conftest.o +configure:5382: $? = 0 +configure:5394: result: yes +configure:5424: checking the maximum length of command line arguments +configure:5533: result: 32768 +configure:5544: checking command to parse /usr/bin/nm -B output from gcc object +configure:5649: gcc -c -g -O2 conftest.c >&5 +configure:5652: $? = 0 +configure:5656: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' \> conftest.nm +configure:5659: $? = 0 +configure:5711: gcc -o conftest -g -O2 conftest.c conftstm.o >&5 +configure:5714: $? = 0 +configure:5752: result: ok +configure:5756: checking for objdir +configure:5771: result: .libs +configure:5861: checking for ar +configure:5877: found /usr/bin/ar +configure:5888: result: ar +configure:5941: checking for ranlib +configure:5957: found /usr/bin/ranlib +configure:5968: result: ranlib +configure:6021: checking for strip +configure:6037: found /usr/bin/strip +configure:6048: result: strip +configure:6320: checking if gcc supports -fno-rtti -fno-exceptions +configure:6338: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 cc1: warning: command line option "-fno-rtti" is valid for C++/ObjC++ but not for C -configure:6272: $? = 0 -configure:6283: result: no -configure:6298: checking for gcc option to produce PIC -configure:6475: result: -fPIC -configure:6483: checking if gcc PIC flag -fPIC works -configure:6501: gcc -c -g -O2 -fPIC -DPIC conftest.c >&5 -configure:6505: $? = 0 -configure:6516: result: yes -configure:6540: checking if gcc supports -c -o file.o -configure:6561: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 -configure:6565: $? = 0 -configure:6585: result: yes -configure:6611: checking whether the gcc linker (/usr/bin/ld) supports shared libraries -configure:7459: result: yes -configure:7485: checking whether -lc should be explicitly linked in -configure:7490: gcc -c -g -O2 conftest.c >&5 -configure:7493: $? = 0 -configure:7507: gcc -shared conftest.o -v -Wl,-soname -Wl,conftest -o conftest 2\>\&1 \| grep -lc \>/dev/null 2\>\&1 -configure:7510: $? = 0 -configure:7522: result: no -configure:7530: checking dynamic linker characteristics -configure:8091: result: GNU/Linux ld.so -configure:8095: checking how to hardcode library paths into programs -configure:8120: result: immediate -configure:8134: checking whether stripping libraries is possible -configure:8139: result: yes -configure:8969: checking if libtool supports shared libraries -configure:8971: result: yes -configure:8974: checking whether to build shared libraries -configure:9032: result: yes -configure:9035: checking whether to build static libraries -configure:9039: result: yes -configure:9131: creating libtool -configure:9678: checking for ld used by g++ -configure:9745: result: /usr/bin/ld -configure:9754: checking if the linker (/usr/bin/ld) is GNU ld -configure:9769: result: yes -configure:9820: checking whether the g++ linker (/usr/bin/ld) supports shared libraries -configure:10648: result: yes -configure:10666: g++ -c -g -O2 conftest.cc >&5 -configure:10669: $? = 0 -configure:10765: checking for g++ option to produce PIC -configure:11017: result: -fPIC -configure:11025: checking if g++ PIC flag -fPIC works -configure:11043: g++ -c -g -O2 -fPIC -DPIC conftest.cc >&5 -configure:11047: $? = 0 -configure:11058: result: yes -configure:11082: checking if g++ supports -c -o file.o -configure:11103: g++ -c -g -O2 -o out/conftest2.o conftest.cc >&5 -configure:11107: $? = 0 -configure:11127: result: yes -configure:11153: checking whether the g++ linker (/usr/bin/ld) supports shared libraries -configure:11178: result: yes -configure:11249: checking dynamic linker characteristics -configure:11810: result: GNU/Linux ld.so -configure:11814: checking how to hardcode library paths into programs -configure:11839: result: immediate -configure:11853: checking whether stripping libraries is possible -configure:11858: result: yes -configure:13165: checking if libtool supports shared libraries -configure:13167: result: yes -configure:13170: checking whether to build shared libraries -configure:13188: result: yes -configure:13191: checking whether to build static libraries -configure:13195: result: yes -configure:13207: checking for f95 option to produce PIC -configure:13384: result: -fPIC -configure:13392: checking if f95 PIC flag -fPIC works -configure:13410: f95 -c -g -O2 -fPIC conftest.f >&5 -configure:13414: $? = 0 -configure:13425: result: yes -configure:13449: checking if f95 supports -c -o file.o -configure:13470: f95 -c -g -O2 -o out/conftest2.o conftest.f >&5 -configure:13474: $? = 0 -configure:13494: result: yes -configure:13520: checking whether the f95 linker (/usr/bin/ld) supports shared libraries -configure:14348: result: yes -configure:14419: checking dynamic linker characteristics -configure:14980: result: GNU/Linux ld.so -configure:14984: checking how to hardcode library paths into programs -configure:15009: result: immediate -configure:15023: checking whether stripping libraries is possible -configure:15028: result: yes -configure:19176: checking for ranlib -configure:19203: result: ranlib -configure:19239: checking fcntl.h usability -configure:19251: gcc -c -g -O2 conftest.c >&5 -configure:19257: $? = 0 -configure:19261: test -z +configure:6342: $? = 0 +configure:6355: result: no +configure:6370: checking for gcc option to produce PIC +configure:6580: result: -fPIC +configure:6588: checking if gcc PIC flag -fPIC works +configure:6606: gcc -c -g -O2 -fPIC -DPIC conftest.c >&5 +configure:6610: $? = 0 +configure:6623: result: yes +configure:6651: checking if gcc static flag -static works +configure:6679: result: yes +configure:6689: checking if gcc supports -c -o file.o +configure:6710: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 +configure:6714: $? = 0 +configure:6736: result: yes +configure:6762: checking whether the gcc linker (/usr/bin/ld) supports shared libraries +configure:7720: result: yes +configure:7741: checking whether -lc should be explicitly linked in +configure:7746: gcc -c -g -O2 conftest.c >&5 +configure:7749: $? = 0 +configure:7764: gcc -shared conftest.o -v -Wl,-soname -Wl,conftest -o conftest 2\>\&1 \| grep -lc \>/dev/null 2\>\&1 +configure:7767: $? = 0 +configure:7779: result: no +configure:7787: checking dynamic linker characteristics +configure:8396: result: GNU/Linux ld.so +configure:8405: checking how to hardcode library paths into programs +configure:8430: result: immediate +configure:8444: checking whether stripping libraries is possible +configure:8449: result: yes +configure:9283: checking if libtool supports shared libraries +configure:9285: result: yes +configure:9288: checking whether to build shared libraries +configure:9309: result: yes +configure:9312: checking whether to build static libraries +configure:9316: result: yes +configure:9408: creating libtool +configure:9999: checking for ld used by g++ +configure:10066: result: /usr/bin/ld +configure:10075: checking if the linker (/usr/bin/ld) is GNU ld +configure:10090: result: yes +configure:10141: checking whether the g++ linker (/usr/bin/ld) supports shared libraries +configure:11079: result: yes +configure:11097: g++ -c -g -O2 conftest.cpp >&5 +configure:11100: $? = 0 +configure:11219: checking for g++ option to produce PIC +configure:11493: result: -fPIC +configure:11501: checking if g++ PIC flag -fPIC works +configure:11519: g++ -c -g -O2 -fPIC -DPIC conftest.cpp >&5 +configure:11523: $? = 0 +configure:11536: result: yes +configure:11564: checking if g++ static flag -static works +configure:11592: result: yes +configure:11602: checking if g++ supports -c -o file.o +configure:11623: g++ -c -g -O2 -o out/conftest2.o conftest.cpp >&5 +configure:11627: $? = 0 +configure:11649: result: yes +configure:11675: checking whether the g++ linker (/usr/bin/ld) supports shared libraries +configure:11700: result: yes +configure:11767: checking dynamic linker characteristics +configure:12376: result: GNU/Linux ld.so +configure:12385: checking how to hardcode library paths into programs +configure:12410: result: immediate +configure:12939: checking if libtool supports shared libraries +configure:12941: result: yes +configure:12944: checking whether to build shared libraries +configure:12964: result: yes +configure:12967: checking whether to build static libraries +configure:12971: result: yes +configure:12981: checking for f95 option to produce PIC +configure:13191: result: -fPIC +configure:13199: checking if f95 PIC flag -fPIC works +configure:13217: f95 -c -g -O2 -fPIC conftest.f >&5 +configure:13221: $? = 0 +configure:13234: result: yes +configure:13262: checking if f95 static flag -static works +configure:13290: result: yes +configure:13300: checking if f95 supports -c -o file.o +configure:13321: f95 -c -g -O2 -o out/conftest2.o conftest.f >&5 +configure:13325: $? = 0 +configure:13347: result: yes +configure:13373: checking whether the f95 linker (/usr/bin/ld) supports shared libraries +configure:14311: result: yes +configure:14378: checking dynamic linker characteristics +configure:14987: result: GNU/Linux ld.so +configure:14996: checking how to hardcode library paths into programs +configure:15021: result: immediate +configure:18655: checking for ranlib +configure:18682: result: ranlib +configure:18718: checking fcntl.h usability +configure:18730: gcc -c -g -O2 conftest.c >&5 +configure:18736: $? = 0 +configure:18740: test -z || test ! -s conftest.err -configure:19264: $? = 0 -configure:19267: test -s conftest.o -configure:19270: $? = 0 -configure:19280: result: yes -configure:19284: checking fcntl.h presence -configure:19294: gcc -E conftest.c -configure:19300: $? = 0 -configure:19320: result: yes -configure:19355: checking for fcntl.h -configure:19362: result: yes -configure:19239: checking netinet/in.h usability -configure:19251: gcc -c -g -O2 conftest.c >&5 -configure:19257: $? = 0 -configure:19261: test -z +configure:18743: $? = 0 +configure:18746: test -s conftest.o +configure:18749: $? = 0 +configure:18759: result: yes +configure:18763: checking fcntl.h presence +configure:18773: gcc -E conftest.c +configure:18779: $? = 0 +configure:18799: result: yes +configure:18834: checking for fcntl.h +configure:18841: result: yes +configure:18718: checking netinet/in.h usability +configure:18730: gcc -c -g -O2 conftest.c >&5 +configure:18736: $? = 0 +configure:18740: test -z || test ! -s conftest.err -configure:19264: $? = 0 -configure:19267: test -s conftest.o -configure:19270: $? = 0 -configure:19280: result: yes -configure:19284: checking netinet/in.h presence -configure:19294: gcc -E conftest.c -configure:19300: $? = 0 -configure:19320: result: yes -configure:19355: checking for netinet/in.h -configure:19362: result: yes -configure:19230: checking for stdlib.h -configure:19235: result: yes -configure:19230: checking for string.h -configure:19235: result: yes -configure:19239: checking sys/ioctl.h usability -configure:19251: gcc -c -g -O2 conftest.c >&5 -configure:19257: $? = 0 -configure:19261: test -z +configure:18743: $? = 0 +configure:18746: test -s conftest.o +configure:18749: $? = 0 +configure:18759: result: yes +configure:18763: checking netinet/in.h presence +configure:18773: gcc -E conftest.c +configure:18779: $? = 0 +configure:18799: result: yes +configure:18834: checking for netinet/in.h +configure:18841: result: yes +configure:18709: checking for stdlib.h +configure:18714: result: yes +configure:18709: checking for string.h +configure:18714: result: yes +configure:18718: checking sys/ioctl.h usability +configure:18730: gcc -c -g -O2 conftest.c >&5 +configure:18736: $? = 0 +configure:18740: test -z || test ! -s conftest.err -configure:19264: $? = 0 -configure:19267: test -s conftest.o -configure:19270: $? = 0 -configure:19280: result: yes -configure:19284: checking sys/ioctl.h presence -configure:19294: gcc -E conftest.c -configure:19300: $? = 0 -configure:19320: result: yes -configure:19355: checking for sys/ioctl.h -configure:19362: result: yes -configure:19239: checking sys/socket.h usability -configure:19251: gcc -c -g -O2 conftest.c >&5 -configure:19257: $? = 0 -configure:19261: test -z +configure:18743: $? = 0 +configure:18746: test -s conftest.o +configure:18749: $? = 0 +configure:18759: result: yes +configure:18763: checking sys/ioctl.h presence +configure:18773: gcc -E conftest.c +configure:18779: $? = 0 +configure:18799: result: yes +configure:18834: checking for sys/ioctl.h +configure:18841: result: yes +configure:18718: checking sys/socket.h usability +configure:18730: gcc -c -g -O2 conftest.c >&5 +configure:18736: $? = 0 +configure:18740: test -z || test ! -s conftest.err -configure:19264: $? = 0 -configure:19267: test -s conftest.o -configure:19270: $? = 0 -configure:19280: result: yes -configure:19284: checking sys/socket.h presence -configure:19294: gcc -E conftest.c -configure:19300: $? = 0 -configure:19320: result: yes -configure:19355: checking for sys/socket.h -configure:19362: result: yes -configure:19239: checking sys/time.h usability -configure:19251: gcc -c -g -O2 conftest.c >&5 -configure:19257: $? = 0 -configure:19261: test -z +configure:18743: $? = 0 +configure:18746: test -s conftest.o +configure:18749: $? = 0 +configure:18759: result: yes +configure:18763: checking sys/socket.h presence +configure:18773: gcc -E conftest.c +configure:18779: $? = 0 +configure:18799: result: yes +configure:18834: checking for sys/socket.h +configure:18841: result: yes +configure:18718: checking sys/time.h usability +configure:18730: gcc -c -g -O2 conftest.c >&5 +configure:18736: $? = 0 +configure:18740: test -z || test ! -s conftest.err -configure:19264: $? = 0 -configure:19267: test -s conftest.o -configure:19270: $? = 0 -configure:19280: result: yes -configure:19284: checking sys/time.h presence -configure:19294: gcc -E conftest.c -configure:19300: $? = 0 -configure:19320: result: yes -configure:19355: checking for sys/time.h -configure:19362: result: yes -configure:19230: checking for unistd.h -configure:19235: result: yes -configure:19239: checking math.h usability -configure:19251: gcc -c -g -O2 conftest.c >&5 -configure:19257: $? = 0 -configure:19261: test -z +configure:18743: $? = 0 +configure:18746: test -s conftest.o +configure:18749: $? = 0 +configure:18759: result: yes +configure:18763: checking sys/time.h presence +configure:18773: gcc -E conftest.c +configure:18779: $? = 0 +configure:18799: result: yes +configure:18834: checking for sys/time.h +configure:18841: result: yes +configure:18709: checking for unistd.h +configure:18714: result: yes +configure:18718: checking math.h usability +configure:18730: gcc -c -g -O2 conftest.c >&5 +configure:18736: $? = 0 +configure:18740: test -z || test ! -s conftest.err -configure:19264: $? = 0 -configure:19267: test -s conftest.o -configure:19270: $? = 0 -configure:19280: result: yes -configure:19284: checking math.h presence -configure:19294: gcc -E conftest.c -configure:19300: $? = 0 -configure:19320: result: yes -configure:19355: checking for math.h -configure:19362: result: yes -configure:19396: checking whether time.h and sys/time.h may both be included -configure:19421: gcc -c -g -O2 conftest.c >&5 -configure:19427: $? = 0 -configure:19431: test -z +configure:18743: $? = 0 +configure:18746: test -s conftest.o +configure:18749: $? = 0 +configure:18759: result: yes +configure:18763: checking math.h presence +configure:18773: gcc -E conftest.c +configure:18779: $? = 0 +configure:18799: result: yes +configure:18834: checking for math.h +configure:18841: result: yes +configure:18875: checking whether time.h and sys/time.h may both be included +configure:18900: gcc -c -g -O2 conftest.c >&5 +configure:18906: $? = 0 +configure:18910: test -z || test ! -s conftest.err -configure:19434: $? = 0 -configure:19437: test -s conftest.o -configure:19440: $? = 0 -configure:19451: result: yes -configure:19478: checking sys/select.h usability -configure:19490: gcc -c -g -O2 conftest.c >&5 -configure:19496: $? = 0 -configure:19500: test -z +configure:18913: $? = 0 +configure:18916: test -s conftest.o +configure:18919: $? = 0 +configure:18930: result: yes +configure:18957: checking sys/select.h usability +configure:18969: gcc -c -g -O2 conftest.c >&5 +configure:18975: $? = 0 +configure:18979: test -z || test ! -s conftest.err -configure:19503: $? = 0 -configure:19506: test -s conftest.o -configure:19509: $? = 0 -configure:19519: result: yes -configure:19523: checking sys/select.h presence -configure:19533: gcc -E conftest.c -configure:19539: $? = 0 -configure:19559: result: yes -configure:19594: checking for sys/select.h -configure:19601: result: yes -configure:19469: checking for sys/socket.h -configure:19474: result: yes -configure:19614: checking types of arguments for select -configure:19647: gcc -c -g -O2 conftest.c >&5 -configure:19653: $? = 0 -configure:19657: test -z +configure:18982: $? = 0 +configure:18985: test -s conftest.o +configure:18988: $? = 0 +configure:18998: result: yes +configure:19002: checking sys/select.h presence +configure:19012: gcc -E conftest.c +configure:19018: $? = 0 +configure:19038: result: yes +configure:19073: checking for sys/select.h +configure:19080: result: yes +configure:18948: checking for sys/socket.h +configure:18953: result: yes +configure:19093: checking types of arguments for select +configure:19126: gcc -c -g -O2 conftest.c >&5 +configure:19132: $? = 0 +configure:19136: test -z || test ! -s conftest.err -configure:19660: $? = 0 -configure:19663: test -s conftest.o -configure:19666: $? = 0 -configure:19682: result: int,fd_set *,struct timeval * -configure:19712: checking for gettimeofday -configure:19769: gcc -o conftest -g -O2 conftest.c >&5 -configure:19775: $? = 0 -configure:19779: test -z +configure:19139: $? = 0 +configure:19142: test -s conftest.o +configure:19145: $? = 0 +configure:19161: result: int,fd_set *,struct timeval * +configure:19191: checking for gettimeofday +configure:19248: gcc -o conftest -g -O2 conftest.c >&5 +configure:19254: $? = 0 +configure:19258: test -z || test ! -s conftest.err -configure:19782: $? = 0 -configure:19785: test -s conftest -configure:19788: $? = 0 -configure:19800: result: yes -configure:19712: checking for memset -configure:19769: gcc -o conftest -g -O2 conftest.c >&5 +configure:19261: $? = 0 +configure:19264: test -s conftest +configure:19267: $? = 0 +configure:19279: result: yes +configure:19191: checking for memset +configure:19248: gcc -o conftest -g -O2 conftest.c >&5 conftest.c:65: warning: conflicting types for built-in function 'memset' -configure:19775: $? = 0 -configure:19779: test -z +configure:19254: $? = 0 +configure:19258: test -z || test ! -s conftest.err -configure:19782: $? = 0 -configure:19785: test -s conftest -configure:19788: $? = 0 -configure:19800: result: yes -configure:19712: checking for select -configure:19769: gcc -o conftest -g -O2 conftest.c >&5 -configure:19775: $? = 0 -configure:19779: test -z +configure:19261: $? = 0 +configure:19264: test -s conftest +configure:19267: $? = 0 +configure:19279: result: yes +configure:19191: checking for select +configure:19248: gcc -o conftest -g -O2 conftest.c >&5 +configure:19254: $? = 0 +configure:19258: test -z || test ! -s conftest.err -configure:19782: $? = 0 -configure:19785: test -s conftest -configure:19788: $? = 0 -configure:19800: result: yes -configure:19712: checking for socket -configure:19769: gcc -o conftest -g -O2 conftest.c >&5 -configure:19775: $? = 0 -configure:19779: test -z +configure:19261: $? = 0 +configure:19264: test -s conftest +configure:19267: $? = 0 +configure:19279: result: yes +configure:19191: checking for socket +configure:19248: gcc -o conftest -g -O2 conftest.c >&5 +configure:19254: $? = 0 +configure:19258: test -z || test ! -s conftest.err -configure:19782: $? = 0 -configure:19785: test -s conftest -configure:19788: $? = 0 -configure:19800: result: yes -configure:19966: creating ./config.status +configure:19261: $? = 0 +configure:19264: test -s conftest +configure:19267: $? = 0 +configure:19279: result: yes +configure:19445: creating ./config.status ## ---------------------- ## ## Running config.status. ## @@ -824,8 +824,8 @@ generated by GNU Autoconf 2.59. Invocation command line was on tesla -config.status:709: creating Makefile -config.status:892: executing depfiles commands +config.status:710: creating Makefile +config.status:893: executing depfiles commands ## ---------------- ## ## Cache variables. ## @@ -910,7 +910,7 @@ am_cv_CC_dependencies_compiler_type=gcc3 am_cv_CXX_dependencies_compiler_type=gcc3 lt_cv_deplibs_check_method=pass_all lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file='/lib/libc.so.6 /lib/libc-2.5.so' +lt_cv_file_magic_test_file= lt_cv_ld_reload_flag=-r lt_cv_objdir=.libs lt_cv_path_LD=/usr/bin/ld @@ -923,14 +923,14 @@ lt_cv_prog_compiler_c_o_F77=yes lt_cv_prog_compiler_rtti_exceptions=no lt_cv_prog_gnu_ld=yes lt_cv_prog_gnu_ldcxx=yes -lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p'\''' +lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\''' lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr) \&\2},/p'\''' lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^. .* \(.*\)$/extern int \1;/p'\''' lt_cv_sys_max_cmd_len=32768 lt_lt_cv_prog_compiler_c_o='"yes"' lt_lt_cv_prog_compiler_c_o_CXX='"yes"' lt_lt_cv_prog_compiler_c_o_F77='"yes"' -lt_lt_cv_sys_global_symbol_pipe='"sed -n -e '\''s/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'\''"' +lt_lt_cv_sys_global_symbol_pipe='"sed -n -e '\''s/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'\''"' lt_lt_cv_sys_global_symbol_to_c_name_address='"sed -n -e '\''s/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'\''"' lt_lt_cv_sys_global_symbol_to_cdecl='"sed -n -e '\''s/^. .* \\(.*\\)\$/extern int \\1;/p'\''"' @@ -938,15 +938,15 @@ lt_lt_cv_sys_global_symbol_to_cdecl='"sed -n -e '\''s/^. .* \\(.*\\)\$/extern in ## Output variables. ## ## ----------------- ## -ACLOCAL='${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run aclocal-1.9' +ACLOCAL='${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run aclocal-1.9' AMDEPBACKSLASH='\' AMDEP_FALSE='#' AMDEP_TRUE='' -AMTAR='${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run tar' +AMTAR='${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run tar' AR='ar' -AUTOCONF='${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run autoconf' -AUTOHEADER='${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run autoheader' -AUTOMAKE='${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run automake-1.9' +AUTOCONF='${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run autoconf' +AUTOHEADER='${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run autoheader' +AUTOMAKE='${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run automake-1.9' AWK='gawk' CC='gcc' CCDEPMODE='depmode=gcc3' @@ -980,7 +980,7 @@ LIBS='' LIBTOOL='$(SHELL) $(top_builddir)/libtool' LN_S='ln -s' LTLIBOBJS='' -MAKEINFO='${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run makeinfo' +MAKEINFO='${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run makeinfo' OBJEXT='o' PACKAGE='libsangoma' PACKAGE_BUGREPORT='anthmct@yahoo.com' @@ -990,6 +990,7 @@ PACKAGE_TARNAME='libsangoma' PACKAGE_VERSION='1.0.0' PATH_SEPARATOR=':' RANLIB='ranlib' +SED='/bin/sed' SET_MAKE='' SHELL='/bin/sh' STRIP='strip' @@ -1024,7 +1025,7 @@ host_os='linux-gnu' host_vendor='pc' includedir='${prefix}/include' infodir='${prefix}/info' -install_sh='/root/3.2/wanpipe/api/libsangoma/install-sh' +install_sh='/root/3.3/wanpipe/api/libsangoma/install-sh' libdir='${exec_prefix}/lib' libexecdir='${exec_prefix}/libexec' libpripath='' diff --git a/api/libsangoma/config.status b/api/libsangoma/config.status index c68e011..01ede5c 100755 --- a/api/libsangoma/config.status +++ b/api/libsangoma/config.status @@ -480,12 +480,12 @@ s,@INSTALL_DATA@,${INSTALL} -m 644,;t t s,@CYGPATH_W@,echo,;t t s,@PACKAGE@,libsangoma,;t t s,@VERSION@,1.0.0,;t t -s,@ACLOCAL@,${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run aclocal-1.9,;t t -s,@AUTOCONF@,${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run autoconf,;t t -s,@AUTOMAKE@,${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run automake-1.9,;t t -s,@AUTOHEADER@,${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run autoheader,;t t -s,@MAKEINFO@,${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run makeinfo,;t t -s,@install_sh@,/root/3.2/wanpipe/api/libsangoma/install-sh,;t t +s,@ACLOCAL@,${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run aclocal-1.9,;t t +s,@AUTOCONF@,${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run autoconf,;t t +s,@AUTOMAKE@,${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run automake-1.9,;t t +s,@AUTOHEADER@,${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run autoheader,;t t +s,@MAKEINFO@,${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run makeinfo,;t t +s,@install_sh@,/root/3.3/wanpipe/api/libsangoma/install-sh,;t t s,@STRIP@,strip,;t t s,@ac_ct_STRIP@,strip,;t t s,@INSTALL_STRIP_PROGRAM@,${SHELL} $(install_sh) -c -s,;t t @@ -493,7 +493,7 @@ s,@mkdir_p@,mkdir -p --,;t t s,@AWK@,gawk,;t t s,@SET_MAKE@,,;t t s,@am__leading_dot@,.,;t t -s,@AMTAR@,${SHELL} /root/3.2/wanpipe/api/libsangoma/missing --run tar,;t t +s,@AMTAR@,${SHELL} /root/3.3/wanpipe/api/libsangoma/missing --run tar,;t t s,@am__tar@,${AMTAR} chof - "$$tardir",;t t s,@am__untar@,${AMTAR} xf -,;t t s,@CC@,gcc,;t t @@ -520,6 +520,7 @@ s,@host@,i686-pc-linux-gnu,;t t s,@host_cpu@,i686,;t t s,@host_vendor@,pc,;t t s,@host_os@,linux-gnu,;t t +s,@SED@,/bin/sed,;t t s,@EGREP@,grep -E,;t t s,@LN_S@,ln -s,;t t s,@ECHO@,echo,;t t diff --git a/api/libsangoma/configure b/api/libsangoma/configure index d2a220b..a773968 100755 --- a/api/libsangoma/configure +++ b/api/libsangoma/configure @@ -280,15 +280,15 @@ fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. -if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string="`eval $cmd`") 2>/dev/null && - echo_test_string="`eval $cmd`" && + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break @@ -464,7 +464,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBPRI_TRUE LIBPRI_FALSE libpripath LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBPRI_TRUE LIBPRI_FALSE libpripath LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -3197,12 +3197,13 @@ do done done done +IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && break + test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in @@ -3227,10 +3228,11 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do fi done done -SED=$lt_cv_path_SED fi +SED=$lt_cv_path_SED + echo "$as_me:$LINENO: result: $SED" >&5 echo "${ECHO_T}$SED" >&6 @@ -3307,7 +3309,7 @@ else if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. + # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &6 if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. + # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 @@ -3381,36 +3392,43 @@ else # Let the user override the test. lt_cv_path_NM="$NM" else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" break ;; *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac ;; esac - esac - fi + fi + done + IFS="$lt_save_ifs" done - IFS="$lt_save_ifs" test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi fi @@ -3457,7 +3475,7 @@ beos*) lt_cv_deplibs_check_method=pass_all ;; -bsdi4*) +bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so @@ -3480,13 +3498,13 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | kfreebsd*-gnu) +freebsd* | kfreebsd*-gnu | dragonfly*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; @@ -3502,7 +3520,7 @@ gnu*) hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file - case "$host_cpu" in + case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so @@ -3518,6 +3536,11 @@ hpux10.20* | hpux11*) esac ;; +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; @@ -3530,15 +3553,6 @@ irix5* | irix6* | nonstopux*) # This must be Linux ELF. linux*) - case $host_cpu in - alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*|x86_64*) - lt_cv_deplibs_check_method=pass_all ;; - *) - # glibc up to 2.1.1 does not perform some relocations on ARM - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; - esac - lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` lt_cv_deplibs_check_method=pass_all ;; @@ -3561,12 +3575,10 @@ nto-qnx*) ;; openbsd*) - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else - lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; @@ -3574,15 +3586,11 @@ osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - solaris*) lt_cv_deplibs_check_method=pass_all ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' @@ -3603,10 +3611,13 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) siemens) lt_cv_deplibs_check_method=pass_all ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; esac ;; -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*) +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac @@ -3624,6 +3635,9 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC @@ -3659,7 +3673,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 3662 "configure"' > conftest.$ac_ext + echo '#line 3676 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -3702,7 +3716,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then - case "`/usr/bin/file conftest.o`" in + case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*linux*) @@ -3815,6 +3829,26 @@ echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6 CFLAGS="$SAVE_CFLAGS" fi ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + esac @@ -4908,7 +4942,12 @@ else fi -ac_ext=cc + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' @@ -5138,6 +5177,8 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +fi + ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' @@ -5231,7 +5272,7 @@ fi # Provide some information about the compiler. -echo "$as_me:5234:" \ +echo "$as_me:5275:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -5421,11 +5462,55 @@ else lt_cv_sys_max_cmd_len=8192; ;; - *) + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while (test "X"`$CONFIG_SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && new_result=`expr "X$teststring" : ".*" 2>&1` && lt_cv_sys_max_cmd_len=$new_result && @@ -5471,9 +5556,6 @@ symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - # Transform an extracted symbol line into a proper C declaration lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" @@ -5495,15 +5577,31 @@ hpux*) # Its linker distinguishes data from code symbols lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDGIRSTW]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; -solaris* | sysv5*) +solaris*) symcode='[BDRT]' ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; sysv4) symcode='[DFNSTU]' ;; @@ -5526,8 +5624,11 @@ esac # Try without a prefix undercore, then with it. for ac_symprfx in "" "_"; do + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + # Write the raw and C identifiers. - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" # Check to see that the pipe works correctly. pipe_works=no @@ -5689,7 +5790,7 @@ esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' +Xsed='sed -e 1s/^X//' sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' # Same as above, but do not quote variable references. @@ -5709,7 +5810,7 @@ rm="rm -f" default_ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except M$VC, +# All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" @@ -5966,6 +6067,7 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" @@ -5985,15 +6087,26 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + # Only perform the check for file, if the check method requires it case $deplibs_check_method in file_magic*) @@ -6019,7 +6132,7 @@ else if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then @@ -6081,7 +6194,7 @@ else if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then @@ -6176,68 +6289,25 @@ lt_simple_link_test_code='int main(){return(0);}\n' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC -# -# Check for any special shared library compilation flags. -# -lt_prog_cc_shlib= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - lt_prog_cc_shlib='-belf' - ;; - esac -fi -if test -n "$lt_prog_cc_shlib"; then - { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5 -echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;} - if echo "$old_CC $old_CFLAGS " | grep "[ ]$lt_prog_cc_shlib[ ]" >/dev/null; then : - else - { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 -echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} - lt_cv_prog_cc_can_build_shared=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5 -echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6 -if test "${lt_prog_compiler_static_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_prog_compiler_static" - printf "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - else - lt_prog_compiler_static_works=yes - fi - fi - $rm conftest* - LDFLAGS="$save_LDFLAGS" - -fi -echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 -echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 - -if test x"$lt_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* @@ -6262,18 +6332,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6268: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6338: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6272: \$? = $ac_status" >&5 + echo "$as_me:6342: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi @@ -6334,6 +6406,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_pic='-fno-common' ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -6350,7 +6427,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -6376,6 +6453,16 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic='-qnocommon' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being @@ -6387,7 +6474,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -6411,12 +6498,19 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; linux*) - case $CC in + case $cc_basename in icc* | ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. @@ -6431,15 +6525,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static='-non_shared' ;; - sco3.2v5*) - lt_prog_compiler_pic='-Kpic' - lt_prog_compiler_static='-dn' - ;; - solaris*) - lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac ;; sunos4*) @@ -6448,7 +6542,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' @@ -6461,6 +6555,17 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' @@ -6495,18 +6600,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6501: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6606: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6505: \$? = $ac_status" >&5 + echo "$as_me:6610: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works=yes fi fi @@ -6527,7 +6634,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= @@ -6537,6 +6644,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works=yes + fi + else + lt_prog_compiler_static_works=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works" >&6 + +if test x"$lt_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 if test "${lt_cv_prog_compiler_c_o+set}" = set; then @@ -6555,23 +6704,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6561: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6710: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:6565: \$? = $ac_status" >&5 + echo "$as_me:6714: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - if test ! -s out/conftest.err; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -6647,6 +6798,16 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) @@ -6657,6 +6818,10 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -6667,6 +6832,27 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) @@ -6717,10 +6903,10 @@ EOF allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -6729,7 +6915,53 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix3*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi else ld_shlibs=no fi @@ -6745,7 +6977,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <&2 @@ -6766,6 +6998,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -6773,31 +7032,6 @@ EOF hardcode_shlibpath_var=no ;; - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_cmds="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - archive_expsym_cmds="$tmp_archive_cmds" - fi - else - ld_shlibs=no - fi - ;; - *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' @@ -6808,16 +7042,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ ;; esac - if test "$ld_shlibs" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) @@ -6829,7 +7058,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported @@ -6863,6 +7092,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ break fi done + ;; esac exp_sym_flag='-bexport' @@ -6881,7 +7111,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ link_all_deplibs=yes if test "$GCC" = yes; then - case $host_os in aix4.012|aix4.012.*) + case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` @@ -6900,8 +7130,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi + ;; esac shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi else # not using gcc if test "$host_cpu" = ia64; then @@ -6909,11 +7143,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -6978,12 +7212,12 @@ rm -f conftest.err conftest.$ac_objext \ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF @@ -7043,13 +7277,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec=' ' + whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -7062,7 +7294,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ld_shlibs=no ;; - bsdi4*) + bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; @@ -7088,52 +7320,52 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; darwin* | rhapsody*) - if test "$GXX" = yes ; then - archive_cmds_need_lc=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag='-undefined dynamic_lookup' - ;; - esac - fi - ;; + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported - whole_archive_flag_spec='-all_load $convenience' + whole_archive_flag_spec='' link_all_deplibs=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else - ld_shlibs=no + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs=no + ;; + esac fi ;; @@ -7167,7 +7399,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes @@ -7190,47 +7422,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi export_dynamic_flag_spec='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' - hardcode_libdir_separator=: - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - ia64*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=no - hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_direct=no + hardcode_shlibpath_var=no ;; *) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: hardcode_direct=yes export_dynamic_flag_spec='${wl}-E' @@ -7278,6 +7525,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_shlibpath_var=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else @@ -7323,7 +7571,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' @@ -7331,21 +7579,15 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_separator=: ;; - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) no_undefined_flag=' -z text' if test "$GCC" = yes; then + wlarc='${wl}' archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else + wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' @@ -7354,8 +7596,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; esac link_all_deplibs=yes ;; @@ -7412,36 +7664,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi fi ;; - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag='${wl}-z ${wl}text' if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no ;; - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -7460,11 +7721,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs" >&5 echo "${ECHO_T}$ld_shlibs" >&6 test "$ld_shlibs" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -7497,6 +7753,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= @@ -7629,7 +7886,7 @@ beos*) shlibpath_var=LIBRARY_PATH ;; -bsdi4*) +bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -7657,7 +7914,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -7687,7 +7945,7 @@ cygwin* | mingw* | pw32*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; @@ -7710,7 +7968,7 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` @@ -7745,8 +8003,17 @@ kfreebsd*-gnu) dynamic_linker='GNU ld.so' ;; -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -7764,14 +8031,19 @@ freebsd*) freebsd2*) shlibpath_overrides_runpath=yes ;; - freebsd3.01* | freebsdelf3.01*) + freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -7791,7 +8063,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -7831,6 +8103,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -7892,7 +8176,7 @@ linux*) libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) - echo '#line 7895 "configure"' > conftest.$ac_ext + echo '#line 8179 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7911,7 +8195,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" fi @@ -7973,8 +8257,13 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no - need_version=yes + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH @@ -8012,13 +8301,6 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - solaris*) version_type=linux need_lib_prefix=no @@ -8044,7 +8326,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -8077,6 +8359,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -8092,12 +8397,17 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6 test "$dynamic_linker" = no && can_build_shared=no +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 hardcode_action= if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var " || \ - test "X$hardcode_automatic"="Xyes" ; then + test -n "$runpath_var" || \ + test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct" != no && @@ -8747,7 +9057,7 @@ fi test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" @@ -8763,7 +9073,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed @@ -8849,7 +9161,7 @@ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 echo "${ECHO_T}$lt_cv_dlopen_self" >&6 if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 if test "${lt_cv_dlopen_self_static+set}" = set; then @@ -8861,7 +9173,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed @@ -8965,7 +9279,7 @@ echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 fi -# Report which librarie types wil actually be built +# Report which library types will actually be built echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $can_build_shared" >&5 @@ -8977,7 +9291,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -8989,43 +9303,6 @@ aix3*) aix4* | aix5*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no - fi - ;; - darwin* | rhapsody*) - if test "$GCC" = yes; then - archive_cmds_need_lc=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag='-undefined dynamic_lookup' - ;; - esac - fi - ;; - esac - output_verbose_link_cmd='echo' - archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring' - module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - whole_archive_flag_spec='-all_load $convenience' - link_all_deplibs=yes - else - ld_shlibs=no fi ;; esac @@ -9052,7 +9329,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -9156,7 +9433,7 @@ echo "$as_me: creating $ofile" >&6;} # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -9167,11 +9444,11 @@ echo "$as_me: creating $ofile" >&6;} SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="$SED -e s/^X//" +Xsed="$SED -e 1s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # The names of the tagged configurations supported by this script. available_tags= @@ -9201,6 +9478,12 @@ fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo @@ -9212,12 +9495,18 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler # Is the compiler the GNU C compiler? with_gcc=$GCC +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + # An ERE matcher. EGREP=$lt_EGREP @@ -9277,7 +9566,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? @@ -9351,11 +9640,11 @@ striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=$lt_predep_objects +predep_objects=\`echo $lt_predep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=$lt_postdep_objects +postdep_objects=\`echo $lt_postdep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place before the objects being linked to create a # shared library. @@ -9367,7 +9656,7 @@ postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method @@ -9447,7 +9736,7 @@ variables_saved_for_relink="$variables_saved_for_relink" link_all_deplibs=$link_all_deplibs # Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec @@ -9542,6 +9831,9 @@ echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} fi fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. @@ -9572,7 +9864,9 @@ echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} case $tagname in CXX) - if test -n "$CXX" && test "X$CXX" != "Xno"; then + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -9592,6 +9886,7 @@ hardcode_libdir_flag_spec_CXX= hardcode_libdir_flag_spec_ld_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= @@ -9609,7 +9904,7 @@ postdeps_CXX= compiler_lib_search_path_CXX= # Source file extension for C++ test sources. -ac_ext=cc +ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o @@ -9619,17 +9914,34 @@ objext_CXX=$objext lt_simple_compile_test_code="int some_variable = 0;\n" # Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *) { return(0); }\n' +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD @@ -9640,18 +9952,27 @@ lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else - unset lt_cv_prog_gnu_ld + $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else - unset lt_cv_path_LD + $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC compiler_CXX=$CC -cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + # We don't want -fno-exception wen compiling C++ code, so set the # no_builtin_flag separately @@ -9722,7 +10043,7 @@ else if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. + # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &6 if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. + # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 conftest.$ac_ext <<_ACEOF @@ -10028,16 +10354,26 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_CXX=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_CXX=' ' + whole_archive_flag_spec_CXX='$convenience' archive_cmds_need_lc_CXX=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + chorus*) case $cc_basename in *) @@ -10056,7 +10392,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -10065,70 +10401,81 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; - - darwin* | rhapsody*) - if test "$GXX" = yes; then - archive_cmds_need_lc_CXX=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag_CXX='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_CXX='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_CXX='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag_CXX='-undefined dynamic_lookup' - ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; esac - fi - ;; - esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_CXX='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_CXX='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes - hardcode_shlibpath_var_CXX=unsupported - whole_archive_flag_spec_CXX='-all_load $convenience' - link_all_deplibs_CXX=yes - else - ld_shlibs_CXX=no - fi - ;; + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_CXX=no + ;; + esac + fi + ;; dgux*) case $cc_basename in - ec++) + ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - ghcx) + ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no @@ -10139,14 +10486,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; esac ;; - freebsd12*) + freebsd[12]*) # C++ shared libraries reported to be fairly broken before switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes @@ -10163,11 +10510,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # location of the library. case $cc_basename in - CC) + CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - aCC) + aCC*) archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when @@ -10177,7 +10524,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; *) if test "$GXX" = yes; then @@ -10191,34 +10538,23 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) hardcode_libdir_flag_spec_ld_CXX='+b $libdir' - hardcode_libdir_separator_CXX=: - ;; - ia64*) - hardcode_libdir_flag_spec_CXX='-L$libdir' ;; *) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi - case "$host_cpu" in - hppa*64*) + case $host_cpu in + hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; - ia64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; *) hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, @@ -10228,14 +10564,17 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac case $cc_basename in - CC) + CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - aCC) - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -10254,9 +10593,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then - case "$host_cpu" in - ia64*|hppa*64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -10270,11 +10612,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; esac ;; + interix3*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; irix5* | irix6*) case $cc_basename in - CC) + CC*) # SGI C++ - archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is @@ -10285,7 +10641,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' fi @@ -10298,7 +10654,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; linux*) case $cc_basename in - KCC) + KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file @@ -10323,17 +10679,41 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; - icpc) + icpc*) # Intel C++ with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac archive_cmds_need_lc_CXX=no - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; - cxx) + pgCC*) + # Portland Group C++ compiler + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' @@ -10364,7 +10744,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; mvs*) case $cc_basename in - cxx) + cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; @@ -10385,9 +10765,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + openbsd*) + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; osf3*) case $cc_basename in - KCC) + KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file @@ -10403,14 +10799,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; - RCC) + RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - cxx) + cxx*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: @@ -10428,7 +10824,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: @@ -10447,7 +10843,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; osf4* | osf5*) case $cc_basename in - KCC) + KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file @@ -10462,17 +10858,17 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # the KAI C++ compiler. old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; - RCC) + RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - cxx) + cxx*) allow_undefined_flag_CXX=' -expect_unresolved \*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ $rm $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' @@ -10491,7 +10887,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: @@ -10512,27 +10908,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - sco*) - archive_cmds_need_lc_CXX=no - case $cc_basename in - CC) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; sunos4*) case $cc_basename in - CC) + CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - lcc) + lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no @@ -10545,36 +10928,33 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; solaris*) case $cc_basename in - CC) + CC*) # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in - solaris2.0-5 | solaris2.0-5.*) ;; + solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The C++ compiler is used as linker so we must use $wl # flag to pass the commands to the underlying system - # linker. + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; esac link_all_deplibs_CXX=yes - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is @@ -10582,7 +10962,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; - gcx) + gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' @@ -10620,12 +11000,63 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; esac ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac ;; tandem*) case $cc_basename in - NCC) + NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no @@ -10678,7 +11109,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 # The `*' in the case matches for architectures that use `case' in # $output_verbose_cmd can trigger glob expansion during the loop # eval without this substitution. - output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`" + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` for p in `eval $output_verbose_link_cmd`; do case $p in @@ -10754,6 +11185,29 @@ fi $rm -f confest.$objext +# PORTME: override above test on systems where it is broken +case $host_os in +interix3*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +solaris*) + case $cc_basename in + CC*) + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + postdeps_CXX='-lCstd -lCrun' + ;; + esac + ;; +esac + + case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac @@ -10801,6 +11255,10 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic @@ -10809,7 +11267,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) ;; *) @@ -10834,18 +11292,28 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; chorus*) case $cc_basename in - cxch68) + cxch68*) # Green Hills C++ Compiler # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_CXX='-qnocommon' + lt_prog_compiler_wl_CXX='-Wl,' + ;; + esac + ;; dgux*) case $cc_basename in - ec++) + ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; - ghcx) + ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; @@ -10853,22 +11321,22 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; esac ;; - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in - CC) + CC*) lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; - aCC) + aCC*) lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case "$host_cpu" in + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -10881,9 +11349,13 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; esac ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; irix5* | irix6* | nonstopux*) case $cc_basename in - CC) + CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. @@ -10894,18 +11366,24 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; linux*) case $cc_basename in - KCC) + KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; - icpc) + icpc* | ecpc*) # Intel C++ lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; - cxx) + pgCC*) + # Portland Group C++ compiler. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. @@ -10922,7 +11400,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; mvs*) case $cc_basename in - cxx) + cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) @@ -10933,14 +11411,14 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; osf3* | osf4* | osf5*) case $cc_basename in - KCC) + KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; - RCC) + RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; - cxx) + cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha @@ -10954,24 +11432,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; psos*) ;; - sco*) - case $cc_basename in - CC) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - *) - ;; - esac - ;; solaris*) case $cc_basename in - CC) + CC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; - gcx) + gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; @@ -10981,12 +11450,12 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; sunos4*) case $cc_basename in - CC) + CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; - lcc) + lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; @@ -10996,7 +11465,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; tandem*) case $cc_basename in - NCC) + NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; @@ -11004,7 +11473,14 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; esac ;; - unixware*) + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac ;; vxworks*) ;; @@ -11037,18 +11513,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:11043: $lt_compile\"" >&5) + (eval echo "\"\$as_me:11519: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:11047: \$? = $ac_status" >&5 + echo "$as_me:11523: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_CXX=yes fi fi @@ -11069,7 +11547,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= @@ -11079,6 +11557,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_CXX=yes + fi + else + lt_prog_compiler_static_works_CXX=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6 + +if test x"$lt_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then @@ -11097,23 +11617,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:11103: $lt_compile\"" >&5) + (eval echo "\"\$as_me:11623: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:11107: \$? = $ac_status" >&5 + echo "$as_me:11627: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - if test ! -s out/conftest.err; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -11168,7 +11690,7 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw*) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' @@ -11179,11 +11701,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 echo "${ECHO_T}$ld_shlibs_CXX" >&6 test "$ld_shlibs_CXX" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -11216,6 +11733,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= @@ -11348,7 +11866,7 @@ beos*) shlibpath_var=LIBRARY_PATH ;; -bsdi4*) +bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -11376,7 +11894,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -11406,7 +11925,7 @@ cygwin* | mingw* | pw32*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; @@ -11429,7 +11948,7 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` @@ -11464,8 +11983,17 @@ kfreebsd*-gnu) dynamic_linker='GNU ld.so' ;; -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -11483,14 +12011,19 @@ freebsd*) freebsd2*) shlibpath_overrides_runpath=yes ;; - freebsd3.01* | freebsdelf3.01*) + freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -11510,7 +12043,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -11550,6 +12083,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -11611,7 +12156,7 @@ linux*) libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) - echo '#line 11614 "configure"' > conftest.$ac_ext + echo '#line 12159 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -11630,7 +12175,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" fi @@ -11692,8 +12237,13 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no - need_version=yes + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH @@ -11731,13 +12281,6 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - solaris*) version_type=linux need_lib_prefix=no @@ -11763,7 +12306,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -11796,6 +12339,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -11811,12 +12377,17 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6 test "$dynamic_linker" = no && can_build_shared=no +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || \ - test -n "$runpath_var CXX" || \ - test "X$hardcode_automatic_CXX"="Xyes" ; then + test -n "$runpath_var_CXX" || \ + test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_CXX" != no && @@ -11848,841 +12419,6 @@ elif test "$shlibpath_overrides_runpath" = yes || enable_fast_install=needless fi -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_cxx_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh @@ -12697,7 +12433,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -12798,6 +12534,12 @@ fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo @@ -12809,12 +12551,18 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU C compiler? with_gcc=$GCC_CXX +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + # An ERE matcher. EGREP=$lt_EGREP @@ -12874,7 +12622,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? @@ -12948,11 +12696,11 @@ striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=$lt_predep_objects_CXX +predep_objects=\`echo $lt_predep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=$lt_postdep_objects_CXX +postdep_objects=\`echo $lt_postdep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place before the objects being linked to create a # shared library. @@ -12964,7 +12712,7 @@ postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_CXX +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method @@ -13044,7 +12792,7 @@ variables_saved_for_relink="$variables_saved_for_relink" link_all_deplibs=$link_all_deplibs_CXX # Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec @@ -13151,16 +12899,42 @@ lt_simple_link_test_code=" program t\n end\n" # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${F77-"f77"} compiler=$CC compiler_F77=$CC -cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'` +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 @@ -13173,7 +12947,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -13182,7 +12956,9 @@ aix3*) fi ;; aix4* | aix5*) - test "$enable_shared" = yes && enable_static=no + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi ;; esac echo "$as_me:$LINENO: result: $enable_shared" >&5 @@ -13195,8 +12971,6 @@ test "$enable_shared" = yes || enable_static=yes echo "$as_me:$LINENO: result: $enable_static" >&5 echo "${ECHO_T}$enable_static" >&6 -test "$ld_shlibs_F77" = no && can_build_shared=no - GCC_F77="$G77" LD_F77="$LD" @@ -13243,6 +13017,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_pic_F77='-fno-common' ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -13259,7 +13038,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -13285,6 +13064,16 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' fi ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_F77='-qnocommon' + lt_prog_compiler_wl_F77='-Wl,' + ;; + esac + ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being @@ -13296,7 +13085,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_wl_F77='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -13320,12 +13109,19 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; linux*) - case $CC in + case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-static' ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-fpic' + lt_prog_compiler_static_F77='-Bstatic' + ;; ccc*) lt_prog_compiler_wl_F77='-Wl,' # All Alpha code is PIC. @@ -13340,15 +13136,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static_F77='-non_shared' ;; - sco3.2v5*) - lt_prog_compiler_pic_F77='-Kpic' - lt_prog_compiler_static_F77='-dn' - ;; - solaris*) - lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_F77='-Qoption ld ';; + *) + lt_prog_compiler_wl_F77='-Wl,';; + esac ;; sunos4*) @@ -13357,7 +13153,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static_F77='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' @@ -13370,6 +13166,17 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_can_build_shared_F77=no + ;; + uts4*) lt_prog_compiler_pic_F77='-pic' lt_prog_compiler_static_F77='-Bstatic' @@ -13404,18 +13211,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13410: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13217: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:13414: \$? = $ac_status" >&5 + echo "$as_me:13221: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_F77=yes fi fi @@ -13436,7 +13245,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_F77= @@ -13446,6 +13255,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_F77=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_F77=yes + fi + else + lt_prog_compiler_static_works_F77=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6 + +if test x"$lt_prog_compiler_static_works_F77" = xyes; then + : +else + lt_prog_compiler_static_F77= +fi + + echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then @@ -13464,23 +13315,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13470: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13321: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:13474: \$? = $ac_status" >&5 + echo "$as_me:13325: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - if test ! -s out/conftest.err; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_F77=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -13556,6 +13409,16 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) @@ -13566,6 +13429,10 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -13576,6 +13443,27 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_F77='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_F77= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) @@ -13626,10 +13514,10 @@ EOF allow_undefined_flag_F77=unsupported always_export_symbols_F77=no enable_shared_with_static_runtimes_F77=yes - export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -13638,9 +13526,55 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else - ld_shlibs=no + ld_shlibs_F77=no + fi + ;; + + interix3*) + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_F77=no fi ;; @@ -13654,7 +13588,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_F77=no cat <&2 @@ -13675,6 +13609,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_F77=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + ;; + sunos4*) archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -13682,31 +13643,6 @@ EOF hardcode_shlibpath_var_F77=no ;; - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_cmds_F77="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - archive_expsym_cmds_F77="$tmp_archive_cmds" - fi - else - ld_shlibs_F77=no - fi - ;; - *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' @@ -13717,16 +13653,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ ;; esac - if test "$ld_shlibs_F77" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_F77='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_F77= - fi + if test "$ld_shlibs_F77" = no; then + runpath_var= + hardcode_libdir_flag_spec_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= fi else # PORTME fill in a description of your system's linker (not GNU ld) @@ -13738,7 +13669,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_F77=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_F77=unsupported @@ -13772,6 +13703,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ break fi done + ;; esac exp_sym_flag='-bexport' @@ -13790,7 +13722,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ link_all_deplibs_F77=yes if test "$GCC" = yes; then - case $host_os in aix4.012|aix4.012.*) + case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` @@ -13809,8 +13741,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_libdir_separator_F77= fi + ;; esac shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi else # not using gcc if test "$host_cpu" = ia64; then @@ -13818,11 +13754,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -13877,12 +13813,12 @@ rm -f conftest.err conftest.$ac_objext \ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_F77="-z nodefs" - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF @@ -13932,13 +13868,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag_F77=' ${wl}-bernotok' allow_undefined_flag_F77=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_F77=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_F77=' ' + whole_archive_flag_spec_F77='$convenience' archive_cmds_need_lc_F77=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -13951,7 +13885,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ld_shlibs_F77=no ;; - bsdi4*) + bsdi[45]*) export_dynamic_flag_spec_F77=-rdynamic ;; @@ -13972,57 +13906,57 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi old_archive_From_new_cmds_F77='true' # FIXME: Should let the user specify the lib program. old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' + fix_srcfile_path_F77='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_F77=yes ;; darwin* | rhapsody*) - if test "$GXX" = yes ; then - archive_cmds_need_lc_F77=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag_F77='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_F77='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_F77='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag_F77='-undefined dynamic_lookup' - ;; - esac - fi - ;; + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_F77='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_F77='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_F77='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + archive_cmds_need_lc_F77=no hardcode_direct_F77=no hardcode_automatic_F77=yes hardcode_shlibpath_var_F77=unsupported - whole_archive_flag_spec_F77='-all_load $convenience' + whole_archive_flag_spec_F77='' link_all_deplibs_F77=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else - ld_shlibs_F77=no + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_F77=no + ;; + esac fi ;; @@ -14056,7 +13990,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes @@ -14079,47 +14013,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi export_dynamic_flag_spec_F77='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_F77='+b $libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no - ;; - ia64*) - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no ;; *) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_F77=: hardcode_direct_F77=yes export_dynamic_flag_spec_F77='${wl}-E' @@ -14167,6 +14116,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_shlibpath_var_F77=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' export_dynamic_flag_spec_F77='${wl}-E' else @@ -14212,7 +14162,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi allow_undefined_flag_F77=' -expect_unresolved \*' archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec_F77='-rpath $libdir' @@ -14220,21 +14170,15 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_separator_F77=: ;; - sco3.2v5*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - export_dynamic_flag_spec_F77='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) no_undefined_flag_F77=' -z text' if test "$GCC" = yes; then + wlarc='${wl}' archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else + wlarc='' archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' @@ -14243,8 +14187,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_shlibpath_var_F77=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; esac link_all_deplibs_F77=yes ;; @@ -14301,36 +14255,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi fi ;; - sysv4.2uw2*) - archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_minus_L_F77=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_F77='${wl}-z,text' + archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_F77='${wl}-z ${wl}text' if test "$GCC" = yes; then - archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_F77=no ;; - sysv5*) - no_undefined_flag_F77=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_F77= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_F77='${wl}-z,text' + allow_undefined_flag_F77='${wl}-z,nodefs' + archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + export_dynamic_flag_spec_F77='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -14349,11 +14312,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 echo "${ECHO_T}$ld_shlibs_F77" >&6 test "$ld_shlibs_F77" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -14386,6 +14344,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_F77 + pic_flag=$lt_prog_compiler_pic_F77 compiler_flags=-v linker_flags=-v verstring= @@ -14518,7 +14477,7 @@ beos*) shlibpath_var=LIBRARY_PATH ;; -bsdi4*) +bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -14546,7 +14505,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -14576,7 +14536,7 @@ cygwin* | mingw* | pw32*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; @@ -14599,7 +14559,7 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` @@ -14634,8 +14594,17 @@ kfreebsd*-gnu) dynamic_linker='GNU ld.so' ;; -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -14653,14 +14622,19 @@ freebsd*) freebsd2*) shlibpath_overrides_runpath=yes ;; - freebsd3.01* | freebsdelf3.01*) + freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -14680,7 +14654,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -14720,6 +14694,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -14781,7 +14767,7 @@ linux*) libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) - echo '#line 14784 "configure"' > conftest.$ac_ext + echo '#line 14770 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -14800,7 +14786,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" fi @@ -14862,8 +14848,13 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no - need_version=yes + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH @@ -14901,13 +14892,6 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - solaris*) version_type=linux need_lib_prefix=no @@ -14933,7 +14917,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -14966,6 +14950,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -14981,12 +14988,17 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6 test "$dynamic_linker" = no && can_build_shared=no +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 hardcode_action_F77= if test -n "$hardcode_libdir_flag_spec_F77" || \ - test -n "$runpath_var F77" || \ - test "X$hardcode_automatic_F77"="Xyes" ; then + test -n "$runpath_var_F77" || \ + test "X$hardcode_automatic_F77" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_F77" != no && @@ -15018,36 +15030,6 @@ elif test "$shlibpath_overrides_runpath" = yes || enable_fast_install=needless fi -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - - # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh @@ -15062,7 +15044,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -15163,6 +15145,12 @@ fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo @@ -15174,12 +15162,18 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_F77 # Is the compiler the GNU C compiler? with_gcc=$GCC_F77 +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + # An ERE matcher. EGREP=$lt_EGREP @@ -15239,7 +15233,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? @@ -15313,11 +15307,11 @@ striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=$lt_predep_objects_F77 +predep_objects=\`echo $lt_predep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=$lt_postdep_objects_F77 +postdep_objects=\`echo $lt_postdep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place before the objects being linked to create a # shared library. @@ -15329,7 +15323,7 @@ postdeps=$lt_postdeps_F77 # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_F77 +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method @@ -15409,7 +15403,7 @@ variables_saved_for_relink="$variables_saved_for_relink" link_all_deplibs=$link_all_deplibs_F77 # Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec @@ -15477,26 +15471,55 @@ objext_GCJ=$objext lt_simple_compile_test_code="class foo {}\n" # Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String argv) {}; }\n' +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${GCJ-"gcj"} compiler=$CC compiler_GCJ=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + # GCJ did not exist at the time GCC didn't implicitly link libc in. archive_cmds_need_lc_GCJ=no +old_archive_cmds_GCJ=$old_archive_cmds + lt_prog_compiler_no_builtin_flag_GCJ= @@ -15519,18 +15542,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15525: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15548: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15529: \$? = $ac_status" >&5 + echo "$as_me:15552: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi @@ -15591,6 +15616,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_pic_GCJ='-fno-common' ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -15607,7 +15637,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -15633,6 +15663,16 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' fi ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_GCJ='-qnocommon' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + esac + ;; mingw* | pw32* | os2*) # This hack is so that the source file can tell whether it is being @@ -15644,7 +15684,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_wl_GCJ='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -15668,12 +15708,19 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 ;; linux*) - case $CC in + case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-static' ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-fpic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; ccc*) lt_prog_compiler_wl_GCJ='-Wl,' # All Alpha code is PIC. @@ -15688,15 +15735,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static_GCJ='-non_shared' ;; - sco3.2v5*) - lt_prog_compiler_pic_GCJ='-Kpic' - lt_prog_compiler_static_GCJ='-dn' - ;; - solaris*) - lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_GCJ='-Qoption ld ';; + *) + lt_prog_compiler_wl_GCJ='-Wl,';; + esac ;; sunos4*) @@ -15705,7 +15752,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 lt_prog_compiler_static_GCJ='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' @@ -15718,6 +15765,17 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_can_build_shared_GCJ=no + ;; + uts4*) lt_prog_compiler_pic_GCJ='-pic' lt_prog_compiler_static_GCJ='-Bstatic' @@ -15752,18 +15810,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15758: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15816: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15762: \$? = $ac_status" >&5 + echo "$as_me:15820: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test ! -s conftest.err; then + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_prog_compiler_pic_works_GCJ=yes fi fi @@ -15784,7 +15844,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_GCJ= @@ -15794,6 +15854,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" +echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6 +if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_GCJ=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_GCJ=yes + fi + else + lt_prog_compiler_static_works_GCJ=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6 + +if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then + : +else + lt_prog_compiler_static_GCJ= +fi + + echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then @@ -15812,23 +15914,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15818: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15920: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15822: \$? = $ac_status" >&5 + echo "$as_me:15924: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - if test ! -s out/conftest.err; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_GCJ=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -15904,6 +16008,16 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` case $host_os in cygwin* | mingw* | pw32*) @@ -15914,6 +16028,10 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -15924,6 +16042,27 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_GCJ= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + # See if GNU ld supports shared libraries. case $host_os in aix3* | aix4* | aix5*) @@ -15974,10 +16113,10 @@ EOF allow_undefined_flag_GCJ=unsupported always_export_symbols_GCJ=no enable_shared_with_static_runtimes_GCJ=yes - export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -15986,9 +16125,55 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else - ld_shlibs=no + ld_shlibs_GCJ=no + fi + ;; + + interix3*) + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_GCJ=no fi ;; @@ -16002,7 +16187,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_GCJ=no cat <&2 @@ -16023,6 +16208,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_GCJ=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + ;; + sunos4*) archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -16030,31 +16242,6 @@ EOF hardcode_shlibpath_var_GCJ=no ;; - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_cmds_GCJ="$tmp_archive_cmds" - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - if test $supports_anon_versioning = yes; then - archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ -cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ -$echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - else - archive_expsym_cmds_GCJ="$tmp_archive_cmds" - fi - else - ld_shlibs_GCJ=no - fi - ;; - *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' @@ -16065,16 +16252,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ ;; esac - if test "$ld_shlibs_GCJ" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_GCJ= - fi + if test "$ld_shlibs_GCJ" = no; then + runpath_var= + hardcode_libdir_flag_spec_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= fi else # PORTME fill in a description of your system's linker (not GNU ld) @@ -16086,7 +16268,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_GCJ=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_GCJ=unsupported @@ -16120,6 +16302,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ break fi done + ;; esac exp_sym_flag='-bexport' @@ -16138,7 +16321,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ link_all_deplibs_GCJ=yes if test "$GCC" = yes; then - case $host_os in aix4.012|aix4.012.*) + case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` @@ -16157,8 +16340,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_libdir_separator_GCJ= fi + ;; esac shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi else # not using gcc if test "$host_cpu" = ia64; then @@ -16166,11 +16353,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~ # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -16235,12 +16422,12 @@ rm -f conftest.err conftest.$ac_objext \ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_GCJ="-z nodefs" - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF @@ -16300,13 +16487,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag_GCJ=' ${wl}-bernotok' allow_undefined_flag_GCJ=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_GCJ=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_GCJ=' ' + whole_archive_flag_spec_GCJ='$convenience' archive_cmds_need_lc_GCJ=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -16319,7 +16504,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ld_shlibs_GCJ=no ;; - bsdi4*) + bsdi[45]*) export_dynamic_flag_spec_GCJ=-rdynamic ;; @@ -16340,57 +16525,57 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi old_archive_From_new_cmds_GCJ='true' # FIXME: Should let the user specify the lib program. old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' + fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_GCJ=yes ;; darwin* | rhapsody*) - if test "$GXX" = yes ; then - archive_cmds_need_lc_GCJ=no - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag_GCJ='-undefined suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_GCJ='-flat_namespace -undefined suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_GCJ='-flat_namespace -undefined suppress' - ;; - 10.*) - allow_undefined_flag_GCJ='-undefined dynamic_lookup' - ;; - esac - fi - ;; + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; esac - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_GCJ='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_GCJ='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_GCJ='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + archive_cmds_need_lc_GCJ=no hardcode_direct_GCJ=no hardcode_automatic_GCJ=yes hardcode_shlibpath_var_GCJ=unsupported - whole_archive_flag_spec_GCJ='-all_load $convenience' + whole_archive_flag_spec_GCJ='' link_all_deplibs_GCJ=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else - ld_shlibs_GCJ=no + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_GCJ=no + ;; + esac fi ;; @@ -16424,7 +16609,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu) + freebsd* | kfreebsd*-gnu | dragonfly*) archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes @@ -16447,47 +16632,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi export_dynamic_flag_spec_GCJ='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no - ;; - ia64*) - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no ;; *) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_GCJ=: hardcode_direct_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' @@ -16535,6 +16735,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_shlibpath_var_GCJ=no if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' export_dynamic_flag_spec_GCJ='${wl}-E' else @@ -16580,7 +16781,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi allow_undefined_flag_GCJ=' -expect_unresolved \*' archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec_GCJ='-rpath $libdir' @@ -16588,21 +16789,15 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_separator_GCJ=: ;; - sco3.2v5*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - export_dynamic_flag_spec_GCJ='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) no_undefined_flag_GCJ=' -z text' if test "$GCC" = yes; then + wlarc='${wl}' archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' else + wlarc='' archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' @@ -16611,8 +16806,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_shlibpath_var_GCJ=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; + *) + whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; esac link_all_deplibs_GCJ=yes ;; @@ -16669,36 +16874,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi fi ;; - sysv4.2uw2*) - archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) + no_undefined_flag_GCJ='${wl}-z,text' + archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_GCJ='${wl}-z ${wl}text' if test "$GCC" = yes; then - archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_GCJ=no ;; - sysv5*) - no_undefined_flag_GCJ=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_GCJ= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_GCJ='${wl}-z,text' + allow_undefined_flag_GCJ='${wl}-z,nodefs' + archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -16717,11 +16931,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 echo "${ECHO_T}$ld_shlibs_GCJ" >&6 test "$ld_shlibs_GCJ" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -16754,6 +16963,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_GCJ + pic_flag=$lt_prog_compiler_pic_GCJ compiler_flags=-v linker_flags=-v verstring= @@ -16886,7 +17096,7 @@ beos*) shlibpath_var=LIBRARY_PATH ;; -bsdi4*) +bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -16914,7 +17124,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -16944,7 +17155,7 @@ cygwin* | mingw* | pw32*) ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; @@ -16967,7 +17178,7 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. if test "$GCC" = yes; then sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` @@ -17002,8 +17213,17 @@ kfreebsd*-gnu) dynamic_linker='GNU ld.so' ;; -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -17021,14 +17241,19 @@ freebsd*) freebsd2*) shlibpath_overrides_runpath=yes ;; - freebsd3.01* | freebsdelf3.01*) + freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -17048,7 +17273,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -17088,6 +17313,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -17149,7 +17386,7 @@ linux*) libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) - echo '#line 17152 "configure"' > conftest.$ac_ext + echo '#line 17389 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -17168,7 +17405,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra" fi @@ -17230,8 +17467,13 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no - need_version=yes + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH @@ -17269,13 +17511,6 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - solaris*) version_type=linux need_lib_prefix=no @@ -17301,7 +17536,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -17334,6 +17569,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -17349,12 +17607,17 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 echo "${ECHO_T}$dynamic_linker" >&6 test "$dynamic_linker" = no && can_build_shared=no +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6 hardcode_action_GCJ= if test -n "$hardcode_libdir_flag_spec_GCJ" || \ - test -n "$runpath_var GCJ" || \ - test "X$hardcode_automatic_GCJ"="Xyes" ; then + test -n "$runpath_var_GCJ" || \ + test "X$hardcode_automatic_GCJ" = "Xyes" ; then # We can hardcode non-existant directories. if test "$hardcode_direct_GCJ" != no && @@ -17386,841 +17649,6 @@ elif test "$shlibpath_overrides_runpath" = yes || enable_fast_install=needless fi -striplib= -old_striplib= -echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - ;; - *) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -char (*f) () = shl_load; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != shl_load; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6 -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main () -{ -shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -char (*f) () = dlopen; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != dlopen; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6 -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main () -{ -dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_svld_dlopen=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main () -{ -dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_dld_link=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh @@ -18235,7 +17663,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -18336,6 +17764,12 @@ fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo @@ -18347,12 +17781,18 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_GCJ # Is the compiler the GNU C compiler? with_gcc=$GCC_GCJ +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + # An ERE matcher. EGREP=$lt_EGREP @@ -18412,7 +17852,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? @@ -18486,11 +17926,11 @@ striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=$lt_predep_objects_GCJ +predep_objects=\`echo $lt_predep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=$lt_postdep_objects_GCJ +postdep_objects=\`echo $lt_postdep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place before the objects being linked to create a # shared library. @@ -18502,7 +17942,7 @@ postdeps=$lt_postdeps_GCJ # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method @@ -18582,7 +18022,7 @@ variables_saved_for_relink="$variables_saved_for_relink" link_all_deplibs=$link_all_deplibs_GCJ # Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec @@ -18656,15 +18096,42 @@ lt_simple_link_test_code="$lt_simple_compile_test_code" # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + # Allow CC to be a program name with arguments. lt_save_CC="$CC" CC=${RC-"windres"} compiler=$CC compiler_RC=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + lt_cv_prog_compiler_c_o_RC=yes # The else clause should only fire when bootstrapping the @@ -18680,7 +18147,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -18781,6 +18248,12 @@ fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os # An echo program that does not interpret backslashes. echo=$lt_echo @@ -18792,12 +18265,18 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_RC # Is the compiler the GNU C compiler? with_gcc=$GCC_RC +gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\` +gcc_ver=\`gcc -dumpversion\` + # An ERE matcher. EGREP=$lt_EGREP @@ -18857,7 +18336,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks=$lt_need_locks # Do we need the lib prefix for modules? @@ -18931,11 +18410,11 @@ striplib=$lt_striplib # Dependencies to place before the objects being linked to create a # shared library. -predep_objects=$lt_predep_objects_RC +predep_objects=\`echo $lt_predep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects=$lt_postdep_objects_RC +postdep_objects=\`echo $lt_postdep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Dependencies to place before the objects being linked to create a # shared library. @@ -18947,7 +18426,7 @@ postdeps=$lt_postdeps_RC # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_RC +compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method @@ -19027,7 +18506,7 @@ variables_saved_for_relink="$variables_saved_for_relink" link_all_deplibs=$link_all_deplibs_RC # Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec +sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\` # Run-time system search path for libraries sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec @@ -20530,6 +20009,7 @@ s,@host@,$host,;t t s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t +s,@SED@,$SED,;t t s,@EGREP@,$EGREP,;t t s,@LN_S@,$LN_S,;t t s,@ECHO@,$ECHO,;t t diff --git a/api/libsangoma/examples/.svn/all-wcprops b/api/libsangoma/examples/.svn/all-wcprops new file mode 100644 index 0000000..c22dd3c --- /dev/null +++ b/api/libsangoma/examples/.svn/all-wcprops @@ -0,0 +1,35 @@ +K 25 +svn:wc:ra_dav:version-url +V 41 +/svn/libsangoma/!svn/ver/1/trunk/examples +END +sound.raw +K 25 +svn:wc:ra_dav:version-url +V 51 +/svn/libsangoma/!svn/ver/1/trunk/examples/sound.raw +END +priserver.c +K 25 +svn:wc:ra_dav:version-url +V 53 +/svn/libsangoma/!svn/ver/1/trunk/examples/priserver.c +END +librc +K 25 +svn:wc:ra_dav:version-url +V 47 +/svn/libsangoma/!svn/ver/1/trunk/examples/librc +END +Makefile +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/libsangoma/!svn/ver/1/trunk/examples/Makefile +END +README +K 25 +svn:wc:ra_dav:version-url +V 48 +/svn/libsangoma/!svn/ver/1/trunk/examples/README +END diff --git a/api/libsangoma/examples/.svn/entries b/api/libsangoma/examples/.svn/entries index df020f5..f2cd7d0 100644 --- a/api/libsangoma/examples/.svn/entries +++ b/api/libsangoma/examples/.svn/entries @@ -1,15 +1,15 @@ 8 dir -237 -svn://sangoma.freeswitch.org/libsangoma/trunk/examples -svn://sangoma.freeswitch.org +1 +https://www.sangomapbx.com/svn/libsangoma/trunk/examples +https://www.sangomapbx.com/svn/libsangoma -2007-05-29T18:03:36.038276Z -206 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root svn:special svn:externals svn:needs-lock @@ -24,7 +24,7 @@ svn:special svn:externals svn:needs-lock -2028fedf-720c-0410-83b8-d54a3e729fb0 +8fe45b59-3c47-0410-bdf9-e5d932a076a6 sound.raw file @@ -32,11 +32,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z da36acc78b83d5047481df0cca63d969 -2006-03-23T23:03:41.659017Z -26 -mikej +2008-02-28T18:51:53.196120Z +1 +root has-props priserver.c @@ -45,11 +45,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 9f83030c20158d91b7ec6bb7a9392dcb -2006-03-23T23:54:12.054610Z -27 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root librc file @@ -57,11 +57,11 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 5c222b74d68b1c7df3f937a9d6321d40 -2006-03-23T23:03:41.659017Z -26 -mikej +2008-02-28T18:51:53.196120Z +1 +root Makefile file @@ -69,11 +69,11 @@ file -2007-07-24T22:45:02.000000Z +2008-02-28T19:04:34.000000Z b58ee42eeb2d5e921bdab940a9fda738 -2007-05-29T18:03:36.038276Z -206 -ncorbic +2008-02-28T18:51:53.196120Z +1 +root README file @@ -81,9 +81,9 @@ file -2007-05-17T23:49:20.000000Z +2008-02-28T19:04:34.000000Z 40538792592cd766e4941d9b37dbaf56 -2006-03-23T23:03:41.659017Z -26 -mikej +2008-02-28T18:51:53.196120Z +1 +root diff --git a/api/libsangoma/libsangoma.c b/api/libsangoma/libsangoma.c index 6fc9025..aaea8a8 100644 --- a/api/libsangoma/libsangoma.c +++ b/api/libsangoma/libsangoma.c @@ -22,26 +22,18 @@ #include "libsangoma.h" #define DFT_CARD "wanpipe1" - -#ifndef WP_TDM_EVENT_FE_ALARM -#warning "Note: TDM FE ALARM not supported by driver" +#ifndef WP_TDM_FEATURE_FE_ALARM +#warning "Warning: TDM FE ALARM not supported by driver" #endif - -#ifndef WP_TDMAPI_EVENT_DTMF -#warning "Note: TDM DTMF EVENTS not supported by driver" +#ifndef WP_TDM_FEATURE_DTMF_EVENTS +#warning "Warning: TDM DTMF not supported by driver" #endif -#ifndef WP_TDMAPI_EVENT_RING -#warning "Note: TDM RING EVENTS not supported by driver" +#ifndef WP_TDM_FEATURE_EVENTS +#warning "Warning: TDM EVENTS not supported by driver" #endif -#ifndef WP_TDMAPI_EVENT_RXHOOK -#warning "Note: TDM RXHOOK EVENTS not supported by driver" -#endif - - - #if defined(WIN32) //extern int verbose; @@ -529,7 +521,7 @@ int sangoma_get_full_cfg(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) printf("\tusr_mtu_mru:\t%d\n",tdm_api->wp_tdm_cmd.usr_mtu_mru); printf("\tidle flag:\t0x%02X\n",tdm_api->wp_tdm_cmd.idle_flag); -#ifdef WP_TDM_EVENT_FE_ALARM +#ifdef WP_TDM_FEATURE_FE_ALARM printf("\tfe alarms:\t0x%02X\n",tdm_api->wp_tdm_cmd.fe_alarms); #endif @@ -774,7 +766,7 @@ int sangoma_tdm_write_rbs(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { -#ifdef WP_TDM_EVENT_TDM_API_EVENTS +#ifdef WP_TDM_FEATURE_EVENTS wp_tdm_api_event_t *rx_event; @@ -802,7 +794,8 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) } break; - + +#ifdef WP_TDM_FEATURE_DTMF_EVENTS case WP_TDMAPI_EVENT_DTMF: printf("%d: GOT DTMF EVENT\n",(int)fd); if (tdm_api->wp_tdm_event.wp_dtmf_event) { @@ -812,6 +805,7 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) rx_event->wp_tdm_api_event_dtmf_port); } break; +#endif case WP_TDMAPI_EVENT_RXHOOK: printf("%d: GOT RXHOOK EVENT\n",(int)fd); @@ -837,13 +831,13 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) } break; -#ifdef WP_TDM_EVENT_FE_ALARM - case WP_TDMAPI_EVENT_FE_ALARM: +#ifdef WP_TDM_FEATURE_FE_ALARM + case WP_TDMAPI_EVENT_ALARM: printf("%d: GOT FE ALARMS EVENT %i\n",(int)fd, - rx_event->wp_tdm_api_event_fe_alarm); + rx_event->wp_tdm_api_event_alarm); if (tdm_api->wp_tdm_event.wp_fe_alarm_event) { tdm_api->wp_tdm_event.wp_fe_alarm_event(fd, - rx_event->wp_tdm_api_event_fe_alarm); + rx_event->wp_tdm_api_event_alarm); } #endif @@ -854,13 +848,12 @@ int sangoma_tdm_read_event(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; #else - return -EINVAL; + printf("Error: Read Event not supported!\n"); + return -1; #endif } - -#ifdef WP_TDMAPI_EVENT_DTMF - +#ifdef WP_TDM_FEATURE_DTMF_EVENTS int sangoma_tdm_enable_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -920,12 +913,8 @@ int sangoma_tdm_disable_rm_dtmf_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; } - #endif - -#ifdef WP_TDMAPI_EVENT_RXHOOK - int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -940,8 +929,6 @@ int sangoma_tdm_enable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; } -NNN - int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { @@ -958,10 +945,6 @@ int sangoma_tdm_disable_rxhook_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) return 0; } -#endif - -#ifdef WP_TDMAPI_EVENT_RING - int sangoma_tdm_enable_ring_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -1149,40 +1132,39 @@ int sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { return tdm_api->wp_tdm_cmd.rbs_poll; } -#endif - -int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { - int err; + int err; - tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_HWEC; - err=sangoma_tdm_cmd_exec(fd,tdm_api); - if (err){ - return err; - } + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_ENABLE_HWEC; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } - return 0; + return 0; } -int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) +int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { - int err; + int err; - tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_HWEC; - err=sangoma_tdm_cmd_exec(fd,tdm_api); - if (err){ - return err; - } + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_DISABLE_HWEC; + err=sangoma_tdm_cmd_exec(fd,tdm_api); + if (err){ + return err; + } - return 0; + return 0; } + /*======================================================== * GET Front End Alarms * */ -#ifdef WP_TDM_EVENT_FE_ALARM +#ifdef WP_TDM_FEATURE_FE_ALARM int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) { int err; @@ -1198,4 +1180,26 @@ int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api) } #endif +/* get current Line Connection state - Connected/Disconnected */ +int sangoma_tdm_get_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char *current_status) +{ + int err; + + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_FE_STATUS; + err = sangoma_tdm_cmd_exec(fd, tdm_api); + *current_status = tdm_api->wp_tdm_cmd.fe_status; + + return err; +} + + +/* set current Line Connection state - Connected/Disconnected. valid only for ISDN BRI */ +int sangoma_tdm_set_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char new_status) +{ + tdm_api->wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_FE_STATUS; + tdm_api->wp_tdm_cmd.fe_status = new_status; + + return sangoma_tdm_cmd_exec(fd, tdm_api); +} + #endif /* WANPIPE_TDM_API */ diff --git a/api/libsangoma/libsangoma.h b/api/libsangoma/libsangoma.h index 438307a..fab9646 100644 --- a/api/libsangoma/libsangoma.h +++ b/api/libsangoma/libsangoma.h @@ -50,6 +50,7 @@ typedef unsigned __int32 u_int32_t; typedef HANDLE sng_fd_t; #else +/* L I N U X */ #include #include #include @@ -76,6 +77,7 @@ typedef HANDLE sng_fd_t; #ifdef WANPIPE_TDM_API # include #endif + #endif #define FNAME_LEN 50 @@ -176,15 +178,20 @@ int sangoma_tdm_disable_tone_events(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_get_fe_alarms(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); -int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); -int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); - - int sangoma_tdm_txsig_onhook(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_txsig_offhook(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_txsig_start(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); int sangoma_tdm_txsig_kewl(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); +int sangoma_tdm_enable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); +int sangoma_tdm_disable_hwec(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api); + +/* get current Line Connection state - Connected/Disconnected */ +int sangoma_tdm_get_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char *current_status); +/* set current Line Connection state - Connected/Disconnected. valid only for ISDN BRI */ +int sangoma_tdm_set_fe_status(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api, unsigned char new_status); + + #ifndef LIBSANGOMA_GET_HWCODING #define LIBSANGOMA_GET_HWCODING 1 #endif @@ -193,3 +200,4 @@ int sangoma_tdm_get_hw_coding(int fd, wanpipe_tdm_api_t *tdm_api); #endif /* WANPIPE_TDM_API */ #endif + diff --git a/api/libsangoma/libtool b/api/libsangoma/libtool index f9613b6..513bbc3 100755 --- a/api/libsangoma/libtool +++ b/api/libsangoma/libtool @@ -22,7 +22,7 @@ # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,11 +33,11 @@ SED="/bin/sed" # Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="/bin/sed -e s/^X//" +Xsed="/bin/sed -e 1s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. -if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # The names of the tagged configurations supported by this script. available_tags=" CXX F77" @@ -67,6 +67,12 @@ fast_install=yes # The host system. host_alias= host=i686-pc-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-pc-linux-gnu +build_os=linux-gnu # An echo program that does not interpret backslashes. echo="echo" @@ -78,12 +84,18 @@ AR_FLAGS="cru" # A C compiler. LTCC="gcc" +# LTCC compiler flags. +LTCFLAGS="-g -O2" + # A language-specific compiler. CC="gcc" # Is the compiler the GNU C compiler? with_gcc=yes +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` +gcc_ver=`gcc -dumpversion` + # An ERE matcher. EGREP="grep -E" @@ -143,7 +155,7 @@ max_cmd_len=32768 # Does compiler simultaneously support -c and -o options? compiler_c_o="yes" -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks="no" # Do we need the lib prefix for modules? @@ -192,7 +204,7 @@ soname_spec="\${libname}\${release}\${shared_ext}\$major" # Commands used to build and install an old-style archive. RANLIB="ranlib" old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" -old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" old_postuninstall_cmds="" # Create an old-style archive from a shared archive. @@ -204,9 +216,9 @@ old_archive_from_expsyms_cmds="" # Commands used to build and install a shared archive. archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ -cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ -\$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ - \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" + cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ + \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" postinstall_cmds="" postuninstall_cmds="" @@ -220,11 +232,11 @@ striplib="strip --strip-unneeded" # Dependencies to place before the objects being linked to create a # shared library. -predep_objects="" +predep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects="" +postdep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place before the objects being linked to create a # shared library. @@ -236,7 +248,7 @@ postdeps="" # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path="" +compiler_lib_search_path=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Method to check whether dependent libraries are shared objects. deplibs_check_method="pass_all" @@ -257,7 +269,7 @@ finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" finish_eval="" # Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" # Transform the output of nm in a proper C declaration global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" @@ -310,16 +322,16 @@ hardcode_automatic=no # Variables whose values should be saved in libtool wrapper scripts and # restored at relink time. -variables_saved_for_relink="PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=unknown # Compile-time system search path for libraries -sys_lib_search_path_spec=" /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../ /lib/i386-redhat-linux/4.1.1/ /lib/ /usr/lib/i386-redhat-linux/4.1.1/ /usr/lib/" +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../ /lib/i386-redhat-linux/4.1.1/ /lib/ /usr/lib/i386-redhat-linux/4.1.1/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib include ld.so.conf.d/*.conf /usr/local/lib " +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/local/lib /usr/lib/qt-3.3/lib " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" @@ -6768,6 +6780,12 @@ fast_install=yes # The host system. host_alias= host=i686-pc-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-pc-linux-gnu +build_os=linux-gnu # An echo program that does not interpret backslashes. echo="echo" @@ -6779,12 +6797,18 @@ AR_FLAGS="cru" # A C compiler. LTCC="gcc" +# LTCC compiler flags. +LTCFLAGS="-g -O2" + # A language-specific compiler. CC="g++" # Is the compiler the GNU C compiler? with_gcc=yes +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` +gcc_ver=`gcc -dumpversion` + # An ERE matcher. EGREP="grep -E" @@ -6844,7 +6868,7 @@ max_cmd_len=32768 # Does compiler simultaneously support -c and -o options? compiler_c_o="yes" -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks="no" # Do we need the lib prefix for modules? @@ -6893,7 +6917,7 @@ soname_spec="\${libname}\${release}\${shared_ext}\$major" # Commands used to build and install an old-style archive. RANLIB="ranlib" old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" -old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" old_postuninstall_cmds="" # Create an old-style archive from a shared archive. @@ -6918,11 +6942,11 @@ striplib="strip --strip-unneeded" # Dependencies to place before the objects being linked to create a # shared library. -predep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.1/crtbeginS.o" +predep_objects=`echo "/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.1/crtbeginS.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.1/crtendS.o /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../crtn.o" +postdep_objects=`echo "/usr/lib/gcc/i386-redhat-linux/4.1.1/crtendS.o /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../crtn.o" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place before the objects being linked to create a # shared library. @@ -6934,7 +6958,7 @@ postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path="-L/usr/lib/gcc/i386-redhat-linux/4.1.1 -L/usr/lib/gcc/i386-redhat-linux/4.1.1 -L/usr/lib/gcc/i386-redhat-linux/4.1.1/../../.." +compiler_lib_search_path=`echo "-L/usr/lib/gcc/i386-redhat-linux/4.1.1 -L/usr/lib/gcc/i386-redhat-linux/4.1.1 -L/usr/lib/gcc/i386-redhat-linux/4.1.1/../../.." | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Method to check whether dependent libraries are shared objects. deplibs_check_method="pass_all" @@ -6955,7 +6979,7 @@ finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" finish_eval="" # Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" # Transform the output of nm in a proper C declaration global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" @@ -7000,7 +7024,7 @@ hardcode_minus_L=no # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. -hardcode_shlibpath_var= +hardcode_shlibpath_var=unsupported # Set to yes if building a shared library automatically hardcodes DIR into the library # and all subsequent libraries and executables linked against it. @@ -7014,10 +7038,10 @@ variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COM link_all_deplibs=unknown # Compile-time system search path for libraries -sys_lib_search_path_spec=" /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../ /lib/i386-redhat-linux/4.1.1/ /lib/ /usr/lib/i386-redhat-linux/4.1.1/ /usr/lib/" +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../ /lib/i386-redhat-linux/4.1.1/ /lib/ /usr/lib/i386-redhat-linux/4.1.1/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib include ld.so.conf.d/*.conf /usr/local/lib " +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/local/lib /usr/lib/qt-3.3/lib " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" @@ -7064,6 +7088,12 @@ fast_install=yes # The host system. host_alias= host=i686-pc-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-pc-linux-gnu +build_os=linux-gnu # An echo program that does not interpret backslashes. echo="echo" @@ -7075,12 +7105,18 @@ AR_FLAGS="cru" # A C compiler. LTCC="gcc" +# LTCC compiler flags. +LTCFLAGS="-g -O2" + # A language-specific compiler. CC="f95" # Is the compiler the GNU C compiler? with_gcc=yes +gcc_dir=`gcc -print-file-name=. | /bin/sed 's,/\.$,,'` +gcc_ver=`gcc -dumpversion` + # An ERE matcher. EGREP="grep -E" @@ -7140,7 +7176,7 @@ max_cmd_len=32768 # Does compiler simultaneously support -c and -o options? compiler_c_o="yes" -# Must we lock files when doing compilation ? +# Must we lock files when doing compilation? need_locks="no" # Do we need the lib prefix for modules? @@ -7189,7 +7225,7 @@ soname_spec="\${libname}\${release}\${shared_ext}\$major" # Commands used to build and install an old-style archive. RANLIB="ranlib" old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib" -old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" old_postuninstall_cmds="" # Create an old-style archive from a shared archive. @@ -7201,9 +7237,9 @@ old_archive_from_expsyms_cmds="" # Commands used to build and install a shared archive. archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ -cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ -\$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ - \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" + cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ + \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" postinstall_cmds="" postuninstall_cmds="" @@ -7217,11 +7253,11 @@ striplib="strip --strip-unneeded" # Dependencies to place before the objects being linked to create a # shared library. -predep_objects="" +predep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place after the objects being linked to create a # shared library. -postdep_objects="" +postdep_objects=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Dependencies to place before the objects being linked to create a # shared library. @@ -7233,7 +7269,7 @@ postdeps="" # The library search path used internally by the compiler when linking # a shared library. -compiler_lib_search_path="" +compiler_lib_search_path=`echo "" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Method to check whether dependent libraries are shared objects. deplibs_check_method="pass_all" @@ -7254,7 +7290,7 @@ finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" finish_eval="" # Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" # Transform the output of nm in a proper C declaration global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" @@ -7313,10 +7349,10 @@ variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COM link_all_deplibs=unknown # Compile-time system search path for libraries -sys_lib_search_path_spec=" /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../ /lib/i386-redhat-linux/4.1.1/ /lib/ /usr/lib/i386-redhat-linux/4.1.1/ /usr/lib/" +sys_lib_search_path_spec=`echo " /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../i386-redhat-linux/lib/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../i386-redhat-linux/4.1.1/ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../ /lib/i386-redhat-linux/4.1.1/ /lib/ /usr/lib/i386-redhat-linux/4.1.1/ /usr/lib/" | $SED -e "s@${gcc_dir}@\${gcc_dir}@g;s@${gcc_ver}@\${gcc_ver}@g"` # Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/lib /usr/lib include ld.so.conf.d/*.conf /usr/local/lib " +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/local/lib /usr/lib/qt-3.3/lib " # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" diff --git a/api/libsangoma/svn-commit.2.tmp b/api/libsangoma/svn-commit.2.tmp new file mode 100644 index 0000000..48940b9 --- /dev/null +++ b/api/libsangoma/svn-commit.2.tmp @@ -0,0 +1,5 @@ +Added new event support +--This line, and those below, will be ignored-- + +M libsangoma.c +M libsangoma.h diff --git a/api/libsangoma/svn-commit.tmp b/api/libsangoma/svn-commit.tmp index d2cd19d..4965420 100644 --- a/api/libsangoma/svn-commit.tmp +++ b/api/libsangoma/svn-commit.tmp @@ -1,4 +1,5 @@ - +Added new event features --This line, and those below, will be ignored-- -A libsangoma.so.conf +M libsangoma.c +M libsangoma.h diff --git a/api/tdmapi/Makefile b/api/tdmapi/Makefile index 95689cd..5618efe 100644 --- a/api/tdmapi/Makefile +++ b/api/tdmapi/Makefile @@ -12,18 +12,21 @@ DEBUG = 2 SYSINC=$(shell if [ -f ../../.sysinclude ]; then cat ../../.sysinclude; else echo ""; fi) ifeq "$(SYSINC)" "" -SYSINC=/lib/modules/$(shell uname -r)/build/include +SYSINC=/usr/src/linux/include endif -SRCINC=../../patches/kdrivers/include VPATH = $(SYSINC) # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib/hdlc -I../lib -I$(SYSINC) -I$(SRCINC) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -DWANPIPE_TDM_API -D_DEBUG_=$(DEBUG) -D_GNUC_ -I../lib/hdlc -I../lib +CFLAGS += -I/usr/include/wanpipe +#CFLAGS = -I$(SYSINC) TARGETS = aft_tdm_voice_api +TARGETS += aft_tdm_voice_api_switch TARGETS += aft_tdm_hdlc_test TARGETS += aft_tdm_voice_api_rbs -#TARGETS += aft_tdm_voice_api_dtmf +TARGETS += aft_tdm_voice_api_dtmf +TARGETS += aft_tdm_voice_api_rm_events #TARGETS += aft_tdm_voice_api_rm_dtmf #TARGETS += aft_tdm_voice_api_rxhook @@ -32,9 +35,18 @@ TARGETS += aft_tdm_voice_api_rbs all: $(TARGETS) @echo "Ok." +install: + for x in $(TARGETS); do \ + install -D -m 755 $$x /usr/bin/$$x; \ + done; + + aft_tdm_voice_api: aft_tdm_voice_api.c ../lib/lib_api.c $(CC) $(CFLAGS) -o $@ $^ -lsangoma -lm +aft_tdm_voice_api_switch: aft_tdm_voice_api_switch.c ../lib/lib_api.c + $(CC) $(CFLAGS) -o $@ $^ -lsangoma -lm + aft_tdm_hdlc_test: aft_tdm_hdlc_test.c ../lib/hdlc/wanpipe_hdlc.c $(CC) $(CFLAGS) -o $@ $^ -lsangoma -lm @@ -44,6 +56,9 @@ aft_tdm_voice_api_rbs: aft_tdm_voice_api_rbs.c ../lib/lib_api.c aft_tdm_voice_api_dtmf: aft_tdm_voice_api_dtmf.c ../lib/lib_api.c $(CC) $(CFLAGS) -o $@ $^ -lsangoma -lm +aft_tdm_voice_api_rm_events: aft_tdm_voice_api_rm_events.c ../lib/lib_api.c + $(CC) $(CFLAGS) -o $@ $^ -lsangoma -lm + aft_tdm_voice_api_rm_dtmf: aft_tdm_voice_api_rm_dtmf.c ../lib/lib_api.c $(CC) $(CFLAGS) -o $@ $^ -lsangoma -lm diff --git a/api/tdmapi/aft_tdm_hdlc_test b/api/tdmapi/aft_tdm_hdlc_test new file mode 100755 index 0000000000000000000000000000000000000000..9b8d37b9b0f420d9ac49da2da96c44b7def1c4db GIT binary patch literal 14729 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 Wlj%76EPuwYYz7+4niK=Rz4<>if_name,&span,&chan); - printf("Socket bound %s to Span=%i Chan=%i\n\n",slot->if_name,span,chan); if (span > 0 && chan > 0) { wanpipe_tdm_api_t tdm_api; @@ -432,7 +431,7 @@ void process_con_tx(timeslot_t *slot) */ memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(wp_tdm_api_tx_hdr_t)); - slot->data=1; + slot->data=0; for (i=0;idata){ Tx_data[i+sizeof(wp_tdm_api_tx_hdr_t)] = slot->data; @@ -480,7 +479,7 @@ void process_con_tx(timeslot_t *slot) printf("TX DATA ORIG: Len=%i\n",Tx_hdlc_len); print_packet(&Tx_data[sizeof(wp_tdm_api_tx_hdr_t)],Tx_hdlc_len); #endif - wanpipe_hdlc_encode(hdlc_eng,&Tx_data[16],Tx_hdlc_len,&Tx_hdlc_data[16],(int*)&Tx_encoded_hdlc_len,&next_idle); + wanpipe_hdlc_encode(hdlc_eng,&Tx_data[16],Tx_hdlc_len,&Tx_hdlc_data[16],&Tx_encoded_hdlc_len,&next_idle); if (Tx_encoded_hdlc_len < (max_tx_len*2)){ int j; for (j=0;j<((max_tx_len*2) - Tx_encoded_hdlc_len);j++){ diff --git a/api/tdmapi/aft_tdm_voice_api b/api/tdmapi/aft_tdm_voice_api new file mode 100755 index 0000000000000000000000000000000000000000..bc238c9852a8591a46717ed7b571e67b199626e5 GIT binary patch literal 17436 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 literal 0 HcmV?d00001 diff --git a/api/tdmapi/aft_tdm_voice_api.c b/api/tdmapi/aft_tdm_voice_api.c index 4f1682e..c3bc330 100644 --- a/api/tdmapi/aft_tdm_voice_api.c +++ b/api/tdmapi/aft_tdm_voice_api.c @@ -414,7 +414,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage((unsigned char*)argv[0]); + usage(argv[0]); return -1; } diff --git a/api/tdmapi/aft_tdm_voice_api_dtmf b/api/tdmapi/aft_tdm_voice_api_dtmf new file mode 100755 index 0000000000000000000000000000000000000000..3ff0382ec0ea2761bda894e7350116c771f9f187 GIT binary patch literal 15943 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 XYSlw_}iLm< +* +* Copyright: (c) 2003-2004 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib_api.h" + +#define MAX_TX_DATA 5000 /* Size of tx data */ +#define MAX_FRAMES 5000 /* Number of frames to transmit */ + +#define MAX_RX_DATA 5000 + +unsigned short Rx_lgth; + +unsigned char Rx_data[MAX_RX_DATA]; +unsigned char Tx_data[MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)]; + +/* Prototypes */ +int MakeConnection(void); +void handle_span_chan( void); +void sig_end(int sigid); + +int dev_fd; +FILE *tx_fd=NULL,*rx_fd=NULL; +wanpipe_tdm_api_t tdm_api; + + +/*************************************************** +* HANDLE SOCKET +* +* o Read a socket +* o Cast data received to api_rx_element_t data type +* o The received packet contains 16 bytes header +* +* ------------------------------------------ +* | 16 bytes | X bytes ... +* ------------------------------------------ +* Header Data +* +* o Data structures: +* ------------------ +* typedef struct { +* union { +* struct { +* unsigned char _event_type; +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_event; +* struct { +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_rx; +* unsigned char reserved[16]; +* }wp_rx_hdr_u; +* #define wp_api_event_type wp_rx_hdr_u.wp_event._event_type +* #define wp_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits +* #define wp_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp +* } wp_tdm_api_rx_hdr_t; +* +* typedef struct { +* wp_tdm_api_rx_hdr_t hdr; +* unsigned char data[1]; +* } wp_tdm_api_rx_element_t; +* +* typedef struct { +* union { +* struct { +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_tx; +* unsigned char reserved[16]; +* }wp_tx_hdr_u; +* #define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp +* } wp_tdm_api_tx_hdr_t; +* +* typedef struct { +* wp_tdm_api_tx_hdr_t hdr; +* unsigned char data[1]; +* } wp_tdm_api_tx_element_t; +* +* #define WPTDM_A_BIT 0x08 +* #define WPTDM_B_BIT 0x04 +* #define WPTDM_C_BIT 0x02 +* #define WPTDM_D_BIT 0x01 +* +*/ + +void handle_span_chan(void) +{ + unsigned int Rx_count,Tx_count,Tx_length; + int err; + +#if 0 + int rlen; + int stream_sync=0; +#endif + + Rx_count = 0; + Tx_count = 0; + + if (tdm_api.wp_tdm_cmd.hdlc) { + Tx_length = tx_size; + } else { + Tx_length = tdm_api.wp_tdm_cmd.usr_mtu_mru; + } + + printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i\n", + read_enable,write_enable,tx_cnt,tx_size,tx_delay); + + sangoma_tdm_enable_dtmf_events(dev_fd, &tdm_api); + + /* Main Rx Tx OOB routine */ + for(;;) { + + err = sangoma_socket_waitfor(dev_fd, 1000, POLLPRI); + printf("ret:%d\n", err); + if (err){ + err=sangoma_tdm_read_event(dev_fd,&tdm_api); + if(err < 0 ) { + printf("Failed to receive EVENT %d\n", err); + break; + } + + printf("GOT OOB EXCEPTION CMD Exiting\n"); + } + + if (++Rx_count >= rx_cnt){ + break; + } + + } + + sangoma_tdm_disable_dtmf_events(dev_fd, &tdm_api); + if (tx_fd){ + fclose(tx_fd); + } + if (rx_fd){ + fclose(rx_fd); + } + close (dev_fd); + + return; +} + +int dtmf_event (int fd, unsigned char digit, unsigned char type, unsigned char port) +{ + printf("%d: DTMV Event: %c (%s:%s)!\n", + fd, + digit, + (port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", + (type == WAN_EC_TONE_PRESENT)?"PRESET":"STOP"); + return 0; +} + + +/*************************************************************** + * Main: + * + * o Make a socket connection to the driver. + * o Call handle_span_chan() to read the socket + * + **************************************************************/ + + +int main(int argc, char* argv[]) +{ + int proceed; + + proceed=init_args(argc,argv); + if (proceed != WAN_TRUE){ + usage(argv[0]); + return -1; + } + + signal(SIGINT,&sig_end); + memset(&tdm_api,0,sizeof(tdm_api)); + tdm_api.wp_tdm_event.wp_dtmf_event = &dtmf_event; + + printf("TDM DTMF PTR = %p\n",tdm_api.wp_tdm_event.wp_dtmf_event); + + dev_fd =-1; + + dev_fd = sangoma_open_tdmapi_span_chan(atoi(card_name),atoi(if_name)); + if( dev_fd < 0){ + printf("Failed to open span chan(%s:%d,%s:%d)\n", + card_name,atoi(card_name),if_name,atoi(if_name)); + exit (1); + } + printf("HANDLING SPAN %i CHAN %i FD=%i\n", + atoi(card_name),atoi(if_name),dev_fd); + + sangoma_tdm_set_codec(dev_fd,&tdm_api,WP_NONE); + sangoma_get_full_cfg(dev_fd, &tdm_api); + + handle_span_chan(); + close(dev_fd); + return 0; + + return 0; +}; + + +void sig_end(int sigid) +{ + + printf("Got Signal %i\n",sigid); + + sangoma_tdm_disable_dtmf_events(dev_fd, &tdm_api); + + if (tx_fd){ + fclose(tx_fd); + } + if (rx_fd){ + fclose(rx_fd); + } + + if (dev_fd){ + close (dev_fd); + } + + exit(1); +} + + + diff --git a/api/tdmapi/aft_tdm_voice_api_rbs b/api/tdmapi/aft_tdm_voice_api_rbs new file mode 100755 index 0000000000000000000000000000000000000000..d81f68c051640bbd2e982ecf89ea5dbd8ca4ad8b GIT binary patch literal 17940 zcmeHPdvsjIc^|z%7BVXvV+b*DiLfy_mMqC~@Jo(mX>B=`<+UU~2#;mGyV6~=+Ff?< z+A>W+L=r(L3d*CWBxxHvCW%`JrRf2K(_n#JjB`?s1Du4EHi6(YE6W%YTw@-M`uoje zb@hNa|M&WgW`6U1^UXKkd^30U&W!K&Hm=FZ$r0ws6?uZlzCXXP8u5}UMX45+xKPX& zbHpda1;`?;x(hrAuOZD)fRK-nhcF95X5Eut$Z!cT18J1aARm+!2-jXG1Ov;95=EDJ z`$0oEUMNJxA|dM~Jr`_Cz`q1EhF5?Ys2A&Cn2$>4qizNZn8DCC{>}*jPI^rFh0(~i zh0#!1G!jd9mZ#$7umQ`WYN`9$rcJUe^&P_>GTzbsN+i! ze*)n`jprct=yWOKt95!N;>!^}g+QAYA$$^n&s7K(6Z*NvBt9l)yI`u1d}N=1I!$w+ zE5<#v8K28kBxWGK7-1Fy{lGj|A~9WqVja_-6Q5hPGAlq}TPcryOuiZ7?NMX52r%jY zp!x66cp+jw%MnNqYx+enKJnKy{*9*hYdjY*>33-S4Nb4m_>9Ku5%c*p0{MTU>7UW~ zcEo%V2&6|f{b9t!cOwkmr`j_Uz1IuO$3h_83qETozmWYh16FO+;M9{9{- zA@NU||4yW--*ku+qTUB9kQ=v@EKWW)(~q}u&Xs3V&h zPlRL42qYr@R3Z@b2kk&CO9jCnjs>_A z1}GAW#Qf=0I0PnYuN&17h{S|H911uA5VoaKDj!*~kXYNeZgri%s(ev4Rhdmyz*TbP z%*a_gH~UY`_=ZASj(i6&hw~j{{xc=$erk@*6Y~JfoOekig6S|{6hj2_W=NbTW@}s` zajvjf1)dU&sSEJ(;M`DvNznqn5b~~NjEd(oMnwx4W74i*jLEs0Fk=0?WQ%*PlLc`IWmxRo&m)Xj|X;<=46URoi>c-h&E@e+tK#)~Y$ z7?ZWb7%!+!#(0T+fw3h-7vpP$=wbXRA?{<0m*}Rx-*ulX%)E`JW$MxP%wItG(L-W% z@#WwcojV7AX^+vlw1Caz@N1)Z=F$>2X~V}PrbTR;c6dl)TE^z9bNDfdX(8Jp-YqdL zWzQ!bl$aK?D~P)!rseD<#0iOML3dJ@n_>^`|x0XVP+xPb7pW5eczHn0ddnkhwd&DqPf5OLr{8$ zoZQi4TW>mgXi)ONKe}qJ@H9$U(I}5=9Vn~J4!pi%+$O+&qK(_^!w^BDXCM0)XeU4qv=!k-JH!yp4z;9 zmOTVTQGW*Flm9z9I`Fuy#0?&>pl#()-_HkrV#AgnzVk4X8Bk@i?_ETDSg!BcXHFD! zzjn3f;hw){;mMgO-c`f)2F`~eF3?E944STBR#hH^Lg;Y7@|E0DFl#3n`i!o9M* z)m20H6OMxlzOo$^wDk_P?cE1$JUtzN{nJ}PAC-RId(_j*#cuac==C8_&sNw>frzJP zAPZuio^ND9r>E!3G_5kzUB%0#D9^pGK!jHQCL}plPZn+$p8ayn`0PPc3ytaR8#7Da z*Di9`+Wsq*LL6?ruX=ixBi=arIHAuzOUukrmN7lsGY=%#-IsaeJ!!JxOOcV;0g?Tp z`&@~q_iv$Je+|XB(LRMTd@*~gwp=RIc<7~J+kCZ1sIg)?vXPN#- zq$^)VZ?tvS&~(DNPPNDLL^mz(v)7QV8*Fu+{RLzJ^U_!D{!fmJqRdZ~V#cn$`;^9Z z6HC1*i5Ncak(^N_=&Rq=%r}yGm2TpI&I~g1VJ#tNkI1po8aNsWyHQV=6@Q+k&#@%~nDAV~e{{VvYdo+_e z78t^yDlvS9UX3~SL5jIZWsdBZ9$-Jpye-Hx!vonq`=`vUMJ|l~UrcX0Cwp_`9yx~> zd!FzX`$p4+_BYs~%fVPVbo3D48$P^Sx=&u-e@k%-=$ZfFC^}ry;OWh!lVYIF`Wjp< zH#18LEVdtli)(9VELK?1h)HlC-bOdxWHYjlv;N0b{YMHooH65!ZWr5&Q0`O1AZ}Ge zot2NQzC)QhWZwAs7GLK6cctpRLwi})bKiihajf(eQkGGRu6(g_=1K!iV zmdw30+zYv|9cX>tlOy}o`lb71wDMKhZ|R{U-qW&C1-oJP%F0S{q~J9;YE@O0XggA{ z3dy>q&lRjjEdFY914KZ6|EA*pS>Nj0^yRK)W$7JgcqE-b!$o@gKq_Z>`lRQ9Vf@nA zxZMM@k2(+LtI=@ce>jRN(Cf4@R2p2KF6?{f3;*1IB{MmVe?h)$s)>$zdU}aAo$h_{ zNfz+*3;`Q64)&|sFGuaE^i0$qNf*=Xo}M?s-FH^gSAZT&e@1FoVYGVy+WE$`(>+vft^KWM`IAQ+AZ{>TQ zp3yI)|9E=lgQljLjhWxRBL~Y~E@Otj38{kzmrsy+n~_;fnRiSr^KzHWuV|Tke-C>h z^EtU-&4C;^khIuBnaky0&Pe9qYSvhoZH1@jS+@Uk%*BsO-8N6}yGR>da?mT8-=U%@ z+V_e}mt3t2*KEU2;hkaxdDn$!zJ|VY%K#Z$1tI!?WSB2Y*IUuHp7sBkF(Q z)xPZ^Glg+_%v=Xi!>hTngp8Lc<3-)4o#@lye*-vpVuHXbBamNXTmm`EW`1!R0^i0O zivr)Kz#j zq%&WE29p%@^xOlQQS#waO36klxeco%>h(R=aY}c1h_%12!9h}9)?kp7BO3gYlmi;P zL-0clO1=-UTZ1x!uWK+Q+podrNZAE&Fo=|U;Aua<`;N>{pzWjvIgO?v}TSLwThx%;xZ1cNl<6M_RYK>05ogxASqrA4ihW^z$)Y5C%~rG9PfPJ z^Ec1ptH+XOVNy@;T@Z@J+TE3z#FVPcGlu=@h%)S9_ECdYlj?Vf~|N7I{zqjU@_i~rM(D#1w6c)a60dLmpM&KWJ8R~KtXBMu;BQ^b zQHjQIOeN~W(ZDVwi^Q5hBpMD`PTWd{gW<@Iu(e^sY74~{;1A}xxuIp&+6}E%^XeAM zyV={+3gJkuUf0@EQ_(qhE2qMS+NS!(bxmun7GG@>%hn->@tS&B2g_5ccWa&3*Sc;) zlU29A-tuCEzJSy{g?*}JRtx^JIRa+eio#|FwZqFLz~A{!di z?$}n1{>NYerdFxue^+Kn>E@Y+H zhH}DIBxTJ_6^SA*w~(}fpt2>maEe;&c+#=jl7Wt}F?pQ5yLrOLe`|CxuzID*Z+SF3J*1N2z2+0-k z1b3fOE3FmbPA3_#3?>zw<85x<(7eoQid)Utv9r*OE!f#+8@Rn;hP&CiF*p5In z60+8D2dym-3|mcT8aO7y_ZBlzk9$&isWNtV-Tr6PBR7g!zXlw)lRTLCK+ zX^%Kl=>^^p{dP*`2|6Z{ap!#aC=+foCF{iYP}kHA7WV+pi=R69(H&DVPtdm`(CP0; zN3m@hJ1>4ZNGu#posaBLB+wq4igAJt!2tFw&x7xVZ4t+^L($-$!)w8}(r~5;b%r9C zcId!=iateMW!M20WlkqdCd!g3ayscw%$2TUs)PGa^lGgLDAGY=($!gx+p~!M=xaaw znz9v$bcB;6wPDI+u8b!%2u=cht`TLSKq!~&?JJaZptF8K-WWOo>-S`=9C5X(3(`0YZy(U!9H?`(bAKM zt)12ySYFR16D-pFaYQo`(GK@O6J-JT-i|O1P)ux=n{ARJsuU(^$b_xE|WiRXLxGoR;b z@XKKR8g&(DA)&$RIz6}J23`Kl+s zlwZj7KEyoR!gAR65nP<(w{F}oys}RZ&Rw6VZ+=}pV zidJB;HWi(1Wxw#DO^Mx4QBn47y{u?jS;VqdMA|sr*q8 zW&wyvS!nD}DUak>>gW&1JI5$8RVoknSYe(Ff+7SHURflSH@Pj@5w!V{lAbI~BxI*tL?KCSP;YrfJ_~VIN*g@nAe^t;S*m zN8y%PY&9vW4;JVySYTDxtZ&)0z*l)renVO1VpCPM#llz^$F0i6(zx!or{y-q zx;Bd)$AyGdQ)5+~myYA4!KLZIW8QT>tqkG^QaG6AyWR?=6VV8c>|rY4FSpcrsi6Hk zgkLCflqGOx(Ml(zD)^}wyj?kW_C4-yvv%_vq^CCEC2x6S?U5Mf_mA;_${Jm)qNYBQ zl5;jk57q(WMnQdc`CP#t{gzd^48Qj+D+WhhX4OWc7*L&6i!FM)94%wN4&{uGrAt;G zJhdr1<7fR2I?fMa#;=hRzFe=kON1gAtN0}nbSz0zO;RP~Y%NzhA5lWm;wdK*)ODZ) z-UEMNkK906uZ!IdXE?;C-Ra8`0R#jG6^PBOpq9Nd@{IaFx-p1}@cV{;%B3__5@%;o2wyPpwaC4|`V(m!{gi7mu4mHRW;KsluazQ$Uxmph z?`?o!A#EP6qxn=Ka4k(fuB#is$1~-I&Y0l_1g@>g$Mtp>5(xyB1-s+{nn%yqeW$jfIf0+yI@lDMwE0?IZaZR%w{Ln{K;;!JZrZi8nCC$h7R)DVpe5cSB^BBGd zkU@FmvwncPJJ*fLAg|&3Ceq|%-|<5(?+dwqAQ-;gF1`ieTksKlKXCE!Olb8-)cXkd zXk*qZ?;nAW{lWg_!+NR5;|NB-5`0)MnLnmGNRp4d2V8u!z&8tgon+7tc^D2M7{S$UL2V0Wsy7hkRRH879f!o0Mf9KL+404M1%8 z7_-mJ^B^vmSa4j9e|~{y8|dHkWw*R1F#vC-LG@$g8SIWZe-Nu1YHFTPSk=t=Kw(t_ z$GyU=U5#&rRd1Q!$9b|x)p%8OWmt|&g=Hi-{uE{_#_sXt3Hb&U98ZeQkqLSFH*KE$ zDxkgxC_29msBxh1#S+us6;?OD=+_F51aUoi@}}BYM&7s)PySCzzxc9le=gduG*)HuaZic& z+f4g%;2CsL)4m*VF99~~%Mmk$7np~;5kdBBu@3RI(3k#_gPCp<;>TR|-41-*g(ud( z6ZHAoeyqO-*nDGP{a*z({gH#4c;5kb>+>-1X&hlk1ivp9&oH4Mw(nO4ASQkTF%PxP zgKJU$H-UMAhn_hD_zYq`=3dkVXc&(ys(Vbu;$q;gjN!jbTnTKx)9_v#zdiAZAkZ6@ z1M@VGl7E?44a`HpWaGWECL{(SpZzcs`nQsR=MDsxH}~e2YupVw=WQkLVsXFbH}~pz zyq4z;Onnb&`fqgkCp0$q?4AeanTrtU)Q9)Vcu^}hC#P>{eXaw3Nc+=_+}WZUnD-J^OM0=W2j)R)9;{~h zMqnOqG3~n%m=F7n_KIpuKPJ8(n8)4>|DdL0T9ouhG)`zd1k3~FhW|NDe;Dngyk7vj z?+yMZ@NF*s46rE-+6}8F?6#q5|!kC+jN~g}^)wXXrD4xdE*3Z1G88J{AJ& zuLS1&VEF5RAA$dH4MhLh0(|W2_>PCEkT?L$oqEIH4$Si*2FHQT{7C*Cz#l^1%UWJP zFduX8Zy#_;Kl&3>H~F8^^m=Wd7l3&v*Yy7{fZhHv49pWorv5X)JYEw*9kkc`q{BYV zz?5GEMjlQw@@4`TqC9otJn|3izD5|a8`#Xh7RG-{ z(~W=h0&_h@nKN;7wjY?s4#-A*zpDAoJl+k>ythY}0=w^p zt_0>|=D!WVJl39wQgwkH?C`G#jQ@izkVG0TwRuwD6bIs zNrw+Mfo-yV%`3q<|$hoL`^?iBI|qd%1H=-6dMdz>)#QN1jBybtHm8yD38mVL`X3&oeH#v1$G9x;iztxu3Ba8ZC3E^ zsJzKZ2K7mV`|^L{PA@(QQ<}O>E5C6z%JS1)K33cq1H~n{E@Ei z+PcM~M^kY>J~`ox3WUg;vB6YYT_0}N#oXV>d1)6PqLOYQ=4SNN*PJ8LniH?)PF0>3 zHy5GNV{IXML)gu!u1ABG-3Z2hb4MV_HuHlVJwa_Ur*$li!0ycMYLB}Wt;{KJSIaxg z?#g)2I=dOEw)O?ToWRQMDagYPz6hoK{EjE|wc$h{nS!&L9ZXpWX5|+h*EMK&CCc+#U6E8x$_3}$oyB$jV z`h<(-^efYNdHH*s5czRQZK$dX+hf#90T&%>S0WkKw#|C5+>VD2Msb{IT&Im)W!L7H zo8a7K853W@uE}-;LH0v%_P+Pj_uzT+Ti#}O3&RkQMpU=Y-4xmbGm)Hw(3v~{V(zND z*`R>?o4Iic*L`<4_c-gTex7iPJrv%-0YbfarQOvH934DwG4+Lh*LC@^3Kv1b_zqBY Oax|fTK^^!10Q?_{QPKzi literal 0 HcmV?d00001 diff --git a/api/tdmapi/aft_tdm_voice_api_rbs.c b/api/tdmapi/aft_tdm_voice_api_rbs.c index efaa45f..7e1a696 100644 --- a/api/tdmapi/aft_tdm_voice_api_rbs.c +++ b/api/tdmapi/aft_tdm_voice_api_rbs.c @@ -449,7 +449,7 @@ int main(int argc, char* argv[]) proceed=init_args(argc,argv); if (proceed != WAN_TRUE){ - usage((unsigned char*)argv[0]); + usage(argv[0]); return -1; } diff --git a/api/tdmapi/aft_tdm_voice_api_rm_dtmf b/api/tdmapi/aft_tdm_voice_api_rm_dtmf new file mode 100755 index 0000000000000000000000000000000000000000..816376169f36ee2420655c224bab94dd239d6c25 GIT binary patch literal 17898 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 literal 0 HcmV?d00001 diff --git a/api/tdmapi/aft_tdm_voice_api_rm_dtmf.c b/api/tdmapi/aft_tdm_voice_api_rm_dtmf.c new file mode 100644 index 0000000..872947a --- /dev/null +++ b/api/tdmapi/aft_tdm_voice_api_rm_dtmf.c @@ -0,0 +1,445 @@ +/***************************************************************************** +* aft_api.c AFT T1/E1: HDLC API Sample Code +* +* Author(s): Nenad Corbic +* +* Copyright: (c) 2003-2004 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib_api.h" + +#define MAX_TX_DATA 5000 /* Size of tx data */ +#define MAX_FRAMES 5000 /* Number of frames to transmit */ + +#define MAX_RX_DATA 5000 + +unsigned short Rx_lgth; + +unsigned char Rx_data[MAX_RX_DATA]; +unsigned char Tx_data[MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)]; + +/* Prototypes */ +int MakeConnection(void); +void handle_span_chan( void); +void sig_end(int sigid); + +int dev_fd; +FILE *tx_fd=NULL,*rx_fd=NULL; +wanpipe_tdm_api_t tdm_api; + + +/*************************************************** +* HANDLE SOCKET +* +* o Read a socket +* o Cast data received to api_rx_element_t data type +* o The received packet contains 16 bytes header +* +* ------------------------------------------ +* | 16 bytes | X bytes ... +* ------------------------------------------ +* Header Data +* +* o Data structures: +* ------------------ +* typedef struct { +* union { +* struct { +* unsigned char _event_type; +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_event; +* struct { +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_rx; +* unsigned char reserved[16]; +* }wp_rx_hdr_u; +* #define wp_api_event_type wp_rx_hdr_u.wp_event._event_type +* #define wp_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits +* #define wp_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp +* } wp_tdm_api_rx_hdr_t; +* +* typedef struct { +* wp_tdm_api_rx_hdr_t hdr; +* unsigned char data[1]; +* } wp_tdm_api_rx_element_t; +* +* typedef struct { +* union { +* struct { +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_tx; +* unsigned char reserved[16]; +* }wp_tx_hdr_u; +* #define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp +* } wp_tdm_api_tx_hdr_t; +* +* typedef struct { +* wp_tdm_api_tx_hdr_t hdr; +* unsigned char data[1]; +* } wp_tdm_api_tx_element_t; +* +* #define WPTDM_A_BIT 0x08 +* #define WPTDM_B_BIT 0x04 +* #define WPTDM_C_BIT 0x02 +* #define WPTDM_D_BIT 0x01 +* +*/ + +void handle_span_chan(void) +{ + unsigned int Rx_count,Tx_count,Tx_length; + wp_tdm_api_rx_element_t* api_rx_el; + wp_tdm_api_tx_element_t * api_tx_el; + fd_set ready,write,oob; + int err,i; + +#if 0 + int rlen; + int stream_sync=0; +#endif + + Rx_count = 0; + Tx_count = 0; + + if (tdm_api.wp_tdm_cmd.hdlc) { + Tx_length = tx_size; + } else { + Tx_length = tdm_api.wp_tdm_cmd.usr_mtu_mru; + } + + printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i\n", + read_enable,write_enable,tx_cnt,tx_size,tx_delay); + + /* Initialize the Tx Data buffer */ + memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)); + + /* Cast the Tx data packet with the tx element + * structure. We must insert a 16 byte + * driver header, which driver will remove + * before passing packet out the physical port */ + api_tx_el = (wp_tdm_api_tx_element_t*)&Tx_data[0]; + + + /* Create a Tx packet based on user info, or + * by deafult incrementing number starting from 0 */ + for (i=0;idata[i] = (unsigned char)i; + }else{ +#if 0 + api_tx_el->data[i] = (unsigned char)tx_data+(i%4); +#else + api_tx_el->data[i] = (unsigned char)tx_data; +#endif + } + } + + sangoma_tdm_enable_rm_dtmf_events(dev_fd, &tdm_api); + + /* Main Rx Tx OOB routine */ + for(;;) { + + /* Initialize all select() descriptors */ + FD_ZERO(&ready); + FD_ZERO(&write); + FD_ZERO(&oob); + FD_SET(dev_fd,&oob); + FD_SET(dev_fd,&ready); + + if (write_enable){ + FD_SET(dev_fd,&write); + } + + /* Select will block, until: + * 1: OOB event, link level change + * 2: Rx data available + * 3: Interface able to Tx */ + + if(select(dev_fd + 1,&ready, &write, &oob, NULL)){ + + fflush(stdout); + if (FD_ISSET(dev_fd,&oob)){ + + /* An OOB event is pending, usually indicating + * a link level change */ + + err=sangoma_tdm_read_event(dev_fd,&tdm_api); + + if(err < 0 ) { + printf("Failed to receive OOB %i , %i\n", Rx_count, err); + err = ioctl(dev_fd,SIOC_WANPIPE_SOCK_STATE,0); + printf("Sock state is %s\n", + (err == 0) ? "CONNECTED" : + (err == 1) ? "DISCONNECTED" : + "CONNECTING"); + break; + } + + printf("GOT OOB EXCEPTION CMD Exiting\n"); + } + + + if (FD_ISSET(dev_fd,&ready)){ + + /* An Rx packet is pending + * 1: Read the rx packet into the Rx_data + * buffer. Confirm len > 0 + * + * 2: Cast Rx_data to the api_rx_element. + * Thus, removing a 16 byte header + * attached by the driver. + * + * 3. Check error_flag: + * CRC,Abort..etc + */ + + memset(Rx_data, 0, sizeof(Rx_data)); + + err = sangoma_readmsg_tdm(dev_fd, + Rx_data, + sizeof(wp_tdm_api_rx_hdr_t), + &Rx_data[sizeof(wp_tdm_api_rx_hdr_t)], + MAX_RX_DATA, 0); + + + if (!read_enable){ + goto bitstrm_skip_read; + } + + /* err indicates bytes received */ + if(err <= 0) { + printf("\nError receiving data\n"); + break; + } + + api_rx_el = (wp_tdm_api_rx_element_t*)&Rx_data[0]; + + /* Check the packet length */ + Rx_lgth = err; + if(Rx_lgth<=0) { + printf("\nShort frame received (%d)\n", + Rx_lgth); + return; + } + +#if 0 + if (api_rx_el->data[0] == tx_data && api_rx_el->data[1] == (tx_data+1)){ + if (!stream_sync){ + printf("GOT SYNC %x\n",api_rx_el->data[0]); + } + stream_sync=1; + }else{ + if (stream_sync){ + printf("OUT OF SYNC: %x\n",api_rx_el->data[0]); + } + } +#endif + + ++Rx_count; + + if (verbose){ + printf("Received %i Length = %i\n", + Rx_count,Rx_lgth); +#if 1 + printf("Data: "); + for(i=0;idata[i]); + } + printf("\n"); +#endif + }else{ + //putchar('R'); + } + + +#if 0 + switch(api_rx_el->hdr.wp_api_event_type){ + case WP_TDM_EVENT_DTMF: + printf("DTMV Event: %c (%s:%s)!\n", + api_rx_el->hdr.wp_api_event_dtmf_digit, + (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_ROUT)?"ROUT":"SOUT", + (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_PRESET)?"PRESET":"STOP"); + break; + case WP_TDM_EVENT_RXHOOK: + printf("RXHOOK Event: %s!\n", + (api_rx_el->hdr.wp_api_event_rxhook_state&WP_TDM_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK"); + break; + case WP_TDM_EVENT_RING: + printf("RING Event: %s!\n", + (api_rx_el->hdr.wp_api_event_ring_state&WP_TDM_EVENT_RING_PRESENT)?"PRESENT":"STOP"); + break; + } +#endif + if (rx_cnt > 0 && Rx_count >= rx_cnt){ + break; + } +bitstrm_skip_read: +; + } + + if (FD_ISSET(dev_fd,&write)){ + + + err = sangoma_writemsg_tdm(dev_fd, + Tx_data,16, + &Tx_data[16], Tx_length, + 0); + if (err <= 0){ + if (errno == EBUSY){ + if (verbose){ + printf("Sock busy try again!\n"); + } + /* Socket busy try sending again !*/ + }else{ + printf("Faild to send %i \n",errno); + perror("Send: "); + break; + } + }else{ + + ++Tx_count; + + if (verbose){ + printf("Packet sent: Sent %i : %i\n", + err,Tx_count); + }else{ + //putchar('T'); + } + } + } + + if (tx_delay){ + usleep(tx_delay); + } + + if (tx_cnt && tx_size && Tx_count >= tx_cnt && !(files_used & TX_FILE_USED)){ + + write_enable=0; + if (rx_cnt > 0){ + /* Dont break let rx finish */ + }else{ + break; + } + } + } + } + + sangoma_tdm_disable_rm_dtmf_events(dev_fd, &tdm_api); + if (tx_fd){ + fclose(tx_fd); + } + if (rx_fd){ + fclose(rx_fd); + } + close (dev_fd); + + return; +} + +int dtmf_event (int fd, unsigned char digit, unsigned char type, unsigned char port) +{ + printf("%d: DTMV Event: %c (%s:%s)!\n", + fd, + digit, + (port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", + (type == WAN_EC_TONE_PRESENT)?"PRESET":"STOP"); + return 0; +} + +/*************************************************************** + * Main: + * + * o Make a socket connection to the driver. + * o Call handle_span_chan() to read the socket + * + **************************************************************/ + + +int main(int argc, char* argv[]) +{ + int proceed; + + proceed=init_args(argc,argv); + if (proceed != WAN_TRUE){ + usage(argv[0]); + return -1; + } + + signal(SIGINT,&sig_end); + memset(&tdm_api,0,sizeof(tdm_api)); + tdm_api.wp_tdm_event.wp_dtmf_event = &dtmf_event; + + printf("TDM DTMF PTR = %p\n",tdm_api.wp_tdm_event.wp_dtmf_event); + + dev_fd =-1; + + dev_fd = sangoma_open_tdmapi_span_chan(1,1/*atoi(card_name),atoi(if_name)*/); + if( dev_fd < 0){ + printf("Failed to open span chan:%s:%s\n",card_name,if_name); + exit (1); + } + printf("HANDLING SPAN %i CHAN %i FD=%i\n", + atoi(card_name),atoi(if_name),dev_fd); + + sangoma_tdm_set_codec(dev_fd,&tdm_api,WP_NONE); + sangoma_get_full_cfg(dev_fd, &tdm_api); + + handle_span_chan(); + close(dev_fd); + return 0; + + return 0; +}; + + +void sig_end(int sigid) +{ + + printf("Got Signal %i\n",sigid); + + sangoma_tdm_disable_rm_dtmf_events(dev_fd, &tdm_api); + + if (tx_fd){ + fclose(tx_fd); + } + if (rx_fd){ + fclose(rx_fd); + } + + if (dev_fd){ + close (dev_fd); + } + + exit(1); +} + + + diff --git a/api/tdmapi/aft_tdm_voice_api_rxhook b/api/tdmapi/aft_tdm_voice_api_rxhook new file mode 100755 index 0000000000000000000000000000000000000000..817dddcce96179740e3477228be04f2795f9f46a GIT binary patch literal 17638 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 +* +* Copyright: (c) 2003-2004 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib_api.h" + +#define MAX_TX_DATA 5000 /* Size of tx data */ +#define MAX_FRAMES 5000 /* Number of frames to transmit */ + +#define MAX_RX_DATA 5000 + +unsigned short Rx_lgth; + +unsigned char Rx_data[MAX_RX_DATA]; +unsigned char Tx_data[MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)]; + +/* Prototypes */ +int MakeConnection(void); +void handle_span_chan( void); +void sig_end(int sigid); + +int dev_fd; +FILE *tx_fd=NULL,*rx_fd=NULL; +wanpipe_tdm_api_t tdm_api; + + +/*************************************************** +* HANDLE SOCKET +* +* o Read a socket +* o Cast data received to api_rx_element_t data type +* o The received packet contains 16 bytes header +* +* ------------------------------------------ +* | 16 bytes | X bytes ... +* ------------------------------------------ +* Header Data +* +* o Data structures: +* ------------------ +* typedef struct { +* union { +* struct { +* unsigned char _event_type; +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_event; +* struct { +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_rx; +* unsigned char reserved[16]; +* }wp_rx_hdr_u; +* #define wp_api_event_type wp_rx_hdr_u.wp_event._event_type +* #define wp_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits +* #define wp_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp +* } wp_tdm_api_rx_hdr_t; +* +* typedef struct { +* wp_tdm_api_rx_hdr_t hdr; +* unsigned char data[1]; +* } wp_tdm_api_rx_element_t; +* +* typedef struct { +* union { +* struct { +* unsigned char _rbs_rx_bits; +* unsigned int _time_stamp; +* }wp_tx; +* unsigned char reserved[16]; +* }wp_tx_hdr_u; +* #define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp +* } wp_tdm_api_tx_hdr_t; +* +* typedef struct { +* wp_tdm_api_tx_hdr_t hdr; +* unsigned char data[1]; +* } wp_tdm_api_tx_element_t; +* +* #define WPTDM_A_BIT 0x08 +* #define WPTDM_B_BIT 0x04 +* #define WPTDM_C_BIT 0x02 +* #define WPTDM_D_BIT 0x01 +* +*/ + +void handle_span_chan(void) +{ + unsigned int Rx_count,Tx_count,Tx_length; + wp_tdm_api_rx_element_t* api_rx_el; + wp_tdm_api_tx_element_t * api_tx_el; + fd_set ready,write,oob; + int err,i; + +#if 0 + int rlen; + int stream_sync=0; +#endif + + Rx_count = 0; + Tx_count = 0; + + if (tdm_api.wp_tdm_cmd.hdlc) { + Tx_length = tx_size; + } else { + Tx_length = tdm_api.wp_tdm_cmd.usr_mtu_mru; + } + + printf("\n\nSocket Handler: Rx=%d Tx=%i TxCnt=%i TxLen=%i TxDelay=%i\n", + read_enable,write_enable,tx_cnt,tx_size,tx_delay); + + /* Initialize the Tx Data buffer */ + memset(&Tx_data[0],0,MAX_TX_DATA + sizeof(wp_tdm_api_rx_hdr_t)); + + /* Cast the Tx data packet with the tx element + * structure. We must insert a 16 byte + * driver header, which driver will remove + * before passing packet out the physical port */ + api_tx_el = (wp_tdm_api_tx_element_t*)&Tx_data[0]; + + + /* Create a Tx packet based on user info, or + * by deafult incrementing number starting from 0 */ + for (i=0;idata[i] = (unsigned char)i; + }else{ +#if 0 + api_tx_el->data[i] = (unsigned char)tx_data+(i%4); +#else + api_tx_el->data[i] = (unsigned char)tx_data; +#endif + } + } + + sangoma_tdm_enable_rxhook_events(dev_fd, &tdm_api); + + /* Main Rx Tx OOB routine */ + for(;;) { + + /* Initialize all select() descriptors */ + FD_ZERO(&ready); + FD_ZERO(&write); + FD_ZERO(&oob); + FD_SET(dev_fd,&oob); + FD_SET(dev_fd,&ready); + + if (write_enable){ + FD_SET(dev_fd,&write); + } + + /* Select will block, until: + * 1: OOB event, link level change + * 2: Rx data available + * 3: Interface able to Tx */ + + if(select(dev_fd + 1,&ready, &write, &oob, NULL)){ + + fflush(stdout); + if (FD_ISSET(dev_fd,&oob)){ + + /* An OOB event is pending, usually indicating + * a link level change */ + + err=sangoma_tdm_read_event(dev_fd,&tdm_api); + + if(err < 0 ) { + printf("Failed to receive OOB %i , %i\n", Rx_count, err); + err = ioctl(dev_fd,SIOC_WANPIPE_SOCK_STATE,0); + printf("Sock state is %s\n", + (err == 0) ? "CONNECTED" : + (err == 1) ? "DISCONNECTED" : + "CONNECTING"); + break; + } + + printf("GOT OOB EXCEPTION CMD Exiting\n"); + } + + + if (FD_ISSET(dev_fd,&ready)){ + + /* An Rx packet is pending + * 1: Read the rx packet into the Rx_data + * buffer. Confirm len > 0 + * + * 2: Cast Rx_data to the api_rx_element. + * Thus, removing a 16 byte header + * attached by the driver. + * + * 3. Check error_flag: + * CRC,Abort..etc + */ + + memset(Rx_data, 0, sizeof(Rx_data)); + + err = sangoma_readmsg_tdm(dev_fd, + Rx_data, + sizeof(wp_tdm_api_rx_hdr_t), + &Rx_data[sizeof(wp_tdm_api_rx_hdr_t)], + MAX_RX_DATA, 0); + + + if (!read_enable){ + goto bitstrm_skip_read; + } + + /* err indicates bytes received */ + if(err <= 0) { + printf("\nError receiving data\n"); + break; + } + + api_rx_el = (wp_tdm_api_rx_element_t*)&Rx_data[0]; + + /* Check the packet length */ + Rx_lgth = err; + if(Rx_lgth<=0) { + printf("\nShort frame received (%d)\n", + Rx_lgth); + return; + } + +#if 0 + if (api_rx_el->data[0] == tx_data && api_rx_el->data[1] == (tx_data+1)){ + if (!stream_sync){ + printf("GOT SYNC %x\n",api_rx_el->data[0]); + } + stream_sync=1; + }else{ + if (stream_sync){ + printf("OUT OF SYNC: %x\n",api_rx_el->data[0]); + } + } +#endif + + ++Rx_count; + + if (verbose){ +#if 0 + printf("Received %i Length = %i\n", + Rx_count,Rx_lgth); + + printf("Data: "); + for(i=0;idata[i]); + } + printf("\n"); +#endif + }else{ + //putchar('R'); + } + + +#if 0 + switch(api_rx_el->hdr.wp_api_event_type){ + case WP_TDM_EVENT_DTMF: + printf("DTMV Event: %c (%s:%s)!\n", + api_rx_el->hdr.wp_api_event_dtmf_digit, + (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_ROUT)?"ROUT":"SOUT", + (api_rx_el->hdr.wp_api_event_dtmf_type&WP_TDM_EVENT_DTMF_PRESET)?"PRESET":"STOP"); + break; + case WP_TDM_EVENT_RXHOOK: + printf("RXHOOK Event: %s!\n", + (api_rx_el->hdr.wp_api_event_rxhook_state&WP_TDM_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK"); + break; + case WP_TDM_EVENT_RING: + printf("RING Event: %s!\n", + (api_rx_el->hdr.wp_api_event_ring_state&WP_TDM_EVENT_RING_PRESENT)?"PRESENT":"STOP"); + break; + } +#endif + + if (rx_cnt > 0 && Rx_count >= rx_cnt){ + break; + } +bitstrm_skip_read: +; + } + + if (FD_ISSET(dev_fd,&write)){ + + + err = sangoma_writemsg_tdm(dev_fd, + Tx_data,16, + &Tx_data[16], Tx_length, + 0); + if (err <= 0){ + if (errno == EBUSY){ + if (verbose){ + printf("Sock busy try again!\n"); + } + /* Socket busy try sending again !*/ + }else{ + printf("Faild to send %i \n",errno); + perror("Send: "); + break; + } + }else{ + + ++Tx_count; + + if (verbose){ + //printf("Packet sent: Sent %i : %i\n", + // err,Tx_count); + }else{ + //putchar('T'); + } + } + } + + if (tx_delay){ + usleep(tx_delay); + } + + if (tx_cnt && tx_size && Tx_count >= tx_cnt && !(files_used & TX_FILE_USED)){ + + write_enable=0; + if (rx_cnt > 0){ + /* Dont break let rx finish */ + }else{ + break; + } + } + } + } + + sangoma_tdm_disable_rxhook_events(dev_fd, &tdm_api); + if (tx_fd){ + fclose(tx_fd); + } + if (rx_fd){ + fclose(rx_fd); + } + close (dev_fd); + return; + +} + +int rxhook_event (int fd, unsigned char state) +{ + printf("%d: RXHOOK Event: %s!\n", + fd, (state & WAN_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK"); + return 0; +} + +/*************************************************************** + * Main: + * + * o Make a socket connection to the driver. + * o Call handle_span_chan() to read the socket + * + **************************************************************/ + + +int main(int argc, char* argv[]) +{ + int proceed; + + proceed=init_args(argc,argv); + if (proceed != WAN_TRUE){ + usage(argv[0]); + return -1; + } + + signal(SIGINT,&sig_end); + memset(&tdm_api,0,sizeof(tdm_api)); + tdm_api.wp_tdm_event.wp_rxhook_event = &rxhook_event; + + printf("TDM RXHOOK PTR = %p\n",tdm_api.wp_tdm_event.wp_rxhook_event); + + dev_fd =-1; + + dev_fd = sangoma_open_tdmapi_span_chan(atoi(card_name),atoi(if_name)); + if( dev_fd < 0){ + printf("Failed to open span chan (%s:%s:%d:%d)\n", + card_name, if_name, + atoi(card_name),atoi(if_name)); + exit (1); + } + printf("HANDLING SPAN %i CHAN %i FD=%i\n", + atoi(card_name),atoi(if_name),dev_fd); + + sangoma_tdm_set_codec(dev_fd,&tdm_api,WP_NONE); + sangoma_get_full_cfg(dev_fd, &tdm_api); + + handle_span_chan(); + close(dev_fd); + return 0; + + return 0; +}; + + +void sig_end(int sigid) +{ + + printf("Got Signal %i\n",sigid); + + sangoma_tdm_disable_rxhook_events(dev_fd, &tdm_api); + + if (tx_fd){ + fclose(tx_fd); + } + if (rx_fd){ + fclose(rx_fd); + } + + if (dev_fd){ + close (dev_fd); + } + + + exit(1); +} + + + diff --git a/api/tdmapi/aft_tdm_voice_api_switch.c b/api/tdmapi/aft_tdm_voice_api_switch.c deleted file mode 100644 index 64d11c3..0000000 --- a/api/tdmapi/aft_tdm_voice_api_switch.c +++ /dev/null @@ -1,368 +0,0 @@ -/***************************************************************************** -* bstrm_hdlc_test_multi.c: Multiple Bstrm Test Receive Module -* -* Author(s): Nenad Corbic -* -* Copyright: (c) 1995-2006 Sangoma Technologies Inc. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* ============================================================================ -* Description: -* -* The chdlc_api.c utility will bind to a socket to a chdlc network -* interface, and continously tx and rx packets to an from the sockets. -* -* This example has been written for a single interface in mind, -* where the same process handles tx and rx data. -* -* A real world example, should use different processes to handle -* tx and rx spearately. -*/ - - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define FALSE 0 -#define TRUE 1 - -/* Enable/Disable tx of random frames */ -#define RAND_FRAME 1 - -#define MAX_NUM_OF_TIMESLOTS 31*16 - -#define LGTH_CRC_BYTES 2 -#define MAX_TX_DATA 1000 //MAX_NUM_OF_TIMESLOTS*10 /* Size of tx data */ -#define MAX_TX_FRAMES 1000000 /* Number of frames to transmit */ - -#define WRITE 1 -#define MAX_IF_NAME 20 -typedef struct { - - int sock; - int rx_cnt; - int tx_cnt; - int data; - int last_error; - int frames; - char if_name[MAX_IF_NAME+1]; - -} timeslot_t; - - -timeslot_t tslot_array[MAX_NUM_OF_TIMESLOTS]; - -int tx_change_data=0, tx_change_data_cnt=0; -int end=0; - - -void print_packet(unsigned char *buf, int len) -{ - int x; - printf("{ | "); - for (x=0;xif_name,&span,&chan); - - if (span > 0 && chan > 0) { - wanpipe_tdm_api_t tdm_api; - slot->sock = sangoma_open_tdmapi_span_chan(span,chan); - if( slot->sock < 0 ) { - perror("Open Span Chan: "); - return( FALSE ); - } - - sangoma_tdm_set_codec(slot->sock,&tdm_api,WP_NONE); - - - printf("Socket bound to Span=%i Chan=%i\n\n",span,chan); - return (TRUE); - } - - return(FALSE); -} - -int api_tdm_fe_alarms_callback(int fd, unsigned char alarm) -{ - int fd_found=0; - int i; - for (i=0;i max_fd){ - max_fd=tslot_array[i].sock; - } - } - i=0; - - - tv.tv_usec = 0; - tv.tv_sec = 10; - - Rx_count = 0; - - for(;;) { - - FD_ZERO(&ready); - FD_ZERO(&oob); - max_fd=0; - for (i=0;i max_fd){ - max_fd=tslot_array[i].sock; - } - } - - tv.tv_usec = 0; - tv.tv_sec = 10; - - if (end){ - break; - } - - /* 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. - */ - slots=0; - if((serr=select(max_fd + 1, &ready, NULL, &oob, &tv))){ - - for (i=0;isock,&oob)){ - sangoma_tdm_read_event(slot->sock,&tdm_api); - } - - - /* Check for rx packets */ - if (FD_ISSET(slot->sock,&ready)){ - - err = sangoma_readmsg_tdm(slot->sock, - Rx_data,sizeof(wp_tdm_api_rx_hdr_t), - &Rx_data[sizeof(wp_tdm_api_rx_hdr_t)], - sizeof(Rx_data), 0); - - /* err indicates bytes received */ - if(err > 0) { - sangoma_writemsg_tdm(tslot_array[i==1?2:1].sock, - Rx_data,sizeof(wp_tdm_api_rx_hdr_t), - &Rx_data[sizeof(wp_tdm_api_rx_hdr_t)], - err, 0); - - } else { - printf("\n%s: Error receiving data\n",slot->if_name); - } - - } /* If rx */ - - } /* for all slots */ - - - } else { - printf("\n: Error selecting rx socket rc=0x%x errno=0x%x\n", - serr,errno); - perror("Select: "); - //break; - } - } - - - printf("\nRx Unloading HDLC\n"); - -} - - - - -/*************************************************************** - * 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 x,i; - - if (argc < 3){ - printf("Usage: rec_wan_sock ...\n"); - exit(0); - } - - nice(-11); - - signal(SIGINT,&sig_end); - signal(SIGTERM,&sig_end); - - memset(&tslot_array,0,sizeof(tslot_array)); - for (i=0;i ++# Makefile for the Linux network (wan) device drivers. + # +-# Licensed under the GNU General Public License, v2.0 or later, +-# at your option. See the file COPYING for details, or the web +-# page http://www.gnu.org/copyleft/gpl.html ++# 3 Aug 2000, Christoph Hellwig ++# Rewritten to use lists instead of if-statements. + # + +-OBJS = +-MODULE_NAME = +-EXTRA_CFLAGS = +-KDIR = +-$(MODULE_NAME)-objs = $(OBJS) +- +-RM = @rm -rf +-JUNK = *~ *.bak DEADJOE +- +-PWD := $(shell pwd) +-SUBDIRS=$(PWD) +- +-# First pass, kernel Makefile reads module objects +-ifneq ($(KERNELRELEASE),) +-obj-m := $(MODULE_NAME).o +- +- +-# Second pass, the actual build. +-else +-KVER ?= $(shell uname -r) +-PWD := $(shell pwd) +-KBUILD_VERBOSE= ++EXTRA_CFLAGS=-Werror $(EXTRA_FLAGS) ++EXTRA_CFLAGS+=-DENABLE_TONE_PLAY -DCONFIG_WANPIPE_HWEC -I/usr/include/wanpipe ++HOME=/common/wanec + +-all: +- $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules +- +-clean: +- $(shell find $(SUBDIRS) -name '*.*o' | xargs rm) +- $(shell find $(SUBDIRS) -name '.*.o.cmd' | xargs rm) +- $(shell rm -f build.sh) +- $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) clean +- +-distclean: clean +- $(RM) $(JUNK) $(OBJS) ++BTDIR=oct6100_api/apilib/bt ++LARGMATHDIR=oct6100_api/apilib/largmath ++LLMANDIR=oct6100_api/apilib/llman ++OCTAPIDIR=oct6100_api/octdeviceapi/oct6100api/oct6100_api ++OCTAPIMIDIR=oct6100_api/octdeviceapi/oct6100api/oct6100_apimi + +-help: +- $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help ++EXTRA_CFLAGS += -I. -I$(HOME)/oct6100_api -I$(HOME)/oct6100_api/include -I$(HOME)/oct6100_api/include/oct6100api -I$(HOME)/oct6100_api/include -I$(HOME)/oct6100_api/include/apilib -I$(HOME)/oct6100_api/include/apilib -I$(HOME)/oct6100_api/include/octrpc -I$(HOME)/oct6100_api/include/oct6100api -I$(HOME)/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY + ++wanec-y := wanec_iface.o wanec_cmd.o wanec_utils.o wanec_dev.o ++wanec-y += $(BTDIR)/octapi_bt0.o $(LARGMATHDIR)/octapi_largmath.o ++wanec-y += $(LLMANDIR)/octapi_llman.o $(OCTAPIMIDIR)/oct6100_mask_interrupts.o ++wanec-y += $(OCTAPIDIR)/oct6100_adpcm_chan.o $(OCTAPIDIR)/oct6100_channel.o ++wanec-y += $(OCTAPIDIR)/oct6100_chip_open.o $(OCTAPIDIR)/oct6100_chip_stats.o ++wanec-y += $(OCTAPIDIR)/oct6100_conf_bridge.o $(OCTAPIDIR)/oct6100_debug.o ++wanec-y += $(OCTAPIDIR)/oct6100_events.o $(OCTAPIDIR)/oct6100_interrupts.o ++wanec-y += $(OCTAPIDIR)/oct6100_memory.o $(OCTAPIDIR)/oct6100_miscellaneous.o ++wanec-y += $(OCTAPIDIR)/oct6100_mixer.o $(OCTAPIDIR)/oct6100_phasing_tsst.o ++wanec-y += $(OCTAPIDIR)/oct6100_playout_buf.o $(OCTAPIDIR)/oct6100_remote_debug.o ++wanec-y += $(OCTAPIDIR)/oct6100_tlv.o $(OCTAPIDIR)/oct6100_tone_detection.o ++wanec-y += $(OCTAPIDIR)/oct6100_tsi_cnct.o $(OCTAPIDIR)/oct6100_tsst.o ++wanec-y += $(OCTAPIDIR)/oct6100_user.o + +-# Indents the kernel source the way linux/Documentation/CodingStyle.txt +-# wants it to be. +-indent: +- indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) ++wanec-objs := $(OBJS) + +-install: +- $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install ++obj-m += wanec.o + +-endif +diff -dur --exclude='*.svn' --exclude='libsangoma*' --exclude='sangoma_mgd*' wanec/Makefile.Kbuild.Linux /common/wanec/Makefile.Kbuild.Linux +--- wanec/Makefile.Kbuild.Linux 2008-03-03 16:12:40.000000000 -0500 ++++ /common/wanec/Makefile.Kbuild.Linux 2007-12-04 15:44:37.000000000 -0500 +@@ -1,57 +1,37 @@ +-# Makefile for hello world kernel 2.6 module. -*-makefile-*- + # +-# Copyright (C) 2004 Joachim Nilsson ++# Makefile for the Linux network (wan) device drivers. + # +-# Licensed under the GNU General Public License, v2.0 or later, +-# at your option. See the file COPYING for details, or the web +-# page http://www.gnu.org/copyleft/gpl.html ++# 3 Aug 2000, Christoph Hellwig ++# Rewritten to use lists instead of if-statements. + # + +-OBJS = +-MODULE_NAME = +-EXTRA_CFLAGS = +-KDIR = +-$(MODULE_NAME)-objs = $(OBJS) +- +-RM = @rm -rf +-JUNK = *~ *.bak DEADJOE +- +-PWD := $(shell pwd) +-SUBDIRS=$(PWD) +- +-# First pass, kernel Makefile reads module objects +-ifneq ($(KERNELRELEASE),) +-obj-m := $(MODULE_NAME).o +- +- +-# Second pass, the actual build. +-else +-KVER ?= $(shell uname -r) +-PWD := $(shell pwd) +-KBUILD_VERBOSE= ++EXTRA_CFLAGS=-Werror $(EXTRA_FLAGS) ++EXTRA_CFLAGS+=-DENABLE_TONE_PLAY -DCONFIG_WANPIPE_HWEC -I/usr/include/wanpipe ++HOME=/common/wanec + +-all: +- $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) CC=$(CC) KBUILD_VERBOSE=$(KBUILD_VERBOSE) modules +- +-clean: +- $(shell find $(SUBDIRS) -name '*.*o' | xargs rm) +- $(shell find $(SUBDIRS) -name '.*.o.cmd' | xargs rm) +- $(shell rm -f build.sh) +- $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) clean +- +-distclean: clean +- $(RM) $(JUNK) $(OBJS) ++BTDIR=oct6100_api/apilib/bt ++LARGMATHDIR=oct6100_api/apilib/largmath ++LLMANDIR=oct6100_api/apilib/llman ++OCTAPIDIR=oct6100_api/octdeviceapi/oct6100api/oct6100_api ++OCTAPIMIDIR=oct6100_api/octdeviceapi/oct6100api/oct6100_apimi + +-help: +- $(MAKE) -C $(KDIR) SUBDIRS=$(SUBDIRS) help ++EXTRA_CFLAGS += -I. -I$(HOME)/oct6100_api -I$(HOME)/oct6100_api/include -I$(HOME)/oct6100_api/include/oct6100api -I$(HOME)/oct6100_api/include -I$(HOME)/oct6100_api/include/apilib -I$(HOME)/oct6100_api/include/apilib -I$(HOME)/oct6100_api/include/octrpc -I$(HOME)/oct6100_api/include/oct6100api -I$(HOME)/oct6100_api/octdeviceapi/oct6100api -DENABLE_TONE_PLAY + ++wanec-y := wanec_iface.o wanec_cmd.o wanec_utils.o wanec_dev.o ++wanec-y += $(BTDIR)/octapi_bt0.o $(LARGMATHDIR)/octapi_largmath.o ++wanec-y += $(LLMANDIR)/octapi_llman.o $(OCTAPIMIDIR)/oct6100_mask_interrupts.o ++wanec-y += $(OCTAPIDIR)/oct6100_adpcm_chan.o $(OCTAPIDIR)/oct6100_channel.o ++wanec-y += $(OCTAPIDIR)/oct6100_chip_open.o $(OCTAPIDIR)/oct6100_chip_stats.o ++wanec-y += $(OCTAPIDIR)/oct6100_conf_bridge.o $(OCTAPIDIR)/oct6100_debug.o ++wanec-y += $(OCTAPIDIR)/oct6100_events.o $(OCTAPIDIR)/oct6100_interrupts.o ++wanec-y += $(OCTAPIDIR)/oct6100_memory.o $(OCTAPIDIR)/oct6100_miscellaneous.o ++wanec-y += $(OCTAPIDIR)/oct6100_mixer.o $(OCTAPIDIR)/oct6100_phasing_tsst.o ++wanec-y += $(OCTAPIDIR)/oct6100_playout_buf.o $(OCTAPIDIR)/oct6100_remote_debug.o ++wanec-y += $(OCTAPIDIR)/oct6100_tlv.o $(OCTAPIDIR)/oct6100_tone_detection.o ++wanec-y += $(OCTAPIDIR)/oct6100_tsi_cnct.o $(OCTAPIDIR)/oct6100_tsst.o ++wanec-y += $(OCTAPIDIR)/oct6100_user.o + +-# Indents the kernel source the way linux/Documentation/CodingStyle.txt +-# wants it to be. +-indent: +- indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) ++wanec-objs := $(OBJS) + +-install: +- $(MAKE) -C $(KDIR) M=$(SUBDIRS) modules_install ++obj-m += wanec.o + +-endif +Only in /common/wanec/mod: CVS +Only in /common/wanec/modinfo: CVS +Only in /common/wanec/oct6100_api/apilib/bt: CVS +Only in /common/wanec/oct6100_api/apilib/bt: octapi_bt0.o +Only in /common/wanec/oct6100_api/apilib/bt: .octapi_bt0.o.cmd +Only in /common/wanec/oct6100_api/apilib: CVS +Only in /common/wanec/oct6100_api/apilib/largmath: CVS +Only in /common/wanec/oct6100_api/apilib/largmath: octapi_largmath.o +Only in /common/wanec/oct6100_api/apilib/largmath: .octapi_largmath.o.cmd +Only in /common/wanec/oct6100_api/apilib/llman: CVS +Only in /common/wanec/oct6100_api/apilib/llman: octapi_llman.o +Only in /common/wanec/oct6100_api/apilib/llman: .octapi_llman.o.cmd +Only in /common/wanec/oct6100_api: CVS +Only in /common/wanec/oct6100_api/include/apilib: CVS +Only in /common/wanec/oct6100_api/include: CVS +Only in /common/wanec/oct6100_api/include/oct6100api: CVS +Only in /common/wanec/oct6100_api/include/octrpc: CVS +Only in /common/wanec/oct6100_api/octdeviceapi: CVS +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api: CVS +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: CVS +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_adpcm_chan.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_adpcm_chan.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_channel.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_channel.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_chip_open.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_chip_open.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_chip_stats.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_chip_stats.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_conf_bridge.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_conf_bridge.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_debug.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_debug.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_events.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_events.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_interrupts.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_interrupts.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_memory.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_memory.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_miscellaneous.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_miscellaneous.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_mixer.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_mixer.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_phasing_tsst.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_phasing_tsst.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_playout_buf.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_playout_buf.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_remote_debug.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_remote_debug.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_tlv.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_tlv.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_tone_detection.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_tone_detection.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_tsi_cnct.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_tsi_cnct.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_tsst.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_tsst.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: oct6100_user.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api: .oct6100_user.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi: CVS +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi: oct6100_mask_interrupts.o +Only in /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi: .oct6100_mask_interrupts.o.cmd +Only in /common/wanec/oct6100_api/octdeviceapiw: CVS +Only in /common/wanec/oct6100_api/octdeviceapiw/oct6100_apiw_freebsd: CVS +Only in /common/wanec/oct6100_api/octdeviceapiw/oct6100_apiw_linux: CVS +Only in /common/wanec: oct6100_api.PR39 +Only in /common/wanec: oct6100_api.PR41 +Only in /common/wanec: oct6100_api.PR43 +Only in /common/wanec: oct6100_api.PR47 +Only in /common/wanec/oct6100_api.PR48/apilib/bt: CVS +Only in /common/wanec/oct6100_api.PR48/apilib/bt: octapi_bt0.o +Only in /common/wanec/oct6100_api.PR48/apilib/bt: .octapi_bt0.o.cmd +Only in /common/wanec/oct6100_api.PR48/apilib: CVS +Only in /common/wanec/oct6100_api.PR48/apilib/largmath: CVS +Only in /common/wanec/oct6100_api.PR48/apilib/largmath: octapi_largmath.o +Only in /common/wanec/oct6100_api.PR48/apilib/largmath: .octapi_largmath.o.cmd +Only in /common/wanec/oct6100_api.PR48/apilib/llman: CVS +Only in /common/wanec/oct6100_api.PR48/apilib/llman: octapi_llman.o +Only in /common/wanec/oct6100_api.PR48/apilib/llman: .octapi_llman.o.cmd +Only in /common/wanec/oct6100_api.PR48: CVS +Only in /common/wanec/oct6100_api.PR48/include/apilib: CVS +Only in /common/wanec/oct6100_api.PR48/include: CVS +Only in /common/wanec/oct6100_api.PR48/include/oct6100api: CVS +Only in /common/wanec/oct6100_api.PR48/include/octrpc: CVS +Only in /common/wanec/oct6100_api.PR48/octdeviceapi: CVS +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api: CVS +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: CVS +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_adpcm_chan.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_adpcm_chan.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_channel.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_channel.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_chip_open.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_chip_open.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_chip_stats.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_chip_stats.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_conf_bridge.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_conf_bridge.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_debug.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_debug.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_events.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_events.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_interrupts.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_interrupts.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_memory.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_memory.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_miscellaneous.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_miscellaneous.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_mixer.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_mixer.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_phasing_tsst.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_phasing_tsst.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_playout_buf.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_playout_buf.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_remote_debug.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_remote_debug.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_tlv.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_tlv.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_tone_detection.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_tone_detection.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_tsi_cnct.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_tsi_cnct.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_tsst.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_tsst.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: oct6100_user.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api: .oct6100_user.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_apimi: CVS +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_apimi: oct6100_mask_interrupts.o +Only in /common/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_apimi: .oct6100_mask_interrupts.o.cmd +Only in /common/wanec/oct6100_api.PR48/octdeviceapiw: CVS +Only in /common/wanec/oct6100_api.PR48/octdeviceapiw/oct6100_apiw_freebsd: CVS +Only in /common/wanec/oct6100_api.PR48/octdeviceapiw/oct6100_apiw_linux: CVS +Only in /common/wanec/tmp: CVS +diff -dur --exclude='*.svn' --exclude='libsangoma*' --exclude='sangoma_mgd*' wanec/.tmp_versions/wanec.mod /common/wanec/.tmp_versions/wanec.mod +--- wanec/.tmp_versions/wanec.mod 2008-03-03 16:12:55.000000000 -0500 ++++ /common/wanec/.tmp_versions/wanec.mod 2008-03-05 18:40:45.000000000 -0500 +@@ -1,2 +1,2 @@ +-/root/3.3/wanpipe/patches/kdrivers/wanec/wanec.ko +-/root/3.3/wanpipe/patches/kdrivers/wanec/wanec_iface.o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_cmd.o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_utils.o /root/3.3/wanpipe/patches/kdrivers/wanec/wanec_dev.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/apilib/bt/octapi_bt0.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/apilib/largmath/octapi_largmath.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/apilib/llman/octapi_llman.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_events.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o /root/3.3/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_user.o ++/common/wanec/wanec.ko ++/common/wanec/wanec_iface.o /common/wanec/wanec_cmd.o /common/wanec/wanec_utils.o /common/wanec/wanec_dev.o /common/wanec/oct6100_api/apilib/bt/octapi_bt0.o /common/wanec/oct6100_api/apilib/largmath/octapi_largmath.o /common/wanec/oct6100_api/apilib/llman/octapi_llman.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_events.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o /common/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_user.o +diff -dur --exclude='*.svn' --exclude='libsangoma*' --exclude='sangoma_mgd*' wanec/wanec_cmd.c /common/wanec/wanec_cmd.c +--- wanec/wanec_cmd.c 2008-02-04 16:39:27.000000000 -0500 ++++ /common/wanec/wanec_cmd.c 2008-03-05 18:11:47.000000000 -0500 +@@ -1408,7 +1408,7 @@ + "%s: Error Pll Jitter\n", + ec->name); + } +- if (ec->f_InterruptFlag.fErrorH100OutOfSync == TRUE){ ++ if (ec->f_InterruptFlag.fErrorH100OutOfSync == TRUE && !ec->ignore_H100){ + DEBUG_EVENT( + "%s: The H100 slave has lost its framing on the bus!\n", + ec->name); +Only in /common/wanec: wanec_cmd.o +Only in /common/wanec: .wanec_cmd.o.cmd +Only in /common/wanec: wanec_dev.o +Only in /common/wanec: .wanec_dev.o.cmd +diff -dur --exclude='*.svn' --exclude='libsangoma*' --exclude='sangoma_mgd*' wanec/wanec_iface.c /common/wanec/wanec_iface.c +--- wanec/wanec_iface.c 2008-02-22 11:21:05.000000000 -0500 ++++ /common/wanec/wanec_iface.c 2008-03-05 18:11:47.000000000 -0500 +@@ -1674,16 +1674,18 @@ + ec_dev_new->fe_start_chan = WAN_FE_START_CHANNEL(&card->fe); + ec_dev_new->fe_max_chans = WAN_FE_MAX_CHANNELS(&card->fe); //max_line_no; // + ec_dev_new->fe_stop_chan = ec_dev_new->fe_start_chan + ec_dev_new->fe_max_chans - 1; +- ++ /* Feb 14, 2008 ++ ** Ignore fe_port_mask for BRI cards. fe_port_mask is for full card, ++ ** but ec_dev created per module. In this case, we have always ++ ** 2 channels (1 and 2). Create fe_channel_map manually */ + if (fe_port_mask && ec_dev_new->fe_media != WAN_MEDIA_BRI){ +- ec_dev_new->fe_channel_map = fe_port_mask; +- }else{ +- int fe_chan = 0; +- for(fe_chan = ec_dev_new->fe_start_chan; fe_chan <= ec_dev_new->fe_stop_chan; fe_chan++){ +- ec_dev_new->fe_channel_map |= (1 << fe_chan); +- } +- } +- ++ ec_dev_new->fe_channel_map = fe_port_mask; ++ }else{ ++ int fe_chan = 0; ++ for(fe_chan = ec_dev_new->fe_start_chan; fe_chan <= ec_dev_new->fe_stop_chan; fe_chan++){ ++ ec_dev_new->fe_channel_map |= (1 << fe_chan); ++ } ++ } + if (!WAN_FE_TDMV_LAW(&card->fe)){ + if (WAN_FE_MEDIA(&card->fe) == WAN_MEDIA_T1){ + WAN_FE_TDMV_LAW(&card->fe) = WAN_TDMV_MULAW; +@@ -1948,6 +1950,13 @@ + wanec_channel_dtmf(ec_dev, event_ctrl->channel, WAN_FALSE, NULL, wanec_verbose); + } + break; ++ case WAN_EVENT_EC_H100_REPORT: ++ if (event_ctrl->mode == WAN_EVENT_DISABLE){ ++ ec->ignore_H100 = 1; ++ }else{ ++ ec->ignore_H100 = 0; ++ } ++ break; + default: + err = -EINVAL; + break; +diff -dur --exclude='*.svn' --exclude='libsangoma*' --exclude='sangoma_mgd*' wanec/wanec_iface.h /common/wanec/wanec_iface.h +--- wanec/wanec_iface.h 2008-02-04 16:37:59.000000000 -0500 ++++ /common/wanec/wanec_iface.h 2008-03-05 18:11:47.000000000 -0500 +@@ -293,6 +293,8 @@ + u_int32_t intcount; + u_int32_t critical; + ++ int ignore_H100; /* Temporary for BRI card */ ++ + wan_spinlock_t lock; + u_int32_t events; /* enable events map */ + int tone_verbose; /* verbose mode for tone events */ +Only in /common/wanec: wanec_iface.o +Only in /common/wanec: .wanec_iface.o.cmd +Only in /common/wanec: wanec.ko +Only in /common/wanec: .wanec.ko.cmd +diff -dur --exclude='*.svn' --exclude='libsangoma*' --exclude='sangoma_mgd*' wanec/wanec.mod.c /common/wanec/wanec.mod.c +--- wanec/wanec.mod.c 2008-02-22 15:56:59.000000000 -0500 ++++ /common/wanec/wanec.mod.c 2008-03-05 18:24:45.000000000 -0500 +@@ -55,4 +55,4 @@ + "depends="; + + +-MODULE_INFO(srcversion, "7BF6911A99A9CA69B41E9F4"); ++MODULE_INFO(srcversion, "A6BF1CF61774AE275ECC9A5"); +Only in /common/wanec: wanec.mod.o +Only in /common/wanec: .wanec.mod.o.cmd +Only in /common/wanec: wanec.o +Only in /common/wanec: .wanec.o.cmd +Only in /common/wanec: wanec_utils.o +Only in /common/wanec: .wanec_utils.o.cmd diff --git a/patches/kdrivers/diff.sh b/patches/kdrivers/diff.sh new file mode 100755 index 0000000..2bebf1f --- /dev/null +++ b/patches/kdrivers/diff.sh @@ -0,0 +1,4 @@ +#!/bin/sh + + +diff -dur "$1" "$2" --exclude=*.svn --exclude=libsangoma* --exclude=sangoma_mgd* > diff diff --git a/patches/kdrivers/include/.sdla_aft_te1.h.swp b/patches/kdrivers/include/.sdla_aft_te1.h.swp new file mode 100644 index 0000000000000000000000000000000000000000..675e2a557efb0df68ff518bd54aeb426d289717e GIT binary patch literal 16384 zcmeI3UyR&F9mkzQlNy>(5?*LU85$6K+q>J{yS+bc!hz%S?wQ+v+V$m<7e>DI?5(+7 zdu4lbIjQ2$3leRmApQvTPXrPOgaoSk&_1-PL?m8NK)eNbfwn@TeME@Ag@o_e-i>!} zFMm)aBsA82v>wlIW`6UX@z3_yx0OAsm&wv>R>JmxBwgzKws`&N*AD&sK}qslH{geF zw*}1an71=R{ug+K8H-(D9kLXqHF`1%v`Z0il3U zKqw#-5DEwdgaZHf3Ix5Q(hcDgVl>ZN;UqV`XZl0>kd9Ke&2KlAZ=7@Bp}SRFb|4G_VR( z@F+L|j)M<^8+bs!4qgV|0bc<-pbQqlN5B#A=KCe-XW%mUHt@k&umm0g9|9-9pWY`) zzXCr2Pk|>v8x+9D!9Cy*cvY69SHPFS=RpgUfDRr84}mxClcd+d74TE=EO-X&0UfM? z6!;`K0uF;WkDwfQ6}$qT19%)+c@gegu3_12f<-xEEZ*`o<5z z55PrG1O;#m+y|~=edK%KdGH*#07_sT90zY>A>=LaRlwI;Ho*$`1b7hq8RPs*@C$Gi zTmlq)4)8gU0k_&t5{tELhY_VN;)IQEp8y81iHCo!Xa`#=4xnm|c=HX@b_5Njd|sZ??9O&C-%y(P-m*MWrw| zv^sZ6p3fz$l3m~>^omg*_#(;C#%qpudz*%N%p#;l&Zzi ze%}=F0K+j?9JAwYhx$(}xwcxuNE`JMt*=J&f-FxSg1SrF3c9YHk7gDja&D1KZfU$gtn~arqn9}C5)H`t18N^PkE`cOPdcj$+NgB% zlg%21I_yGmfGolkVjtp8!Qw?71prKKs`Fp443ybS?FcA(IY(vW> zOeCEAga?>B;jxaOFsW-rorjYKAyOv&sk_|>k5h>ly18o5yir|_&k?OCBd{%~qei@O z+AtIYCrD(lJZcaN!KbQTP*jc9H^X}Jqh@8bw!sHgtKY(?pckqLnf3KyWB52Q>GG;# zD73tBZjhf>(W#^X?^DjG<`aG5mkWM4iUeA5pZy?%yPaPit1#|f{Q*o}2Bl!*^; ztWqA1le-@xKBRo$)A%FBj=N=ci0V2md%N$Mf$cg(@t8?kJb-jMq~>~oA6uiFL~YwW zQd4zOXWO=q=*%-oSXZffMkx`J8Wx-SZ>CT<cvu41e=Hh6hR?9WLq*45qs})+S>t_{1qYAFM$touIk{_Mezc6Ee&nEW?7um=e zD@Ez1URkYfHYlAMZ~pcTjZ{?d7(3HgMMdO^ClU=*aYr=ic!dSgVN8Cz1&7F{Qo#kZ zUeQX4=u8`{C57_9#V-nL+!kj~i;N$ar1ZPFWu!Futm%;K(lo&h#JpT#j%gtPd0Tc< z)*U;r5s&z{(TGH|FuvO>(5>vHv@FjNw?%?BBPF}Z9G^||JEfEvkUh8W5x2)9;1n^P zJ<`Dx^AfJevgwmvf2(8rZDx_Jy|5ZSJfz{af?d;Nq~P`)D~zJ22(!`5umaw8*To&* z9>IM!tdPasKpS0u;8U@(L5j>_9yF-&mYM@Md2yp{!vW9T_RKE9Zi_eV$4#H&9Ux6e z>oE&~*|WF$0po2UDrQ_yN<&Q5?d^H?b~|`nPBo{(0hqxkERcrjY`a~P7_8ZLT-@^7 z%qP0j#0a36(hu6M=RZzHMvI(wn&Gg0#*a$#$h!h_S?1ni*46ZymI}I4{Beq`Ax4K9 zHTpdsonZspu@B!f@8(=fOZ@r&8+d;IHQ>+xc>I>G;ragipa)Ka4}-Un{}%Wocpdy6 z{0{JP*MQiB0zv_yfKWgvAQTV^2nB=!LII(GP(Uc~KTsfkb%X_;Xe|#fN?qF`@?cqN z*W6*$56tFHDqbq1Se!6vkS5Kx=}eu9?fL4~t`$&^`7B6PO0062onaXo{wI5jQM|qLXfyCSBXv*nw|WHb1$}>5hP!h2C9JMVyXHm87c82z K*&b;Jb^iw&Nbwo~ literal 0 HcmV?d00001 diff --git a/patches/kdrivers/include/.wanpipe.h.swp b/patches/kdrivers/include/.wanpipe.h.swp deleted file mode 100644 index 3360be10179d0adfe6f707a7f071a591ee99eb01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 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 diff --git a/patches/kdrivers/include/aft_a104.h b/patches/kdrivers/include/aft_a104.h index 3b0ed31..be0dcb1 100644 --- a/patches/kdrivers/include/aft_a104.h +++ b/patches/kdrivers/include/aft_a104.h @@ -39,7 +39,7 @@ int a104_global_chip_config(sdla_t *card); int a104_global_chip_unconfig(sdla_t *card); -int a104_chip_config(sdla_t *card); +int a104_chip_config(sdla_t *card, wandev_conf_t*); int a104_chip_unconfig(sdla_t *card); int a104_chan_dev_config(sdla_t *card, void *chan); int a104_chan_dev_unconfig(sdla_t *card, void *chan); diff --git a/patches/kdrivers/include/aft_analog.h b/patches/kdrivers/include/aft_analog.h index 1cadc6d..14fb6b1 100644 --- a/patches/kdrivers/include/aft_analog.h +++ b/patches/kdrivers/include/aft_analog.h @@ -21,7 +21,7 @@ int aft_analog_global_chip_config(sdla_t *card); int aft_analog_global_chip_unconfig(sdla_t *card); -int aft_analog_chip_config(sdla_t *card); +int aft_analog_chip_config(sdla_t *card, wandev_conf_t *); int aft_analog_chip_unconfig(sdla_t *card); int aft_analog_chan_dev_config(sdla_t *card, void *chan); int aft_analog_chan_dev_unconfig(sdla_t *card, void *chan); diff --git a/patches/kdrivers/include/aft_bri.h b/patches/kdrivers/include/aft_bri.h new file mode 100755 index 0000000..49a988d --- /dev/null +++ b/patches/kdrivers/include/aft_bri.h @@ -0,0 +1,55 @@ +/***************************************************************************** +* aft_bri.h WANPIPE(tm) BRI Hardware Support +* +* Authors: David Rokhvarg +* +* Copyright: (c) 1984-2007 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +* March 15, 2007 David Rokhvarg Initial version. +*****************************************************************************/ + +#ifndef _AFT_BRI_H +#define _AFT_BRI_H + +#ifdef WAN_KERNEL + +#if 0 +#define A200_SECURITY_16_ECCHAN 0x00 +#define A200_SECURITY_32_ECCHAN 0x01 +#define A200_SECURITY_0_ECCHAN 0x05 +#define A200_ECCHAN(val) \ + ((val) == A200_SECURITY_16_ECCHAN) ? 16 : \ + ((val) == A200_SECURITY_32_ECCHAN) ? 32 : 0 +#endif + +int aft_bri_global_chip_config(sdla_t *card); +int aft_bri_global_chip_unconfig(sdla_t *card); +int aft_bri_chip_config(sdla_t *card, wandev_conf_t*); +int aft_bri_chip_unconfig(sdla_t *card); +int aft_bri_chan_dev_config(sdla_t *card, void *chan); +int aft_bri_chan_dev_unconfig(sdla_t *card, void *chan); +int aft_bri_led_ctrl(sdla_t *card, int color, int led_pos, int on); +int aft_bri_test_sync(sdla_t *card, int tx_only); +int bri_check_ec_security(sdla_t *card); + +int __aft_bri_write_fe (void* card, ...); +int aft_bri_write_fe (void* card, ...); +unsigned char __aft_bri_read_fe (void* card, ...); +unsigned char aft_bri_read_fe (void* card, ...); + +int aft_bri_write_cpld(sdla_t *card, unsigned short off,unsigned short data); +unsigned char aft_bri_read_cpld(sdla_t *card, unsigned short cpld_off); + +void aft_bri_fifo_adjust(sdla_t *card,u32 level); + +int aft_bri_dchan_transmit(sdla_t *card, void *chan_ptr, void *src_data_buffer, unsigned int buffer_len); +int aft_bri_dchan_receive( sdla_t *card, void *chan_ptr, void *dst_data_buffer, unsigned int buffer_len); + +#endif/* WAN_KERNEL */ + +#endif/* _AFT_BRI_H */ diff --git a/patches/kdrivers/include/if_wanpipe.h b/patches/kdrivers/include/if_wanpipe.h index c2f3c1a..b9ac671 100644 --- a/patches/kdrivers/include/if_wanpipe.h +++ b/patches/kdrivers/include/if_wanpipe.h @@ -219,7 +219,7 @@ enum { #define WAN_PACKET_FASTROUTE 6 /* Fastrouted frame */ -/* X25 specific */ +/* AF Socket specific */ #define WAN_PACKET_DATA 0 #define WAN_PACKET_CMD 1 #define WAN_PACKET_ERR 2 diff --git a/patches/kdrivers/include/if_wanpipe_common.h b/patches/kdrivers/include/if_wanpipe_common.h index 62ba967..9c3c1a3 100644 --- a/patches/kdrivers/include/if_wanpipe_common.h +++ b/patches/kdrivers/include/if_wanpipe_common.h @@ -1,5 +1,5 @@ /***************************************************************************** -* if_wanipe_common.h Sangoma Driver/Socket common area definitions. +* if_wanpipe_common.h Sangoma Driver/Socket common area definitions. * * Author: Nenad Corbic * @@ -29,6 +29,10 @@ # include # include # include +#elif defined(__WINDOWS__) +# include +# include +# include #endif @@ -42,13 +46,10 @@ typedef struct { int (*output) (netdevice_t*,netskb_t*,struct sockaddr*, struct rtentry*); #else int (*send) (netskb_t* skb, netdevice_t*); -#endif struct net_device_stats* (*get_stats) (netdevice_t*); - int (*ioctl) (netdevice_t*, struct ifreq*, int); - void (*tx_timeout) (netdevice_t*); -#if defined (__LINUX__) - int (*change_mtu)(netdevice_t *dev, int new_mtu); #endif + int (*ioctl) (netdevice_t*, struct ifreq*, wan_ioctl_cmd_t); + void (*tx_timeout) (netdevice_t*); } wanpipe_common_iface_t; typedef struct { @@ -58,20 +59,41 @@ typedef struct { /* netdevice_t *next; */ /* netdevice_t *slave; */ void *card; netdevice_t *dev; + struct mtx ifmtx; unsigned char state; unsigned char usedby; wan_tasklet_t bh_task; wan_timer_t dev_timer; struct socket *sk; /* Wanpipe Sock bind's here (Not used)*/ unsigned int protocol; - unsigned short lcn; + unsigned short lcn; void *lip; unsigned int lip_prot; + int is_spppdev; /* special mode for ADSL PPP_VC/PPP_LLC */ +# if defined(NETGRAPH) + char ng_nodename [NG_NODELEN+1]; + int ng_running; + node_p ng_node; + hook_p ng_upper_hook; + hook_p ng_lower_hook; + hook_p ng_debug_hook; + int ng_lowerhooks; + int ng_upperhooks; + int ng_datahooks; + struct ifqueue lo_queue; + struct ifqueue hi_queue; + short ng_timeout; + struct callout ng_timeout_handle; + u_long ng_out_deficit; /* output since last input */ + u_char ng_promisc; /* promiscuous mode enabled */ + u_char ng_autoSrcAddr; /* always overwrite source address */ +# endif #elif defined(__LINUX__) /* !!! IMPORTANT !!! <- Do not move this parameter (GENERIC-PPP) */ void* *prot_ptr; netdevice_t *next; /*slave;*/ void *card; + struct net_device_stats if_stats; atomic_t receive_block; atomic_t command; @@ -99,6 +121,26 @@ typedef struct { void *lip; unsigned int lip_prot; +#elif defined(__WINDOWS__) + + void *prot_ptr; + netdevice_t* dev; + unsigned char state; + unsigned char usedby; + + void *card; + + void* sk; + + void *lip; + + //A104 additions + unsigned int protocol; + wan_tasklet_t bh_task; + + //ADSL additions + wan_tasklet_t wanpipe_task; /* Immediate BH handler task */ + unsigned int lip_prot; #endif int is_netdev; wanpipe_common_iface_t iface; diff --git a/patches/kdrivers/include/sdla_56k.h b/patches/kdrivers/include/sdla_56k.h index b4522d1..00da98a 100644 --- a/patches/kdrivers/include/sdla_56k.h +++ b/patches/kdrivers/include/sdla_56k.h @@ -103,7 +103,7 @@ typedef struct { } sdla_56k_param_t; extern int sdla_56k_default_cfg(void* arg1, void* p56k_cfg); -extern int sdla_56k_iface_init(void* pfe); +extern int sdla_56k_iface_init(void* pfe, void *p_fe_iface); #endif /* WAN_KERNEL */ diff --git a/patches/kdrivers/include/sdla_adccp.h b/patches/kdrivers/include/sdla_adccp.h index cfd63f2..522961d 100644 --- a/patches/kdrivers/include/sdla_adccp.h +++ b/patches/kdrivers/include/sdla_adccp.h @@ -27,6 +27,7 @@ */ #pragma pack(1) + /****** CONSTANTS DEFINITIONS ***********************************************/ #define X25_MAX_CHAN 255 /* max number of open X.25 circuits */ @@ -54,16 +55,16 @@ */ typedef struct X25Cmd { - unsigned char command ; /* command code */ - unsigned short length ; /* transfer data length */ - unsigned char result ; /* return code */ - unsigned char pf ; /* P/F bit */ - unsigned short lcn ; /* logical channel */ - unsigned char qdm ; /* Q/D/M bits */ - unsigned char cause ; /* cause field */ - unsigned char diagn ; /* diagnostics */ - unsigned char pktType ; /* packet type */ - unsigned char resrv[4] ; /* reserved */ + unsigned char command ; /* command code */ + unsigned short length ; /* transfer data length */ + unsigned char result ; /* return code */ + unsigned char pf ; /* P/F bit */ + unsigned short lcn ; /* logical channel */ + unsigned char qdm ; /* Q/D/M bits */ + unsigned char cause ; /* cause field */ + unsigned char diagn ; /* diagnostics */ + unsigned char pktType ; /* packet type */ + unsigned char resrv[4] ; /* reserved */ } TX25Cmd; /* @@ -226,9 +227,9 @@ typedef struct X25Cmd */ typedef struct X25Mbox { - unsigned char opflag ; /* 00h: execution flag */ - TX25Cmd cmd ; /* 01h: command block */ - unsigned char data[1] ; /* 10h: data buffer */ + unsigned char opflag ; /* 00h: execution flag */ + TX25Cmd cmd ; /* 01h: command block */ + unsigned char data[1] ; /* 10h: data buffer */ } TX25Mbox; /*---------------------------------------------------------------------------- @@ -236,11 +237,11 @@ typedef struct X25Mbox */ typedef struct X25TimeStamp { - unsigned char month ; - unsigned char date ; - unsigned char sec ; - unsigned char min ; - unsigned char hour ; + unsigned char month ; + unsigned char date ; + unsigned char sec ; + unsigned char min ; + unsigned char hour ; } TX25TimeStamp; /*---------------------------------------------------------------------------- @@ -250,11 +251,11 @@ typedef struct X25TimeStamp */ typedef struct X25Status { - TX25TimeStamp tstamp ; /* 08h: timestamp (BCD) */ - unsigned char iflags ; /* 0Dh: interrupt flags */ - unsigned char imask ; /* 0Eh: interrupt mask */ - unsigned char hdlc_status ; /* 10h: misc. HDLC/X25 flags */ - unsigned char ghdlc_status ; /* channel status bytes */ + TX25TimeStamp tstamp ; /* 08h: timestamp (BCD) */ + unsigned char iflags ; /* 0Dh: interrupt flags */ + unsigned char imask ; /* 0Eh: interrupt mask */ + unsigned char hdlc_status ; /* 10h: misc. HDLC/X25 flags */ + unsigned char ghdlc_status ; /* channel status bytes */ } TX25Status; /* @@ -292,9 +293,9 @@ typedef struct X25Status */ typedef struct X25GlobalVars { - unsigned char resrv ; /* 00h: reserved */ - unsigned char dtrCtl ; /* 01h: DTR control code */ - unsigned char resErr ; /* 01h: '1' - reset modem error */ + unsigned char resrv ; /* 00h: reserved */ + unsigned char dtrCtl ; /* 01h: DTR control code */ + unsigned char resErr ; /* 01h: '1' - reset modem error */ } TX25GlobalVars; /* @@ -308,7 +309,7 @@ typedef struct X25GlobalVars */ typedef struct X25ModemStatus { - unsigned char status ; /* 00h: modem status */ + unsigned char status ; /* 00h: modem status */ } TX25ModemStatus; /* @@ -322,11 +323,11 @@ typedef struct X25ModemStatus */ typedef struct X25LinkStatus { - unsigned char txQueued ; /* 00h: queued Tx I-frames*/ - unsigned char rxQueued ; /* 01h: queued Rx I-frames*/ - unsigned char station ; /* 02h: DTE/DCE config. */ - unsigned char reserved ; /* 03h: reserved */ - unsigned char sfTally ; /* 04h: supervisory frame tally */ + unsigned char txQueued ; /* 00h: queued Tx I-frames*/ + unsigned char rxQueued ; /* 01h: queued Rx I-frames*/ + unsigned char station ; /* 02h: DTE/DCE config. */ + unsigned char reserved ; /* 03h: reserved */ + unsigned char sfTally ; /* 04h: supervisory frame tally */ } TX25LinkStatus; /* @@ -340,23 +341,23 @@ typedef struct X25LinkStatus */ typedef struct HdlcStats { /* a number of ... */ - unsigned short rxIFrames ; /* 00h: ready Rx I-frames */ - unsigned short rxNoseq ; /* 02h: frms out-of-sequence */ - unsigned short rxNodata ; /* 04h: I-frms without data */ - unsigned short rxDiscarded ; /* 06h: discarded frames */ - unsigned short rxTooLong ; /* 08h: frames too long */ - unsigned short rxBadAddr ; /* 0Ah: frms with inval.addr*/ - unsigned short txAcked ; /* 0Ch: acknowledged I-frms */ - unsigned short txRetransm ; /* 0Eh: re-transmit. I-frms */ - unsigned short t1Timeout ; /* 10h: T1 timeouts */ - unsigned short rxSABM ; /* 12h: received SABM frames */ - unsigned short rxDISC ; /* 14h: received DISC frames */ - unsigned short rxDM ; /* 16h: received DM frames */ - unsigned short rxFRMR ; /* 18h: FRMR frames received */ - unsigned short txSABM ; /* 1Ah: transm. SABM frames*/ - unsigned short txDISC ; /* 1Ch: transm. DISC frames*/ - unsigned short txDM ; /* 1Eh: transm. DM frames */ - unsigned short txFRMR ; /* 20h: transm. FRMR frames*/ + unsigned short rxIFrames ; /* 00h: ready Rx I-frames */ + unsigned short rxNoseq ; /* 02h: frms out-of-sequence */ + unsigned short rxNodata ; /* 04h: I-frms without data */ + unsigned short rxDiscarded ; /* 06h: discarded frames */ + unsigned short rxTooLong ; /* 08h: frames too long */ + unsigned short rxBadAddr ; /* 0Ah: frms with inval.addr*/ + unsigned short txAcked ; /* 0Ch: acknowledged I-frms */ + unsigned short txRetransm ; /* 0Eh: re-transmit. I-frms */ + unsigned short t1Timeout ; /* 10h: T1 timeouts */ + unsigned short rxSABM ; /* 12h: received SABM frames */ + unsigned short rxDISC ; /* 14h: received DISC frames */ + unsigned short rxDM ; /* 16h: received DM frames */ + unsigned short rxFRMR ; /* 18h: FRMR frames received */ + unsigned short txSABM ; /* 1Ah: transm. SABM frames*/ + unsigned short txDISC ; /* 1Ch: transm. DISC frames*/ + unsigned short txDM ; /* 1Eh: transm. DM frames */ + unsigned short txFRMR ; /* 20h: transm. FRMR frames*/ } THdlcStats; /* --------------------------------------------------------------------------- @@ -364,16 +365,16 @@ typedef struct HdlcStats */ typedef struct HdlcCommErr { /* a number of ... */ - unsigned char rxOverrun ; /* 00h: Rx overrun errors */ - unsigned char rxBadCrc ; /* 01h: Rx CRC errors */ - unsigned char rxAborted ; /* 02h: Rx aborted frames */ - unsigned char rxDropped ; /* 03h: frames lost */ - unsigned char txAborted ; /* 04h: Tx aborted frames */ - unsigned char txUnderrun ; /* 05h: Tx underrun errors */ - unsigned char txMissIntr ; /* 06h: missed underrun ints */ - unsigned char reserved ; /* 07h: reserved */ - unsigned char droppedDCD ; /* 08h: times DCD dropped */ - unsigned char droppedCTS ; /* 09h: times CTS dropped */ + unsigned char rxOverrun ; /* 00h: Rx overrun errors */ + unsigned char rxBadCrc ; /* 01h: Rx CRC errors */ + unsigned char rxAborted ; /* 02h: Rx aborted frames */ + unsigned char rxDropped ; /* 03h: frames lost */ + unsigned char txAborted ; /* 04h: Tx aborted frames */ + unsigned char txUnderrun ; /* 05h: Tx underrun errors */ + unsigned char txMissIntr ; /* 06h: missed underrun ints */ + unsigned char reserved ; /* 07h: reserved */ + unsigned char droppedDCD ; /* 08h: times DCD dropped */ + unsigned char droppedCTS ; /* 09h: times CTS dropped */ } THdlcCommErr; /* --------------------------------------------------------------------------- @@ -381,47 +382,47 @@ typedef struct HdlcCommErr */ typedef struct X25Config { - unsigned char baudRate ; /* 00h: */ - unsigned char t1 ; /* 01h: */ - unsigned char t2 ; /* 02h: */ - unsigned char n2 ; /* 03h: */ - unsigned short hdlcMTU ; /* 04h: */ - unsigned char hdlcWindow ; /* 06h: */ - unsigned char t4 ; /* 07h: */ - unsigned char autoModem ; /* 08h: */ - unsigned char autoHdlc ; /* 09h: */ - unsigned char hdlcOptions ; /* 0Ah: */ - unsigned char station ; /* 0Bh: */ - unsigned char local_station_address ; + unsigned char baudRate ; /* 00h: */ + unsigned char t1 ; /* 01h: */ + unsigned char t2 ; /* 02h: */ + unsigned char n2 ; /* 03h: */ + unsigned short hdlcMTU ; /* 04h: */ + unsigned char hdlcWindow ; /* 06h: */ + unsigned char t4 ; /* 07h: */ + unsigned char autoModem ; /* 08h: */ + unsigned char autoHdlc ; /* 09h: */ + unsigned char hdlcOptions ; /* 0Ah: */ + unsigned char station ; /* 0Bh: */ + unsigned char local_station_address ; #if 0 - unsigned char pktWindow ; /* 0Ch: */ - unsigned short defPktSize ; /* 0Dh: */ - unsigned short pktMTU ; /* 0Fh: */ - unsigned short loPVC ; /* 11h: */ - unsigned short hiPVC ; /* 13h: */ - unsigned short loIncommingSVC ; /* 15h: */ - unsigned short hiIncommingSVC ; /* 17h: */ - unsigned short loTwoWaySVC ; /* 19h: */ - unsigned short hiTwoWaySVC ; /* 1Bh: */ - unsigned short loOutgoingSVC ; /* 1Dh: */ - unsigned short hiOutgoingSVC ; /* 1Fh: */ - unsigned short options ; /* 21h: */ - unsigned char responseOpt ; /* 23h: */ - unsigned short facil1 ; /* 24h: */ - unsigned short facil2 ; /* 26h: */ - unsigned short ccittFacil ; /* 28h: */ - unsigned short otherFacil ; /* 2Ah: */ - unsigned short ccittCompat ; /* 2Ch: */ - unsigned char t10t20 ; /* 2Eh: */ - unsigned char t11t21 ; /* 2Fh: */ - unsigned char t12t22 ; /* 30h: */ - unsigned char t13t23 ; /* 31h: */ - unsigned char t16t26 ; /* 32H: */ - unsigned char t28 ; /* 33h: */ - unsigned char r10r20 ; /* 34h: */ - unsigned char r12r22 ; /* 35h: */ - unsigned char r13r23 ; /* 36h: */ + unsigned char pktWindow ; /* 0Ch: */ + unsigned short defPktSize ; /* 0Dh: */ + unsigned short pktMTU ; /* 0Fh: */ + unsigned short loPVC ; /* 11h: */ + unsigned short hiPVC ; /* 13h: */ + unsigned short loIncommingSVC ; /* 15h: */ + unsigned short hiIncommingSVC ; /* 17h: */ + unsigned short loTwoWaySVC ; /* 19h: */ + unsigned short hiTwoWaySVC ; /* 1Bh: */ + unsigned short loOutgoingSVC ; /* 1Dh: */ + unsigned short hiOutgoingSVC ; /* 1Fh: */ + unsigned short options ; /* 21h: */ + unsigned char responseOpt ; /* 23h: */ + unsigned short facil1 ; /* 24h: */ + unsigned short facil2 ; /* 26h: */ + unsigned short ccittFacil ; /* 28h: */ + unsigned short otherFacil ; /* 2Ah: */ + unsigned short ccittCompat ; /* 2Ch: */ + unsigned char t10t20 ; /* 2Eh: */ + unsigned char t11t21 ; /* 2Fh: */ + unsigned char t12t22 ; /* 30h: */ + unsigned char t13t23 ; /* 31h: */ + unsigned char t16t26 ; /* 32H: */ + unsigned char t28 ; /* 33h: */ + unsigned char r10r20 ; /* 34h: */ + unsigned char r12r22 ; /* 35h: */ + unsigned char r13r23 ; /* 36h: */ #endif } TX25Config; @@ -431,21 +432,21 @@ typedef struct X25Config */ typedef struct X25ChanAlloc /*----- Channel allocation -*/ { - unsigned short loPVC ; /* 00h: lowest PVC number */ - unsigned short hiPVC ; /* 02h: highest PVC number */ - unsigned short loIncommingSVC ; /* 04h: lowest incoming SVC */ - unsigned short hiIncommingSVC ; /* 06h: highest incoming SVC */ - unsigned short loTwoWaySVC ; /* 08h: lowest two-way SVC */ - unsigned short hiTwoWaySVC ; /* 0Ah: highest two-way SVC */ - unsigned short loOutgoingSVC ; /* 0Ch: lowest outgoing SVC */ - unsigned short hiOutgoingSVC ; /* 0Eh: highest outgoing SVC */ + unsigned short loPVC ; /* 00h: lowest PVC number */ + unsigned short hiPVC ; /* 02h: highest PVC number */ + unsigned short loIncommingSVC ; /* 04h: lowest incoming SVC */ + unsigned short hiIncommingSVC ; /* 06h: highest incoming SVC */ + unsigned short loTwoWaySVC ; /* 08h: lowest two-way SVC */ + unsigned short hiTwoWaySVC ; /* 0Ah: highest two-way SVC */ + unsigned short loOutgoingSVC ; /* 0Ch: lowest outgoing SVC */ + unsigned short hiOutgoingSVC ; /* 0Eh: highest outgoing SVC */ } TX25ChanAlloc; typedef struct X25ChanCfg /*------ Channel configuration -----*/ { - unsigned char type ; /* 00h: channel type */ - unsigned char txConf ; /* 01h: Tx packet and window sizes */ - unsigned char rxConf ; /* 01h: Rx packet and window sizes */ + unsigned char type ; /* 00h: channel type */ + unsigned char txConf ; /* 01h: Tx packet and window sizes */ + unsigned char rxConf ; /* 01h: Rx packet and window sizes */ } TX25ChanCfg; /* @@ -461,38 +462,38 @@ typedef struct X25ChanCfg /*------ Channel configuration -----*/ */ typedef struct X25Stats { /* number of packets Tx/Rx'ed */ - unsigned short txRestartRqst ; /* 00h: Restart Request */ - unsigned short rxRestartRqst ; /* 02h: Restart Request */ - unsigned short txRestartConf ; /* 04h: Restart Confirmation */ - unsigned short rxRestartConf ; /* 06h: Restart Confirmation */ - unsigned short txResetRqst ; /* 08h: Reset Request */ - unsigned short rxResetRqst ; /* 0Ah: Reset Request */ - unsigned short txResetConf ; /* 0Ch: Reset Confirmation */ - unsigned short rxResetConf ; /* 0Eh: Reset Confirmation */ - unsigned short txCallRequest ; /* 10h: Call Request */ - unsigned short rxCallRequest ; /* 12h: Call Request */ - unsigned short txCallAccept ; /* 14h: Call Accept */ - unsigned short rxCallAccept ; /* 16h: Call Accept */ - unsigned short txClearRqst ; /* 18h: Clear Request */ - unsigned short rxClearRqst ; /* 1Ah: Clear Request */ - unsigned short txClearConf ; /* 1Ch: Clear Confirmation */ - unsigned short rxClearConf ; /* 1Eh: Clear Confirmation */ - unsigned short txDiagnostic ; /* 20h: Diagnostic */ - unsigned short rxDiagnostic ; /* 22h: Diagnostic */ - unsigned short txRegRqst ; /* 24h: Registration Request */ - unsigned short rxRegRqst ; /* 26h: Registration Request */ - unsigned short txRegConf ; /* 28h: Registration Confirm.*/ - unsigned short rxRegConf ; /* 2Ah: Registration Confirm.*/ - unsigned short txInterrupt ; /* 2Ch: Interrupt */ - unsigned short rxInterrupt ; /* 2Eh: Interrupt */ - unsigned short txIntrConf ; /* 30h: Interrupt Confirm. */ - unsigned short rxIntrConf ; /* 32h: Interrupt Confirm. */ - unsigned short txData ; /* 34h: Data */ - unsigned short rxData ; /* 36h: Data */ - unsigned short txRR ; /* 38h: RR */ - unsigned short rxRR ; /* 3Ah: RR */ - unsigned short txRNR ; /* 3Ch: RNR */ - unsigned short rxRNR ; /* 3Eh: RNR */ + unsigned short txRestartRqst ; /* 00h: Restart Request */ + unsigned short rxRestartRqst ; /* 02h: Restart Request */ + unsigned short txRestartConf ; /* 04h: Restart Confirmation */ + unsigned short rxRestartConf ; /* 06h: Restart Confirmation */ + unsigned short txResetRqst ; /* 08h: Reset Request */ + unsigned short rxResetRqst ; /* 0Ah: Reset Request */ + unsigned short txResetConf ; /* 0Ch: Reset Confirmation */ + unsigned short rxResetConf ; /* 0Eh: Reset Confirmation */ + unsigned short txCallRequest ; /* 10h: Call Request */ + unsigned short rxCallRequest ; /* 12h: Call Request */ + unsigned short txCallAccept ; /* 14h: Call Accept */ + unsigned short rxCallAccept ; /* 16h: Call Accept */ + unsigned short txClearRqst ; /* 18h: Clear Request */ + unsigned short rxClearRqst ; /* 1Ah: Clear Request */ + unsigned short txClearConf ; /* 1Ch: Clear Confirmation */ + unsigned short rxClearConf ; /* 1Eh: Clear Confirmation */ + unsigned short txDiagnostic ; /* 20h: Diagnostic */ + unsigned short rxDiagnostic ; /* 22h: Diagnostic */ + unsigned short txRegRqst ; /* 24h: Registration Request */ + unsigned short rxRegRqst ; /* 26h: Registration Request */ + unsigned short txRegConf ; /* 28h: Registration Confirm.*/ + unsigned short rxRegConf ; /* 2Ah: Registration Confirm.*/ + unsigned short txInterrupt ; /* 2Ch: Interrupt */ + unsigned short rxInterrupt ; /* 2Eh: Interrupt */ + unsigned short txIntrConf ; /* 30h: Interrupt Confirm. */ + unsigned short rxIntrConf ; /* 32h: Interrupt Confirm. */ + unsigned short txData ; /* 34h: Data */ + unsigned short rxData ; /* 36h: Data */ + unsigned short txRR ; /* 38h: RR */ + unsigned short rxRR ; /* 3Ah: RR */ + unsigned short txRNR ; /* 3Ch: RNR */ + unsigned short rxRNR ; /* 3Eh: RNR */ } TX25Stats; /*---------------------------------------------------------------------------- @@ -500,12 +501,12 @@ typedef struct X25Stats */ typedef struct X25EventLog { - unsigned char type ; /* 00h: transaction type */ - unsigned short lcn ; /* 01h: logical channel num */ - unsigned char packet ; /* 03h: async packet type */ - unsigned char cause ; /* 04h: X.25 cause field */ - unsigned char diag ; /* 05h: X.25 diag field */ - TX25TimeStamp ts ; /* 06h: time stamp */ + unsigned char type ; /* 00h: transaction type */ + unsigned short lcn ; /* 01h: logical channel num */ + unsigned char packet ; /* 03h: async packet type */ + unsigned char cause ; /* 04h: X.25 cause field */ + unsigned char diag ; /* 05h: X.25 diag field */ + TX25TimeStamp ts ; /* 06h: time stamp */ } TX25EventLog; /* @@ -538,8 +539,8 @@ typedef struct X25EventLog */ typedef struct X25TraceCfg { - unsigned char flags ; /* 00h: trace configuration flags */ - unsigned char timeout ; /* 01h: timeout for trace delay mode*/ + unsigned char flags ; /* 00h: trace configuration flags */ + unsigned char timeout ; /* 01h: timeout for trace delay mode*/ } TX25TraceCfg; /* @@ -559,12 +560,12 @@ typedef struct X25TraceCfg */ typedef struct X25Trace /*----- Trace data structure -------*/ { - unsigned short length ; /* 00h: trace data length */ - unsigned char type ; /* 02h: trace type */ - unsigned char lost_cnt ; /* 03h: N of traces lost */ - TX25TimeStamp tstamp ; /* 04h: mon/date/sec/min/hour */ - unsigned short millisec ; /* 09h: ms time stamp */ - unsigned char data[0] ; /* 0Bh: traced frame */ + unsigned short length ; /* 00h: trace data length */ + unsigned char type ; /* 02h: trace type */ + unsigned char lost_cnt ; /* 03h: N of traces lost */ + TX25TimeStamp tstamp ; /* 04h: mon/date/sec/min/hour */ + unsigned short millisec ; /* 09h: ms time stamp */ + unsigned char data[0] ; /* 0Bh: traced frame */ } TX25Trace; /* @@ -589,17 +590,17 @@ typedef struct X25Trace /*----- Trace data structure -------*/ typedef struct HDLCFrame /*----- DHLC Frame Format ----------*/ { - unsigned char addr ; /* address field */ - unsigned char cntl ; /* control field */ - unsigned char data[0] ; + unsigned char addr ; /* address field */ + unsigned char cntl ; /* control field */ + unsigned char data[0] ; } THDLCFrame; typedef struct X25Pkt /*----- X.25 Paket Format ----------*/ { - unsigned char lcn_hi ; /* 4 MSB of Logical Channel Number */ - unsigned char lcn_lo ; /* 8 LSB of Logical Channel Number */ - unsigned char type ; - unsigned char data[0] ; + unsigned char lcn_hi ; /* 4 MSB of Logical Channel Number */ + unsigned char lcn_lo ; /* 8 LSB of Logical Channel Number */ + unsigned char type ; + unsigned char data[0] ; } TX25Pkt; /* @@ -633,27 +634,27 @@ typedef struct X25Pkt /*----- X.25 Paket Format ----------*/ typedef struct { - TX25Cmd cmd ; - char data[X25_MAX_DATA] ; + TX25Cmd cmd ; + char data[X25_MAX_DATA] ; } mbox_cmd_t; #if 0 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 ; - char reserved[7] ; + 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 ; + char reserved[7] ; }x25api_hdr_t; typedef struct { - x25api_hdr_t hdr ; - char data[X25_MAX_DATA] ; + x25api_hdr_t hdr ; + char data[X25_MAX_DATA] ; }x25api_t; #endif @@ -673,75 +674,72 @@ typedef struct { #if 0 typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* command code */ - unsigned short length ; /* transfer data length */ - unsigned char result ; /* return code */ - unsigned char pf ; /* P/F bit */ - unsigned short lcn ; /* logical channel */ - unsigned char qdm ; /* Q/D/M bits */ - unsigned char cause ; /* cause field */ - unsigned char diagn ; /* diagnostics */ - unsigned char pktType ; /* packet type */ - unsigned char resrv[4] ; /* reserved */ + unsigned char opp_flag ; /* the opp flag */ + unsigned char command ; /* command code */ + unsigned short length ; /* transfer data length */ + unsigned char result ; /* return code */ + unsigned char pf ; /* P/F bit */ + unsigned short lcn ; /* logical channel */ + unsigned char qdm ; /* Q/D/M bits */ + unsigned char cause ; /* cause field */ + unsigned char diagn ; /* diagnostics */ + unsigned char pktType ; /* packet type */ + unsigned char resrv[4] ; /* reserved */ } cblock_t; typedef struct { - ip_pkt_t ip_pkt ; - udp_pkt_t udp_pkt ; - wp_mgmt_t wp_mgmt ; - cblock_t cblock ; - unsigned char data[4080] ; + ip_pkt_t ip_pkt ; + udp_pkt_t udp_pkt ; + wp_mgmt_t wp_mgmt ; + cblock_t cblock ; + unsigned char data[4080] ; } x25_udp_pkt_t; #endif typedef struct read_hdlc_stat { - unsigned short inf_frames_rx_ok ; - unsigned short inf_frames_rx_out_of_seq ; - unsigned short inf_frames_rx_no_data ; - unsigned short inf_frames_rx_dropped ; - unsigned short inf_frames_rx_data_too_long ; - unsigned short inf_frames_rx_invalid_addr ; - unsigned short inf_frames_tx_ok ; - unsigned short inf_frames_tx_retransmit ; - unsigned short T1_timeouts ; - unsigned short SABM_frames_rx ; - unsigned short DISC_frames_rx ; - unsigned short DM_frames_rx ; - unsigned short FRMR_frames_rx ; - unsigned short SABM_frames_tx ; - unsigned short DISC_frames_tx ; - unsigned short DM_frames_tx ; - unsigned short FRMR_frames_tx ; + unsigned short inf_frames_rx_ok ; + unsigned short inf_frames_rx_out_of_seq ; + unsigned short inf_frames_rx_no_data ; + unsigned short inf_frames_rx_dropped ; + unsigned short inf_frames_rx_data_too_long ; + unsigned short inf_frames_rx_invalid_addr ; + unsigned short inf_frames_tx_ok ; + unsigned short inf_frames_tx_retransmit ; + unsigned short T1_timeouts ; + unsigned short SABM_frames_rx ; + unsigned short DISC_frames_rx ; + unsigned short DM_frames_rx ; + unsigned short FRMR_frames_rx ; + unsigned short SABM_frames_tx ; + unsigned short DISC_frames_tx ; + unsigned short DM_frames_tx ; + unsigned short FRMR_frames_tx ; } read_hdlc_stat_t; typedef struct read_comms_err_stats{ - unsigned char overrun_err_rx ; - unsigned char CRC_err ; - unsigned char abort_frames_rx ; - unsigned char frames_dropped_buf_full ; - unsigned char abort_frames_tx ; - unsigned char transmit_underruns ; - unsigned char missed_tx_underruns_intr ; - unsigned char reserved ; - unsigned char DCD_drop ; - unsigned char CTS_drop ; + unsigned char overrun_err_rx ; + unsigned char CRC_err ; + unsigned char abort_frames_rx ; + unsigned char frames_dropped_buf_full ; + unsigned char abort_frames_tx ; + unsigned char transmit_underruns ; + unsigned char missed_tx_underruns_intr ; + unsigned char reserved ; + unsigned char DCD_drop ; + unsigned char CTS_drop ; } read_comms_err_stats_t; typedef struct trace_data { - unsigned short length ; - unsigned char type ; - unsigned char trace_dropped ; - unsigned char reserved[5] ; - unsigned short timestamp ; - unsigned char data ; + unsigned short length ; + unsigned char type ; + unsigned char trace_dropped ; + unsigned char reserved[5] ; + unsigned short timestamp ; + unsigned char data ; } trace_data_t; enum {UDP_XPIPE_TYPE}; - -#pragma pack() - #define XPIPE_ENABLE_TRACING 0x14 #define XPIPE_DISABLE_TRACING 0x14 #define XPIPE_GET_TRACE_INFO 0x16 @@ -770,5 +768,6 @@ enum {UDP_XPIPE_TYPE}; #define TRACE_ALL_HDLC_FRMS 0x40 #define TRACE_DATA_FRMS 0x08 +#pragma pack() #endif /* _SDLA_X25_H */ diff --git a/patches/kdrivers/include/sdla_adsl.h b/patches/kdrivers/include/sdla_adsl.h index 0febfc3..83482dd 100644 --- a/patches/kdrivers/include/sdla_adsl.h +++ b/patches/kdrivers/include/sdla_adsl.h @@ -2,7 +2,7 @@ * Copyright (c) 2002 * Alex Feldman . All rights reserved. * - * $Id: sdla_adsl.h,v 1.8 2006/07/25 19:44:50 sangoma Exp $ + * $Id: sdla_adsl.h,v 1.9 2008/01/09 17:45:29 sangoma Exp $ */ /************************************************************************* @@ -24,6 +24,8 @@ #if defined(__FreeBSD__) || defined(__OpenBSD__) # include +#elif defined(__WINDOWS__) +# include #elif defined(__LINUX__) || defined(__KERNEL__) # include #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) @@ -65,10 +67,12 @@ typedef struct adsl_cfg { unsigned char adsl_selected_standard; } adsl_cfg_t; +#if !defined(__WINDOWS__) #undef wan_udphdr_data #define wan_udphdr_data wan_udphdr_adsl_data #undef wan_udp_data #define wan_udp_data wan_udp_hdr.wan_udphdr_adsl_data +#endif #ifdef WAN_KERNEL @@ -88,6 +92,13 @@ typedef struct adsl_private_area #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) struct ifmedia media; /* media information */ #endif +#if defined(__WINDOWS__) + void *sdla_net_dev; + void *card; + struct net_device_stats if_stats; + wan_tasklet_t adsl_if_send_task; /* Immediate BH handler task */ + wan_trace_t trace_info; +#endif } adsl_private_area_t; diff --git a/patches/kdrivers/include/sdla_adsl_iface.h b/patches/kdrivers/include/sdla_adsl_iface.h index 3ffaccf..1ac3254 100644 --- a/patches/kdrivers/include/sdla_adsl_iface.h +++ b/patches/kdrivers/include/sdla_adsl_iface.h @@ -32,6 +32,8 @@ #define ADSL_ACTUAL_CONFIGURATION 0x15 #define ADSL_ACTUAL_INTERLEAVE_STATUS 0x16 #define ADSL_ATM_CELL_COUNTER 0x17 +#define ADSL_EEPROM_WRITE 0x18 +#define ADSL_EEPROM_READ 0x19 typedef struct adsl_failures diff --git a/patches/kdrivers/include/sdla_aft_te1.h b/patches/kdrivers/include/sdla_aft_te1.h index 79118ab..fed0099 100644 --- a/patches/kdrivers/include/sdla_aft_te1.h +++ b/patches/kdrivers/include/sdla_aft_te1.h @@ -25,10 +25,19 @@ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) # include # include +#elif defined(__WINDOWS__) +# include +# include +# include +# include +# define COMPILE_COMMON_PRIVATE_AREA +# include +# define AFT_MAX_CHIP_SECURITY_CNT 100 #else # include # include # include +# include #endif #define AFT_PORT0_OFFSET 0x00000 @@ -79,6 +88,7 @@ # define AFT_CHIPCFG_TE1_CFG_BIT 0 # define AFT_CHIPCFG_56K_CFG_BIT 0 # define AFT_CHIPCFG_ANALOG_CLOCK_SELECT_BIT 0 +# define AFT_CHIPCFG_A500_NET_SYNC_CLOCK_SELECT_BIT 0 # define AFT_CHIPCFG_SFR_EX_BIT 1 # define AFT_CHIPCFG_SFR_IN_BIT 2 # define AFT_CHIPCFG_FE_INTR_CFG_BIT 3 @@ -101,12 +111,26 @@ # define AFT_CHIPCFG_ANALOG_INTR_MASK 0x0F /* Analog */ # define AFT_CHIPCFG_ANALOG_INTR_SHIFT 9 +# define AFT_CHIPCFG_A500_INTR_MASK 0x0F /* A500 BRI - interrupt pending from upto 4 remoras. + bit 9 - remora 1 + bit 10- remora 2 + bit 11- remora 3 + bit 12- remora 4 + */ +# define AFT_CHIPCFG_A500_INTR_SHIFT 9 +# define A500_LINE_SYNC_MASTER_BIT 31 + + # define AFT_CHIPCFG_A108_EC_CLOCK_SRC_MASK 0x07 /* A108 */ # define AFT_CHIPCFG_A108_EC_CLOCK_SRC_SHIFT 9 # define AFT_CHIPCFG_A104D_EC_SECURITY_BIT 12 # define AFT_CHIPCFG_A108_EC_INTR_ENABLE_BIT 12 /* A108 */ + +# define AFT_CHIPCFG_A500_EC_INTR_ENABLE_BIT 14 /* A500 - BRI not used for now */ + + # define AFT_CHIPCFG_EC_INTR_STAT_BIT 13 @@ -122,6 +146,7 @@ # define AFT_CHIPCFG_A200_EC_SECURITY_BIT 15 /* Analog */ # define AFT_CHIPCFG_A108_EC_SECURITY_BIT 15 /* A108 */ +# define AFT_CHIPCFG_A500_EC_SECURITY_BIT 15 /* A500/BRI */ # define AFT_CHIPCFG_P3_TDMV_INTR_BIT 16 # define AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT 16 /* A108 Global Fifo Sync Bit */ @@ -225,12 +250,16 @@ aft_chipcfg_get_tdmv_intr_stats(u32 reg) # define AFT_CHIPCFG_A108_TDMV_INTR_MASK 0xFF # define AFT_CHIPCFG_A108_TDMV_INTR_SHIFT 8 + # define AFT_CHIPCFG_A108_FIFO_INTR_MASK 0xFF # define AFT_CHIPCFG_A108_FIFO_INTR_SHIFT 16 # define AFT_CHIPCFG_A108_DMA_INTR_MASK 0xFF # define AFT_CHIPCFG_A108_DMA_INTR_SHIFT 24 + + + /* A108 Interrupt Status Functions */ static __inline u32 @@ -265,6 +294,46 @@ aft_chipcfg_a108_get_tdmv_intr_stats(u32 reg) return reg; } + +/* AFT Serial specific bits */ + +# define AFT_CHIPCFG_SERIAL_WDT_INTR_MASK 0xF +# define AFT_CHIPCFG_SERIAL_WDT_INTR_SHIFT 0 + +# define AFT_CHIPCFG_SERIAL_STATUS_INTR_MASK 0xFFF +# define AFT_CHIPCFG_SERIAL_STATUS_INTR_SHIFT 4 + +# define AFT_CHIPCFG_SERIAL_CTS_STATUS_INTR_BIT 0 +# define AFT_CHIPCFG_SERIAL_DCD_STATUS_INTR_BIT 1 +# define AFT_CHIPCFG_SERIAL_RTS_STATUS_INTR_BIT 2 + +/* Serial specific functions */ + +static __inline u32 +aft_chipcfg_serial_get_status_intr_stats(u32 reg, int port) +{ + reg=reg>>AFT_CHIPCFG_SERIAL_STATUS_INTR_SHIFT; + reg&=AFT_CHIPCFG_SERIAL_STATUS_INTR_MASK; + + if (port) { + port--; + } + reg=(reg>>(3*port))&0x07; + + return reg; +} + + +static __inline u32 +aft_chipcfg_serial_get_wdt_intr_stats(u32 reg) +{ + reg=reg>>AFT_CHIPCFG_SERIAL_WDT_INTR_SHIFT; + reg&=AFT_CHIPCFG_SERIAL_WDT_INTR_MASK; + return reg; +} + + + /* 56k IRQ status bits */ # define AFT_CHIPCFG_A56K_WDT_INTR_BIT 0 # define AFT_CHIPCFG_A56K_DMA_INTR_BIT 24 @@ -382,10 +451,20 @@ aft_fifo_mark_gset(u32 *reg, u8 mark) } + /*====================================================== - * PER PORT * - * AFT INTERRUPT Configuration Registers + * AFT AFT_CHIP_STAT_REG + * + *=====================================================*/ + + + + + +/*====================================================== + * + * AFT_LINE_CFG_REG * *=====================================================*/ @@ -403,6 +482,7 @@ aft_fifo_mark_gset(u32 *reg, u8 mark) #define AFT_RX_FIFO_INTR_PENDING_REG 0x118 +#define AFT_SERIAL_LINE_CFG_REG 0x210 # define AFT_LCFG_FE_IFACE_RESET_BIT 0 # define AFT_LCFG_TX_FE_SYNC_STAT_BIT 1 @@ -438,8 +518,6 @@ aft_fifo_mark_gset(u32 *reg, u8 mark) # define AFT_LCFG_A108_FE_TE1_MODE_BIT 30 /* A108 */ - - static __inline void aft_lcfg_fe_clk_source(u32 *reg, u32 src) { @@ -541,6 +619,16 @@ aft_dmactrl_set_max_logic_ch(u32 *reg, int max_logic_ch) *reg|=(max_logic_ch<> AFT_DMACTRL_MAX_LOGIC_CH_SHIFT; + return max_logic_ch; +} + + /*====================================================== * PER PORT * @@ -717,6 +805,53 @@ aft_dmachain_enable_tdmv_and_mtu_size(u32 *reg, int size) } + +/*====================================================== + * PER PORT + * + * AFT DMA Descr RAM Registers + * AFT_SERIAL_LINE_CFG_REG + *=====================================================*/ + +#define AFT_SERIAL_LCFG_RTS_BIT 0 +#define AFT_SERIAL_LCFG_DTR_BIT 1 +#define AFT_SERIAL_LCFG_CTS_BIT 2 +#define AFT_SERIAL_LCFG_DCD_BIT 3 +#define AFT_SERIAL_LCFG_POLARITY_BIT 4 +#define AFT_SERIAL_LCFG_SWMODE_BIT 5 + +#define AFT_SERIAL_LCFG_BAUD_SHIFT 8 +#define AFT_SERIAL_LCFG_BAUD_MASK 0xFFFF + +#define AFT_SERIAL_LCFG_CLK_SRC_BIT 24 +#define AFT_SERIAL_LCFG_CTS_INTR_EN_BIT 25 +#define AFT_SERIAL_LCFG_DCD_INTR_EN_BIT 26 +#define AFT_SERIAL_LCFG_IDLE_DET_BIT 27 + +#define AFT_SERIAL_LCFG_LCODING_MASK 0x07 +#define AFT_SERIAL_LCFG_LCODING_SHIFT 28 + +#define AFT_SERIAL_LCFG_IFACE_TYPE_BIT 31 + +static __inline void +aft_serial_set_baud_rate(u32 *reg, u32 rate) +{ + u32 div= (14745600/(2*rate)); + u32 remain= (14745600%(2*rate)); + if (!remain || (remain/2 > rate)) { + div=div-1; + } + *reg&=~(AFT_SERIAL_LCFG_BAUD_MASK< MCLBYTES - 16){ + new_mtu = MCLBYTES-16; + } +#endif + return new_mtu; } static __inline unsigned short aft_dma_buf_bits(unsigned short dma_bufs) @@ -1020,7 +1173,7 @@ static __inline int aft_get_num_of_slots(u32 total_slots, u32 chan_slots) { int num_of_slots=0; - int i; + u32 i; for (i=0;idevname,chan->if_name,reg); - } - } - if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%s: Rx Error: Abort from Target: pci fatal error 0x%X!\n", - card->devname,chan->if_name,reg); - } - } - if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%s: Rx Error: No 'DeviceSelect' from target: pci fatal error 0x%X!\n", - card->devname,chan->if_name,reg); - } - } - if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%s: Rx Error: 'Retry' exceeds maximum (64k): pci fatal error 0x%X!\n", - card->devname,chan->if_name,reg); - } - } - - chan->errstats.Rx_pci_errors++; - chan->if_stats.rx_errors++; - card->wandev.stats.rx_errors++; - return 1; - } - - if (chan->hdlc_eng){ - - /* Checking Rx DMA Frame start bit. (information for api) */ - if (!wan_test_bit(AFT_RXDMA_HI_START_BIT,®)){ - DEBUG_TEST("%s:%s RxDMA Intr: Start flag missing: MTU Mismatch! Reg=0x%X\n", - card->devname,chan->if_name,reg); - chan->if_stats.rx_frame_errors++; - chan->opstats.Rx_Data_discard_long_count++; - chan->errstats.Rx_hdlc_corrupiton++; - card->wandev.stats.rx_errors++; - return 1; - } - - /* Checking Rx DMA Frame end bit. (information for api) */ - if (!wan_test_bit(AFT_RXDMA_HI_EOF_BIT,®)){ - DEBUG_TEST("%s:%s: RxDMA Intr: End flag missing: MTU Mismatch! Reg=0x%X\n", - card->devname,chan->if_name,reg); - chan->if_stats.rx_frame_errors++; - chan->opstats.Rx_Data_discard_long_count++; - chan->errstats.Rx_hdlc_corrupiton++; - card->wandev.stats.rx_errors++; - return 1; - - } else { /* Check CRC error flag only if this is the end of Frame */ - - if (wan_test_bit(AFT_RXDMA_HI_FCS_ERR_BIT,®)){ - DEBUG_TEST("%s:%s: RxDMA Intr: CRC Error! Reg=0x%X Len=%d\n", - card->devname,chan->if_name,reg, - (reg&AFT_RXDMA_HI_DMA_LENGTH_MASK)>>2); - chan->if_stats.rx_frame_errors++; - chan->errstats.Rx_crc_err_count++; - card->wandev.stats.rx_crc_errors++; - data_error = 1; - } - - /* Check if this frame is an abort, if it is - * drop it and continue receiving */ - if (wan_test_bit(AFT_RXDMA_HI_FRM_ABORT_BIT,®)){ - DEBUG_TEST("%s:%s: RxDMA Intr: Abort! Reg=0x%X\n", - card->devname,chan->if_name,reg); - chan->if_stats.rx_frame_errors++; - chan->errstats.Rx_hdlc_corrupiton++; - card->wandev.stats.rx_frame_errors++; - data_error = 1; - } - -#if 0 - if (chan->common.usedby != API && data_error){ - return 1; - } -#else - if (data_error) { - return 1; - } -#endif - - } - } - - return 0; -} - - - void aft_free_logical_channel_num (sdla_t *card, int logic_ch); void aft_dma_max_logic_ch(sdla_t *card); void aft_fe_intr_ctrl(sdla_t *card, int status); void __aft_fe_intr_ctrl(sdla_t *card, int status); void aft_wdt_set(sdla_t *card, unsigned char val); void aft_wdt_reset(sdla_t *card); - +void wanpipe_wake_stack(private_area_t* chan); #endif diff --git a/patches/kdrivers/include/sdla_aft_te1.h~ b/patches/kdrivers/include/sdla_aft_te1.h~ deleted file mode 100644 index 9833cb2..0000000 --- a/patches/kdrivers/include/sdla_aft_te1.h~ +++ /dev/null @@ -1,1585 +0,0 @@ -/***************************************************************************** -* sdla_aft_te1.h -* -* WANPIPE(tm) AFT Hardware Support -* -* Authors: Nenad Corbic -* -* Copyright: (c) 2003-2005 Sangoma Technologies Inc. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* ============================================================================ -* Jan 07, 2003 Nenad Corbic Initial version. -*****************************************************************************/ - - -#ifndef _SDLA_AFT_TE1_H -#define _SDLA_AFT_TE1_H - - -#ifdef WAN_KERNEL - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# include -# include -#else -# include -# include -# include -#endif - -#define AFT_PORT0_OFFSET 0x00000 -#define AFT_PORT1_OFFSET 0x04000 -#define AFT_PORT2_OFFSET 0x08000 -#define AFT_PORT3_OFFSET 0x0C000 - -#define AFT_PORT4_OFFSET 0x10000 -#define AFT_PORT5_OFFSET 0x14000 -#define AFT_PORT6_OFFSET 0x18000 -#define AFT_PORT7_OFFSET 0x1C000 - -#define AFT_PORT_REG(card,reg) (reg+(0x4000*card->wandev.comm_port)) - -/*====================================================== - * GLOBAL (All Ports) - * - * AFT Chip PCI Registers - * - * Global Configuration Area for All Ports - * - *=====================================================*/ - -#define AFT_CHIP_CFG_REG 0x40 - -#define AFT_ANALOG_MCPU_IFACE_RW 0x44 - -#define AFT_WDT_CTRL_REG 0x48 -#define AFT_WDT_1TO4_CTRL_REG AFT_WDT_CTRL_REG - -#define AFT_DATA_MUX_REG 0x4C - -#define AFT_FIFO_MARK_REG 0x50 - -#define AFT_MCPU_INTERFACE_RW 0x54 - -#define AFT_ANALOG_SPI_IFACE_RW 0x54 - -#define AFT_CHIP_STAT_REG 0x58 - -#define AFT_WDT_4TO8_CTRL_REG 0x5C - - -/*================================================= - A104 CHIP CFG REGISTERS -*/ - -# define AFT_CHIPCFG_TE1_CFG_BIT 0 -# define AFT_CHIPCFG_56K_CFG_BIT 0 -# define AFT_CHIPCFG_ANALOG_CLOCK_SELECT_BIT 0 -# define AFT_CHIPCFG_SFR_EX_BIT 1 -# define AFT_CHIPCFG_SFR_IN_BIT 2 -# define AFT_CHIPCFG_FE_INTR_CFG_BIT 3 - -# define AFT_CHIPCFG_A104D_EC_SEC_KEY_MASK 0x7 -# define AFT_CHIPCFG_A104D_EC_SEC_KEY_SHIFT 4 - -# define AFT_CHIPCFG_A200_EC_SEC_KEY_MASK 0x3 -# define AFT_CHIPCFG_A200_EC_SEC_KEY_SHIFT 16 - -# define AFT_CHIPCFG_SPI_SLOW_BIT 5 /* Slow down SPI */ -#if 0 -# define AFT_CHIPCFG_EC_INTR_CFG_BIT 4 /* Shark or Analog */ -# define AFT_CHIPCFG_SECURITY_CFG_BIT 6 -#endif - -# define AFT_CHIPCFG_RAM_READY_BIT 7 -# define AFT_CHIPCFG_HDLC_CTRL_RDY_BIT 8 - -# define AFT_CHIPCFG_ANALOG_INTR_MASK 0x0F /* Analog */ -# define AFT_CHIPCFG_ANALOG_INTR_SHIFT 9 - -# define AFT_CHIPCFG_A108_EC_CLOCK_SRC_MASK 0x07 /* A108 */ -# define AFT_CHIPCFG_A108_EC_CLOCK_SRC_SHIFT 9 - -# define AFT_CHIPCFG_A104D_EC_SECURITY_BIT 12 -# define AFT_CHIPCFG_A108_EC_INTR_ENABLE_BIT 12 /* A108 */ - -# define AFT_CHIPCFG_EC_INTR_STAT_BIT 13 - - -/* A104 A200 A108 Differ Here - * By default any register without device name is - * common to all all. - */ - -# define AFT_CHIPCFG_P1_TDMV_INTR_BIT 14 - -# define AFT_CHIPCFG_P2_TDMV_INTR_BIT 15 -# define AFT_CHIPCFG_A104_TDM_ACK_BIT 15 - -# define AFT_CHIPCFG_A200_EC_SECURITY_BIT 15 /* Analog */ -# define AFT_CHIPCFG_A108_EC_SECURITY_BIT 15 /* A108 */ - -# define AFT_CHIPCFG_P3_TDMV_INTR_BIT 16 -# define AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT 16 /* A108 Global Fifo Sync Bit */ - -# define AFT_CHIPCFG_P4_TDMV_INTR_BIT 17 -# define AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT 17 /* A108 Quad DMA Ring buf enable */ - -# define AFT_CHIPCFG_P1_WDT_INTR_BIT 18 -# define AFT_CHIPCFG_P2_WDT_INTR_BIT 19 -# define AFT_CHIPCFG_P3_WDT_INTR_BIT 20 -# define AFT_CHIPCFG_P4_WDT_INTR_BIT 21 - -# define AFT_CHIPCFG_A108_EC_INTER_STAT_BIT 21 /* A108 */ - -# define AFT_CHIPCFG_FE_INTR_STAT_BIT 22 -# define AFT_CHIPCFG_SECURITY_STAT_BIT 23 - - -/* A104 & A104D IRQ Status Bits */ - -# define AFT_CHIPCFG_HDLC_INTR_MASK 0x0F -# define AFT_CHIPCFG_HDLC_INTR_SHIFT 24 - -# define AFT_CHIPCFG_DMA_INTR_MASK 0x0F -# define AFT_CHIPCFG_DMA_INTR_SHIFT 28 - -# define AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK 30 -# define AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK 31 - -# define AFT_CHIPCFG_WDT_INTR_MASK 0x0F -# define AFT_CHIPCFG_WDT_INTR_SHIFT 18 - -# define AFT_CHIPCFG_TDMV_INTR_MASK 0x0F -# define AFT_CHIPCFG_TDMV_INTR_SHIFT 14 - -# define AFT_CHIPCFG_WDT_FE_INTR_STAT 0 -# define AFT_CHIPCFG_WDT_TX_INTR_STAT 1 -# define AFT_CHIPCFG_WDT_RX_INTR_STAT 2 - - - -/* A104 & A104D Interrupt Status Funcitons */ - -static __inline u32 -aft_chipcfg_get_hdlc_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_HDLC_INTR_SHIFT; - reg&=AFT_CHIPCFG_HDLC_INTR_MASK; - return reg; -} - -static __inline u32 -aft_chipcfg_get_analog_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_ANALOG_INTR_SHIFT; - reg&=AFT_CHIPCFG_ANALOG_INTR_MASK; - return reg; -} - -static __inline void -aft_chipcfg_set_oct_clk_src(u32 *reg, u32 src) -{ - *reg&=~(AFT_CHIPCFG_A108_EC_CLOCK_SRC_MASK<>AFT_CHIPCFG_DMA_INTR_SHIFT; - reg&=AFT_CHIPCFG_DMA_INTR_MASK; - return reg; -} - -static __inline u32 -aft_chipcfg_get_wdt_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_WDT_INTR_SHIFT; - reg&=AFT_CHIPCFG_WDT_INTR_MASK; - return reg; -} - -static __inline u32 -aft_chipcfg_get_tdmv_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_TDMV_INTR_SHIFT; - reg&=AFT_CHIPCFG_TDMV_INTR_MASK; - return reg; -} - - - - -/* A108 IRQ Status Bits on CHIP_STAT_REG */ - -# define AFT_CHIPCFG_A108_WDT_INTR_MASK 0xFF -# define AFT_CHIPCFG_A108_WDT_INTR_SHIFT 0 - -# define AFT_CHIPCFG_A108_TDMV_INTR_MASK 0xFF -# define AFT_CHIPCFG_A108_TDMV_INTR_SHIFT 8 - -# define AFT_CHIPCFG_A108_FIFO_INTR_MASK 0xFF -# define AFT_CHIPCFG_A108_FIFO_INTR_SHIFT 16 - -# define AFT_CHIPCFG_A108_DMA_INTR_MASK 0xFF -# define AFT_CHIPCFG_A108_DMA_INTR_SHIFT 24 - -/* A108 Interrupt Status Functions */ - -static __inline u32 -aft_chipcfg_a108_get_fifo_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_A108_FIFO_INTR_SHIFT; - reg&=AFT_CHIPCFG_A108_FIFO_INTR_MASK; - return reg; -} - -static __inline u32 -aft_chipcfg_a108_get_dma_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_A108_DMA_INTR_SHIFT; - reg&=AFT_CHIPCFG_A108_DMA_INTR_MASK; - return reg; -} - -static __inline u32 -aft_chipcfg_a108_get_wdt_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_A108_WDT_INTR_SHIFT; - reg&=AFT_CHIPCFG_A108_WDT_INTR_MASK; - return reg; -} - -static __inline u32 -aft_chipcfg_a108_get_tdmv_intr_stats(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_A108_TDMV_INTR_SHIFT; - reg&=AFT_CHIPCFG_A108_TDMV_INTR_MASK; - return reg; -} - -/* 56k IRQ status bits */ -# define AFT_CHIPCFG_A56K_WDT_INTR_BIT 0 -# define AFT_CHIPCFG_A56K_DMA_INTR_BIT 24 -# define AFT_CHIPCFG_A56K_FIFO_INTR_BIT 16 - -# define AFT_CHIPCFG_A56K_FE_MASK 0x7F -# define AFT_CHIPCFG_A56K_FE_SHIFT 9 - -static __inline u32 -aft_chipcfg_a56k_read_fe(u32 reg) -{ - reg=reg>>AFT_CHIPCFG_A56K_FE_SHIFT; - reg&=AFT_CHIPCFG_A56K_FE_MASK; - return reg; -} - -static __inline u32 -aft_chipcfg_a56k_write_fe(u32 reg, u32 val) -{ - val&=AFT_CHIPCFG_A56K_FE_MASK; - - reg &= ~(AFT_CHIPCFG_A56K_FE_MASK<>AFT_CHIPCFG_A104D_EC_SEC_KEY_SHIFT)&AFT_CHIPCFG_A104D_EC_SEC_KEY_MASK){ - - case 0x00: - return 0; - case 0x01: - return 32; - case 0x02: - return 64; - case 0x03: - return 96; - case 0x04: - return 128; - case 0x05: - return 256; - default: - return 0; - } - - return 0; -} - - -static __inline u32 -aft_chipcfg_get_a200_ec_channels(u32 reg) -{ - switch ((reg>>AFT_CHIPCFG_A200_EC_SEC_KEY_SHIFT)&AFT_CHIPCFG_A200_EC_SEC_KEY_MASK){ - - case 0x00: - return 0; - case 0x01: - return 16; - case 0x02: - return 32; - default: - return 0; - } - - return 0; -} - -# define AFT_WDTCTRL_MASK 0xFF -# define AFT_WDTCTRL_TIMEOUT 75 /* ms */ - -static __inline void -aft_wdt_ctrl_reset(u8 *reg) -{ - *reg=0xFF; -} -static __inline void -aft_wdt_ctrl_set(u8 *reg, u8 timeout) -{ - timeout&=AFT_WDTCTRL_MASK; - *reg=timeout; -} - - -#define AFT_FIFO_MARK_32_MASK 0x3F -#define AFT_FIFO_MARK_32_SHIFT 0 - -#define AFT_FIFO_MARK_64_MASK 0x3F -#define AFT_FIFO_MARK_64_SHIFT 6 - -#define AFT_FIFO_MARK_128_MASK 0x3F -#define AFT_FIFO_MARK_128_SHIFT 12 - -#define AFT_FIFO_MARK_256_MASK 0x3F -#define AFT_FIFO_MARK_256_SHIFT 18 - -#define AFT_FIFO_MARK_512_MASK 0x3F -#define AFT_FIFO_MARK_512_SHIFT 24 - -static __inline void -aft_fifo_mark_gset(u32 *reg, u8 mark) -{ - mark&=AFT_FIFO_MARK_32_MASK; - - *reg=0; - *reg=(mark<>AFT_LCFG_TDMV_CH_NUM_SHIFT)&AFT_LCFG_TDMV_CH_NUM_MASK; - if (cnt < 32){ - cnt++; - } - *reg&=~(AFT_LCFG_TDMV_CH_NUM_MASK<>AFT_LCFG_TDMV_CH_NUM_SHIFT)&AFT_LCFG_TDMV_CH_NUM_MASK; - if (cnt > 0){ - cnt--; - } - *reg&=~(AFT_LCFG_TDMV_CH_NUM_MASK<>AFT_DMACHAIN_TX_ADDR_CNT_SHIFT; - reg&=AFT_DMACHAIN_TX_ADDR_CNT_MASK; - return reg; -} -static __inline void -aft_dmachain_set_tx_dma_addr(u32 *reg, int addr) -{ - *reg&=~(AFT_DMACHAIN_TX_ADDR_CNT_MASK<>AFT_DMACHAIN_RX_ADDR_CNT_SHIFT; - reg&=AFT_DMACHAIN_RX_ADDR_CNT_MASK; - return reg; -} - - -static __inline void -aft_dmachain_set_rx_dma_addr(u32 *reg, int addr) -{ - *reg&=~(AFT_DMACHAIN_RX_ADDR_CNT_MASK<>AFT_TXDMA_LO_ALIGN_SHIFT; - reg&=AFT_TXDMA_LO_ALIGN_MASK; - return reg; -} - -static __inline void -aft_txdma_hi_set_dma_length(u32 *reg, int len, int align) -{ - *reg&=~(AFT_TXDMA_HI_DMA_LENGTH_MASK<>2)+align; - len&=AFT_TXDMA_HI_DMA_LENGTH_MASK; - *reg|=(len<>AFT_TXDMA_HI_DMA_LENGTH_SHIFT; - reg&=AFT_TXDMA_HI_DMA_LENGTH_MASK; - reg=reg<<2; - return reg; -} - -static __inline u32 -aft_txdma_hi_get_dma_status(u32 reg) -{ - reg=reg>>AFT_TXDMA_HI_DMA_STATUS_SHIFT; - reg&=AFT_TXDMA_HI_DMA_STATUS_MASK; - return reg; -} - -static __inline void -aft_rxdma_lo_set_alignment(u32 *reg, int align) -{ - *reg&=~(AFT_RXDMA_LO_ALIGN_MASK<>AFT_RXDMA_LO_ALIGN_SHIFT; - reg&=AFT_RXDMA_LO_ALIGN_MASK; - return reg; -} - -static __inline void -aft_rxdma_hi_set_dma_length(u32 *reg, int len, int align) -{ - *reg&=~(AFT_RXDMA_HI_DMA_LENGTH_MASK<>2)-align; - len&=AFT_RXDMA_HI_DMA_LENGTH_MASK; - *reg|=(len<>AFT_RXDMA_HI_DMA_LENGTH_SHIFT; - reg&=AFT_RXDMA_HI_DMA_LENGTH_MASK; - reg=reg<<2; - return reg; -} - -static __inline u32 -aft_rxdma_hi_get_dma_status(u32 reg) -{ - reg=reg>>AFT_RXDMA_HI_DMA_STATUS_SHIFT; - reg&=AFT_RXDMA_HI_DMA_STATUS_MASK; - return reg; -} - - -#define FIFO_32B 0x00 -#define FIFO_64B 0x01 -#define FIFO_128B 0x03 -#define FIFO_256B 0x07 -#define FIFO_512B 0x0F -#define FIFO_1024B 0x1F - - - -/*=============================================== - -*/ - -/* Default Active DMA channel used by the - * DMA Engine */ -#define AFT_DEFLT_ACTIVE_CH 0 - -#define MAX_AFT_TX_DMA_SIZE 0xFFFF - -#define MIN_WP_PRI_MTU 8 -#define DEFAULT_WP_PRI_MTU 1500 - -/* Maximum MTU for AFT card - * 8192-4=8188. This is a hardware - * limitation. - */ -#define MAX_WP_PRI_MTU 8188 - -#define MAX_DMA_PER_CH 20 -#define MIN_DMA_PER_CH 2 - -#define WP_MAX_FIFO_FRAMES 7 - -#define AFT_DEFAULT_DATA_MUX_MAP 0x01234567 -enum { - WAN_AFT_RED, - WAN_AFT_GREEN -}; - -enum { - WAN_AFT_OFF, - WAN_AFT_ON -}; - - -/*========================================== - * Board CPLD Interface Section - * - *=========================================*/ - - -#define PMC_CONTROL_REG 0x00 - -/* Used to reset the pcm - * front end - * 0: Reset Enable - * 1: Normal Operation - */ -#define PMC_RESET_BIT 0 - -/* Used to set the pmc clock - * source: - * 0 = E1 - * 1 = T1 - */ -#define PMC_CLOCK_SELECT 1 - -#define LED_CONTROL_REG 0x01 - -#define JP8_VALUE 0x02 -#define JP7_VALUE 0x01 -#define SW0_VALUE 0x04 -#define SW1_VALUE 0x08 - -#define CUSTOMER_CPLD_ID_REG 0x0A - -/* -------------------------------------- */ - -#define WRITE_DEF_SECTOR_DSBL 0x01 -#define FRONT_END_TYPE_MASK 0x38 - - -#define MEMORY_TYPE_SRAM 0x00 -#define MEMORY_TYPE_FLASH 0x01 -#define MASK_MEMORY_TYPE_SRAM 0x10 -#define MASK_MEMORY_TYPE_FLASH 0x20 - -#define BIT_A18_SECTOR_SA4_SA7 0x20 -#define USER_SECTOR_START_ADDR 0x40000 - -#define MAX_TRACE_QUEUE 100 - -#define HDLC_FREE_LOGIC_CH 0x1F -#define AFT_DEFLT_ACTIVE_CH 0 - -static __inline unsigned short aft_valid_mtu(unsigned short mtu) -{ - if (mtu <= 128){ - return 256; - }else if (mtu <= 256){ - return 512; - }else if (mtu <= 512){ - return 1024; - }else if (mtu <= 1024){ - return 2048; - }else if (mtu <= 2048){ - return 4096; - }else if (mtu <= 4096){ - return 8188; - }else if (mtu <= 8188){ - return 8188; - }else{ - return 0; - } -} - -static __inline unsigned short aft_dma_buf_bits(unsigned short dma_bufs) -{ - if (dma_bufs < 2){ - return 0; - }else if (dma_bufs < 3){ - return 1; - }else if (dma_bufs < 5){ - return 2; - }else if (dma_bufs < 9){ - return 3; - }else if (dma_bufs < 17){ - return 4; - }else{ - return 0; - } -} - - -static __inline void -aft_set_led(unsigned int color, int led_pos, int on, u32 *reg) -{ - if (color == WAN_AFT_RED){ - if (on == WAN_AFT_OFF){ - wan_clear_bit(AFT_LCFG_RED_LED_BIT,reg); - }else{ - wan_set_bit(AFT_LCFG_RED_LED_BIT,reg); - } - }else{ - if (on == WAN_AFT_OFF){ - wan_clear_bit(AFT_LCFG_GREEN_LED_BIT,reg); - }else{ - wan_set_bit(AFT_LCFG_GREEN_LED_BIT,reg); - } - } -} - -static __inline int -aft_get_num_of_slots(u32 total_slots, u32 chan_slots) -{ - int num_of_slots=0; - int i; - for (i=0;i= MAX_AFT_HW_DEV){ \ - DEBUG_EVENT("%s:%d: Critical Invalid AFT HW DEV Type %d\n", \ - __FUNCTION__,__LINE__,type); \ - return -EINVAL; \ - }\ - if (!wan_test_bit(0,&aft_hwdev[type].init)) { \ - DEBUG_EVENT("%s:%d: Critical AFT HW DEV Type %d not initialized\n", \ - __FUNCTION__,__LINE__,type); \ - return -EINVAL; \ - } - -#define ASSERT_AFT_HWDEV_VOID(type) \ - if (type >= MAX_AFT_HW_DEV){ \ - DEBUG_EVENT("%s:%d: Critical Invalid AFT HW DEV Type %d\n", \ - __FUNCTION__,__LINE__,type); \ - return; \ - }\ - if (!aft_hwdev[type] || !wan_test_bit(0,&aft_hwdev[type].init)) { \ - DEBUG_EVENT("%s:%d: Critical AFT HW DEV Type %d not initialized\n", \ - __FUNCTION__,__LINE__,type); \ - return; \ - } - - -#endif /* WAN_KERNEL */ - -/*================================================================ - * DRIVER SPECIFIC DEFINES - * - *================================================================*/ - - -#undef wan_udphdr_data -#define wan_udphdr_data wan_udphdr_u.aft.data - - -#define MAX_TRACE_BUFFER (MAX_LGTH_UDP_MGNT_PKT - \ - sizeof(iphdr_t) - \ - sizeof(udphdr_t) - \ - sizeof(wan_mgmt_t) - \ - sizeof(wan_trace_info_t) - \ - sizeof(wan_cmd_t)) - -enum { - TX_DMA_BUF_INIT =0, - TX_DMA_BUF_USED -}; - -enum { - ROUTER_UP_TIME = 0x50, - ENABLE_TRACING, - DISABLE_TRACING, - GET_TRACE_INFO, - READ_CODE_VERSION, - FLUSH_OPERATIONAL_STATS, - OPERATIONAL_STATS, - READ_OPERATIONAL_STATS, - READ_CONFIGURATION, - READ_COMMS_ERROR_STATS, - FLUSH_COMMS_ERROR_STATS, - AFT_LINK_STATUS, - AFT_MODEM_STATUS, - AFT_HWEC_STATUS, - DIGITAL_LOOPTEST -}; - -#define UDPMGMT_SIGNATURE "AFTPIPEA" - - -/* the line trace status element presented by the frame relay code */ -typedef struct { - unsigned char flag ; /* ready flag */ - unsigned short length ; /* trace length */ - unsigned char rsrv0[2] ; /* reserved */ - unsigned char attr ; /* trace attributes */ - unsigned short tmstamp ; /* time stamp */ - unsigned char rsrv1[4] ; /* reserved */ - unsigned int offset ; /* buffer absolute address */ -}aft_trc_el_t; - -typedef struct wp_rx_element -{ - unsigned int dma_addr; - unsigned int reg; - unsigned int align; - unsigned char pkt_error; -}wp_rx_element_t; - - -typedef struct aft_config -{ - unsigned int aft_chip_cfg_reg; - unsigned int aft_dma_control_reg; -}aft_config_t; - - - -#if defined(__LINUX__) -enum { - SIOC_AFT_CUSTOMER_ID = SIOC_WANPIPE_DEVPRIVATE, - SIOC_AFT_SS7_FORCE_RX, - SIOC_WANPIPE_API -}; -#endif - -#pragma pack(1) - -/* the operational statistics structure */ -typedef struct { - - /* Data frame transmission statistics */ - unsigned long Data_frames_Tx_count ; - /* # of frames transmitted */ - unsigned long Data_bytes_Tx_count ; - /* # of bytes transmitted */ - unsigned long Data_Tx_throughput ; - /* transmit throughput */ - unsigned long no_ms_for_Data_Tx_thruput_comp ; - /* millisecond time used for the Tx throughput computation */ - unsigned long Tx_Data_discard_lgth_err_count ; - - /* Data frame reception statistics */ - unsigned long Data_frames_Rx_count ; - /* number of frames received */ - unsigned long Data_bytes_Rx_count ; - /* number of bytes received */ - unsigned long Data_Rx_throughput ; - /* receive throughput */ - unsigned long no_ms_for_Data_Rx_thruput_comp ; - /* millisecond time used for the Rx throughput computation */ - unsigned long Rx_Data_discard_short_count ; - /* received Data frames discarded (too short) */ - unsigned long Rx_Data_discard_long_count ; - /* received Data frames discarded (too long) */ - unsigned long Rx_Data_discard_inactive_count ; - /* received Data frames discarded (link inactive) */ - - /* Incomming frames with a format error statistics */ - unsigned short Rx_frm_incomp_CHDLC_hdr_count ; - /* frames received of with incomplete Cisco HDLC header */ - unsigned short Rx_frms_too_long_count ; - /* frames received of excessive length count */ - - /* CHDLC link active/inactive and loopback statistics */ - unsigned short link_active_count ; - /* number of times that the link went active */ - unsigned short link_inactive_modem_count ; - /* number of times that the link went inactive (modem failure) */ - unsigned short link_inactive_keepalive_count ; - /* number of times that the link went inactive (keepalive failure) */ - unsigned short link_looped_count ; - /* link looped count */ - - unsigned long Data_frames_Tx_realign_count; - -} aft_op_stats_t; - -typedef struct { - unsigned short Rx_overrun_err_count; - unsigned short Rx_crc_err_count ; /* receiver CRC error count */ - unsigned short Rx_abort_count ; /* abort frames recvd count */ - unsigned short Rx_hdlc_corrupiton; /* receiver disabled */ - unsigned short Rx_pci_errors; /* missed tx underrun interrupt count */ - unsigned short Rx_dma_descr_err; /*secondary-abort frames tx count */ - unsigned short DCD_state_change_count ; /* DCD state change */ - unsigned short CTS_state_change_count ; /* CTS state change */ - - unsigned short Tx_pci_errors; /* missed tx underrun interrupt count */ - unsigned short Tx_dma_errors; /* missed tx underrun interrupt count */ - - unsigned int Tx_pci_latency; /* missed tx underrun interrupt count */ - unsigned int Tx_dma_len_nonzero; /* Tx dma descriptor len not zero */ - -} aft_comm_err_stats_t; - -enum wanpipe_aft_api_events { - WP_API_EVENT_NONE, - WP_API_EVENT_DTMF, - WP_API_EVENT_RM_DTMF, - WP_API_EVENT_RXHOOK, - WP_API_EVENT_RING, - WP_API_EVENT_TONE, - WP_API_EVENT_RING_DETECT, - WP_API_EVENT_TXSIG_KEWL, - WP_API_EVENT_TXSIG_START, - WP_API_EVENT_TXSIG_OFFHOOK, - WP_API_EVENT_TXSIG_ONHOOK, - WP_API_EVENT_ONHOOKTRANSFER, - WP_API_EVENT_SETPOLARITY - -}; - -#define WP_API_EVENT_ENABLE 0x01 -#define WP_API_EVENT_DISABLE 0x02 -#define WP_API_EVENT_MODE_DECODE(mode) \ - ((mode) == WP_API_EVENT_ENABLE) ? "Enable" : \ - ((mode) == WP_API_EVENT_DISABLE) ? "Disable" : \ - "(Unknown mode)" - -#define WP_API_EVENT_RXHOOK_OFF 0x01 -#define WP_API_EVENT_RXHOOK_ON 0x02 - -#define WP_API_EVENT_RING_PRESENT 0x01 -#define WP_API_EVENT_RING_STOP 0x02 - -/* tone type */ -#define WP_API_EVENT_TONE_DIAL 0x01 -#define WP_API_EVENT_TONE_BUSY 0x02 -#define WP_API_EVENT_TONE_RING 0x03 -#define WP_API_EVENT_TONE_CONGESTION 0x04 - -typedef struct { - unsigned char error_flag; - unsigned short time_stamp; - unsigned char event_type; - union { - struct { - u_int16_t channel; - union { - struct { - unsigned char rbs_bits; - } rbs; - struct { - unsigned char state; - } rxhook; - struct { - unsigned char state; - } ring; - struct { - unsigned char digit; /* DTMF: digit */ - unsigned char port; /* DTMF: SOUT/ROUT */ - unsigned char type; /* DTMF: PRESET/STOP */ - } dtmf; - } u_event; - } wp_api_event; - unsigned char reserved[12]; - }hdr_u; -#define wp_api_rx_hdr_event_channel hdr_u.wp_api_event.channel -#define wp_api_rx_hdr_event_rxhook_state hdr_u.wp_api_event.u_event.rxhook.state -#define wp_api_rx_hdr_event_ring_state hdr_u.wp_api_event.u_event.ring.state -#define wp_api_rx_hdr_event_dtmf_digit hdr_u.wp_api_event.u_event.dtmf.digit -#define wp_api_rx_hdr_event_dtmf_type hdr_u.wp_api_event.u_event.dtmf.type -#define wp_api_rx_hdr_event_dtmf_port hdr_u.wp_api_event.u_event.dtmf.port -#define wp_api_rx_hdr_event_ringdetect_state hdr_u.wp_api_event.u_event.ring.state -} api_rx_hdr_t; - -typedef struct { - api_rx_hdr_t api_rx_hdr; - unsigned char data[1]; -} api_rx_element_t; - -typedef struct { - unsigned char type; - unsigned char force_tx; - unsigned char data[8]; -} api_tx_ss7_hdr_t; - -typedef struct { - u_int8_t type; - u_int8_t mode; - u_int8_t tone; - u_int16_t channel; - u_int16_t polarity; - u_int16_t ohttimer; - -} api_tdm_event_hdr_t; - -typedef struct { - union { - api_tx_ss7_hdr_t ss7; - api_tdm_event_hdr_t event; - unsigned char reserved[16]; - }u; -#define wp_api_tx_hdr_event_type u.event.type -#define wp_api_tx_hdr_event_mode u.event.mode -#define wp_api_tx_hdr_event_tone u.event.tone -#define wp_api_tx_hdr_event_channel u.event.channel -#define wp_api_tx_hdr_event_ohttimer u.event.ohttimer -#define wp_api_tx_hdr_event_polarity u.event.polarity -} api_tx_hdr_t; - -typedef struct { - api_tx_hdr_t api_tx_hdr; - unsigned char data[1]; -} api_tx_element_t; - - - - -#pragma pack() - -/* Possible RX packet errors */ -enum { - WP_FIFO_ERROR_BIT, - WP_CRC_ERROR_BIT, - WP_ABORT_ERROR_BIT, -}; - - -#ifdef WAN_KERNEL - -#define AFT_MIN_FRMW_VER 0x11 -#define AFT_TDMV_FRM_VER 0x11 -#define AFT_TDMV_FRM_CLK_SYNC_VER 0x14 -#define AFT_TDMV_SHARK_FRM_CLK_SYNC_VER 0x17 -#define AFT_TDMV_SHARK_A108_FRM_CLK_SYNC_VER 0x25 -#define AFT_56K_MIN_FRMW_VER 0x00 - -#define AFT_MIN_ANALOG_FRMW_VER 0x05 - -typedef struct aft_dma_chain -{ - unsigned long init; - sdla_dma_addr_t dma_addr; - u32 dma_len; - u32 dma_map_len; - netskb_t *skb; - u32 index; - - u32 dma_descr; - u32 len_align; - u32 reg; - - u8 pkt_error; - void* dma_virt; - u32 dma_offset; - u32 dma_toggle; -}aft_dma_chain_t; - -typedef struct dma_history{ - u8 end; - u8 cur; - u8 begin; - u8 status; - u8 loc; -}dma_history_t; - -#define MAX_DMA_HIST_SIZE 10 -#define MAX_AFT_DMA_CHAINS 16 -#define MAX_TX_BUF MAX_AFT_DMA_CHAINS*2+1 -#define MAX_RX_BUF MAX_AFT_DMA_CHAINS*4+1 -#define AFT_DMA_INDEX_OFFSET 0x200 - - -typedef struct aft_dma_ring -{ - unsigned char rxdata[128]; - unsigned char txdata[128]; -}aft_dma_ring_t; - -#define AFT_DMA_RING_MAX 4 - -typedef struct aft_dma_swring { - int tx_toggle; - int rx_toggle; - aft_dma_ring_t rbuf[AFT_DMA_RING_MAX]; -}aft_dma_swring_t; - - -typedef struct private_area -{ - wanpipe_common_t common; - sdla_t *card; - - wan_xilinx_conf_if_t cfg; - - wan_skb_queue_t wp_tx_pending_list; - wan_skb_queue_t wp_tx_complete_list; - netskb_t *tx_dma_skb; - u8 tx_dma_cnt; - - wan_skb_queue_t wp_rx_free_list; - wan_skb_queue_t wp_rx_complete_list; - - wan_skb_queue_t wp_rx_stack_complete_list; - wan_skb_queue_t wp_rx_zap_complete_list; - - unsigned long time_slot_map; - unsigned char num_of_time_slots; - long logic_ch_num; - - unsigned char hdlc_eng; - unsigned long dma_status; - unsigned char protocol; - - struct net_device_stats if_stats; - - int tracing_enabled; /* For enabling Tracing */ - unsigned long router_start_time; - unsigned long trace_timeout; - - unsigned long tick_counter; /* For 5s timeout counter */ - unsigned long router_up_time; - - unsigned char mc; /* Mulitcast support on/off */ - - unsigned char interface_down; - - /* Polling task queue. Each interface - * has its own task queue, which is used - * to defer events from the interrupt */ - wan_taskq_t poll_task; - wan_timer_info_t poll_delay_timer; - - u8 gateway; - u8 true_if_encoding; - -#if defined(__LINUX__) - /* Entry in proc fs per each interface */ - struct proc_dir_entry *dent; -#endif - unsigned char udp_pkt_data[sizeof(wan_udp_pkt_t)+10]; - atomic_t udp_pkt_len; - - char if_name[WAN_IFNAME_SZ+1]; - - u8 idle_flag; - u16 max_idle_size; - u8 idle_start; - - u8 pkt_error; - u8 rx_fifo_err_cnt; - - int first_time_slot; - int last_time_slot; - - netskb_t *tx_idle_skb; - unsigned char rx_dma; - unsigned char pci_retry; - - unsigned char fifo_size_code; - unsigned char fifo_base_addr; - unsigned char fifo_size; - - int dma_mru; - int mru,mtu; - - void * prot_ch; - int prot_state; - - wan_trace_t trace_info; - - /* TE1 Specific Dma Chains */ - unsigned char tx_chain_indx,tx_pending_chain_indx; - aft_dma_chain_t tx_dma_chain_table[MAX_AFT_DMA_CHAINS]; - - unsigned char rx_chain_indx,rx_pending_chain_indx; - aft_dma_chain_t rx_dma_chain_table[MAX_AFT_DMA_CHAINS]; - int rx_no_data_cnt; - - unsigned long dma_chain_status; - unsigned long up; - int tx_attempts; - - aft_op_stats_t opstats; - aft_comm_err_stats_t errstats; - - unsigned char *tx_realign_buf; - unsigned char single_dma_chain; - unsigned char tslot_sync; - - dma_history_t dma_history[MAX_DMA_HIST_SIZE]; - unsigned int dma_index; - - /* Used by ss7 mangle code */ - api_tx_hdr_t tx_api_hdr; - unsigned char *tx_ss7_realign_buf; - - int tdmv_chan; - unsigned int tdmv_irq_cfg; - - unsigned char channelized_cfg; - unsigned char tdmv_zaptel_cfg; - - unsigned int tdmv_rx_delay; - unsigned char tdmv_rx_delay_cfg; - unsigned short max_tx_bufs; - unsigned short max_tx_bufs_orig; - - unsigned int ss7_force_rx; - - unsigned char lip_atm; - -#if defined(__LINUX__) - wanpipe_tdm_api_dev_t wp_tdm_api_dev; -#endif - int rx_api_crc_bytes; - - netskb_t *rx_rtp_skb; - netskb_t *tx_rtp_skb; - u32 tdm_call_status; - struct private_area *next; - - aft_dma_swring_t swring; - -}private_area_t; - - -enum { - AFT_CHIP_CONFIGURED, - AFT_FRONT_END_UP, - AFT_TDM_GLOBAL_ISR, - AFT_TDM_RING_BUF, - AFT_TDM_FAST_ISR, - AFT_TDM_SW_RING_BUF -}; - -void aft_free_logical_channel_num (sdla_t *card, int logic_ch); -void aft_dma_max_logic_ch(sdla_t *card); -void aft_fe_intr_ctrl(sdla_t *card, int status); -void __aft_fe_intr_ctrl(sdla_t *card, int status); -void aft_wdt_set(sdla_t *card, unsigned char val); -void aft_wdt_reset(sdla_t *card); - - -#endif - - -#endif diff --git a/patches/kdrivers/include/sdla_aft_te3.h b/patches/kdrivers/include/sdla_aft_te3.h index f1b28ce..fe418d0 100644 --- a/patches/kdrivers/include/sdla_aft_te3.h +++ b/patches/kdrivers/include/sdla_aft_te3.h @@ -864,8 +864,6 @@ set_te3_tx_fract_baud_rate(unsigned int *reg, *reg&=TE3_TX_FRACT_BAUD_RATE_MASK; *reg|=(counter<hw.type != SDLA_S514){ + card->mbox = (void *) card->hw.dpmbase; + }else{ + /* for a S514 adapter, set a pointer to the actual mailbox in the */ + /* allocated virtual memory area */ + card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT; + } +} + +static __inline wan_mbox_t *get_card_mailbox(sdla_t *card) +{ + return (wan_mbox_t*)card->mbox; +} + +static __inline void *get_card_flags(sdla_t *card) +{ + return card->flags; +} + +static __inline void set_card_flags(sdla_t *card, void *ptr) +{ + card->flags = ptr; +} +static __inline void *get_card_rxmb(sdla_t *card) +{ + return card->u.atm.rxmb; +} + +static __inline void set_card_rxmb(sdla_t *card, void *ptr) +{ + card->u.atm.rxmb = ptr; + if((void*)ptr > card->u.atm.rxbuf_last){ + card->u.atm.rxmb = card->u.atm.rxbuf_base; + } +} + +static __inline void *get_card_txbuf(sdla_t *card) +{ + return card->u.atm.txbuf; +} + +static __inline void set_card_txbuf(sdla_t *card, void *ptr) +{ + card->u.atm.txbuf = ptr; + if ((void*)ptr > card->u.atm.txbuf_last){ + card->u.atm.txbuf = card->u.atm.txbuf_base; + } +} + +#endif +#endif diff --git a/patches/kdrivers/include/sdla_bri.h b/patches/kdrivers/include/sdla_bri.h new file mode 100755 index 0000000..1487fd5 --- /dev/null +++ b/patches/kdrivers/include/sdla_bri.h @@ -0,0 +1,366 @@ +/*************************************************************************** + * sdla_bri.h Sangoma ISDN-BRI definitions (for Cologne XHFC-2SU chip). + * + * Author(s): David Rokhvarg + * + * Copyright: (c) 1984 - 2007 Sangoma Technologies Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * ============================================================================ + * February 14, 2007 David Rokhvarg + * v1.0 Initial version. + * + * February 26, 2008 David Rokhvarg + * v1.1 Imrovements in SU State transition code. + * Implemented T3 and T4 timers. + * + ****************************************************************************** + */ + +#ifndef __SDLA_BRI_H +# define __SDLA_BRI_H + +#if defined(__LINUX__) +# include +#else +# include +#endif + +/******************************************************************************* +** DEFINES and MACROS +*******************************************************************************/ + +#define IS_BRI_CARD(card) IS_BRI_FEMEDIA(&(card)->fe) + +#define WAN_BRI_START_CHANNEL 1 + +#define MAX_BRI_REMORAS 4 +#define MAX_BRI_MODULES_PER_REMORA 3 + +/* + Maximum of 4 remoras, 3 modules on each - maximum 12 modules. + On each module there is 1 dual-port ISDN BRI chip. + On each line there are 2 B-channels and 1 D-channel. +*/ +#define MAX_BRI_MODULES 12 +#define MAX_BRI_CHANNELS 2 /* Number of channels per device */ +#define MAX_BRI_LINES (MAX_BRI_MODULES*MAX_BRI_CHANNELS) + +/* + The maximum number of BRI timeslots is 32. + This is needed for the d-chan, which is always at the otherwise unused timeslot 31. + But AFT hardware is actually using only 24 timeslots - only for the b-chans. +*/ +#define MAX_TIMESLOTS 32 +#define BRI_DCHAN_LOGIC_CHAN 31 + +#define BRI_DCHAN_ACTIVE_CFG_CHAN 2 + +#define MAX_BRI_TIMESLOTS 3 /* this is the number of b-chans (2) and the d-chan on one BRI line */ + +#define MAX_TENT_CHANNELS MAX_BRI_MODULES + +#define MOD_TYPE_NONE 0 /* corresponds to module which is not installed */ +#define MOD_TYPE_NT 1 +#define MOD_TYPE_TE 2 +#define MOD_TYPE_TEST 3 + +#define WP_BRI_DECODE_MOD_TYPE(type) \ + (type == MOD_TYPE_NT) ? "NT" : \ + (type == MOD_TYPE_TE) ? "TE" : "Unknown" + +/* SPI interface */ +#define MOD_CHAIN_DISABLED 0 +#define MOD_CHAIN_ENABLED 1 + +#define SPI_INTERFACE_REG 0x54 +#define SPI_MAX_RETRY_COUNT 10 + +#define MOD_SPI_RESET 0x40000000 +#define MOD_SPI_BUSY 0x80000000 +#define MOD_SPI_V3_STAT 0x08000000 /* bit 27 used as START in version 1-2-3 */ +#define MOD_SPI_START 0x08000000 + +#define BRI_FE_MAGIC 0x150D + +#define WAN_BRI_OPERMODE_LEN 20 + +#if !defined(__WINDOWS__) +/* Front-End UDP command */ +#define WAN_FE_TONES (WAN_FE_UDP_CMD_START + 0) +#define WAN_FE_RING (WAN_FE_UDP_CMD_START + 1) +#define WAN_FE_REGDUMP (WAN_FE_UDP_CMD_START + 2) +#define WAN_FE_STATS (WAN_FE_UDP_CMD_START + 3) + +#define WAN_BRI_SET_ECHOTUNE _IOW (ZT_CODE, 63, struct wan_bri_echo_coefs) +#endif + +/****************************************************************************** +** XHFC definitions +*******************************************************************************/ + +/* max. number of S/U ports per XHFC-2SU controller */ +#define BRI_MAX_PORTS_PER_CHIP 2 +#define PORT_0 0 +#define PORT_1 1 + +/* flags in _u16 port mode */ +#define PORT_UNUSED 0x0000 +#define PORT_MODE_NT 0x0001 +#define PORT_MODE_TE 0x0002 +#define PORT_MODE_S0 0x0004 +#define PORT_MODE_UP 0x0008 +#define PORT_MODE_EXCH_POL 0x0010 +#define PORT_MODE_LOOP 0x0020 +#define NT_TIMER 0x8000 + +/* NT / TE defines */ +#define NT_T1_COUNT 25 /* number of 4ms interrupts for G2 timeout */ +#define CLK_DLY_TE 0x0e /* CLKDEL in TE mode */ +#define CLK_DLY_NT 0x6c /* CLKDEL in NT mode */ +#define STA_ACTIVATE 0x60 /* start activation in A_SU_WR_STA */ +#define STA_DEACTIVATE 0x40 /* start deactivation in A_SU_WR_STA */ +#define LIF_MODE_NT 0x04 /* Line Interface NT mode */ + +#define XHFC_TIMER_T3 8000 /* 8s activation timer T3 */ +#define XHFC_TIMER_T4 500 /* 500ms deactivation timer T4 */ + +/* xhfc Layer1 physical commands */ +#define HFC_L1_ACTIVATE_TE 0x01 +#define HFC_L1_FORCE_DEACTIVATE_TE 0x02 +#define HFC_L1_ACTIVATE_NT 0x03 +#define HFC_L1_DEACTIVATE_NT 0x04 +#define HFC_L1_TESTLOOP_B1 0x05 +#define HFC_L1_TESTLOOP_B2 0x06 + +/* xhfc Layer1 Flags (stored in bri_xhfc_port_t->l1_flags) */ +#define HFC_L1_ACTIVATING 1 +#define HFC_L1_ACTIVATED 2 +#define HFC_L1_DEACTTIMER 4 +#define HFC_L1_ACTTIMER 8 + +/* Layer1 timer Flags (stored in bri_xhfc_port_t->timer_flags) */ +#define T3_TIMER_ACTIVE 1 +#define T4_TIMER_ACTIVE 2 + +#define FIFO_MASK_TX 0x55555555 +#define FIFO_MASK_RX 0xAAAAAAAA + + +#ifndef MAX_DFRAME_LEN_L1 +#define MAX_DFRAME_LEN_L1 300 +#endif + +#define USE_F0_COUNTER 1 /* akkumulate F0 counter diff every irq */ +#define TRANSP_PACKET_SIZE 0 /* minium tranparent packet size for transmittion to upper layer */ + +typedef struct sdla_bri_cfg_ { + int not_used; + int opermode; + char opermode_name[WAN_BRI_OPERMODE_LEN]; +/* int tdmv_law;*/ /* WAN_TDMV_ALAW or WAN_TDMV_MULAW */ + char clock_mode; +} sdla_bri_cfg_t; + +#if defined(WAN_KERNEL) + +#if !defined(WAN_DEBUG_FE) + +/* no debugging info compiled */ +/* NT/TE */ +# define WRITE_BRI_REG(mod_no,reg,val) \ + fe->write_fe_reg( fe->card, \ + (int)mod_no, \ + fe->bri_param.mod[mod_no].type, \ + fe->bri_param.mod[mod_no].chain, \ + (int)reg, (int)val) + +# define READ_BRI_REG(mod_no,reg) \ + fe->read_fe_reg( fe->card, \ + (int)mod_no, \ + fe->bri_param.mod[mod_no].type, \ + fe->bri_param.mod[mod_no].chain, \ + (int)reg) + +#else + +#warning "WAN_DEBUG_FE - Debugging Defined" +/* NT/TE */ +# define WRITE_BRI_REG(mod_no,reg,val) \ + fe->write_fe_reg( fe->card, \ + (int)mod_no, \ + fe->bri_param.mod[mod_no].type, \ + fe->bri_param.mod[mod_no].chain, \ + (int)reg, (int)val,__FILE__,(int)__LINE__) + +# define READ_BRI_REG(mod_no,reg) \ + fe->read_fe_reg( fe->card, \ + (int)mod_no, \ + fe->bri_param.mod[mod_no].type, \ + fe->bri_param.mod[mod_no].chain, \ + (int)reg,__FILE__,(int)__LINE__) + +#endif/* #if !defined(WAN_DEBUG_FE) */ + +#define __READ_BRI_REG(mod_no,reg) \ + fe->__read_fe_reg( fe->card, \ + (int)mod_no, \ + fe->bri_param.mod[mod_no].type, \ + fe->bri_param.mod[mod_no].chain, \ + (int)reg) + + +/***************************************************************/ +/* port struct for each S/U port */ +typedef struct { + u_int8_t idx; /* port idx in hw->port[idx] */ + void *hw; /* back pointer to 'wp_bri_module_t' */ + u_int16_t mode; /* NT/TE / ST/U */ + u_int32_t l1_flags; + u_int32_t timer_flags; + + int drx_indx; + int dtx_indx, bytes2transmit; + u_int8_t drxbuf[MAX_DFRAME_LEN_L1]; + u_int8_t dtxbuf[MAX_DFRAME_LEN_L1]; + + /* layer1 ISDN timer */ + wan_timer_t t3_timer; + wan_timer_t t4_timer; + + /* chip registers */ + reg_a_su_rd_sta su_state; + reg_a_su_ctrl0 su_ctrl0; + reg_a_su_ctrl1 su_ctrl1; + reg_a_su_ctrl2 su_ctrl2; + reg_a_st_ctrl3 st_ctrl3; + + /* DavidR */ + reg_a_sl_cfg sl_cfg;/* for data direction programming on pins STIO1 and STIO2 */ + + u_int32_t clock_routing_state, clock_routing_counter; + + u_int32_t l1_state;/* BRI L1 current state of the line */ + int nt_timer; +} bri_xhfc_port_t; + + +/******************************************************************************* +** TYPEDEF STRUCTURE +*******************************************************************************/ +typedef struct { + unsigned int mod_no; + /* Both ports of a module will always be in the + SAME mode - TE or NT. */ + int type; + int chain; + unsigned long events; + +#if 0 +#if defined(__WINDOWS__) + wan_event_ctrl_t current_control_event; + wan_event_ctrl_t *current_control_event_ptr; +#else + WAN_LIST_HEAD(, wan_event_ctrl_) event_head; +#endif +#endif + /* TDM Voice applications */ + int sig; + + /**********************************/ + int num_ports; /* number of S and U interfaces */ + int max_fifo; /* always 4 fifos per port */ + u_int8_t max_z; /* fifo depth -1 */ + + bri_xhfc_port_t port[BRI_MAX_PORTS_PER_CHIP]; /* 2 ports - one for each Line intercace */ + + u_int32_t irq_cnt; /* count irqs */ + u_int32_t f0_cnt; /* last F0 counter value */ + u_int32_t f0_akku; /* akkumulated f0 counter deltas */ + + /* chip registers */ + reg_r_pcm_md0 pcm_md0; + reg_r_pcm_md1 pcm_md1; + /**********************************/ + + void *fe; /* pointer back to 'sdla_fe_t' */ + +} wp_bri_module_t; + +typedef struct { +/* u_int16_t type; */ + unsigned int mod_no; /* A500 - ISDN BRI Remora */ + unsigned char ec_dtmf_port; /* EC DTMF: SOUT or ROUT */ + unsigned long ts_map; + u_int8_t tone; +} sdla_bri_event_t; + +typedef struct sdla_bri_param { + int not_used; + + /* each module has 2 lines, */ + wp_bri_module_t mod[MAX_BRI_LINES]; + /* + Maximum of 4 remoras, 3 modules on each - maximum 12 modules. + On each module there is 1 dual-port ISDN BRI chip. + On each line there are 2 B-channels and 1 D-channel. + + It means we have 48 timeslots (B-channels only!), and 32 bits are not enough. + First 0-23 timeslots will be mapped on 'module_map[0]' and 24-47 will be mapped + on 'module_map[1]'. + */ + u_int32_t module_map[2]; /* Map of available module */ + u_int16_t max_fe_channels; /* Number of available modules */ + + u_int8_t critical; + + /* + Flag indicating if this logical 'card' (sdla_t) which represents a BRI line, + is the 'clock reference port' for the physical A500 card. + Only ONE 'card' may have this flag set to WANOPT_YES, all others must be + WANOPT_NO. + TE mode: if 'is_clock_master' is set to WANOPT_YES, clock recovered from + the line will be routed to ALL other BRI modules on the card. + */ + u_int8_t is_clock_master; + +} sdla_bri_param_t; + + +/******************************************************************************* + DEFINES AND MACROS + *******************************************************************************/ + +/* AFT register - Intel x86 definition. */ +typedef struct bri_reg{ + u_int32_t data:8; /* lsb */ + u_int32_t contrl:8; + + u_int32_t reserv1:8; + u_int32_t mod_addr:2; /* 00, 01, 10 - adresses modules, + code 11 - address of status register per-remora. + */ + + u_int32_t remora_addr:4; /* Select Remora. Maximum is 4 (from 0 to 3) for BRI */ + + u_int32_t reset:1; + u_int32_t start:1;/* msb */ +}bri_reg_t; + +#define READ_BIT (1 << 7) +#define ADDR_BIT (1 << 6) + +/******************************************************************************* +** FUNCTION PROTOTYPES +*******************************************************************************/ +extern int wp_bri_iface_init(void*); + +#endif/* WAN_KERNEL */ + +/***************************************************************/ + +#endif /* __SDLA_BRI_H */ diff --git a/patches/kdrivers/include/sdla_bscmp.h b/patches/kdrivers/include/sdla_bscmp.h index 45d81d1..c87a5ec 100644 --- a/patches/kdrivers/include/sdla_bscmp.h +++ b/patches/kdrivers/include/sdla_bscmp.h @@ -2,9 +2,9 @@ #ifndef _BSC_HEADER_ #define _BSC_HEADER_ - #pragma pack(1) + /*========== MAILBOX COMMANDS AND RETURN CODES ==========*/ #define BSC_READ 0x00 #define BSC_WRITE 0x01 @@ -52,91 +52,91 @@ */ /* control block */ typedef struct { - unsigned char opp_flag ; - unsigned char command ; - unsigned short buffer_length ; - unsigned char return_code ; - unsigned char misc_tx_rx_bits ; - unsigned short heading_length ; - unsigned short notify ; - unsigned char station ; - unsigned char poll_address ; - unsigned char select_address ; - unsigned char device_address ; - unsigned char notify_extended ; - unsigned char reserved ; - unsigned char data[MDATALEN] ; + unsigned char opp_flag ; + unsigned char command ; + unsigned short buffer_length ; + unsigned char return_code ; + unsigned char misc_tx_rx_bits ; + unsigned short heading_length ; + unsigned short notify ; + unsigned char station ; + unsigned char poll_address ; + unsigned char select_address ; + unsigned char device_address ; + unsigned char notify_extended ; + unsigned char reserved ; + unsigned char data[MDATALEN] ; } BSC_MAILBOX_STRUCT; typedef struct { - unsigned char line_speed_number ; - unsigned short max_data_frame_size ; - unsigned char secondary_station ; - unsigned char num_consec_PAD_eof ; - unsigned char num_add_lead_SYN ; - unsigned char conversational_mode ; - unsigned char pp_dial_up_operation ; - unsigned char switched_CTS_RTS ; - unsigned char EBCDIC_encoding ; - unsigned char auto_open ; - unsigned char misc_bits ; - unsigned char protocol_options1 ; - unsigned char protocol_options2 ; - unsigned short reserved_pp ; - unsigned char max_retransmissions ; - unsigned short fast_poll_retries ; - unsigned short TTD_retries ; - unsigned short restart_timer ; - unsigned short pp_slow_restart_timer ; - unsigned short TTD_timer ; - unsigned short pp_delay_between_EOT_ENQ ; - unsigned short response_timer ; - unsigned short rx_data_timer ; - unsigned short NAK_retrans_delay_timer ; - unsigned short wait_CTS_timer ; - unsigned char mp_max_consec_ETX ; - unsigned char mp_general_poll_address ; - unsigned short sec_poll_timeout ; - unsigned char pri_poll_skips_inactive ; - unsigned char sec_additional_stn_send_gpoll ; - unsigned char pri_select_retries ; - unsigned char mp_multipoint_options ; - unsigned short reserved ; + unsigned char line_speed_number ; + unsigned short max_data_frame_size ; + unsigned char secondary_station ; + unsigned char num_consec_PAD_eof ; + unsigned char num_add_lead_SYN ; + unsigned char conversational_mode ; + unsigned char pp_dial_up_operation ; + unsigned char switched_CTS_RTS ; + unsigned char EBCDIC_encoding ; + unsigned char auto_open ; + unsigned char misc_bits ; + unsigned char protocol_options1 ; + unsigned char protocol_options2 ; + unsigned short reserved_pp ; + unsigned char max_retransmissions ; + unsigned short fast_poll_retries ; + unsigned short TTD_retries ; + unsigned short restart_timer ; + unsigned short pp_slow_restart_timer ; + unsigned short TTD_timer ; + unsigned short pp_delay_between_EOT_ENQ ; + unsigned short response_timer ; + unsigned short rx_data_timer ; + unsigned short NAK_retrans_delay_timer ; + unsigned short wait_CTS_timer ; + unsigned char mp_max_consec_ETX ; + unsigned char mp_general_poll_address ; + unsigned short sec_poll_timeout ; + unsigned char pri_poll_skips_inactive ; + unsigned char sec_additional_stn_send_gpoll ; + unsigned char pri_select_retries ; + unsigned char mp_multipoint_options ; + unsigned short reserved ; } BSC_CONFIG_STRUCT; typedef struct { - unsigned char max_tx_queue ; - unsigned char max_rx_queue ; - unsigned char station_flags ; + unsigned char max_tx_queue ; + unsigned char max_rx_queue ; + unsigned char station_flags ; }ADD_STATION_STRUCT; typedef struct { - unsigned char station ; - unsigned short time_stamp ; - unsigned char reserved[13] ; + unsigned char station ; + unsigned short time_stamp ; + unsigned char reserved[13] ; } api_rx_hdr_t; typedef struct { - api_rx_hdr_t api_rx_hdr ; - void * data ; + api_rx_hdr_t api_rx_hdr ; + void * data ; } api_rx_element_t; typedef struct { - unsigned char station ; - unsigned char misc_tx_rx_bits ; - unsigned char reserved[14] ; + unsigned char station ; + unsigned char misc_tx_rx_bits ; + unsigned char reserved[14] ; } api_tx_hdr_t; typedef struct { - api_tx_hdr_t api_tx_hdr ; - void * data ; + api_tx_hdr_t api_tx_hdr ; + void * data ; } api_tx_element_t; -#pragma pack() - #define SIOC_WANPIPE_EXEC_CMD SIOC_WANPIPE_DEVPRIVATE +#pragma pack() + #endif diff --git a/patches/kdrivers/include/sdla_bscstrm.h b/patches/kdrivers/include/sdla_bscstrm.h index d45dfe7..8d97474 100644 --- a/patches/kdrivers/include/sdla_bscstrm.h +++ b/patches/kdrivers/include/sdla_bscstrm.h @@ -1,4 +1,4 @@ -/* $Header: /usr/local/cvsroot/wanpipe_linux/code/include/sdla_bscstrm.h,v 1.3 2004/09/28 21:47:30 sangoma Exp $ */ +/* $Header: /usr/local/cvsroot/wanpipe_linux/code/include/sdla_bscstrm.h,v 1.4 2007/05/24 17:45:25 sangoma Exp $ */ /* @@ -12,6 +12,9 @@ /* * $Log: sdla_bscstrm.h,v $ + * Revision 1.4 2007/05/24 17:45:25 sangoma + * Removed PACKED from include files + * * Revision 1.3 2004/09/28 21:47:30 sangoma * *** empty log message *** * @@ -234,25 +237,25 @@ typedef struct { #define RX_EXCESSIVE_LGTH_ERR_APP_LVL 0x20 /* the received block was too long (application level) */ typedef struct { - unsigned char station ; - unsigned short time_stamp ; - unsigned char reserved[13] ; + unsigned char station ; + 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_hdr_t api_rx_hdr ; + unsigned char data[1] ; } api_rx_element_t; typedef struct { - unsigned char station ; - unsigned char misc_tx_rx_bits ; - unsigned char reserved[14] ; + unsigned char station ; + unsigned char misc_tx_rx_bits ; + unsigned char reserved[14] ; } api_tx_hdr_t; typedef struct { - api_tx_hdr_t api_tx_hdr ; - unsigned char data[1] ; + api_tx_hdr_t api_tx_hdr ; + unsigned char data[1] ; } api_tx_element_t; #pragma pack() diff --git a/patches/kdrivers/include/sdla_bstrm.h b/patches/kdrivers/include/sdla_bstrm.h index a793ea2..af936f2 100644 --- a/patches/kdrivers/include/sdla_bstrm.h +++ b/patches/kdrivers/include/sdla_bstrm.h @@ -13,13 +13,11 @@ * Sep 24, 1998 Jaspreet Singh o Initial Version. *****************************************************************************/ - -#ifndef __SDLA_BSTRM__ -#define __SDLA_BSTRM__ +#ifndef __SDLA_BSTRM_H__ +#define __SDLA_BSTRM_H__ #pragma pack(1) - /* Status flag for determining whether to perform a check on socket receive * queue. */ @@ -84,20 +82,20 @@ for the mailbox header area, we are left with a mailbox data size of 4064 bytes. /* the mailbox structure */ typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* the user command */ - unsigned short buffer_length ; /* the data length */ - unsigned char return_code ; /* the return code */ - unsigned char misc_Tx_Rx_bits ; /* miscellaneous transmit and receive bits */ - unsigned char Rx_error_bits ; /* an indication of a block received with an error */ - unsigned short Rx_time_stamp ; /* a millisecond receive time stamp */ - unsigned char reserved[7] ; /* reserved for later use */ - char data[SIZEOF_MB_DATA_BFR] ; /* the data area */ + unsigned char opp_flag ; /* the opp flag */ + unsigned char command ; /* the user command */ + unsigned short buffer_length ; /* the data length */ + unsigned char return_code ; /* the return code */ + unsigned char misc_Tx_Rx_bits ; /* miscellaneous transmit and receive bits */ + unsigned char Rx_error_bits ; /* an indication of a block received with an error */ + unsigned short Rx_time_stamp ; /* a millisecond receive time stamp */ + unsigned char reserved[7] ; /* reserved for later use */ + char data[SIZEOF_MB_DATA_BFR] ; /* the data area */ } MAILBOX_STRUCT; typedef struct { - pid_t pid_num ; - MAILBOX_STRUCT cmdarea ; + pid_t pid_num ; + MAILBOX_STRUCT cmdarea ; } CMDBLOCK_STRUCT; /* definitions for setting the configuration */ @@ -134,18 +132,18 @@ typedef struct { /* the configuration structure */ typedef struct { - unsigned long baud_rate ; /* the baud rate */ - unsigned long adapter_frequency ; /* the adapter frequecy */ - unsigned short max_data_length ; /* the maximum length of a BSC data block */ - unsigned short EBCDIC_encoding ; /* EBCDIC/ASCII encoding */ - unsigned short Rx_block_type ; /* the type of BSC block to be received */ - unsigned short no_consec_PADs_EOB ; /* the number of consecutive PADs indicating the end of the block */ - unsigned short no_add_lead_Tx_SYN_chars ; /* the number of additional leading transmit SYN characters */ - unsigned short no_bits_per_char ; /* the number of bits per character */ - unsigned short parity ; /* parity */ - unsigned short misc_config_options ; /* miscellaneous configuration options */ - unsigned short statistics_options ; /* statistic options */ - unsigned short modem_config_options ; /* modem configuration options */ + unsigned long baud_rate ; /* the baud rate */ + unsigned long adapter_frequency ; /* the adapter frequecy */ + unsigned short max_data_length ; /* the maximum length of a BSC data block */ + unsigned short EBCDIC_encoding ; /* EBCDIC/ASCII encoding */ + unsigned short Rx_block_type ; /* the type of BSC block to be received */ + unsigned short no_consec_PADs_EOB ; /* the number of consecutive PADs indicating the end of the block */ + unsigned short no_add_lead_Tx_SYN_chars ; /* the number of additional leading transmit SYN characters */ + unsigned short no_bits_per_char ; /* the number of bits per character */ + unsigned short parity ; /* parity */ + unsigned short misc_config_options ; /* miscellaneous configuration options */ + unsigned short statistics_options ; /* statistic options */ + unsigned short modem_config_options ; /* modem configuration options */ } CONFIGURATION_STRUCT; @@ -173,13 +171,13 @@ typedef struct { /* definitions for reading the operational statistics */ /* the operational statistics structure */ typedef struct { - unsigned long no_blocks_Rx ; /* the number of data blocks received and made available for the application */ - unsigned long no_bytes_Rx ; /* the number of bytes received and made available for the application */ - unsigned long no_blocks_Tx ; /* the number of data blocks transmitted */ - unsigned long no_bytes_Tx ; /* the number of bytes transmitted */ + unsigned long no_blocks_Rx ; /* the number of data blocks received and made available for the application */ + unsigned long no_bytes_Rx ; /* the number of bytes received and made available for the application */ + unsigned long no_blocks_Tx ; /* the number of data blocks transmitted */ + unsigned long no_bytes_Tx ; /* the number of bytes transmitted */ } OPERATIONAL_STATS_STRUCT; -#pragma pack() + /* definitions for interrupt usage */ /* 'interrupt_triggers' bit mapping set by a SET_INTERRUPT_TRIGGERS command */ @@ -211,3 +209,7 @@ typedef struct { #define RX_OVERRUN_ERROR 0x02 /* a receive overrun error occurred */ #define RX_EXCESSIVE_LGTH_ERR_INT_LVL 0x10 /* the received block was too long (interrupt level) */ #define RX_EXCESSIVE_LGTH_ERR_APP_LVL 0x20 /* the received block was too long (application level) */ + +#pragma pack() + +#endif diff --git a/patches/kdrivers/include/sdla_chdlc.h b/patches/kdrivers/include/sdla_chdlc.h index 062e6b4..1ac5783 100644 --- a/patches/kdrivers/include/sdla_chdlc.h +++ b/patches/kdrivers/include/sdla_chdlc.h @@ -32,6 +32,7 @@ #define _SDLA_CHDLC_H #if defined(__LINUX__) +# include # include #else # include @@ -65,12 +66,12 @@ #if 0 typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* the user command */ - unsigned short buffer_length ; /* the data length */ - unsigned char return_code ; /* the return code */ - unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] ; /* reserved for later */ - unsigned char data[SIZEOF_MB_DATA_BFR] ; /* the data area */ + unsigned char opp_flag ; /* the opp flag */ + unsigned char command ; /* the user command */ + unsigned short buffer_length ; /* the data length */ + unsigned char return_code ; /* the return code */ + unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] ; /* reserved for later */ + unsigned char data[SIZEOF_MB_DATA_BFR] ; /* the data area */ } CHDLC_MAILBOX_STRUCT; #endif @@ -219,6 +220,15 @@ typedef struct { #define LINK_DISCONNECTED 0x21 #define NO_TX_BFRS_AVAIL 0x24 +typedef struct { + unsigned char modem_status; +} MODEM_STATUS_STRUCT; + +#define SET_MODEM_DTR_HIGH 0x01 +#define SET_MODEM_RTS_HIGH 0x02 + +#define MODEM_CTS_MASK 0x20 +#define MODEM_DCD_MASK 0x08 /* ---------------------------------------------------------------------------- * Constants for the SET_GLOBAL_CONFIGURATION/READ_GLOBAL_CONFIGURATION commands @@ -226,10 +236,10 @@ typedef struct { /* the global configuration structure */ typedef struct { - unsigned short adapter_config_options ; /* adapter config options */ - unsigned short app_IRQ_timeout ; /* application IRQ timeout */ - unsigned int adapter_operating_frequency ; /* adapter operating frequency */ - unsigned short frame_transmit_timeout ; + unsigned short adapter_config_options ; /* adapter config options */ + unsigned short app_IRQ_timeout ; /* application IRQ timeout */ + unsigned int adapter_operating_frequency ; /* adapter operating frequency */ + unsigned short frame_transmit_timeout ; } GLOBAL_CONFIGURATION_STRUCT; /* settings for the 'app_IRQ_timeout' */ @@ -243,7 +253,7 @@ typedef struct { /* the global statistics structure */ typedef struct { - unsigned short app_IRQ_timeout_count ; + unsigned short app_IRQ_timeout_count ; } GLOBAL_STATS_STRUCT; @@ -254,16 +264,16 @@ typedef struct { /* the communications error statistics structure */ typedef struct { - unsigned short Rx_overrun_err_count ; - unsigned short CRC_err_count ; /* receiver CRC error count */ - unsigned short Rx_abort_count ; /* abort frames recvd count */ - unsigned short Rx_dis_pri_bfrs_full_count ;/* receiver disabled */ - unsigned short comms_err_stat_reserved_1 ;/* reserved for later */ - unsigned short sec_Tx_abort_msd_Tx_int_count ; /* secondary - abort frames transmitted count (missed Tx interrupt) */ - unsigned short missed_Tx_und_int_count ; /* missed tx underrun interrupt count */ - unsigned short sec_Tx_abort_count ; /*secondary-abort frames tx count */ - unsigned short DCD_state_change_count ; /* DCD state change */ - unsigned short CTS_state_change_count ; /* CTS state change */ + unsigned short Rx_overrun_err_count ; + unsigned short CRC_err_count ; /* receiver CRC error count */ + unsigned short Rx_abort_count ; /* abort frames recvd count */ + unsigned short Rx_dis_pri_bfrs_full_count ;/* receiver disabled */ + unsigned short comms_err_stat_reserved_1 ;/* reserved for later */ + unsigned short sec_Tx_abort_msd_Tx_int_count ; /* secondary - abort frames transmitted count (missed Tx interrupt) */ + unsigned short missed_Tx_und_int_count ; /* missed tx underrun interrupt count */ + unsigned short sec_Tx_abort_count ; /*secondary-abort frames tx count */ + unsigned short DCD_state_change_count ; /* DCD state change */ + unsigned short CTS_state_change_count ; /* CTS state change */ } COMMS_ERROR_STATS_STRUCT; @@ -274,9 +284,9 @@ typedef struct { /* the trace configuration structure (SET_TRACE_CONFIGURATION/READ_TRACE_CONFIGURATION commands) */ typedef struct { - unsigned char trace_config ; /* trace configuration */ - unsigned short trace_deactivation_timer ; /* trace deactivation timer */ - unsigned int ptr_trace_stat_el_cfg_struct ; /* a pointer to the line trace element configuration structure */ + unsigned char trace_config ; /* trace configuration */ + unsigned short trace_deactivation_timer ; /* trace deactivation timer */ + unsigned int ptr_trace_stat_el_cfg_struct ; /* a pointer to the line trace element configuration structure */ } LINE_TRACE_CONFIG_STRUCT; /* 'trace_config' bit settings */ @@ -289,22 +299,22 @@ typedef struct { /* the line trace status element configuration structure */ typedef struct { - unsigned short number_trace_status_elements ; /* number of line trace elements */ - unsigned int base_addr_trace_status_elements ; /* base address of the trace element list */ - unsigned int next_trace_element_to_use ; /* pointer to the next trace element to be used */ - unsigned int base_addr_trace_buffer ; /* base address of the trace data buffer */ - unsigned int end_addr_trace_buffer ; /* end address of the trace data buffer */ + unsigned short number_trace_status_elements ; /* number of line trace elements */ + unsigned int base_addr_trace_status_elements ; /* base address of the trace element list */ + unsigned int next_trace_element_to_use ; /* pointer to the next trace element to be used */ + unsigned int base_addr_trace_buffer ; /* base address of the trace data buffer */ + unsigned int end_addr_trace_buffer ; /* end address of the trace data buffer */ } TRACE_STATUS_EL_CFG_STRUCT; /* the line trace status element structure */ typedef struct { - unsigned char opp_flag ; /* opp flag */ - unsigned short trace_length ; /* trace length */ - unsigned char trace_type ; /* trace type */ - unsigned short trace_time_stamp ; /* time stamp */ - unsigned short trace_reserved_1 ; /* reserved for later use */ - unsigned int trace_reserved_2 ; /* reserved for later use */ - unsigned int ptr_data_bfr ; /* ptr to the trace data buffer */ + unsigned char opp_flag ; /* opp flag */ + unsigned short trace_length ; /* trace length */ + unsigned char trace_type ; /* trace type */ + unsigned short trace_time_stamp ; /* time stamp */ + unsigned short trace_reserved_1 ; /* reserved for later use */ + unsigned int trace_reserved_2 ; /* reserved for later use */ + unsigned int ptr_data_bfr ; /* ptr to the trace data buffer */ } TRACE_STATUS_ELEMENT_STRUCT; /* "trace_type" bit settings */ @@ -318,8 +328,8 @@ typedef struct { /* the line trace statistics structure */ typedef struct { - unsigned int frames_traced_count ; /* number of frames traced */ - unsigned int trc_frms_not_recorded_count ; /* number of trace frames discarded */ + unsigned int frames_traced_count ; /* number of frames traced */ + unsigned int trc_frms_not_recorded_count ; /* number of trace frames discarded */ } LINE_TRACE_STATS_STRUCT; @@ -341,24 +351,24 @@ typedef struct { /* the CHDLC configuration structure */ typedef struct { - unsigned int baud_rate ; /* the baud rate */ - unsigned short line_config_options ; /* line configuration options */ - unsigned short modem_config_options ; /* modem configration options */ - unsigned short modem_status_timer ; /* timer for monitoring modem status changes */ - unsigned short CHDLC_API_options ; /* CHDLC API options */ - unsigned short CHDLC_protocol_options ; /* CHDLC protocol options */ - unsigned short percent_data_buffer_for_Tx ; /* percentage data buffering used for Tx */ - unsigned short CHDLC_statistics_options ; /* CHDLC operational statistics options */ - unsigned short max_CHDLC_data_field_length ; /* the maximum length of the CHDLC Data field */ - unsigned short transmit_keepalive_timer ; /* the transmit keepalive timer */ - unsigned short receive_keepalive_timer ; /* the receive keepalive timer */ - unsigned short keepalive_error_tolerance ; /* the receive keepalive error tolerance */ - unsigned short SLARP_request_timer ; /* the SLARP request timer */ - unsigned int IP_address ; /* the IP address */ - unsigned int IP_netmask ; /* the IP netmask */ - unsigned int ptr_shared_mem_info_struct ; /* a pointer to the shared memory area information structure */ - unsigned int ptr_CHDLC_Tx_stat_el_cfg_struct ; /* a pointer to the transmit status element configuration structure */ - unsigned int ptr_CHDLC_Rx_stat_el_cfg_struct ; /* a pointer to the receive status element configuration structure */ + unsigned int baud_rate ; /* the baud rate */ + unsigned short line_config_options ; /* line configuration options */ + unsigned short modem_config_options ; /* modem configration options */ + unsigned short modem_status_timer ; /* timer for monitoring modem status changes */ + unsigned short CHDLC_API_options ; /* CHDLC API options */ + unsigned short CHDLC_protocol_options ; /* CHDLC protocol options */ + unsigned short percent_data_buffer_for_Tx ; /* percentage data buffering used for Tx */ + unsigned short CHDLC_statistics_options ; /* CHDLC operational statistics options */ + unsigned short max_CHDLC_data_field_length ; /* the maximum length of the CHDLC Data field */ + unsigned short transmit_keepalive_timer ; /* the transmit keepalive timer */ + unsigned short receive_keepalive_timer ; /* the receive keepalive timer */ + unsigned short keepalive_error_tolerance ; /* the receive keepalive error tolerance */ + unsigned short SLARP_request_timer ; /* the SLARP request timer */ + unsigned int IP_address ; /* the IP address */ + unsigned int IP_netmask ; /* the IP netmask */ + unsigned int ptr_shared_mem_info_struct ; /* a pointer to the shared memory area information structure */ + unsigned int ptr_CHDLC_Tx_stat_el_cfg_struct ; /* a pointer to the transmit status element configuration structure */ + unsigned int ptr_CHDLC_Rx_stat_el_cfg_struct ; /* a pointer to the receive status element configuration structure */ } CHDLC_CONFIGURATION_STRUCT; /* settings for the 'line_config_options' */ @@ -460,10 +470,10 @@ typedef struct { /* the CHDLC status structure */ typedef struct { - unsigned char CHDLC_link_status ; /* CHDLC link status */ - unsigned char no_Data_frms_for_app ; /* number of Data frames available for the application */ - unsigned char receiver_status ; /* enabled/disabled */ - unsigned char SLARP_state ; /* internal SLARP state */ + unsigned char CHDLC_link_status ; /* CHDLC link status */ + unsigned char no_Data_frms_for_app ; /* number of Data frames available for the application */ + unsigned char receiver_status ; /* enabled/disabled */ + unsigned char SLARP_state ; /* internal SLARP state */ } CHDLC_LINK_STATUS_STRUCT; /* settings for the 'CHDLC_link_status' variable */ @@ -478,10 +488,10 @@ typedef struct { /* the structure used for the SET_CHDLC_INTERRUPT_TRIGGERS/READ_CHDLC_INTERRUPT_TRIGGERS command */ typedef struct { - unsigned char CHDLC_interrupt_triggers ; /* CHDLC interrupt trigger configuration */ - unsigned char IRQ ; /* IRQ to be used */ - unsigned short interrupt_timer ; /* interrupt timer */ - unsigned short misc_interrupt_bits ; /* miscellaneous bits */ + unsigned char CHDLC_interrupt_triggers ; /* CHDLC interrupt trigger configuration */ + unsigned char IRQ ; /* IRQ to be used */ + unsigned short interrupt_timer ; /* interrupt timer */ + unsigned short misc_interrupt_bits ; /* miscellaneous bits */ } CHDLC_INT_TRIGGERS_STRUCT; /* 'CHDLC_interrupt_triggers' bit settings */ @@ -515,19 +525,19 @@ typedef struct { /* the Data frame transmit status element configuration structure */ typedef struct { - unsigned short number_Tx_status_elements ; /* number of transmit status elements */ - unsigned int base_addr_Tx_status_elements ; /* base address of the transmit element list */ - unsigned int next_Tx_status_element_to_use ; /* pointer to the next transmit element to be used */ + unsigned short number_Tx_status_elements ; /* number of transmit status elements */ + unsigned int base_addr_Tx_status_elements ; /* base address of the transmit element list */ + unsigned int next_Tx_status_element_to_use ; /* pointer to the next transmit element to be used */ } CHDLC_TX_STATUS_EL_CFG_STRUCT; /* the Data frame transmit status element structure */ typedef struct { - unsigned char opp_flag ; /* opp flag */ - unsigned short frame_length ; /* length of the frame to be transmitted */ - unsigned char misc_Tx_bits ; /* miscellaneous transmit bits */ - unsigned int reserved_2 ; /* reserved for internal use */ - unsigned int reserved_3 ; /* reserved for internal use */ - unsigned int ptr_data_bfr ; /* pointer to the data area */ + unsigned char opp_flag ; /* opp flag */ + unsigned short frame_length ; /* length of the frame to be transmitted */ + unsigned char misc_Tx_bits ; /* miscellaneous transmit bits */ + unsigned int reserved_2 ; /* reserved for internal use */ + unsigned int reserved_3 ; /* reserved for internal use */ + unsigned int ptr_data_bfr ; /* pointer to the data area */ } CHDLC_DATA_TX_STATUS_EL_STRUCT; @@ -556,22 +566,22 @@ typedef struct { /* the Data frame receive status element configuration structure */ typedef struct { - unsigned short number_Rx_status_elements ; /* number of receive status elements */ - unsigned int base_addr_Rx_status_elements ; /* base address of the receive element list */ - unsigned int next_Rx_status_element_to_use ; /* pointer to the next receive element to be used */ - unsigned int base_addr_Rx_buffer ; /* base address of the receive data buffer */ - unsigned int end_addr_Rx_buffer ; /* end address of the receive data buffer */ + unsigned short number_Rx_status_elements ; /* number of receive status elements */ + unsigned int base_addr_Rx_status_elements ; /* base address of the receive element list */ + unsigned int next_Rx_status_element_to_use ; /* pointer to the next receive element to be used */ + unsigned int base_addr_Rx_buffer ; /* base address of the receive data buffer */ + unsigned int end_addr_Rx_buffer ; /* end address of the receive data buffer */ } CHDLC_RX_STATUS_EL_CFG_STRUCT; /* the Data frame receive status element structure */ typedef struct { - unsigned char opp_flag ; /* opp flag */ - unsigned short frame_length ; /* length of the received frame */ - unsigned char error_flag ; /* frame errors (HDLC_STREAMING_MODE)*/ - unsigned short time_stamp ; /* receive time stamp (HDLC_STREAMING_MODE) */ - unsigned int reserved_1 ; /* reserved for internal use */ - unsigned short reserved_2 ; /* reserved for internal use */ - unsigned int ptr_data_bfr ; /* pointer to the data area */ + unsigned char opp_flag ; /* opp flag */ + unsigned short frame_length ; /* length of the received frame */ + unsigned char error_flag ; /* frame errors (HDLC_STREAMING_MODE)*/ + unsigned short time_stamp ; /* receive time stamp (HDLC_STREAMING_MODE) */ + unsigned int reserved_1 ; /* reserved for internal use */ + unsigned short reserved_2 ; /* reserved for internal use */ + unsigned int ptr_data_bfr ; /* pointer to the data area */ } CHDLC_DATA_RX_STATUS_EL_STRUCT; @@ -593,41 +603,41 @@ typedef struct { /* the global information structure */ typedef struct { - unsigned char global_status ; /* global status */ - unsigned char modem_status ; /* current modem status */ - unsigned char global_excep_conditions ; /* global exception conditions */ - unsigned char glob_info_reserved[5] ; /* reserved */ - unsigned char codename[4] ; /* Firmware name */ - unsigned char codeversion[4] ; /* Firmware version */ + unsigned char global_status ; /* global status */ + unsigned char modem_status ; /* current modem status */ + unsigned char global_excep_conditions ; /* global exception conditions */ + unsigned char glob_info_reserved[5] ; /* reserved */ + unsigned char codename[4] ; /* Firmware name */ + unsigned char codeversion[4] ; /* Firmware version */ } GLOBAL_INFORMATION_STRUCT; /* the CHDLC information structure */ typedef struct { - unsigned char CHDLC_status ; /* CHDLC status */ - unsigned char CHDLC_excep_conditions ; /* CHDLC exception conditions */ - unsigned char CHDLC_info_reserved[14] ; /* reserved */ + unsigned char CHDLC_status ; /* CHDLC status */ + unsigned char CHDLC_excep_conditions ; /* CHDLC exception conditions */ + unsigned char CHDLC_info_reserved[14] ; /* reserved */ } CHDLC_INFORMATION_STRUCT; /* the interrupt information structure */ typedef struct { - unsigned char interrupt_type ; /* type of interrupt triggered */ - unsigned char interrupt_permission ; /* interrupt permission mask */ - unsigned char int_info_reserved[14] ; /* reserved */ + unsigned char interrupt_type ; /* type of interrupt triggered */ + unsigned char interrupt_permission ; /* interrupt permission mask */ + unsigned char int_info_reserved[14] ; /* reserved */ } INTERRUPT_INFORMATION_STRUCT; /* the S508/FT1 information structure */ typedef struct { - unsigned char parallel_port_A_input ; /* input - parallel port A */ - unsigned char parallel_port_B_input ; /* input - parallel port B */ - unsigned char FT1_info_reserved[14] ; /* reserved */ + unsigned char parallel_port_A_input ; /* input - parallel port A */ + unsigned char parallel_port_B_input ; /* input - parallel port B */ + unsigned char FT1_info_reserved[14] ; /* reserved */ } FT1_INFORMATION_STRUCT; /* the shared memory area information structure */ typedef struct { - GLOBAL_INFORMATION_STRUCT global_info_struct ; /* the global information structure */ - CHDLC_INFORMATION_STRUCT CHDLC_info_struct ; /* the CHDLC information structure */ - INTERRUPT_INFORMATION_STRUCT interrupt_info_struct ; /* the interrupt information structure */ - FT1_INFORMATION_STRUCT FT1_info_struct ; /* the S508/FT1 information structure */ + GLOBAL_INFORMATION_STRUCT global_info_struct ; /* the global information structure */ + CHDLC_INFORMATION_STRUCT CHDLC_info_struct ; /* the CHDLC information structure */ + INTERRUPT_INFORMATION_STRUCT interrupt_info_struct ; /* the interrupt information structure */ + FT1_INFORMATION_STRUCT FT1_info_struct ; /* the S508/FT1 information structure */ } SHARED_MEMORY_INFO_STRUCT; /* ---------------------------------------------------------------------------- @@ -640,55 +650,55 @@ typedef struct { #ifndef HDLC_PROT_ONLY typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* the user command */ - unsigned short buffer_length ; /* the data length */ - unsigned char return_code ; /* the return code */ - unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] ; /* reserved for later */ + unsigned char opp_flag ; /* the opp flag */ + unsigned char command ; /* the user command */ + unsigned short buffer_length ; /* the data length */ + unsigned char return_code ; /* the return code */ + unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] ; /* reserved for later */ } cblock_t; /* UDP management packet layout (data area of ip packet) */ /* typedef struct { - unsigned char signature[8] ; - unsigned char request_reply ; - unsigned char id ; - unsigned char reserved[6] ; - cblock_t cblock ; - unsigned char num_frames ; - unsigned char ismoredata ; - unsigned char data[SIZEOF_MB_DATA_BFR] ; + unsigned char signature[8] ; + unsigned char request_reply ; + unsigned char id ; + unsigned char reserved[6] ; + cblock_t cblock ; + unsigned char num_frames ; + unsigned char ismoredata ; + unsigned char data[SIZEOF_MB_DATA_BFR] ; } udp_management_packet_t; */ typedef struct { - unsigned char num_frames ; - unsigned char ismoredata ; + unsigned char num_frames ; + unsigned char ismoredata ; } trace_info_t; #if 0 typedef struct { - ip_pkt_t ip_pkt ; - udp_pkt_t udp_pkt ; - wp_mgmt_t wp_mgmt ; - cblock_t cblock ; - trace_info_t trace_info ; - unsigned char data[SIZEOF_MB_DATA_BFR] ; + ip_pkt_t ip_pkt ; + udp_pkt_t udp_pkt ; + wp_mgmt_t wp_mgmt ; + cblock_t cblock ; + trace_info_t trace_info ; + unsigned char data[SIZEOF_MB_DATA_BFR] ; } chdlc_udp_pkt_t; #endif typedef struct ft1_exec_cmd{ - unsigned char command ; /* the user command */ - unsigned short buffer_length ; /* the data length */ - unsigned char return_code ; /* the return code */ - unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] ; + unsigned char command ; /* the user command */ + unsigned short buffer_length ; /* the data length */ + unsigned char return_code ; /* the return code */ + unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] ; } ft1_exec_cmd_t; typedef struct { - unsigned char opp_flag ; - ft1_exec_cmd_t cmd ; - unsigned char data[SIZEOF_MB_DATA_BFR] ; + unsigned char opp_flag ; + ft1_exec_cmd_t cmd ; + unsigned char data[SIZEOF_MB_DATA_BFR] ; } ft1_exec_t; @@ -699,19 +709,19 @@ typedef struct { /* UDP/IP packet (for UDP management) layout */ /* typedef struct { - unsigned char reserved[2] ; - unsigned short ip_length ; - unsigned char reserved2[4] ; - unsigned char ip_ttl ; - unsigned char ip_protocol ; - unsigned short ip_checksum ; - unsigned int ip_src_address ; - unsigned int ip_dst_address ; - unsigned short udp_src_port ; - unsigned short udp_dst_port ; - unsigned short udp_length ; - unsigned short udp_checksum ; - udp_management_packet_t um_packet ; + unsigned char reserved[2] ; + unsigned short ip_length ; + unsigned char reserved2[4] ; + unsigned char ip_ttl ; + unsigned char ip_protocol ; + unsigned short ip_checksum ; + unsigned int ip_src_address ; + unsigned int ip_dst_address ; + unsigned short udp_src_port ; + unsigned short udp_dst_port ; + unsigned short udp_length ; + unsigned short udp_checksum ; + udp_management_packet_t um_packet ; } ip_packet_t; */ @@ -720,36 +730,36 @@ typedef struct { #if 0 typedef struct { - unsigned char status ; - unsigned char data_avail ; - unsigned short real_length ; - unsigned short time_stamp ; - unsigned char data[1] ; + unsigned char status ; + unsigned char data_avail ; + unsigned short real_length ; + unsigned short time_stamp ; + unsigned char data[1] ; } trace_pkt_t; #endif typedef struct { - unsigned char error_flag ; - unsigned short time_stamp ; - unsigned int sec ; - unsigned int usec ; - unsigned char reserved[5] ; + unsigned char error_flag ; + unsigned short time_stamp ; + unsigned int sec ; + unsigned int usec ; + unsigned char reserved[5] ; } api_rx_hdr_t; typedef struct { - api_rx_hdr_t api_rx_hdr ; - unsigned char data[1] ; + api_rx_hdr_t api_rx_hdr ; + unsigned char data[1] ; } api_rx_element_t; typedef struct { - unsigned char attr ; - unsigned char misc_Tx_bits ; - unsigned char reserved[14] ; + unsigned char attr ; + unsigned char misc_Tx_bits ; + unsigned char reserved[14] ; } api_tx_hdr_t; typedef struct { - api_tx_hdr_t api_tx_hdr ; - unsigned char data[1] ; + api_tx_hdr_t api_tx_hdr ; + unsigned char data[1] ; } api_tx_element_t; #endif //HDLC_PROT_ONLY @@ -768,7 +778,6 @@ typedef struct { } ft1_config_t; -#pragma pack() /* settings for the 'framing_mode' */ #define ESF_FRAMING 0x00 /* ESF framing */ @@ -807,13 +816,23 @@ typedef struct { #define AUTO_FT1_CFG_FAIL_OP_MODE 0x0C #define AUTO_FT1_CFG_FAIL_INVALID_LINE 0x0D +#if !defined(__WINDOWS__) #undef wan_udphdr_data #define wan_udphdr_data wan_udphdr_u.chdlc.data +#endif #ifdef __KERNEL__ #undef wan_udp_data #define wan_udp_data wan_udp_hdr.wan_udphdr_u.chdlc.data #endif +#pragma pack() + + +#if defined(__LINUX__) +enum { + SIOC_MBOX_CMD = SIOC_WANPIPE_DEVPRIVATE +}; +#endif #endif /* _SDLA_CHDLC_H */ diff --git a/patches/kdrivers/include/sdla_fr.h b/patches/kdrivers/include/sdla_fr.h index 53023c9..e07e1a6 100644 --- a/patches/kdrivers/include/sdla_fr.h +++ b/patches/kdrivers/include/sdla_fr.h @@ -34,8 +34,10 @@ * -------- -------- * GNU C Linux */ + #pragma pack(1) + /* Adapter memory layout */ #define FR_MB_VECTOR 0xE000 /* mailbox window vector */ #define FR502_RX_VECTOR 0xA000 /* S502 direct receive window vector */ @@ -63,14 +65,14 @@ */ typedef struct fr_cmd { - unsigned char command ; /* command code */ - unsigned short length ; /* length of data buffer */ - unsigned char result ; /* return code */ - unsigned short dlci ; /* DLCI number */ - unsigned char attr ; /* FECN, BECN, DE and C/R bits */ - unsigned short rxlost1 ; /* frames discarded at int. level */ - unsigned int rxlost2 ; /* frames discarded at app. level */ - unsigned char rsrv[2] ; /* reserved for future use */ + unsigned char command ; /* command code */ + unsigned short length ; /* length of data buffer */ + unsigned char result ; /* return code */ + unsigned short dlci ; /* DLCI number */ + unsigned char attr ; /* FECN, BECN, DE and C/R bits */ + unsigned short rxlost1 ; /* frames discarded at int. level */ + unsigned int rxlost2 ; /* frames discarded at app. level */ + unsigned char rsrv[2] ; /* reserved for future use */ } fr_cmd_t; @@ -116,14 +118,14 @@ typedef struct fr_cmd */ typedef struct fr502_flags { - unsigned char rsrv1[1] ; /* 00h: */ - unsigned char tx_ready ; /* 01h: Tx buffer available */ - unsigned char rx_ready ; /* 02h: Rx frame available */ - unsigned char event ; /* 03h: asynchronous event */ - unsigned char mstatus ; /* 04h: modem status */ - unsigned char rsrv2[8] ; /* 05h: */ - unsigned char iflag ; /* 0Dh: interrupt flag */ - unsigned char imask ; /* 0Eh: interrupt mask */ + unsigned char rsrv1[1] ; /* 00h: */ + unsigned char tx_ready ; /* 01h: Tx buffer available */ + unsigned char rx_ready ; /* 02h: Rx frame available */ + unsigned char event ; /* 03h: asynchronous event */ + unsigned char mstatus ; /* 04h: modem status */ + unsigned char rsrv2[8] ; /* 05h: */ + unsigned char iflag ; /* 0Dh: interrupt flag */ + unsigned char imask ; /* 0Eh: interrupt mask */ } fr502_flags_t; /*---------------------------------------------------------------------------- @@ -132,14 +134,14 @@ typedef struct fr502_flags */ typedef struct fr508_flags { - unsigned char rsrv1[3] ; /* 00h: reserved */ - unsigned char event ; /* 03h: asynchronous event */ - unsigned char mstatus ; /* 04h: modem status */ - unsigned char rsrv2[11] ; /* 05h: reserved */ - unsigned char iflag ; /* 10h: interrupt flag */ - unsigned char imask ; /* 11h: interrupt mask */ - unsigned int tse_offs ; /* 12h: Tx status element */ - unsigned short dlci ; /* 16h: DLCI NUMBER */ + unsigned char rsrv1[3] ; /* 00h: reserved */ + unsigned char event ; /* 03h: asynchronous event */ + unsigned char mstatus ; /* 04h: modem status */ + unsigned char rsrv2[11] ; /* 05h: reserved */ + unsigned char iflag ; /* 10h: interrupt flag */ + unsigned char imask ; /* 11h: interrupt mask */ + unsigned int tse_offs ; /* 12h: Tx status element */ + unsigned short dlci ; /* 16h: DLCI NUMBER */ } fr508_flags_t; /* 'event' field defines */ @@ -168,12 +170,12 @@ typedef struct fr508_flags */ typedef struct fr_buf_info { - unsigned short rse_num ; /* 00h: number of status elements */ - unsigned int rse_base ; /* 02h: receive status array base */ - unsigned int rse_next ; /* 06h: next status element */ - unsigned int buf_base ; /* 0Ah: rotational buffer base */ - unsigned short reserved ; /* 0Eh: */ - unsigned int buf_top ; /* 10h: rotational buffer top */ + unsigned short rse_num ; /* 00h: number of status elements */ + unsigned int rse_base ; /* 02h: receive status array base */ + unsigned int rse_next ; /* 06h: next status element */ + unsigned int buf_base ; /* 0Ah: rotational buffer base */ + unsigned short reserved ; /* 0Eh: */ + unsigned int buf_top ; /* 10h: rotational buffer top */ } fr_buf_info_t; /*---------------------------------------------------------------------------- @@ -184,24 +186,24 @@ typedef struct fr_buf_info */ typedef struct fr_rx_buf_ctl { - unsigned char flag ; /* 00h: ready flag */ - unsigned short length ; /* 01h: frame length */ - unsigned short dlci ; /* 03h: DLCI */ - unsigned char attr ; /* 05h: FECN/BECN/DE/CR */ - unsigned short tmstamp ; /* 06h: time stamp */ - unsigned short rsrv[2] ; /* 08h: */ - unsigned int offset ; /* 0Ch: buffer absolute address */ + unsigned char flag ; /* 00h: ready flag */ + unsigned short length ; /* 01h: frame length */ + unsigned short dlci ; /* 03h: DLCI */ + unsigned char attr ; /* 05h: FECN/BECN/DE/CR */ + unsigned short tmstamp ; /* 06h: time stamp */ + unsigned short rsrv[2] ; /* 08h: */ + unsigned int offset ; /* 0Ch: buffer absolute address */ } fr_rx_buf_ctl_t; typedef struct fr_tx_buf_ctl { - unsigned char flag ; /* 00h: ready flag */ - unsigned short rsrv0[2] ; /* 01h: */ - unsigned short length ; /* 05h: frame length */ - unsigned short dlci ; /* 07h: DLCI */ - unsigned char attr ; /* 09h: FECN/BECN/DE/CR */ - unsigned short rsrv1 ; /* 0Ah: */ - unsigned int offset ; /* 0Ch: buffer absolute address */ + unsigned char flag ; /* 00h: ready flag */ + unsigned short rsrv0[2] ; /* 01h: */ + unsigned short length ; /* 05h: frame length */ + unsigned short dlci ; /* 07h: DLCI */ + unsigned char attr ; /* 09h: FECN/BECN/DE/CR */ + unsigned short rsrv1 ; /* 0Ah: */ + unsigned int offset ; /* 0Ch: buffer absolute address */ } fr_tx_buf_ctl_t; /*---------------------------------------------------------------------------- @@ -209,23 +211,23 @@ typedef struct fr_tx_buf_ctl */ typedef struct fr_conf { - unsigned short station ; /* 00h: CPE/Node */ - unsigned short options ; /* 02h: configuration options */ - unsigned short kbps ; /* 04h: baud rate in kbps */ - unsigned short port ; /* 06h: RS-232/V.35 */ - unsigned short mtu ; /* 08h: max. transmit length */ - unsigned short t391 ; /* 0Ah: */ - unsigned short t392 ; /* 0Ch: */ - unsigned short n391 ; /* 0Eh: */ - unsigned short n392 ; /* 10h: */ - unsigned short n393 ; /* 12h: */ - unsigned short cir_fwd ; /* 14h: */ - unsigned short bc_fwd ; /* 16h: */ - unsigned short be_fwd ; /* 18h: */ - unsigned short cir_bwd ; /* 1Ah: */ - unsigned short bc_bwd ; /* 1Ch: */ - unsigned short be_bwd ; /* 1Eh: */ - unsigned short dlci[0] ; /* 20h: */ + unsigned short station ; /* 00h: CPE/Node */ + unsigned short options ; /* 02h: configuration options */ + unsigned short kbps ; /* 04h: baud rate in kbps */ + unsigned short port ; /* 06h: RS-232/V.35 */ + unsigned short mtu ; /* 08h: max. transmit length */ + unsigned short t391 ; /* 0Ah: */ + unsigned short t392 ; /* 0Ch: */ + unsigned short n391 ; /* 0Eh: */ + unsigned short n392 ; /* 10h: */ + unsigned short n393 ; /* 12h: */ + unsigned short cir_fwd ; /* 14h: */ + unsigned short bc_fwd ; /* 16h: */ + unsigned short be_fwd ; /* 18h: */ + unsigned short cir_bwd ; /* 1Ah: */ + unsigned short bc_bwd ; /* 1Ch: */ + unsigned short be_bwd ; /* 1Eh: */ + unsigned short dlci[0] ; /* 20h: */ } fr_conf_t; /* 'station_type' defines */ @@ -262,26 +264,26 @@ typedef struct fr_conf /* the line trace status element presented by the frame relay code */ typedef struct { - unsigned char flag ; /* ready flag */ - unsigned short length ; /* trace length */ - unsigned char rsrv0[2] ; /* reserved */ - unsigned char attr ; /* trace attributes */ - unsigned short tmstamp ; /* time stamp */ - unsigned char rsrv1[4] ; /* reserved */ - unsigned int offset ; /* buffer absolute address */ + unsigned char flag ; /* ready flag */ + unsigned short length ; /* trace length */ + unsigned char rsrv0[2] ; /* reserved */ + unsigned char attr ; /* trace attributes */ + unsigned short tmstamp ; /* time stamp */ + unsigned char rsrv1[4] ; /* reserved */ + unsigned int offset ; /* buffer absolute address */ } fr_trc_el_t; typedef struct { - unsigned char status ; /* status flag */ - unsigned char data_passed ; /* 0 if no data passed, 1 if */ + unsigned char status ; /* status flag */ + unsigned char data_passed ; /* 0 if no data passed, 1 if */ /* data passed */ - unsigned short length ; /* frame length */ - unsigned short tmstamp ; /* time stamp */ + unsigned short length ; /* frame length */ + unsigned short tmstamp ; /* time stamp */ } fpipemon_trc_hdr_t; typedef struct { - fpipemon_trc_hdr_t fpipemon_trc_hdr ; - unsigned char data[FR_MAX_NO_DATA_BYTES_IN_FRAME] ; + fpipemon_trc_hdr_t fpipemon_trc_hdr ; + unsigned char data[FR_MAX_NO_DATA_BYTES_IN_FRAME] ; } fpipemon_trc_t; /* bit settings for the 'status' byte - note that bits 1, 2 and 3 are used */ @@ -311,13 +313,13 @@ typedef struct { */ typedef struct fr_dlc_conf { - unsigned short conf_flags ; /* 00h: configuration bits */ - unsigned short cir_fwd ; /* 02h: */ - unsigned short bc_fwd ; /* 04h: */ - unsigned short be_fwd ; /* 06h: */ - unsigned short cir_bwd ; /* 08h: */ - unsigned short bc_bwd ; /* 0Ah: */ - unsigned short be_bwd ; /* 0Ch: */ + unsigned short conf_flags ; /* 00h: configuration bits */ + unsigned short cir_fwd ; /* 02h: */ + unsigned short bc_fwd ; /* 04h: */ + unsigned short be_fwd ; /* 06h: */ + unsigned short cir_bwd ; /* 08h: */ + unsigned short bc_bwd ; /* 0Ah: */ + unsigned short be_bwd ; /* 0Ch: */ } fr_dlc_conf_t; /*---------------------------------------------------------------------------- @@ -327,8 +329,8 @@ typedef struct fr_dlc_conf */ typedef struct fr502_intr_ctl { - unsigned char mode ; /* 00h: interrupt enable flags */ - unsigned short tx_len ; /* 01h: required Tx buffer size */ + unsigned char mode ; /* 00h: interrupt enable flags */ + unsigned short tx_len ; /* 01h: required Tx buffer size */ } fr502_intr_ctl_t; /*---------------------------------------------------------------------------- @@ -338,11 +340,11 @@ typedef struct fr502_intr_ctl */ typedef struct fr508_intr_ctl { - unsigned char mode ; /* 00h: interrupt enable flags */ - unsigned short tx_len ; /* 01h: required Tx buffer size */ - unsigned char irq ; /* 03h: IRQ level to activate */ - unsigned char flags ; /* 04h: ?? */ - unsigned short timeout ; /* 05h: ms, for timer interrupt */ + unsigned char mode ; /* 00h: interrupt enable flags */ + unsigned short tx_len ; /* 01h: required Tx buffer size */ + unsigned char irq ; /* 03h: IRQ level to activate */ + unsigned char flags ; /* 04h: ?? */ + unsigned short timeout ; /* 05h: ms, for timer interrupt */ } fr508_intr_ctl_t; /*---------------------------------------------------------------------------- @@ -351,12 +353,12 @@ typedef struct fr508_intr_ctl */ typedef struct fr_dlc_Status { - unsigned char status ; /* 00h: link/DLCI status */ + unsigned char status ; /* 00h: link/DLCI status */ struct { - unsigned short dlci ; /* 01h: DLCI number */ - unsigned char status ; /* 03h: DLCI status */ - } circuit[1] ; + unsigned short dlci ; /* 01h: DLCI number */ + unsigned char status ; /* 03h: DLCI status */ + } circuit[1] ; } fr_dlc_status_t; /* 'status' defines */ @@ -378,34 +380,34 @@ typedef struct fr_dlc_Status */ typedef struct fr_link_stat { - unsigned short rx_too_long ; /* 00h: */ - unsigned short rx_dropped ; /* 02h: */ - unsigned short rx_dropped2 ; /* 04h: */ - unsigned short rx_bad_dlci ; /* 06h: */ - unsigned short rx_bad_format ; /* 08h: */ - unsigned short retransmitted ; /* 0Ah: */ - unsigned short cpe_tx_FSE ; /* 0Ch: */ - unsigned short cpe_tx_LIV ; /* 0Eh: */ - unsigned short cpe_rx_FSR ; /* 10h: */ - unsigned short cpe_rx_LIV ; /* 12h: */ - unsigned short node_rx_FSE ; /* 14h: */ - unsigned short node_rx_LIV ; /* 16h: */ - unsigned short node_tx_FSR ; /* 18h: */ - unsigned short node_tx_LIV ; /* 1Ah: */ - unsigned short rx_ISF_err ; /* 1Ch: */ - unsigned short rx_unsolicited ; /* 1Eh: */ - unsigned short rx_SSN_err ; /* 20h: */ - unsigned short rx_RSN_err ; /* 22h: */ - unsigned short T391_timeouts ; /* 24h: */ - unsigned short T392_timeouts ; /* 26h: */ - unsigned short N392_reached ; /* 28h: */ - unsigned short cpe_SSN_RSN ; /* 2Ah: */ - unsigned short current_SSN ; /* 2Ch: */ - unsigned short current_RSN ; /* 2Eh: */ - unsigned short curreny_T391 ; /* 30h: */ - unsigned short current_T392 ; /* 32h: */ - unsigned short current_N392 ; /* 34h: */ - unsigned short current_N393 ; /* 36h: */ + unsigned short rx_too_long ; /* 00h: */ + unsigned short rx_dropped ; /* 02h: */ + unsigned short rx_dropped2 ; /* 04h: */ + unsigned short rx_bad_dlci ; /* 06h: */ + unsigned short rx_bad_format ; /* 08h: */ + unsigned short retransmitted ; /* 0Ah: */ + unsigned short cpe_tx_FSE ; /* 0Ch: */ + unsigned short cpe_tx_LIV ; /* 0Eh: */ + unsigned short cpe_rx_FSR ; /* 10h: */ + unsigned short cpe_rx_LIV ; /* 12h: */ + unsigned short node_rx_FSE ; /* 14h: */ + unsigned short node_rx_LIV ; /* 16h: */ + unsigned short node_tx_FSR ; /* 18h: */ + unsigned short node_tx_LIV ; /* 1Ah: */ + unsigned short rx_ISF_err ; /* 1Ch: */ + unsigned short rx_unsolicited ; /* 1Eh: */ + unsigned short rx_SSN_err ; /* 20h: */ + unsigned short rx_RSN_err ; /* 22h: */ + unsigned short T391_timeouts ; /* 24h: */ + unsigned short T392_timeouts ; /* 26h: */ + unsigned short N392_reached ; /* 28h: */ + unsigned short cpe_SSN_RSN ; /* 2Ah: */ + unsigned short current_SSN ; /* 2Ch: */ + unsigned short current_RSN ; /* 2Eh: */ + unsigned short curreny_T391 ; /* 30h: */ + unsigned short current_T392 ; /* 32h: */ + unsigned short current_N392 ; /* 34h: */ + unsigned short current_N393 ; /* 36h: */ } fr_link_stat_t; /*---------------------------------------------------------------------------- @@ -415,18 +417,18 @@ typedef struct fr_link_stat */ typedef struct fr_dlci_stat { - unsigned int tx_frames ; /* 00h: */ - unsigned int tx_bytes ; /* 04h: */ - unsigned int rx_frames ; /* 08h: */ - unsigned int rx_bytes ; /* 0Ch: */ - unsigned int rx_dropped ; /* 10h: */ - unsigned int rx_inactive ; /* 14h: */ - unsigned int rx_exceed_CIR ; /* 18h: */ - unsigned int rx_DE_set ; /* 1Ch: */ - unsigned int tx_throughput ; /* 20h: */ - unsigned int tx_calc_timer ; /* 24h: */ - unsigned int rx_throughput ; /* 28h: */ - unsigned int rx_calc_timer ; /* 2Ch: */ + unsigned int tx_frames ; /* 00h: */ + unsigned int tx_bytes ; /* 04h: */ + unsigned int rx_frames ; /* 08h: */ + unsigned int rx_bytes ; /* 0Ch: */ + unsigned int rx_dropped ; /* 10h: */ + unsigned int rx_inactive ; /* 14h: */ + unsigned int rx_exceed_CIR ; /* 18h: */ + unsigned int rx_DE_set ; /* 1Ch: */ + unsigned int tx_throughput ; /* 20h: */ + unsigned int tx_calc_timer ; /* 24h: */ + unsigned int rx_throughput ; /* 28h: */ + unsigned int rx_calc_timer ; /* 2Ch: */ } fr_dlci_stat_t; #endif @@ -436,15 +438,15 @@ typedef struct fr_dlci_stat */ typedef struct fr_comm_stat { - unsigned char rx_overruns ; /* 00h: */ - unsigned char rx_bad_crc ; /* 01h: */ - unsigned char rx_aborts ; /* 02h: */ - unsigned char rx_too_long ; /* 03h: */ - unsigned char tx_aborts ; /* 04h: */ - unsigned char tx_underruns ; /* 05h: */ - unsigned char tx_missed_undr ; /* 06h: */ - unsigned char dcd_dropped ; /* 07h: */ - unsigned char cts_dropped ; /* 08h: */ + unsigned char rx_overruns ; /* 00h: */ + unsigned char rx_bad_crc ; /* 01h: */ + unsigned char rx_aborts ; /* 02h: */ + unsigned char rx_too_long ; /* 03h: */ + unsigned char tx_aborts ; /* 04h: */ + unsigned char tx_underruns ; /* 05h: */ + unsigned char tx_missed_undr ; /* 06h: */ + unsigned char dcd_dropped ; /* 07h: */ + unsigned char cts_dropped ; /* 08h: */ } fr_comm_stat_t; /*---------------------------------------------------------------------------- @@ -459,15 +461,15 @@ typedef struct fr_comm_stat typedef struct arphdr_fr { - unsigned short ar_hrd ; /* format of hardware addr */ - unsigned short ar_pro ; /* format of protocol addr */ - unsigned char ar_hln ; /* length of hardware addr */ - unsigned char ar_pln ; /* length of protocol addr */ - unsigned short ar_op ; /* ARP opcode */ - unsigned short ar_sha ; /* Sender DLCI addr 2 bytes */ - unsigned int ar_sip ; /* Sender IP addr 4 bytes */ - unsigned short ar_tha ; /* Target DLCI addr 2 bytes */ - unsigned int ar_tip ; /* Target IP addr 4 bytes */ + unsigned short ar_hrd ; /* format of hardware addr */ + unsigned short ar_pro ; /* format of protocol addr */ + unsigned char ar_hln ; /* length of hardware addr */ + unsigned char ar_pln ; /* length of protocol addr */ + unsigned short ar_op ; /* ARP opcode */ + unsigned short ar_sha ; /* Sender DLCI addr 2 bytes */ + unsigned int ar_sip ; /* Sender IP addr 4 bytes */ + unsigned short ar_tha ; /* Target DLCI addr 2 bytes */ + unsigned int ar_tip ; /* Target IP addr 4 bytes */ } arphdr_fr_t; /*---------------------------------------------------------------------------- @@ -475,11 +477,11 @@ typedef struct arphdr_fr */ typedef struct arphdr_1490 { - unsigned char control ; /* UI, etc... */ - unsigned char pad ; /* Pad */ - unsigned char NLPID ; /* SNAP */ - unsigned char OUI[3] ; /* Ethertype, etc... */ - unsigned short PID ; /* ARP, IP, etc... */ + unsigned char control ; /* UI, etc... */ + unsigned char pad ; /* Pad */ + unsigned char NLPID ; /* SNAP */ + unsigned char OUI[3] ; /* Ethertype, etc... */ + unsigned short PID ; /* ARP, IP, etc... */ } arphdr_1490_t; /* valid ip_protocol for UDP management */ @@ -543,28 +545,28 @@ typedef struct { } drvstats_gen_t; typedef struct { - unsigned char attr ; - unsigned short time_stamp ; - unsigned char reserved[13] ; + unsigned char attr ; + unsigned short time_stamp ; + unsigned char reserved[13] ; } api_rx_hdr_t; typedef struct { - api_rx_hdr_t api_rx_hdr ; - void * data ; + api_rx_hdr_t api_rx_hdr ; + void * data ; } api_rx_element_t; typedef struct { - unsigned char attr ; - unsigned char reserved[15] ; + unsigned char attr ; + unsigned char reserved[15] ; } api_tx_hdr_t; typedef struct { - api_tx_hdr_t api_tx_hdr ; - void * data ; + api_tx_hdr_t api_tx_hdr ; + void * data ; } api_tx_element_t; -#pragma pack() +#pragma pack() #endif /* _SDLA_FR_H */ diff --git a/patches/kdrivers/include/sdla_front_end.h b/patches/kdrivers/include/sdla_front_end.h index 0b2944f..820a336 100644 --- a/patches/kdrivers/include/sdla_front_end.h +++ b/patches/kdrivers/include/sdla_front_end.h @@ -1,13 +1,14 @@ /* ************************************************************************************* * * - * FRNT_END.H - the 'C' header file for the Sangoma S508/S514 adapter front-end API. * + * sdla_front_end.h - the 'C' header file for the Sangoma S508/S514 adapter front-end API. * * * ************************************************************************************* */ #ifndef _SDLA_FRONT_END_H_ #define _SDLA_FRONT_END_H_ + /* ************************************************************************* * DEFINES AND MACROS * @@ -23,6 +24,8 @@ #define WAN_MEDIA_STS1 0x06 #define WAN_MEDIA_J1 0x07 #define WAN_MEDIA_FXOFXS 0x08 +#define WAN_MEDIA_BRI 0x09 +#define WAN_MEDIA_SERIAL 0x0A /*The line code */ #define WAN_LCODE_NONE 0x00 @@ -42,19 +45,26 @@ #define WAN_FR_E3_G751 0x07 #define WAN_FR_E3_G832 0x08 #define WAN_FR_DS3_Cbit 0x09 -#define WAN_FR_DS3_M13 0x10 +#define WAN_FR_DS3_M13 0x0A +#define WAN_FR_SLC96 0x0B /* Clocking Master/Normal */ #define WAN_NORMAL_CLK 0x01 #define WAN_MASTER_CLK 0x02 +/* Serial Card FE options */ +#define WAN_FE_V35 0x01 +#define WAN_FE_RS232 0x02 + /* Front-End DEBUG flags */ -#define WAN_FE_DEBUG_NONE 0x00 -#define WAN_FE_DEBUG_RBS 0x01 -#define WAN_FE_DEBUG_ALARM 0x02 -#define WAN_FE_DEBUG_VOLTAGE 0x03 -#define WAN_FE_DEBUG_RECONFIG 0x04 -#define WAN_FE_DEBUG_REG 0x05 +#define WAN_FE_DEBUG_NONE 0x00 +#define WAN_FE_DEBUG_RBS 0x01 +#define WAN_FE_DEBUG_ALARM 0x02 +#define WAN_FE_DEBUG_VOLTAGE 0x03 +#define WAN_FE_DEBUG_RECONFIG 0x04 +#define WAN_FE_DEBUG_REG 0x05 +#define WAN_FE_DEBUG_CONFIG_VERIFY 0x06 +#define WAN_FE_DEBUG_HOOK 0x07 /* Front-End DEBUG sub-flags */ /* Sub-flags for RBS debugging */ @@ -134,8 +144,10 @@ #define IS_TE1_56K_MEDIA(fe_cfg)(IS_TE1_MEDIA(fe_cfg) || \ IS_56K_MEDIA(fe_cfg) #define IS_DS3_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_DS3) -#define IS_E3_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_E3) +#define IS_E3_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_E3) #define IS_FXOFXS_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_FXOFXS) +#define IS_BRI_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_BRI) +#define IS_SERIAL_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_SERIAL) #define IS_TXTRISTATE(fe_cfg) (FE_TXTRISTATE(fe_cfg) == WANOPT_YES) @@ -151,6 +163,8 @@ (FE_MEDIA(fe_cfg) == WAN_MEDIA_DS3) ? "DS3" : \ (FE_MEDIA(fe_cfg) == WAN_MEDIA_E3) ? "E3" : \ (FE_MEDIA(fe_cfg) == WAN_MEDIA_FXOFXS) ? "FXO/FXS" : \ + (FE_MEDIA(fe_cfg) == WAN_MEDIA_BRI) ? "BRI" : \ + (FE_MEDIA(fe_cfg) == WAN_MEDIA_SERIAL) ? "V35/RS232" : \ "Unknown" #define LCODE_DECODE(fe_cfg) \ @@ -168,7 +182,8 @@ (FE_FRAME(fe_cfg) == WAN_FR_E3_G751) ? "G.751" : \ (FE_FRAME(fe_cfg) == WAN_FR_E3_G832) ? "G.832" : \ (FE_FRAME(fe_cfg) == WAN_FR_DS3_Cbit) ? "C-bit" : \ - (FE_FRAME(fe_cfg) == WAN_FR_DS3_M13) ? "M13" : "Unknown" + (FE_FRAME(fe_cfg) == WAN_FR_DS3_M13) ? "M13" : \ + (FE_FRAME(fe_cfg) == WAN_FR_SLC96) ? "SLC-96" : "Unknown" @@ -187,21 +202,20 @@ typedef struct { unsigned int line_no; unsigned char tx_tristate_mode; unsigned int tdmv_law; - unsigned char poll_mode; /* enable fe poll driven arch */ + unsigned char poll_mode; union { sdla_te_cfg_t te_cfg; sdla_te3_cfg_t te3_cfg; sdla_remora_cfg_t remora; + sdla_bri_cfg_t bri; } cfg; } sdla_fe_cfg_t; typedef struct { - unsigned int alarms; - unsigned int liu_alarms; - unsigned int bert_alarms; + u_int32_t alarms; union { sdla_te_stats_t te1_stats; - //sdla_te_pmon_t te_pmon; + /*sdla_te_pmon_t te_pmon;*/ sdla_te3_pmon_t te3_pmon; } u; #define te_pmon u.te1_stats.pmon @@ -210,6 +224,7 @@ typedef struct { typedef struct { unsigned char type; unsigned char mode; + int mod_no; /* A200/A400 */ union{ struct { int channel; @@ -220,12 +235,24 @@ typedef struct { int reg; unsigned char value; } reg; + struct { + int offhook; + }hook; } fe_debug_un; #define fe_debug_rbs fe_debug_un.rbs #define fe_debug_reg fe_debug_un.reg +#define fe_debug_hook fe_debug_un.hook } sdla_fe_debug_t; +/* Front-End status */ +#define FE_STATUS_DECODE(fe_status) \ + (fe_status == FE_DISCONNECTED) ? "disconnected" :\ + (fe_status == FE_CONNECTED) ? "connected" : \ + "unknown" + +#define WAN_FE_STATUS_DECODE(fe) FE_STATUS_DECODE((fe)->fe_status) + #ifdef WAN_KERNEL #define FE_ASSERT(val) if (val) return; @@ -242,6 +269,8 @@ typedef struct { #define IS_FXOFXS_FEMEDIA(fe) IS_FXOFXS_MEDIA(&((fe)->fe_cfg)) #define IS_FE_TXTRISTATE(fe) IS_TXTRISTATE(&((fe)->fe_cfg)) #define IS_FR_FEUNFRAMED(fe) IS_FR_UNFRAMED(&((fe)->fe_cfg)) +#define IS_BRI_FEMEDIA(fe) IS_BRI_MEDIA(&((fe)->fe_cfg)) +#define IS_SERIAL_FEMEDIA(fe) IS_SERIAL_MEDIA(&((fe)->fe_cfg)) #define WAN_FE_MEDIA(fe) FE_MEDIA(&((fe)->fe_cfg)) #define WAN_FE_LCODE(fe) FE_LCODE(&((fe)->fe_cfg)) @@ -254,15 +283,16 @@ typedef struct { #define FE_LCODE_DECODE(fe) LCODE_DECODE(&((fe)->fe_cfg)) #define FE_FRAME_DECODE(fe) FRAME_DECODE(&((fe)->fe_cfg)) +#define WAN_FE_START_CHANNEL(fe) \ + (IS_TE1_FEMEDIA(fe)) ? GET_TE_START_CHANNEL(fe) : \ + (IS_FXOFXS_FEMEDIA(fe)) ? WAN_RM_START_CHANNEL: \ + (IS_BRI_FEMEDIA(fe)) ? WAN_BRI_START_CHANNEL: 0 + #define WAN_FE_MAX_CHANNELS(fe) \ (IS_TE1_FEMEDIA(fe)) ? GET_TE_CHANNEL_RANGE(fe) : \ - (IS_FXOFXS_FEMEDIA(fe)) ? MAX_FXOFXS_CHANNELS : 0 + (IS_FXOFXS_FEMEDIA(fe)) ? MAX_FXOFXS_CHANNELS : \ + (IS_BRI_FEMEDIA(fe)) ? MAX_BRI_CHANNELS : 0 -/* Front-End status */ -#define WAN_FE_STATUS_DECODE(fe) \ - ((fe)->fe_status == FE_DISCONNECTED) ? "disconnected" :\ - ((fe)->fe_status == FE_CONNECTED) ? "connected" : \ - "unknown" #if 0 enum fe_status { FE_UNITIALIZED = 0x00, @@ -390,7 +420,7 @@ typedef struct sdla_fe_timer_event_ { WAN_LIST_ENTRY(sdla_fe_timer_event_) next; } sdla_fe_timer_event_t; -#define WAN_FE_MAX_QEVENT_LEN 20 +#define WAN_FE_MAX_QEVENT_LEN 20 typedef struct { char *name; void *card; @@ -406,21 +436,25 @@ typedef struct { #define te_param fe_param.te #define te3_param fe_param.te3 #define rm_param fe_param.remora +#define bri_param fe_param.bri sdla_te_param_t te; sdla_56k_param_t k56_param; sdla_te3_param_t te3; sdla_remora_param_t remora; + sdla_bri_param_t bri; } fe_param; -#define fe_alarm fe_stats.alarms -#define liu_alarm fe_stats.liu_alarms -#define bert_alarm fe_stats.bert_alarms - sdla_fe_stats_t fe_stats; +#define fe_alarm fe_stats.alarms + sdla_fe_stats_t fe_stats; - wan_spinlock_t lock; + wan_spinlock_t lockirq; wan_timer_t timer; +#if defined(__WINDOWS__) + WAN_LIST_HEAD(fe_timer_event_list_head, sdla_fe_timer_event_) event; +#else WAN_LIST_HEAD(, sdla_fe_timer_event_) event; - unsigned int event_map; - +#endif + unsigned int event_map; + int (*write_cpld)(void*, unsigned short, unsigned char); int (*read_cpld)(void*, unsigned short, unsigned char); int (*write_fe_cpld)(void*, unsigned short, unsigned char); @@ -477,9 +511,10 @@ typedef struct { int (*if_unconfig)(void *fe, u32, u8); int (*disable_irq)(void *fe); int (*polling)(sdla_fe_t *fe); + int (*add_timer)(sdla_fe_t *fe, unsigned long); int (*isr)(sdla_fe_t *fe); int (*process_udp)(sdla_fe_t *fe, void*, unsigned char*); - unsigned int (*read_alarm)(sdla_fe_t *fe, int); + u_int32_t (*read_alarm)(sdla_fe_t *fe, int); int (*read_pmon)(sdla_fe_t *fe, int); int (*flush_pmon)(sdla_fe_t *fe); /* Set Front-End alarm (T1/E1) */ @@ -490,8 +525,10 @@ typedef struct { char* (*print_fe_act_channels)(sdla_fe_t*); /* Print Front-End alarm (T1/E1/56K) */ int (*print_fe_alarm)(sdla_fe_t*,unsigned int); - /* Get front end status */ + /* Get front end status: Connected/Disconnected */ int (*get_fe_status)(sdla_fe_t *fe, unsigned char*); + /* Set front end status: Connected/Disconnected only ISDN BRI */ + int (*set_fe_status)(sdla_fe_t *fe, unsigned char); /* Get front end media type */ unsigned char (*get_fe_media)(sdla_fe_t *fe); /* Get front end media type string */ @@ -499,9 +536,9 @@ typedef struct { /* Set Line-loopback modes */ int (*set_fe_lbmode)(sdla_fe_t*, unsigned char, unsigned char); /* Update Alarm Status for proc file system */ - int (*update_alarm_info)(sdla_fe_t*, struct seq_file* m, int* stop_cnt); + int (*update_alarm_info)(sdla_fe_t*, struct seq_file*, int*); /* Update PMON Status for proc file system */ - int (*update_pmon_info)(sdla_fe_t*, struct seq_file* m, int* stop_cnt); + int (*update_pmon_info)(sdla_fe_t*, struct seq_file*, int*); /* AFT T1/E1 cards only */ int (*led_ctrl)(sdla_fe_t*, int mode); /* Check RBS bits (T1/E1 cards) */ @@ -521,7 +558,10 @@ typedef struct { void (*enable_timer)(sdla_fe_t* fe, unsigned char cmd, unsigned int delay); #endif /* Available front-end map */ - unsigned int (*active_map)(sdla_fe_t *fe); + /* BRI addition - one Wanpipe may have two lines, provide the 'line_no' when + getting the active channels map. + */ + unsigned int (*active_map)(sdla_fe_t *fe, unsigned char line_no); /* Transmit DTMF number */ int (*set_dtmf)(sdla_fe_t*, int, unsigned char); /* Enable/Disable FE interrupt */ @@ -530,6 +570,11 @@ typedef struct { int (*event_ctrl)(sdla_fe_t*, wan_event_ctrl_t*); /* Front-End watchdog */ int (*watchdog)(sdla_fe_t*); + /* Transmit ISDN BRI D-chan data */ + int (*isdn_bri_dchan_tx)(sdla_fe_t*, void*, unsigned int); + /* Receive ISDN BRI D-chan data */ + int (*isdn_bri_dchan_rx)(sdla_fe_t*, void*, unsigned int); + } sdla_fe_iface_t; /* diff --git a/patches/kdrivers/include/sdla_front_end.h~ b/patches/kdrivers/include/sdla_front_end.h~ deleted file mode 100644 index 8dba5c0..0000000 --- a/patches/kdrivers/include/sdla_front_end.h~ +++ /dev/null @@ -1,547 +0,0 @@ -/* - ************************************************************************************* - * * - * FRNT_END.H - the 'C' header file for the Sangoma S508/S514 adapter front-end API. * - * * - ************************************************************************************* -*/ -#ifndef _SDLA_FRONT_END_H_ -#define _SDLA_FRONT_END_H_ - -/* -************************************************************************* -* DEFINES AND MACROS * -************************************************************************* -*/ -/* Front-End media type */ -#define WAN_MEDIA_NONE 0x00 -#define WAN_MEDIA_T1 0x01 -#define WAN_MEDIA_E1 0x02 -#define WAN_MEDIA_56K 0x03 -#define WAN_MEDIA_DS3 0x04 -#define WAN_MEDIA_E3 0x05 -#define WAN_MEDIA_STS1 0x06 -#define WAN_MEDIA_J1 0x07 -#define WAN_MEDIA_FXOFXS 0x08 - -/*The line code */ -#define WAN_LCODE_NONE 0x00 -#define WAN_LCODE_AMI 0x01 /* T1/E1/DS3/E3 */ -#define WAN_LCODE_B8ZS 0x02 /* T1 */ -#define WAN_LCODE_HDB3 0x03 /* E1/E3 */ -#define WAN_LCODE_B3ZS 0x04 /* DS3 */ - -/* Framing modes */ -#define WAN_FR_NONE 0x00 -#define WAN_FR_ESF 0x01 -#define WAN_FR_D4 0x02 -#define WAN_FR_ESF_JAPAN 0x03 -#define WAN_FR_CRC4 0x04 -#define WAN_FR_NCRC4 0x05 -#define WAN_FR_UNFRAMED 0x06 -#define WAN_FR_E3_G751 0x07 -#define WAN_FR_E3_G832 0x08 -#define WAN_FR_DS3_Cbit 0x09 -#define WAN_FR_DS3_M13 0x10 - -/* Clocking Master/Normal */ -#define WAN_NORMAL_CLK 0x01 -#define WAN_MASTER_CLK 0x02 - -/* Front-End DEBUG flags */ -#define WAN_FE_DEBUG_NONE 0x00 -#define WAN_FE_DEBUG_RBS 0x01 -#define WAN_FE_DEBUG_ALARM 0x02 -#define WAN_FE_DEBUG_VOLTAGE 0x03 -#define WAN_FE_DEBUG_RECONFIG 0x04 -#define WAN_FE_DEBUG_REG 0x05 - -/* Front-End DEBUG sub-flags */ -/* Sub-flags for RBS debugging */ -#define WAN_FE_DEBUG_RBS_RX_ENABLE 0x01 -#define WAN_FE_DEBUG_RBS_TX_ENABLE 0x02 -#define WAN_FE_DEBUG_RBS_RX_DISABLE 0x03 -#define WAN_FE_DEBUG_RBS_TX_DISABLE 0x04 -#define WAN_FE_DEBUG_RBS_READ 0x05 -#define WAN_FE_DEBUG_RBS_SET 0x06 -#define WAN_FE_DEBUG_RBS_PRINT 0x07 -#define WAN_FE_DEBUG_RBS_DECODE(mode) \ - ((mode) == WAN_FE_DEBUG_RBS_RX_ENABLE) ? "Enable RBS RX" : \ - ((mode) == WAN_FE_DEBUG_RBS_TX_ENABLE) ? "Enable RBS TX" : \ - ((mode) == WAN_FE_DEBUG_RBS_RX_DISABLE) ? "Disable RBS RX" : \ - ((mode) == WAN_FE_DEBUG_RBS_TX_DISABLE) ? "Disable RBS TX" : \ - ((mode) == WAN_FE_DEBUG_RBS_READ) ? "Read RBS" : \ - ((mode) == WAN_FE_DEBUG_RBS_SET) ? "Set RBS" : \ - ((mode) == WAN_FE_DEBUG_RBS_PRINT) ? "Print RBS" : "Unknown" - -/* Sub-flags for ALARM debugging */ -#define WAN_FE_DEBUG_ALARM_AIS_ENABLE 0x01 -#define WAN_FE_DEBUG_ALARM_AIS_DISABLE 0x02 -#define WAN_FE_DEBUG_ALARM_DECODE(mode) \ - ((mode) == WAN_FE_DEBUG_ALARM_AIS_ENABLE) ? "Enable TX AIS" : \ - ((mode) == WAN_FE_DEBUG_ALARM_AIS_DISABLE) ? "Disable TX AIS" : \ - "Unknown" - -/* Front-End TX tri-state mode flags */ -#define WAN_FE_TXMODE_ENABLE 0x01 -#define WAN_FE_TXMODE_DISABLE 0x02 - -/* Read alarm flag */ -#define WAN_FE_ALARM_NONE 0x00 -#define WAN_FE_ALARM_READ 0x01 -#define WAN_FE_ALARM_PRINT 0x02 -#define WAN_FE_ALARM_UPDATE 0x04 -#define IS_FE_ALARM_READ(action) ((action) & WAN_FE_ALARM_READ) -#define IS_FE_ALARM_PRINT(action) ((action) & WAN_FE_ALARM_PRINT) -#define IS_FE_ALARM_UPDATE(action) ((action) & WAN_FE_ALARM_UPDATE) - -/* Read pmon flag */ -#define WAN_FE_PMON_UPDATE 0x01 -#define WAN_FE_PMON_PRINT 0x02 -#define WAN_FE_PMON_READ 0x04 -#define IS_FE_PMON_UPDATE(action) ((action) & WAN_FE_PMON_UPDATE) -#define IS_FE_PMON_PRINT(action) ((action) & WAN_FE_PMON_PRINT) -#define IS_FE_PMON_READ(action) ((action) & WAN_FE_PMON_READ) - -/* FE interrupt action command */ -#define WAN_FE_INTR_ENABLE 0x01 -#define WAN_FE_INTR_MASK 0x02 - -/* FE event action command */ -#define WAN_FE_EVENT_ENABLE 0x01 -#define WAN_FE_EVENT_MASK 0x02 - -/* Alaw/Mulaw */ -#define WAN_TDMV_ALAW 0x01 -#define WAN_TDMV_MULAW 0x02 - -#define FE_MEDIA(fe_cfg) ((fe_cfg)->media) -#define FE_SUBMEDIA(fe_cfg) ((fe_cfg)->sub_media) -#define FE_LCODE(fe_cfg) ((fe_cfg)->lcode) -#define FE_FRAME(fe_cfg) ((fe_cfg)->frame) -#define FE_LINENO(fe_cfg) ((fe_cfg)->line_no) -#define FE_TXTRISTATE(fe_cfg) ((fe_cfg)->tx_tristate_mode) -#define FE_TDMV_LAW(fe_cfg) ((fe_cfg)->tdmv_law) - -#define IS_T1_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_T1) -#define IS_E1_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_E1) -#define IS_J1_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_T1 && \ - FE_SUBMEDIA(fe_cfg) == WAN_MEDIA_J1) -#define IS_TE1_MEDIA(fe_cfg) (IS_T1_MEDIA(fe_cfg) || \ - IS_E1_MEDIA(fe_cfg) || \ - IS_J1_MEDIA(fe_cfg)) -#define IS_56K_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_56K) -#define IS_TE1_56K_MEDIA(fe_cfg)(IS_TE1_MEDIA(fe_cfg) || \ - IS_56K_MEDIA(fe_cfg) -#define IS_DS3_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_DS3) -#define IS_E3_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_E3) -#define IS_FXOFXS_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_FXOFXS) - -#define IS_TXTRISTATE(fe_cfg) (FE_TXTRISTATE(fe_cfg) == WANOPT_YES) - -#define IS_FR_UNFRAMED(fe_cfg) (FE_FRAME(fe_cfg) == WAN_FR_UNFRAMED) - -#define MEDIA_DECODE(fe_cfg) \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_T1 && \ - FE_SUBMEDIA(fe_cfg)==WAN_MEDIA_J1)?"J1" : \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_T1) ? "T1" : \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_E1) ? "E1" : \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_J1) ? "J1" : \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_56K) ? "56K" : \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_DS3) ? "DS3" : \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_E3) ? "E3" : \ - (FE_MEDIA(fe_cfg) == WAN_MEDIA_FXOFXS) ? "FXO/FXS" : \ - "Unknown" - -#define LCODE_DECODE(fe_cfg) \ - (FE_LCODE(fe_cfg) == WAN_LCODE_AMI) ? "AMI" : \ - (FE_LCODE(fe_cfg) == WAN_LCODE_B8ZS) ? "B8ZS" : \ - (FE_LCODE(fe_cfg) == WAN_LCODE_HDB3) ? "HDB3" : \ - (FE_LCODE(fe_cfg) == WAN_LCODE_B3ZS) ? "B3ZS" : "Unknown" - -#define FRAME_DECODE(fe_cfg) \ - (FE_FRAME(fe_cfg) == WAN_FR_ESF) ? "ESF" : \ - (FE_FRAME(fe_cfg) == WAN_FR_D4) ? "D4" : \ - (FE_FRAME(fe_cfg) == WAN_FR_CRC4) ? "CRC4" : \ - (FE_FRAME(fe_cfg) == WAN_FR_NCRC4) ? "non-CRC4" : \ - (FE_FRAME(fe_cfg) == WAN_FR_UNFRAMED) ? "Unframed" : \ - (FE_FRAME(fe_cfg) == WAN_FR_E3_G751) ? "G.751" : \ - (FE_FRAME(fe_cfg) == WAN_FR_E3_G832) ? "G.832" : \ - (FE_FRAME(fe_cfg) == WAN_FR_DS3_Cbit) ? "C-bit" : \ - (FE_FRAME(fe_cfg) == WAN_FR_DS3_M13) ? "M13" : "Unknown" - - - -/* front-end configuration and access interface commands */ -#define READ_FRONT_END_REGISTER (WAN_FE_CMD_START+0) /* 0x90 read from front-end register */ -#define WRITE_FRONT_END_REGISTER (WAN_FE_CMD_START+1) /* 0x91 write to front-end register */ -#define READ_FRONT_END_STATISTICS (WAN_FE_CMD_START+2) /* 0x92 read the front-end statistics */ -#define FLUSH_FRONT_END_STATISTICS (WAN_FE_CMD_START+3) /* 0x93 flush the front-end statistics */ - - -typedef struct { - unsigned char media; - unsigned char sub_media; - unsigned char lcode; - unsigned char frame; - unsigned int line_no; - unsigned char tx_tristate_mode; - unsigned int tdmv_law; - unsigned char poll_mode; /* enable fe poll driven arch */ - union { - sdla_te_cfg_t te_cfg; - sdla_te3_cfg_t te3_cfg; - sdla_remora_cfg_t remora; - } cfg; -} sdla_fe_cfg_t; - -typedef struct { - unsigned int alarms; - unsigned int liu_alarms; - unsigned int bert_alarms; - union { - sdla_te_stats_t te1_stats; - //sdla_te_pmon_t te_pmon; - sdla_te3_pmon_t te3_pmon; - } u; -#define te_pmon u.te1_stats.pmon -} sdla_fe_stats_t; - -typedef struct { - unsigned char type; - unsigned char mode; - union{ - struct { - int channel; - unsigned char abcd; - } rbs; - struct { - int read; - int reg; - unsigned char value; - } reg; - } fe_debug_un; -#define fe_debug_rbs fe_debug_un.rbs -#define fe_debug_reg fe_debug_un.reg -} sdla_fe_debug_t; - - -#ifdef WAN_KERNEL - -#define FE_ASSERT(val) if (val) return; -#define FE_ASSERT1(val) if (val) return 1; - -#define WAN_FECALL(dev, func, x) \ - ((dev)->fe_iface.func) ? (dev)->fe_iface.func x : -EINVAL - -#define IS_T1_FEMEDIA(fe) IS_T1_MEDIA(&((fe)->fe_cfg)) -#define IS_E1_FEMEDIA(fe) IS_E1_MEDIA(&((fe)->fe_cfg)) -#define IS_TE1_FEMEDIA(fe) IS_TE1_MEDIA(&((fe)->fe_cfg)) -#define IS_56K_FEMEDIA(fe) IS_56K_MEDIA(&((fe)->fe_cfg)) -#define IS_J1_FEMEDIA(fe) IS_J1_MEDIA(&((fe)->fe_cfg)) -#define IS_FXOFXS_FEMEDIA(fe) IS_FXOFXS_MEDIA(&((fe)->fe_cfg)) -#define IS_FE_TXTRISTATE(fe) IS_TXTRISTATE(&((fe)->fe_cfg)) -#define IS_FR_FEUNFRAMED(fe) IS_FR_UNFRAMED(&((fe)->fe_cfg)) - -#define WAN_FE_MEDIA(fe) FE_MEDIA(&((fe)->fe_cfg)) -#define WAN_FE_LCODE(fe) FE_LCODE(&((fe)->fe_cfg)) -#define WAN_FE_FRAME(fe) FE_FRAME(&((fe)->fe_cfg)) -#define WAN_FE_LINENO(fe) FE_LINENO(&((fe)->fe_cfg)) -#define WAN_FE_TXTRISTATE(fe) FE_TXTRISTATE(&((fe)->fe_cfg)) -#define WAN_FE_TDMV_LAW(fe) FE_TDMV_LAW(&((fe)->fe_cfg)) - -#define FE_MEDIA_DECODE(fe) MEDIA_DECODE(&((fe)->fe_cfg)) -#define FE_LCODE_DECODE(fe) LCODE_DECODE(&((fe)->fe_cfg)) -#define FE_FRAME_DECODE(fe) FRAME_DECODE(&((fe)->fe_cfg)) - -#define WAN_FE_MAX_CHANNELS(fe) \ - (IS_TE1_FEMEDIA(fe)) ? GET_TE_CHANNEL_RANGE(fe) : \ - (IS_FXOFXS_FEMEDIA(fe)) ? MAX_FXOFXS_CHANNELS : 0 - -/* Front-End status */ -#define WAN_FE_STATUS_DECODE(fe) \ - ((fe)->fe_status == FE_DISCONNECTED) ? "disconnected" :\ - ((fe)->fe_status == FE_CONNECTED) ? "connected" : \ - "unknown" -#if 0 -enum fe_status { - FE_UNITIALIZED = 0x00, - FE_DISCONNECTED, - FE_CONNECTED -}; -#endif - -/* adapter configuration interface commands */ -#define SET_ADAPTER_CONFIGURATION (WAN_INTERFACE_CMD_START+0) /* 0xA0 set adapter configuration */ -#define READ_ADAPTER_CONFIGURATION (WAN_INTERFACE_CMD_START+1) /* 0xA1 read adapter configuration */ - -/* return codes from interface commands */ -#define LGTH_FE_CFG_DATA_INVALID 0x91 /* the length of the FE_RX_DISC_TX_IDLE_STRUCT is invalid */ -#define LGTH_ADAPTER_CFG_DATA_INVALID 0x91 /* the length of the passed configuration data is invalid */ -#define INVALID_FE_CFG_DATA 0x92 /* the passed SET_FE_RX_DISC_TX_IDLE_CFG data is invalid */ -#define ADPTR_OPERATING_FREQ_INVALID 0x92 /* an invalid adapter operating frequency was selected */ -#define PROT_CFG_BEFORE_FE_CFG 0x93 /* set the protocol-level configuration before setting the FE configuration */ - -#define SET_FE_RX_DISC_TX_IDLE_CFG 0x98 /* set the front-end Rx discard/Tx idle configuration */ -#define READ_FE_RX_DISC_TX_IDLE_CFG 0x99 /* read the front-end Rx discard/Tx idle configuration */ -#define SET_TE1_SIGNALING_CFG 0x9A /* set the T1/E1 signaling configuration */ -#define READ_TE1_SIGNALING_CFG 0x9B /* read the T1/E1 signaling configuration */ - - -#define COMMAND_INVALID_FOR_ADAPTER 0x9F /* the command is invalid for the adapter type */ - - -/* --------------------------------------------------------------------------------- - * Constants for the SET_FE_RX_DISC_TX_IDLE_CFG/READ_FE_RX_DISC_TX_IDLE_CFG commands - * --------------------------------------------------------------------------------*/ - -#define NO_ACTIVE_RX_TIME_SLOTS_T1 24 /* T1 - no active time slots used for reception */ -#define NO_ACTIVE_TX_TIME_SLOTS_T1 24 /* T1 - no active time slots used for transmission */ -#define NO_ACTIVE_RX_TIME_SLOTS_E1 32 /* E1 - no active time slots used for reception */ -#define NO_ACTIVE_TX_TIME_SLOTS_E1 31 /* E1 - no active time slots used for transmission (channel 0 reserved for framing) */ - -/* the structure used for the SET_FE_RX_DISC_TX_IDLE_CFG/READ_FE_RX_DISC_TX_IDLE_CFG command */ -#pragma pack(1) -typedef struct { - unsigned short lgth_Rx_disc_bfr; /* the length of the Rx discard buffer */ - unsigned short lgth_Tx_idle_bfr; /* the length of the Tx idle buffer */ - /* the transmit idle data buffer */ - unsigned char Tx_idle_data_bfr[NO_ACTIVE_TX_TIME_SLOTS_E1]; -} FE_RX_DISC_TX_IDLE_STRUCT; -#pragma pack() - - -/* ---------------------------------------------------------------------------- - * Constants for front-end access - * --------------------------------------------------------------------------*/ - -/* the structure used for the READ_FRONT_END_REGISTER/WRITE_FRONT_END_REGISTER command */ -#pragma pack(1) -typedef struct { - unsigned short register_number; /* the register number to be read from or written to */ - unsigned char register_value; /* the register value read/written */ -} FRONT_END_REG_STRUCT; -#pragma pack() - -#pragma pack(1) -typedef struct { - unsigned char opp_flag; /* opp flag */ - - union { - struct { - unsigned char RR8_56k; /* register #8 value - 56K CSU/DSU */ - unsigned char RR9_56k; /* register #9 value - 56K CSU/DSU */ - unsigned char RRA_56k; /* register #A value - 56K CSU/DSU */ - unsigned char RRB_56k; /* register #B value - 56K CSU/DSU */ - unsigned char RRC_56k; /* register #C value - 56K CSU/DSU */ - } stat_56k; - } FE_U; - -} FRONT_END_STATUS_STRUCT; -#pragma pack() - - -/* ----------------------------------------------------------------------------- - * Constants for the READ_FRONT_END_STATISTICS command - * ---------------------------------------------------------------------------*/ - -/* the front-end statistics structure */ -#pragma pack(1) -typedef struct { - unsigned int FE_interrupt_count; /* the number of front-end interrupts generated */ - unsigned int FE_app_timeout_count; /* the number of front-end interrupt application timeouts */ -} FE_STATISTICS_STRUCT; -#pragma pack() - - - -/* -------------------------------------------------------------------------------- - * Constants for the SET_ADAPTER_CONFIGURATION/READ_ADAPTER_CONFIGURATION commands - * -------------------------------------------------------------------------------*/ - -/* the adapter configuration structure */ -#pragma pack(1) -typedef struct { - unsigned short adapter_type; /* type of adapter */ - unsigned short adapter_config; /* miscellaneous adapter configuration options */ - unsigned int operating_frequency; /* adapter operating frequency */ -} ADAPTER_CONFIGURATION_STRUCT; -#pragma pack() - -typedef int (WRITE_FRONT_END_REG_T)(void*, ...); -typedef unsigned char (READ_FRONT_END_REG_T)(void*, ...); - -enum { - AFT_LED_ON, - AFT_LED_OFF, - AFT_LED_TOGGLE -}; - -typedef struct sdla_fe_timer_event_ { - unsigned char type; - u_int8_t mode; - int delay; - union{ -#define te_event u_fe.te -#define rm_event u_fe.rm - sdla_te_event_t te; - sdla_rm_event_t rm; - } u_fe; - WAN_LIST_ENTRY(sdla_fe_timer_event_) next; -} sdla_fe_timer_event_t; - -#define WAN_FE_MAX_QEVENT_LEN 20 -typedef struct { - char *name; - void *card; - sdla_fe_cfg_t fe_cfg; - /* FIXME: Remove the following parameters from wandev_t */ - unsigned char fe_status; -/* unsigned int fe_alarm; */ - unsigned char fe_chip_id; - unsigned char fe_max_ports; - unsigned char fe_debug; - /* ^^^ */ - union { -#define te_param fe_param.te -#define te3_param fe_param.te3 -#define rm_param fe_param.remora - sdla_te_param_t te; - sdla_56k_param_t k56_param; - sdla_te3_param_t te3_param; - sdla_remora_param_t remora; - } fe_param; -#define fe_alarm fe_stats.alarms -#define liu_alarm fe_stats.liu_alarms -#define bert_alarm fe_stats.bert_alarms - sdla_fe_stats_t fe_stats; - - wan_spinlock_t lock; - wan_timer_t timer; - WAN_LIST_HEAD(, sdla_fe_timer_event_) event; - unsigned int event_map; - - int (*write_cpld)(void*, unsigned short, unsigned char); - int (*read_cpld)(void*, unsigned short, unsigned char); - int (*write_fe_cpld)(void*, unsigned short, unsigned char); - int (*read_fe_cpld)(void*, unsigned short, unsigned char); - int (*write_framer)(void*,unsigned short,unsigned short); - unsigned int (*read_framer)(void*,unsigned short); - WRITE_FRONT_END_REG_T *write_fe_reg; - READ_FRONT_END_REG_T *read_fe_reg; - READ_FRONT_END_REG_T *__read_fe_reg; -#if defined(__WINDOWS__) - int remora_modules_counter;/* set in wp_remora_config() */ -#endif -} sdla_fe_t; - -/* -** Sangoma Front-End interface structure -*/ -#if 0 -typedef struct { - /* In-Service or Not (T1/E1/56K) */ - unsigned int (*get_fe_service_status)(void*); - /* Print Front-End alarm (T1/E1/56K) */ - void (*print_fe_alarm)(void*,unsigned int); - /* Print Front-End alarm (T1/E1/56K) */ - char* (*print_fe_act_channels)(void*); - /* Set Front-End alarm (T1/E1) */ - void (*set_fe_alarm)(void*,unsigned int); - /* Set extra interrupt type (after link get connected)) */ - int (*set_fe_sigcfg)(void*, unsigned int); -} sdla_fe_iface_t; -#endif - -#if defined(__LINUX__) -# include -#elif defined(__WINDOWS__) -# include /* for wan_event_ctrl_t */ -#endif - -/* -** Sangoma Front-End interface structure (new version) -** FIXME: replace sdla_fe_iface_t with the new version! */ -typedef struct { - int (*reset)(void *fe, int, int); - int (*global_config)(void *fe); - int (*global_unconfig)(void *fe); - int (*chip_config)(void *fe); - int (*config)(void *fe); - int (*post_init)(void*); - /* Set extra T1/E1 configuration */ - int (*reconfig)(sdla_fe_t*); - int (*unconfig)(void *fe); - int (*pre_release)(void*); - int (*if_config)(void *fe, u32, u8); - int (*if_unconfig)(void *fe, u32, u8); - int (*disable_irq)(void *fe); - int (*polling)(sdla_fe_t *fe); - int (*isr)(sdla_fe_t *fe); - int (*process_udp)(sdla_fe_t *fe, void*, unsigned char*); - unsigned int (*read_alarm)(sdla_fe_t *fe, int); - int (*read_pmon)(sdla_fe_t *fe, int); - int (*flush_pmon)(sdla_fe_t *fe); - /* Set Front-End alarm (T1/E1) */ - int (*set_fe_alarm)(sdla_fe_t *fe, unsigned int); - /* Set extra interrupt type (after link get connected)) */ - int (*set_fe_sigctrl)(sdla_fe_t*, int, unsigned long, int); - /* Print Front-End alarm (T1/E1/56K) */ - char* (*print_fe_act_channels)(sdla_fe_t*); - /* Print Front-End alarm (T1/E1/56K) */ - int (*print_fe_alarm)(sdla_fe_t*,unsigned int); - /* Get front end status */ - int (*get_fe_status)(sdla_fe_t *fe, unsigned char*); - /* Get front end media type */ - unsigned char (*get_fe_media)(sdla_fe_t *fe); - /* Get front end media type string */ - char* (*get_fe_media_string)(void); - /* Set Line-loopback modes */ - int (*set_fe_lbmode)(sdla_fe_t*, unsigned char, unsigned char); - /* Update Alarm Status for proc file system */ - int (*update_alarm_info)(sdla_fe_t*, struct seq_file* m, int* stop_cnt); - /* Update PMON Status for proc file system */ - int (*update_pmon_info)(sdla_fe_t*, struct seq_file* m, int* stop_cnt); - /* AFT T1/E1 cards only */ - int (*led_ctrl)(sdla_fe_t*, int mode); - /* Check RBS bits (T1/E1 cards) */ - int (*check_rbsbits)(sdla_fe_t*, int, unsigned int, int); - /* Read RBS bits (T1/E1 cards) */ - unsigned char (*read_rbsbits)(sdla_fe_t*, int, int); - /* Set RBS bits (T1/E1 cards, voice) */ - int (*set_rbsbits)(sdla_fe_t*, int, unsigned char); - /* Report RBS bits (T1/E1 cards) */ - int (*report_rbsbits)(sdla_fe_t*); - /* Get Front-End SNMP data */ - int (*get_snmp_data)(sdla_fe_t*, void*, void*); - /* Check if the interrupt is for this port */ - int (*check_isr)(sdla_fe_t *fe); -#if defined(__WINDOWS__) - /* Enable TE1 poll timer (WINDOWS ONLY) */ - void (*enable_timer)(sdla_fe_t* fe, unsigned char cmd, unsigned int delay); -#endif - /* Available front-end map */ - unsigned int (*active_map)(sdla_fe_t *fe); - /* Transmit DTMF number */ - int (*set_dtmf)(sdla_fe_t*, int, unsigned char); - /* Enable/Disable FE interrupt */ - int (*intr_ctrl)(sdla_fe_t*, int, u_int8_t, u_int8_t, unsigned int); - /* Event Control */ - int (*event_ctrl)(sdla_fe_t*, wan_event_ctrl_t*); - /* Front-End watchdog */ - int (*watchdog)(sdla_fe_t*); -} sdla_fe_iface_t; - -/* -** Sangoma Front-End interface structure (new version) -** FIXME: replace sdla_fe_iface_t with the new version! */ -typedef struct { - - int (*check_hook_state)(sdla_fe_t *, int); - int (*hook_state)(sdla_fe_t *, int, int); - -} sdla_fe_notify_iface_t; - -#endif /* WAN_KERNEL */ - -#endif diff --git a/patches/kdrivers/include/sdla_hdlc.h b/patches/kdrivers/include/sdla_hdlc.h index 2bcb1b4..ee73c18 100644 --- a/patches/kdrivers/include/sdla_hdlc.h +++ b/patches/kdrivers/include/sdla_hdlc.h @@ -13,8 +13,8 @@ * Oct 14, 1998 Jaspreet Singh o Initial Version. *****************************************************************************/ -#ifndef _SDLA_HDLC___ -#define _SDLA_HDLC___ +#ifndef __SDLA_HDLC_H__ +#define __SDLA_HDLC_H__ #pragma pack(1) @@ -52,13 +52,13 @@ */ typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* the command code */ - unsigned short buffer_length ; /* the data length */ - unsigned char return_code ; /* the return code */ - unsigned char PF_bit ; /* the HDLC P/F bit */ - char MB_reserved[NUMBER_HDLC_MB_RES_BYTES] ; /* for later use */ - char data[MAX_NO_DATA_BYTES_IN_I_FRAME] ; /* the data area */ + unsigned char opp_flag ; /* the opp flag */ + unsigned char command ; /* the command code */ + unsigned short buffer_length ; /* the data length */ + unsigned char return_code ; /* the return code */ + unsigned char PF_bit ; /* the HDLC P/F bit */ + char MB_reserved[NUMBER_HDLC_MB_RES_BYTES] ; /* for later use */ + char data[MAX_NO_DATA_BYTES_IN_I_FRAME] ; /* the data area */ } HDLC_MAILBOX_STRUCT; @@ -67,20 +67,20 @@ typedef struct { typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* the command code */ - unsigned short buffer_length ; /* the data length */ - unsigned char return_code ; /* the return code */ - unsigned char PF_bit ; /* the HDLC P/F bit */ - char MB_reserved[NUMBER_HDLC_MB_RES_BYTES] ; /* for later use */ - char data[SIZEOF_HDLC_MB_DATA_BFR] ; /* the data area */ + unsigned char opp_flag ; /* the opp flag */ + unsigned char command ; /* the command code */ + unsigned short buffer_length ; /* the data length */ + unsigned char return_code ; /* the return code */ + unsigned char PF_bit ; /* the HDLC P/F bit */ + char MB_reserved[NUMBER_HDLC_MB_RES_BYTES] ; /* for later use */ + char data[SIZEOF_HDLC_MB_DATA_BFR] ; /* the data area */ } TRUE_HDLC_MAILBOX_STRUCT; typedef struct { - pid_t pid_num ; - HDLC_MAILBOX_STRUCT cmdarea ; + pid_t pid_num ; + HDLC_MAILBOX_STRUCT cmdarea ; } CMDBLOCK_STRUCT; @@ -288,9 +288,9 @@ typedef struct { typedef struct { - unsigned char trace_config ; /* trace configuration */ - unsigned short trace_deactivation_timer ; /* trace deactivation timer */ - unsigned long ptr_trace_stat_el_cfg_struct ; /* a pointer to the line trace element configuration structure */ + unsigned char trace_config ; /* trace configuration */ + unsigned short trace_deactivation_timer ; /* trace deactivation timer */ + unsigned long ptr_trace_stat_el_cfg_struct ; /* a pointer to the line trace element configuration structure */ } LINE_TRACE_CONFIG_STRUCT; @@ -309,11 +309,11 @@ typedef struct { typedef struct { - unsigned short number_trace_status_elements ; /* number of line trace elements */ - unsigned long base_addr_trace_status_elements ;/* base address of the trace element list */ - unsigned long next_trace_element_to_use ; /* pointer to the next trace element to be used */ - unsigned long base_addr_trace_buffer ; /* base address of the trace data buffer */ - unsigned long end_addr_trace_buffer ; /* end address of the trace data buffer */ + unsigned short number_trace_status_elements ; /* number of line trace elements */ + unsigned long base_addr_trace_status_elements ;/* base address of the trace element list */ + unsigned long next_trace_element_to_use ; /* pointer to the next trace element to be used */ + unsigned long base_addr_trace_buffer ; /* base address of the trace data buffer */ + unsigned long end_addr_trace_buffer ; /* end address of the trace data buffer */ } TRACE_STATUS_EL_CFG_STRUCT; @@ -323,13 +323,13 @@ typedef struct { typedef struct { - unsigned char opp_flag ; /* opp flag */ - unsigned short trace_length ; /* trace length */ - unsigned char trace_type ; /* trace type */ - unsigned short trace_time_stamp ;/* time stamp */ - unsigned short trace_reserved_1 ;/* reserved for later use */ - unsigned long trace_reserved_2 ; /* reserved for later use */ - unsigned long ptr_data_bfr ; /* pointer to the trace data buffer */ + unsigned char opp_flag ; /* opp flag */ + unsigned short trace_length ; /* trace length */ + unsigned char trace_type ; /* trace type */ + unsigned short trace_time_stamp ;/* time stamp */ + unsigned short trace_reserved_1 ;/* reserved for later use */ + unsigned long trace_reserved_2 ; /* reserved for later use */ + unsigned long ptr_data_bfr ; /* pointer to the trace data buffer */ } TRACE_STATUS_ELEMENT_STRUCT; @@ -360,24 +360,24 @@ typedef struct { typedef struct { - unsigned long baud_rate ; /* the baud rate */ - unsigned short line_config_options ; /* line configuration options */ - unsigned short modem_config_options ; /* modem configuration options */ - unsigned short HDLC_API_options ; /* HDLC API options */ - unsigned short HDLC_protocol_options ; /* HDLC protocol options */ - unsigned short HDLC_buffer_config_options ; /* HDLC buffer configuration options */ - unsigned short HDLC_statistics_options ; /* HDLC operational statistics options */ - unsigned short configured_as_DTE ; /* DTE or DCE configuration */ - unsigned short max_HDLC_I_field_length ; /* the maximum length of the HDLC I-field */ - unsigned short HDLC_I_frame_window ; /* k - the I-frame window (maximum number of outstanding I-frames) */ - unsigned short HDLC_T1_timer ; /* the HDLC T1 timer */ - unsigned short HDLC_T2_timer ; /* the HDLC T2 timer */ - unsigned short HDLC_T3_timer ; /* the HDLC T3 timer */ - unsigned short HDLC_T4_timer ; /* the HDLC T4 timer */ - unsigned short HDLC_N2_counter ; /* the HDLC N2 counter */ - unsigned long ptr_shared_mem_info_struct ;/* a pointer to the shared memory area information structure */ - unsigned long ptr_HDLC_Tx_stat_el_cfg_struct ;/* a pointer to the transmit status element configuration structure */ - unsigned long ptr_HDLC_Rx_stat_el_cfg_struct ;/* a pointer to the receive status element configuration structure */ + unsigned long baud_rate ; /* the baud rate */ + unsigned short line_config_options ; /* line configuration options */ + unsigned short modem_config_options ; /* modem configuration options */ + unsigned short HDLC_API_options ; /* HDLC API options */ + unsigned short HDLC_protocol_options ; /* HDLC protocol options */ + unsigned short HDLC_buffer_config_options ; /* HDLC buffer configuration options */ + unsigned short HDLC_statistics_options ; /* HDLC operational statistics options */ + unsigned short configured_as_DTE ; /* DTE or DCE configuration */ + unsigned short max_HDLC_I_field_length ; /* the maximum length of the HDLC I-field */ + unsigned short HDLC_I_frame_window ; /* k - the I-frame window (maximum number of outstanding I-frames) */ + unsigned short HDLC_T1_timer ; /* the HDLC T1 timer */ + unsigned short HDLC_T2_timer ; /* the HDLC T2 timer */ + unsigned short HDLC_T3_timer ; /* the HDLC T3 timer */ + unsigned short HDLC_T4_timer ; /* the HDLC T4 timer */ + unsigned short HDLC_N2_counter ; /* the HDLC N2 counter */ + unsigned long ptr_shared_mem_info_struct ;/* a pointer to the shared memory area information structure */ + unsigned long ptr_HDLC_Tx_stat_el_cfg_struct ;/* a pointer to the transmit status element configuration structure */ + unsigned long ptr_HDLC_Rx_stat_el_cfg_struct ;/* a pointer to the receive status element configuration structure */ } HDLC_CONFIGURATION_STRUCT; @@ -604,9 +604,9 @@ typedef struct { */ typedef struct { - unsigned char interrupt_type ; /* type of interrupt triggered */ - unsigned char interrupt_permission ; /* interrupt permission mask */ - unsigned char int_info_reserved[14] ; /* reserved */ + unsigned char interrupt_type ; /* type of interrupt triggered */ + unsigned char interrupt_permission ; /* interrupt permission mask */ + unsigned char int_info_reserved[14] ; /* reserved */ } HDLC_INTERRUPT_INFO_STRUCT; @@ -633,9 +633,9 @@ typedef struct { typedef struct { - unsigned short number_Tx_status_elements ; /* number of transmit status elements */ - unsigned long base_addr_Tx_status_elements ; /* base address of the transmit element list */ - unsigned long next_Tx_status_element_to_use ; /* pointer to the next transmit element to be used */ + unsigned short number_Tx_status_elements ; /* number of transmit status elements */ + unsigned long base_addr_Tx_status_elements ; /* base address of the transmit element list */ + unsigned long next_Tx_status_element_to_use ; /* pointer to the next transmit element to be used */ } HDLC_TX_STATUS_EL_CFG_STRUCT; @@ -644,12 +644,12 @@ typedef struct { */ typedef struct { - unsigned char opp_flag ; /* opp flag */ - unsigned short I_frame_length ; /* length of the frame*/ - unsigned char P_bit ; /* P-bit setting in the frame */ - unsigned long reserved_1 ; /* reserved for internal use */ - unsigned long reserved_2 ; /* reserved for internal use */ - unsigned long ptr_data_bfr ; /* pointer to the data area */ + unsigned char opp_flag ; /* opp flag */ + unsigned short I_frame_length ; /* length of the frame*/ + unsigned char P_bit ; /* P-bit setting in the frame */ + unsigned long reserved_1 ; /* reserved for internal use */ + unsigned long reserved_2 ; /* reserved for internal use */ + unsigned long ptr_data_bfr ; /* pointer to the data area */ } HDLC_I_FRM_TX_STATUS_EL_STRUCT; @@ -665,11 +665,11 @@ typedef struct { typedef struct { - unsigned short number_Rx_status_elements ; /* number of receive status elements */ - unsigned long base_addr_Rx_status_elements ; /* base address of the receive element list */ - unsigned long next_Rx_status_element_to_use ; /* pointer to the next receive element to be used */ - unsigned long base_addr_Rx_buffer ; /* base address of the receive data buffer */ - unsigned long end_addr_Rx_buffer ; /* end address of the receive data buffer */ + unsigned short number_Rx_status_elements ; /* number of receive status elements */ + unsigned long base_addr_Rx_status_elements ; /* base address of the receive element list */ + unsigned long next_Rx_status_element_to_use ; /* pointer to the next receive element to be used */ + unsigned long base_addr_Rx_buffer ; /* base address of the receive data buffer */ + unsigned long end_addr_Rx_buffer ; /* end address of the receive data buffer */ } HDLC_RX_STATUS_EL_CFG_STRUCT; /* @@ -677,12 +677,12 @@ typedef struct { */ typedef struct { - unsigned char opp_flag ; /* opp flag */ - unsigned short I_frame_length ; /*length of the recvd frame */ - unsigned char P_bit ; /* P-bit setting in the frame */ - unsigned long reserved_1 ; /* reserved for internal use */ - unsigned long reserved_2 ; /* reserved for internal use */ - unsigned long ptr_data_bfr ; /* pointer to the data area */ + unsigned char opp_flag ; /* opp flag */ + unsigned short I_frame_length ; /*length of the recvd frame */ + unsigned char P_bit ; /* P-bit setting in the frame */ + unsigned long reserved_1 ; /* reserved for internal use */ + unsigned long reserved_2 ; /* reserved for internal use */ + unsigned long ptr_data_bfr ; /* pointer to the data area */ } HDLC_I_FRM_RX_STATUS_EL_STRUCT; @@ -700,12 +700,12 @@ typedef struct { typedef struct { - unsigned char global_status ; /* global status */ - unsigned char modem_status ;/* current modem status*/ - unsigned char global_excep_conditions ; /* global exception conditions */ - unsigned char glob_info_reserved[5] ; /* reserved */ - unsigned char code_name[4] ; /* code name */ - unsigned char code_version[4] ; /* code version */ + unsigned char global_status ; /* global status */ + unsigned char modem_status ;/* current modem status*/ + unsigned char global_excep_conditions ; /* global exception conditions */ + unsigned char glob_info_reserved[5] ; /* reserved */ + unsigned char code_name[4] ; /* code name */ + unsigned char code_version[4] ; /* code version */ } GLOBAL_INFORMATION_STRUCT; @@ -716,9 +716,9 @@ typedef struct { typedef struct { - unsigned char parallel_port_A_input ; /* input - parallel port A */ - unsigned char parallel_port_B_input ; /* input - parallel port B */ - unsigned char FT1_info_reserved[14] ; /* reserved */ + unsigned char parallel_port_A_input ; /* input - parallel port A */ + unsigned char parallel_port_B_input ; /* input - parallel port B */ + unsigned char FT1_info_reserved[14] ; /* reserved */ } FT1_INFORMATION_STRUCT; @@ -728,14 +728,14 @@ typedef struct { typedef struct { - unsigned char HDLC_status ; /* HDLC status */ - unsigned char HDLC_excep_frms_Rx ; /* HDLC exception conditions - received frames */ - unsigned char HDLC_excep_frms_Tx ; /* HDLC exception conditions - transmitted frames */ - unsigned char HDLC_excep_miscellaneous ; /* HDLC exception conditions - miscellaneous */ - unsigned char rotating_SUP_frm_count ; /* rotating Supervisory frame count */ - unsigned char LAPB_status ; /* internal LAPB status */ - unsigned char internal_HDLC_status ; /* internal HDLC status */ - unsigned char HDLC_info_reserved[9] ; /* reserved */ + unsigned char HDLC_status ; /* HDLC status */ + unsigned char HDLC_excep_frms_Rx ; /* HDLC exception conditions - received frames */ + unsigned char HDLC_excep_frms_Tx ; /* HDLC exception conditions - transmitted frames */ + unsigned char HDLC_excep_miscellaneous ; /* HDLC exception conditions - miscellaneous */ + unsigned char rotating_SUP_frm_count ; /* rotating Supervisory frame count */ + unsigned char LAPB_status ; /* internal LAPB status */ + unsigned char internal_HDLC_status ; /* internal HDLC status */ + unsigned char HDLC_info_reserved[9] ; /* reserved */ } HDLC_INFORMATION_STRUCT; @@ -748,14 +748,12 @@ typedef struct { typedef struct { - GLOBAL_INFORMATION_STRUCT global_info ; /* the global information structure */ - FT1_INFORMATION_STRUCT FT1_info ; /* the S508/FT1 information structure */ - HDLC_INFORMATION_STRUCT HDLC_info ; /* the HDLC information structure */ - HDLC_INTERRUPT_INFO_STRUCT HDLC_interrupt_info ; /* the HDLC interrupt information structure */ + GLOBAL_INFORMATION_STRUCT global_info ; /* the global information structure */ + FT1_INFORMATION_STRUCT FT1_info ; /* the S508/FT1 information structure */ + HDLC_INFORMATION_STRUCT HDLC_info ; /* the HDLC information structure */ + HDLC_INTERRUPT_INFO_STRUCT HDLC_interrupt_info ; /* the HDLC interrupt information structure */ } HDLC_SHARED_MEMORY_INFO_STRUCT; - -#pragma pack() - +#pragma pack() #endif diff --git a/patches/kdrivers/include/sdla_mp_fr.h b/patches/kdrivers/include/sdla_mp_fr.h index c2e1ba9..55f6822 100644 --- a/patches/kdrivers/include/sdla_mp_fr.h +++ b/patches/kdrivers/include/sdla_mp_fr.h @@ -18,8 +18,6 @@ #define MAX_FR_CHANNELS 1023 #define HIGHEST_VALID_DLCI MAX_FR_CHANNELS-1 -#pragma pack(1) - typedef struct { unsigned ea1 : 1; unsigned cr : 1; @@ -30,9 +28,7 @@ typedef struct { unsigned becn : 1; unsigned fecn : 1; unsigned dlcil: 4; -}fr_hdr; - -#pragma pack() +}__attribute__ ((packed)) fr_hdr; #define FR_HEADER_LEN 8 @@ -57,6 +53,14 @@ typedef struct { #define FR_LINK_INOPER 0x00 /* for global status (DLCI == 0) */ #define FR_LINK_OPER 0x01 +#if 0 +#define FR_DLCI_INOPER 0x00 +#define FR_DLCI_DELETED 0x01 /* for circuit status (DLCI != 0) */ +#define FR_DLCI_ACTIVE 0x02 +#define FR_DLCI_WAITING 0x04 +#define FR_DLCI_NEW 0x08 +#define FR_DLCI_REPORT 0x40 +#endif #define PVC_STATE_NEW 0x01 #define PVC_STATE_ACTIVE 0x02 diff --git a/patches/kdrivers/include/sdla_ppp.h b/patches/kdrivers/include/sdla_ppp.h index 1a7cf57..42d42ab 100644 --- a/patches/kdrivers/include/sdla_ppp.h +++ b/patches/kdrivers/include/sdla_ppp.h @@ -26,10 +26,11 @@ * -------- -------- * GNU C Linux */ -#pragma pack(1) #include +#pragma pack(1) + /* Adapter memory layout and important constants */ #define PPP508_MB_VECT 0xE000 /* mailbox window vector */ #define PPP508_MB_OFFS 0 /* mailbox offset */ @@ -46,27 +47,27 @@ * PPP Command Block. */ typedef struct ppp_cmd{ - unsigned char command ; /* command code */ - unsigned short length ; /* length of data buffer */ - unsigned char result ; /* return code */ - unsigned char rsrv[11] ; /* reserved for future use */ + unsigned char command ; /* command code */ + unsigned short length ; /* length of data buffer */ + unsigned char result ; /* return code */ + unsigned char rsrv[11] ; /* reserved for future use */ } ppp_cmd_t; typedef struct { - unsigned char status ; - unsigned char data_avail ; - unsigned short real_length ; - unsigned short time_stamp ; - unsigned char data[1] ; + unsigned char status ; + unsigned char data_avail ; + unsigned short real_length ; + unsigned short time_stamp ; + unsigned char data[1] ; } trace_pkt_t; typedef struct { - unsigned char opp_flag ; - unsigned char trace_type ; - unsigned short trace_length ; - unsigned short trace_data_ptr ; - unsigned short trace_time_stamp ; + unsigned char opp_flag ; + unsigned char trace_type ; + unsigned short trace_length ; + unsigned short trace_data_ptr ; + unsigned short trace_time_stamp ; } trace_element_t; @@ -82,9 +83,9 @@ typedef struct { */ typedef struct ppp_mbox { - unsigned char flag ; /* 00h: command execution flag */ - ppp_cmd_t cmd ; /* 01h: command block */ - unsigned char data[1] ; /* 10h: variable length data buffer */ + unsigned char flag ; /* 00h: command execution flag */ + ppp_cmd_t cmd ; /* 01h: command block */ + unsigned char data[1] ; /* 10h: variable length data buffer */ } ppp_mbox_t; #endif /*---------------------------------------------------------------------------- @@ -94,17 +95,17 @@ typedef struct ppp_mbox */ typedef struct ppp_flags { - unsigned char iflag ; /* 00: interrupt flag */ - unsigned char imask ; /* 01: interrupt mask */ - unsigned char resrv ; - unsigned char mstatus ; /* 03: modem status */ - unsigned char lcp_state ; /* 04: LCP state */ - unsigned char ppp_phase ; /* 05: PPP phase */ - unsigned char ip_state ; /* 06: IPCP state */ - unsigned char ipx_state ; /* 07: IPXCP state */ - unsigned char pap_state ; /* 08: PAP state */ - unsigned char chap_state ; /* 09: CHAP state */ - unsigned short disc_cause ; /* 0A: disconnection cause */ + unsigned char iflag ; /* 00: interrupt flag */ + unsigned char imask ; /* 01: interrupt mask */ + unsigned char resrv ; + unsigned char mstatus ; /* 03: modem status */ + unsigned char lcp_state ; /* 04: LCP state */ + unsigned char ppp_phase ; /* 05: PPP phase */ + unsigned char ip_state ; /* 06: IPCP state */ + unsigned char ipx_state ; /* 07: IPXCP state */ + unsigned char pap_state ; /* 08: PAP state */ + unsigned char chap_state ; /* 09: CHAP state */ + unsigned short disc_cause ; /* 0A: disconnection cause */ } ppp_flags_t; /* 'iflag' defines */ @@ -163,16 +164,16 @@ typedef struct ppp_flags */ typedef struct ppp508_buf_info { - unsigned short txb_num ; /* 00: number of transmit buffers */ - unsigned int txb_ptr ; /* 02: pointer to the buffer ctl. */ - unsigned int txb_nxt ; - unsigned char rsrv1[22] ; - unsigned short rxb_num ; /* 20: number of receive buffers */ - unsigned int rxb_ptr ; /* 22: pointer to the buffer ctl. */ - unsigned int rxb1_ptr ; /* 26: pointer to the first buf.ctl. */ - unsigned int rxb_base ; /* 2A: pointer to the buffer base */ - unsigned char rsrv2[2] ; - unsigned int rxb_end ; /* 30: pointer to the buffer end */ + unsigned short txb_num ; /* 00: number of transmit buffers */ + unsigned int txb_ptr ; /* 02: pointer to the buffer ctl. */ + unsigned int txb_nxt ; + unsigned char rsrv1[22] ; + unsigned short rxb_num ; /* 20: number of receive buffers */ + unsigned int rxb_ptr ; /* 22: pointer to the buffer ctl. */ + unsigned int rxb1_ptr ; /* 26: pointer to the first buf.ctl. */ + unsigned int rxb_base ; /* 2A: pointer to the buffer base */ + unsigned char rsrv2[2] ; + unsigned int rxb_end ; /* 30: pointer to the buffer end */ } ppp508_buf_info_t; /*---------------------------------------------------------------------------- @@ -180,17 +181,17 @@ typedef struct ppp508_buf_info */ typedef struct ppp_buf_ctl { - unsigned char flag ; /* 00: 'buffer ready' flag */ - unsigned short length ; /* 01: length of data */ - unsigned char reserved1[1] ; /* 03: */ - unsigned char proto ; /* 04: protocol */ - unsigned short timestamp ; /* 05: time stamp (Rx only) */ - unsigned char reserved2[5] ; /* 07: */ + unsigned char flag ; /* 00: 'buffer ready' flag */ + unsigned short length ; /* 01: length of data */ + unsigned char reserved1[1] ; /* 03: */ + unsigned char proto ; /* 04: protocol */ + unsigned short timestamp ; /* 05: time stamp (Rx only) */ + unsigned char reserved2[5] ; /* 07: */ union { unsigned short o_p[2]; /* 1C: buffer offset & page (S502) */ unsigned int ptr; /* 1C: buffer pointer (S508) */ - } buf ; + } buf ; } ppp_buf_ctl_t; /*---------------------------------------------------------------------------- @@ -198,31 +199,31 @@ typedef struct ppp_buf_ctl */ typedef struct ppp508_conf { - unsigned int line_speed ; /* 00: baud rate, bps */ - unsigned short txbuf_percent ; /* 04: % of Tx buffer */ - unsigned short conf_flags ; /* 06: configuration bits */ - unsigned short mtu_local ; /* 08: local MTU */ - unsigned short mtu_remote ; /* 0A: remote MTU */ - unsigned short restart_tmr ; /* 0C: restart timer */ - unsigned short auth_rsrt_tmr ; /* 0E: authentication timer */ - unsigned short auth_wait_tmr ; /* 10: authentication timer */ - unsigned short mdm_fail_tmr ; /* 12: modem failure timer */ - unsigned short dtr_drop_tmr ; /* 14: DTR drop timer */ - unsigned short connect_tmout ; /* 16: connection timeout */ - unsigned short conf_retry ; /* 18: max. retry */ - unsigned short term_retry ; /* 1A: max. retry */ - unsigned short fail_retry ; /* 1C: max. retry */ - unsigned short auth_retry ; /* 1E: max. retry */ - unsigned char auth_options ; /* 20: authentication opt. */ - unsigned char ip_options ; /* 21: IP options */ - unsigned int ip_local ; /* 22: local IP address */ - unsigned int ip_remote ; /* 26: remote IP address */ - unsigned char ipx_options ; /* 2A: IPX options */ - unsigned char ipx_netno[4] ; /* 2B: IPX net number */ - unsigned char ipx_local[6] ; /* 2F: local IPX node number*/ - unsigned char ipx_remote[6] ; /* 35: remote IPX node num.*/ - unsigned char ipx_router[48] ; /* 3B: IPX router name*/ - unsigned int alt_cpu_clock ; /* 6B: */ + unsigned int line_speed ; /* 00: baud rate, bps */ + unsigned short txbuf_percent ; /* 04: % of Tx buffer */ + unsigned short conf_flags ; /* 06: configuration bits */ + unsigned short mtu_local ; /* 08: local MTU */ + unsigned short mtu_remote ; /* 0A: remote MTU */ + unsigned short restart_tmr ; /* 0C: restart timer */ + unsigned short auth_rsrt_tmr ; /* 0E: authentication timer */ + unsigned short auth_wait_tmr ; /* 10: authentication timer */ + unsigned short mdm_fail_tmr ; /* 12: modem failure timer */ + unsigned short dtr_drop_tmr ; /* 14: DTR drop timer */ + unsigned short connect_tmout ; /* 16: connection timeout */ + unsigned short conf_retry ; /* 18: max. retry */ + unsigned short term_retry ; /* 1A: max. retry */ + unsigned short fail_retry ; /* 1C: max. retry */ + unsigned short auth_retry ; /* 1E: max. retry */ + unsigned char auth_options ; /* 20: authentication opt. */ + unsigned char ip_options ; /* 21: IP options */ + unsigned int ip_local ; /* 22: local IP address */ + unsigned int ip_remote ; /* 26: remote IP address */ + unsigned char ipx_options ; /* 2A: IPX options */ + unsigned char ipx_netno[4] ; /* 2B: IPX net number */ + unsigned char ipx_local[6] ; /* 2F: local IPX node number*/ + unsigned char ipx_remote[6] ; /* 35: remote IPX node num.*/ + unsigned char ipx_router[48] ; /* 3B: IPX router name*/ + unsigned int alt_cpu_clock ; /* 6B: */ } ppp508_conf_t; /*---------------------------------------------------------------------------- @@ -231,17 +232,17 @@ typedef struct ppp508_conf */ typedef struct ppp508_connect_info { - unsigned short mru ; /* 00-01 Remote Max Rec' Unit */ - unsigned char ip_options ; /* 02: Negotiated ip options */ - unsigned int ip_local ; /* 03-06: local IP address */ - unsigned int ip_remote ; /* 07-0A: remote IP address */ - unsigned char ipx_options ; /* 0B: Negotiated ipx options */ - unsigned char ipx_netno[4] ; /* 0C-0F: IPX net number */ - unsigned char ipx_local[6] ; /* 10-1F: local IPX node # */ - unsigned char ipx_remote[6] ; /* 16-1B: remote IPX node # */ - unsigned char ipx_router[48] ; /* 1C-4B: IPX router name */ - unsigned char auth_status ; /* 4C: Authentication Status */ - unsigned char inbd_auth_peerID[1] ; /* 4D: variable length inbound authenticated peer ID */ + unsigned short mru ; /* 00-01 Remote Max Rec' Unit */ + unsigned char ip_options ; /* 02: Negotiated ip options */ + unsigned int ip_local ; /* 03-06: local IP address */ + unsigned int ip_remote ; /* 07-0A: remote IP address */ + unsigned char ipx_options ; /* 0B: Negotiated ipx options */ + unsigned char ipx_netno[4] ; /* 0C-0F: IPX net number */ + unsigned char ipx_local[6] ; /* 10-1F: local IPX node # */ + unsigned char ipx_remote[6] ; /* 16-1B: remote IPX node # */ + unsigned char ipx_router[48] ; /* 1C-4B: IPX router name */ + unsigned char auth_status ; /* 4C: Authentication Status */ + unsigned char inbd_auth_peerID[1] ; /* 4D: variable length inbound authenticated peer ID */ } ppp508_connect_info_t; /* 'line_speed' field */ @@ -286,10 +287,10 @@ typedef struct ppp508_connect_info */ typedef struct ppp508_get_conf { - unsigned int bps ; /* 00: baud rate, bps */ - ppp508_conf_t conf ; /* 04: requested config. */ - unsigned short txb_num ; /* 6F: number of Tx buffers */ - unsigned short rxb_num ; /* 71: number of Rx buffers */ + unsigned int bps ; /* 00: baud rate, bps */ + ppp508_conf_t conf ; /* 04: requested config. */ + unsigned short txb_num ; /* 6F: number of Tx buffers */ + unsigned short rxb_num ; /* 71: number of Rx buffers */ } ppp508_get_conf_t; /*---------------------------------------------------------------------------- @@ -297,13 +298,13 @@ typedef struct ppp508_get_conf */ typedef struct ppp508_stats { - unsigned short reserved1 ; /* 00: */ - unsigned short rx_bad_len ; /* 02: */ - unsigned short reserved2 ; /* 04: */ - unsigned int tx_frames ; /* 06: */ - unsigned int tx_bytes ; /* 0A: */ - unsigned int rx_frames ; /* 0E: */ - unsigned int rx_bytes ; /* 12: */ + unsigned short reserved1 ; /* 00: */ + unsigned short rx_bad_len ; /* 02: */ + unsigned short reserved2 ; /* 04: */ + unsigned int tx_frames ; /* 06: */ + unsigned int tx_bytes ; /* 0A: */ + unsigned int rx_frames ; /* 0E: */ + unsigned int rx_bytes ; /* 12: */ } ppp508_stats_t; /*---------------------------------------------------------------------------- @@ -311,25 +312,25 @@ typedef struct ppp508_stats */ typedef struct ppp_err_stats { - unsigned char rx_overrun ; /* 00: Rx overrun errors */ - unsigned char rx_bad_crc ; /* 01: Rx CRC errors */ - unsigned char rx_abort ; /* 02: Rx aborted frames */ - unsigned char rx_lost ; /* 03: Rx frames lost */ - unsigned char tx_abort ; /* 04: Tx aborted frames */ - unsigned char tx_underrun ; /* 05: Tx underrun errors */ - unsigned char tx_missed_intr ; /* 06: Tx underruns missed */ - unsigned char reserved ; /* 07: Tx underruns missed */ - unsigned char dcd_trans ; /* 08: DCD transitions */ - unsigned char cts_trans ; /* 09: CTS transitions */ + unsigned char rx_overrun ; /* 00: Rx overrun errors */ + unsigned char rx_bad_crc ; /* 01: Rx CRC errors */ + unsigned char rx_abort ; /* 02: Rx aborted frames */ + unsigned char rx_lost ; /* 03: Rx frames lost */ + unsigned char tx_abort ; /* 04: Tx aborted frames */ + unsigned char tx_underrun ; /* 05: Tx underrun errors */ + unsigned char tx_missed_intr ; /* 06: Tx underruns missed */ + unsigned char reserved ; /* 07: Tx underruns missed */ + unsigned char dcd_trans ; /* 08: DCD transitions */ + unsigned char cts_trans ; /* 09: CTS transitions */ } ppp_err_stats_t; /* Data structure for SET_TRIGGER_INTR command */ typedef struct ppp_intr_info{ - unsigned char i_enable ; /* 0 Interrupt enable bits */ - unsigned char irq ; /* 1 Irq number */ - unsigned short timer_len ; /* 2 Timer delay */ + unsigned char i_enable ; /* 0 Interrupt enable bits */ + unsigned char irq ; /* 1 Irq number */ + unsigned short timer_len ; /* 2 Timer delay */ } ppp_intr_info_t; @@ -364,7 +365,6 @@ typedef struct ppp_intr_info{ #define UDPDRV_SIGNATURE "DRVSTATS" #define UDPMGMT_UDP_PROTOCOL 0x11 - -#pragma pack() +#pragma pack() #endif /* _SDLA_PPP_H */ diff --git a/patches/kdrivers/include/sdla_remora.h b/patches/kdrivers/include/sdla_remora.h index a3daeb1..cf58d5b 100644 --- a/patches/kdrivers/include/sdla_remora.h +++ b/patches/kdrivers/include/sdla_remora.h @@ -37,6 +37,8 @@ #define IS_FXOFXS_CARD(card) IS_FXOFXS_FEMEDIA(&(card)->fe) +#define WAN_RM_START_CHANNEL 1 + #define MAX_REMORA_MODULES 24 #define MAX_FXOFXS_CHANNELS MAX_REMORA_MODULES @@ -88,14 +90,21 @@ #define WAN_RM_OPERMODE_LEN 20 /* Front-End UDP command */ +#if defined(__WINDOWS__) +#define WAN_FE_TONES 13 +#define WAN_FE_RING (WAN_FE_TONES + 1) +#define WAN_FE_REGDUMP (WAN_FE_TONES + 2) +#define WAN_FE_STATS (WAN_FE_TONES + 3) +#else #define WAN_FE_TONES (WAN_FE_UDP_CMD_START + 0) #define WAN_FE_RING (WAN_FE_UDP_CMD_START + 1) #define WAN_FE_REGDUMP (WAN_FE_UDP_CMD_START + 2) #define WAN_FE_STATS (WAN_FE_UDP_CMD_START + 3) +#endif #define WAN_RM_SET_ECHOTUNE _IOW (ZT_CODE, 63, struct wan_rm_echo_coefs) -/* FE interrupt types */ +/* RM interrupt types */ #define WAN_RM_INTR_NONE 0x00 #define WAN_RM_INTR_GLOBAL 0x01 @@ -119,22 +128,28 @@ ** TYPEDEF STRUCTURE *******************************************************************************/ typedef struct sdla_remora_cfg_ { - int not_used; - int opermode; - char opermode_name[WAN_RM_OPERMODE_LEN]; + + int opermode; + char opermode_name[WAN_RM_OPERMODE_LEN]; /* int tdmv_law;*/ /* WAN_TDMV_ALAW or WAN_TDMV_MULAW */ - int reversepolarity; - int battthresh; - int battdebounce; - int network_sync; + int reversepolarity; + int battthresh; + int battdebounce; + int network_sync; + + u_int8_t relaxcfg; /* do not failed during config if one of + ** the modules failed to configure */ int fxs_rxgain; int fxs_txgain; u_int8_t fxs_fastringer; u_int8_t fxs_lowpower; + u_int8_t fxs_pulsedialing; int fxo_rxgain; int fxo_txgain; + + int fxs_ringampl; } sdla_remora_cfg_t; typedef struct { @@ -151,7 +166,7 @@ typedef struct { int ring_volt; /* RING voltage (mV) (FXS) */ int bat_volt; /* VBAT voltage (mV) (FXS) */ int volt; /* Line voltage status (FXO) */ - //u_int8_t hook; /* On/Off hook state */ + /*u_int8_t hook; */ /* On/Off hook state */ } wan_remora_stats_t; typedef struct { @@ -185,70 +200,90 @@ struct wan_rm_echo_coefs { #if !defined(WAN_DEBUG_FE) # define WRITE_RM_FXS_REG(mod_no,chain,reg,val) \ - fe->write_fe_reg( fe->card, \ + fe->write_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ (int)MOD_TYPE_FXS, \ (int)chain, \ (int)reg, \ (int)val) # define READ_RM_FXS_REG(mod_no,chain,reg) \ - fe->read_fe_reg( fe->card, \ + fe->read_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ (int)MOD_TYPE_FXS, \ (int)chain, \ (int)reg) # define WRITE_RM_FXO_REG(mod_no,chain,reg,val) \ - fe->write_fe_reg( fe->card, \ + fe->write_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ (int)MOD_TYPE_FXO, \ (int)chain, \ (int)reg, \ (int)val) # define READ_RM_FXO_REG(mod_no,chain,reg) \ - fe->read_fe_reg( fe->card, \ + fe->read_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ (int)MOD_TYPE_FXO, \ (int)chain, \ (int)reg) # define WRITE_RM_REG(mod_no,reg,val) \ - fe->write_fe_reg( fe->card, \ + fe->write_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ - fe->rm_param.mod[mod_no].type, \ - fe->rm_param.mod[mod_no].chain, \ + (int)fe->rm_param.mod[mod_no].type, \ + (int)fe->rm_param.mod[mod_no].chain, \ (int)reg, (int)val) # define READ_RM_REG(mod_no,reg) \ - fe->read_fe_reg( fe->card, \ + fe->read_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ - fe->rm_param.mod[mod_no].type, \ - fe->rm_param.mod[mod_no].chain, \ + (int)fe->rm_param.mod[mod_no].type, \ + (int)fe->rm_param.mod[mod_no].chain, \ (int)reg) #else -# define WRITE_RM_FXS_REG(mod_no,chain,reg,val) \ - fe->write_fe_reg(fe->card,(int)mod_no,(int)MOD_TYPE_FXS,(int)chain,(int)reg,(int)val,__FILE__,(int)__LINE__) +# define WRITE_RM_FXS_REG(mod_no,chain,reg,val) \ + fe->write_fe_reg( ((sdla_t*)fe->card)->hw, \ + (int)mod_no, \ + (int)MOD_TYPE_FXS, \ + (int)chain, \ + (int)reg, (int)val, \ + __FILE__,(int)__LINE__) # define READ_RM_FXS_REG(mod_no,chain,reg) \ - fe->read_fe_reg(fe->card, (int)mod_no,(int)MOD_TYPE_FXS,(int)chain,(int)reg,__FILE__,__LINE__) + fe->read_fe_reg( ((sdla_t*)fe->card)->hw, \ + (int)mod_no, \ + (int)MOD_TYPE_FXS, \ + (int)chain, \ + (int)reg, \ + __FILE__,__LINE__) # define WRITE_RM_FXO_REG(mod_no,chain,reg,val) \ - fe->write_fe_reg(fe->card,(int)mod_no,(int)MOD_TYPE_FXO,(int)chain,(int)reg,(int)val,__FILE__,(int)__LINE__) + fe->write_fe_reg( ((sdla_t*)fe->card)->hw, \ + (int)mod_no, \ + (int)MOD_TYPE_FXO, \ + (int)chain, \ + (int)reg,(int)val, \ + __FILE__,(int)__LINE__) # define READ_RM_FXO_REG(mod_no,chain,reg) \ - fe->read_fe_reg(fe->card, (int)mod_no,(int)MOD_TYPE_FXO,(int)chain,(int)reg,__FILE__,(int)__LINE__) + fe->read_fe_reg( ((sdla_t*)fe->card)->hw, \ + (int)mod_no, \ + (int)MOD_TYPE_FXO, \ + (int)chain, \ + (int)reg, \ + __FILE__,(int)__LINE__) # define WRITE_RM_REG(mod_no,reg,val) \ - fe->write_fe_reg( fe->card, \ + fe->write_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ - fe->rm_param.mod[mod_no].type, \ - fe->rm_param.mod[mod_no].chain, \ + (int)fe->rm_param.mod[mod_no].type, \ + (int)fe->rm_param.mod[mod_no].chain, \ (int)reg, (int)val,__FILE__,(int)__LINE__) # define READ_RM_REG(mod_no,reg) \ - fe->read_fe_reg( fe->card, \ + fe->read_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ - fe->rm_param.mod[mod_no].type, \ - fe->rm_param.mod[mod_no].chain, \ + (int)fe->rm_param.mod[mod_no].type, \ + (int)fe->rm_param.mod[mod_no].chain, \ (int)reg,__FILE__,(int)__LINE__) #endif #define __READ_RM_REG(mod_no,reg) \ - fe->__read_fe_reg( fe->card, \ + fe->__read_fe_reg( ((sdla_t*)fe->card)->hw, \ (int)mod_no, \ - fe->rm_param.mod[mod_no].type, \ - fe->rm_param.mod[mod_no].chain, \ + (int)fe->rm_param.mod[mod_no].type, \ + (int)fe->rm_param.mod[mod_no].chain, \ (int)reg) @@ -332,12 +367,14 @@ typedef struct { typedef struct { // u_int16_t type; - int mod_no; /* A200-Remora */ + unsigned int mod_no; /* A200-Remora */ unsigned char ec_dtmf_port; /* EC DTMF: SOUT or ROUT */ unsigned long ts_map; u_int8_t tone; int ohttimer; /* On-hook transfer */ int polarity; /* SETPOLARITY */ + unsigned short reg; /* fe register */ + unsigned char value; /* fe register value */ } sdla_rm_event_t; typedef struct sdla_remora_param { @@ -355,7 +392,12 @@ typedef struct sdla_remora_param { // u16 timer_delay; u32 intcount; - unsigned long last_watchdog; + wan_ticks_t last_watchdog; + + int reg_dbg_busy; + int reg_dbg_ready; + unsigned char reg_dbg_value; + } sdla_remora_param_t; @@ -364,7 +406,7 @@ typedef struct sdla_remora_param { /******************************************************************************* ** FUNCTION PROTOTYPES *******************************************************************************/ -extern int wp_remora_iface_init(void*); +extern int wp_remora_iface_init(void*, void*); #undef EXTERN #endif /* __SDLA_REMORA_H */ diff --git a/patches/kdrivers/include/sdla_serial.h b/patches/kdrivers/include/sdla_serial.h new file mode 100644 index 0000000..8e47a5c --- /dev/null +++ b/patches/kdrivers/include/sdla_serial.h @@ -0,0 +1,62 @@ +/***************************************************************************** + * sdla_serial.h Sangoma AFT Base Serial configuration definitions. + * + * Author: Alex Feldman + * + * 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. + + * ============================================================================ + * Oct 10, 2007 Alex Feldman Initial version. + **************************************************************************** +*/ + +#ifndef _SDLA_SERIAL_H_ +#define _SDLA_SERIAL_H_ + +/******************************************************************************* + DEFINES AND MACROS + ******************************************************************************/ + +#define AFT_SERIAL_OSC 14745600 + +#define REG_FLOWCNTRL 0x00 + +#define BIT_FLOWCNTRL_RTS 0x00000001 +#define BIT_FLOWCNTRL_DTR 0x00000002 +#define BIT_FLOWCNTRL_CTS 0x00000004 +#define BIT_FLOWCNTRL_DCD 0x00000008 + +#define BITS_BAUDRATE(baud,asyn_if) ((( AFT_SERIAL_OSC / (2 * ((async_if) ? 16 :1) * (baud))) - 1 ) << 8) + +#define BIT_INTCTRL_CLK_MASTER 0x01000000 /* Internal clock (from oscillator) */ +#define BIT_INTCTRL_NRZI 0x10000000 /* NRZI */ +#define BIT_INTCTRL_FM1 0x20000000 /* FM1 */ +#define BIT_INTCTRL_FM0 0x30000000 /* FM0 */ +#define BIT_INTCTRL_MANCHESTER 0x40000000 /* MANCHESTER */ +#define BIT_INTCTRL_ASYNCH 0x80000000 /* Asynchronous */ + +#define MAX_SERIAL_LINES 4 +/******************************************************************************* + FUNCTION PROTOTYPES + ******************************************************************************/ + + +#ifdef WAN_KERNEL + +#define IS_SERIAL_CARD(card) IS_SERIAL_FEMEDIA(&(card)->fe) + +int aft_serial_write_fe(void* phw, ...); +#define __aft_serial_write_fe aft_serial_write_fe +u32 aft_serial_read_fe(void* phw, ...); +#define __aft_serial_read_fe aft_serial_read_fe + +int32_t wp_serial_iface_init(void *pfe_iface); + +#endif /* WAN_KERNEL */ + +#endif /* _SDLA_SERIAL_H_ */ diff --git a/patches/kdrivers/include/sdla_tdmv.h b/patches/kdrivers/include/sdla_tdmv.h index f69221c..0e3de6c 100644 --- a/patches/kdrivers/include/sdla_tdmv.h +++ b/patches/kdrivers/include/sdla_tdmv.h @@ -104,6 +104,7 @@ typedef struct wan_tdmv_iface_ ******************************************************************************/ EXTERN int wp_tdmv_te1_init(wan_tdmv_iface_t *iface); EXTERN int wp_tdmv_remora_init(wan_tdmv_iface_t *iface); +EXTERN int wp_tdmv_bri_init(wan_tdmv_iface_t *iface); #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER EXTERN int wp_tdmv_echo_check(wan_tdmv_t *wan_tdmv, void *current_ztchan, int channo); diff --git a/patches/kdrivers/include/sdla_tdmv.mar8.h b/patches/kdrivers/include/sdla_tdmv.mar8.h deleted file mode 100644 index 8a200d7..0000000 --- a/patches/kdrivers/include/sdla_tdmv.mar8.h +++ /dev/null @@ -1,70 +0,0 @@ -/****************************************************************************** - * sdla_tdmv.h - * - * Author: Alex Feldman - * - * 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. - * ============================================================================ - ****************************************************************************** - */ - -#ifndef __SDLA_TDMV_H -# define __SDLA_TDMV_H - -#ifdef __SDLA_TDMV_SRC -# define EXTERN -#else -# define EXTERN extern -#endif - - -/* -******************************************************************************* -** DEFINES and MACROS -******************************************************************************* -*/ -#define WAN_TDMV_IDLE_FLAG 0x7F - -/* -******************************************************************************* -** TYPEDEF STRUCTURE -******************************************************************************* -*/ -typedef struct wan_tdmv_ { - void *sc; - int max_tx_len; - int max_timeslots; - int brt_enable; - int spanno; - WAN_LIST_ENTRY(wan_tdmv_) next; -} wan_tdmv_t; - -/* -******************************************************************************* -** FUNCTION PROTOTYPES -******************************************************************************* -*/ -EXTERN int wp_tdmv_check_mtu(void*, unsigned long); -EXTERN int wp_tdmv_init(void*, wanif_conf_t*); -EXTERN void wp_tdmv_free(wan_tdmv_t*); -EXTERN void wp_tdmv_state(void*, int); -EXTERN int wp_tdmv_rx_tx(void*, netskb_t*); -EXTERN void wp_tdmv_report_rbsbits(void*, int, unsigned char); -EXTERN void wp_tdmv_report_alarms(void*, unsigned long); - -EXTERN int wp_tdmv_create(void* pcard, wandev_conf_t *conf); -EXTERN int wp_tdmv_reg(void*, wanif_conf_t*, int); -EXTERN int wp_tdmv_unreg(void* pcard, unsigned long ts_map); -EXTERN int wp_tdmv_remove(void* pcard); -EXTERN int wp_tdmv_rx_chan(wan_tdmv_t *wan_tdmv, int channo, - unsigned char *rxbuf, - unsigned char *txbuf); -EXTERN int wp_tdmv_rx_tx_span(void *pcard); - -#undef EXTERN -#endif /* __SDLA_VOIP_H */ diff --git a/patches/kdrivers/include/sdla_te1.h b/patches/kdrivers/include/sdla_te1.h index e62b28e..712c66c 100644 --- a/patches/kdrivers/include/sdla_te1.h +++ b/patches/kdrivers/include/sdla_te1.h @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: sdla_te1.h,v 1.57 2007/04/04 16:25:49 sangoma Exp $ + * $Id: sdla_te1.h,v 1.71 2008/03/03 19:21:02 sangoma Exp $ */ /***************************************************************************** @@ -81,19 +81,26 @@ #define WAN_TE_SIG_INTR 0x02 /* Framer Alarm bit mask */ -#define WAN_TE_BIT_ALOS_ALARM 0x0001 -#define WAN_TE_BIT_LOS_ALARM 0x0002 -#define WAN_TE_BIT_ALTLOS_ALARM 0x0004 -#define WAN_TE_BIT_OOF_ALARM 0x0008 -#define WAN_TE_BIT_RED_ALARM 0x0010 -#define WAN_TE_BIT_AIS_ALARM 0x0020 -#define WAN_TE_BIT_OOSMF_ALARM 0x0040 -#define WAN_TE_BIT_OOCMF_ALARM 0x0080 -#define WAN_TE_BIT_OOOF_ALARM 0x0100 -#define WAN_TE_BIT_RAI_ALARM 0x0200 -#define WAN_TE_BIT_YEL_ALARM 0x0400 -#define WAN_TE_BIT_LOOPUP_CODE 0x2000 -#define WAN_TE_BIT_LOOPDOWN_CODE 0x4000 +#define WAN_TE_BIT_FRAMER_ALARM_MASK 0x0000FFFF +#define WAN_TE_BIT_LIU_ALARM_MASK 0x00F00000 +#define WAN_TE_BIT_ALOS_ALARM 0x00000001 +#define WAN_TE_BIT_LOS_ALARM 0x00000002 +#define WAN_TE_BIT_ALTLOS_ALARM 0x00000004 +#define WAN_TE_BIT_OOF_ALARM 0x00000008 +#define WAN_TE_BIT_RED_ALARM 0x00000010 +#define WAN_TE_BIT_AIS_ALARM 0x00000020 +#define WAN_TE_BIT_OOSMF_ALARM 0x00000040 +#define WAN_TE_BIT_OOCMF_ALARM 0x00000080 +#define WAN_TE_BIT_OOOF_ALARM 0x00000100 +#define WAN_TE_BIT_RAI_ALARM 0x00000200 +#define WAN_TE_BIT_YEL_ALARM 0x00000400 +#define WAN_TE_BIT_LOOPUP_CODE 0x00002000 +#define WAN_TE_BIT_LOOPDOWN_CODE 0x00004000 +#define WAN_TE_BIT_LIU_ALARM 0x00100000 +#define WAN_TE_BIT_LIU_ALARM_SC 0x00200000 +#define WAN_TE_BIT_LIU_ALARM_OC 0x00400000 +#define WAN_TE_BIT_LIU_ALARM_LOS 0x00800000 + #define WAN_TE_BIT_TE1_ALARM 0x8000 /* for Windows only */ #define IS_TE_ALARM(alarm, mask) (alarm & mask) #define IS_TE_ALOS_ALARM(alarm) IS_TE_ALARM(alarm, WAN_TE_BIT_ALOS_ALARM) @@ -116,12 +123,6 @@ #define WAN_TE_BIT_PMON_FER 0x20 /* framing bit error (T1-pmc) */ #define WAN_TE_BIT_PMON_FAS 0x40 /* Frame Alginment signal (E1) */ -/* LIU Alarm bit mask */ -#define WAN_TE_BIT_LIU_ALARM 0x8000 /* print liu status */ -#define WAN_TE_BIT_LIU_ALARM_SC 0x0001 -#define WAN_TE_BIT_LIU_ALARM_OC 0x0002 -#define WAN_TE_BIT_LIU_ALARM_LOS 0x0004 - /* T1/E1 statistics bit mask */ #define WAN_TE_STATS_BIT_ALARM 0x0001 #define WAN_TE_STATS_BIT_RXLEVEL 0x0002 @@ -149,7 +150,7 @@ #define WAN_T1_533_655 0x11 /* T1/E1: Recever */ -#define WAN_TE1_RX_SLEVEL_NONE 0 +#define WAN_TE1_RX_SLEVEL_NONE 0 #define WAN_TE1_RX_SLEVEL_43_DB 430 /* 43 dB E1, RMONEN=0 */ #define WAN_TE1_RX_SLEVEL_36_DB 360 /* 36 dB T1, RMONEN=0 */ #define WAN_TE1_RX_SLEVEL_30_DB 300 /* 30 dB RMONEN=0 | 1 */ @@ -182,44 +183,27 @@ #define WAN_TE1_FR_FLB_MODE 0x09 #define WAN_TE1_FR_PLB_MODE 0x0A #define WAN_TE1_FR_RLB_MODE 0x0B -#define WAN_TE1_LB_TYPE_DECODE(type) \ - (type == WAN_TE1_LINELB_MODE) ? "Line Loopback" : \ - (type == WAN_TE1_PAYLB_MODE) ? "Payload Loopback" : \ - (type == WAN_TE1_DDLB_MODE) ? "Diagnostic Digital Loopback" : \ - (type == WAN_TE1_TX_LB_MODE) ? "TX Loopback" : \ - (type == WAN_TE1_LIU_ALB_MODE) ? "Analog LIU Loopback" : \ - (type == WAN_TE1_LIU_LLB_MODE) ? "Local LIU Loopback" : \ - (type == WAN_TE1_LIU_RLB_MODE) ? "Remote LIU Loopback" : \ - (type == WAN_TE1_LIU_DLB_MODE) ? "Dual LIU Loopback" : \ - (type == WAN_TE1_FR_FLB_MODE) ? "Framer Loopback" : \ - (type == WAN_TE1_FR_RLB_MODE) ? "Remote Framer Loopback" : \ - (type == WAN_TE1_FR_PLB_MODE) ? "Payload Framer Loopback" : \ +#define WAN_TE1_LB_MODE_DECODE(mode) \ + ((mode) == WAN_TE1_LINELB_MODE) ? "Line Loopback" : \ + ((mode) == WAN_TE1_PAYLB_MODE) ? "Payload Loopback" : \ + ((mode) == WAN_TE1_DDLB_MODE) ? "Diagnostic Digital Loopback" : \ + ((mode) == WAN_TE1_TX_LB_MODE) ? "TX Loopback" : \ + ((mode) == WAN_TE1_LIU_ALB_MODE) ? "Analog LIU Loopback" : \ + ((mode) == WAN_TE1_LIU_LLB_MODE) ? "Local LIU Loopback" : \ + ((mode) == WAN_TE1_LIU_RLB_MODE) ? "Remote LIU Loopback" : \ + ((mode) == WAN_TE1_LIU_DLB_MODE) ? "Dual LIU Loopback" : \ + ((mode) == WAN_TE1_FR_FLB_MODE) ? "Framer Loopback" : \ + ((mode) == WAN_TE1_FR_RLB_MODE) ? "Remote Framer Loopback" : \ + ((mode) == WAN_TE1_FR_PLB_MODE) ? "Payload Framer Loopback" : \ "Unknown Loopback" /* Line loopback activate/deactive modes */ #define WAN_TE1_ACTIVATE_LB 0x01 #define WAN_TE1_DEACTIVATE_LB 0x02 - -#if 1 -#define WAN_TE1_LB_MODE_DECODE(mode) \ - ((mode) == WAN_TE1_LINELB_MODE) ? "Line Loopback" : \ - ((mode) == WAN_TE1_PAYLB_MODE) ? "Payload Loopback" : \ - ((mode) == WAN_TE1_DDLB_MODE) ? "Diagnostic Digital Loopback" : \ - ((mode) == WAN_TE1_TX_LB_MODE) ? "TX Loopback" : \ - ((mode) == WAN_TE1_LIU_ALB_MODE) ? "Analog LIU Loopback" : \ - ((mode) == WAN_TE1_LIU_LLB_MODE) ? "Local LIU Loopback" : \ - ((mode) == WAN_TE1_LIU_RLB_MODE) ? "Remote LIU Loopback" : \ - ((mode) == WAN_TE1_LIU_DLB_MODE) ? "Dual LIU Loopback" : \ - ((mode) == WAN_TE1_FR_FLB_MODE) ? "Framer Loopback" : \ - ((mode) == WAN_TE1_FR_RLB_MODE) ? "Remote Framer Loopback" : \ - ((mode) == WAN_TE1_FR_PLB_MODE) ? "Payload Framer Loopback" : \ - "Unknown Loopback" -#else -#define WAN_TE1_LB_MODE_DECODE(mode) \ - (mode == WAN_TE1_ACTIVATE_LB) ? "Activate" : \ - (mode == WAN_TE1_DEACTIVATE_LB) ? "Deactivate" :\ +#define WAN_TE1_LB_ACTION_DECODE(action) \ + ((action) == WAN_TE1_ACTIVATE_LB) ? "Activate" : \ + ((action) == WAN_TE1_DEACTIVATE_LB) ? "Deactivate" :\ "Unknown" -#endif /* T1/E1 front end Master clock source */ #define WAN_TE1_REFCLK_OSC 0x00 @@ -295,6 +279,7 @@ #define TE_POLL_CONFIG 0x0B #define TE_POLL_READ 0x0C #define TE_POLL_WRITE 0x0D +#define TE_POLL_CONFIG_VERIFY 0x0E #define TE_LINKCRIT_TIMER 0x0F #define WAN_TE_POLL_LINKREADY 0x10 @@ -317,6 +302,11 @@ #define FE_HIMPEDANCE_MODE(fe_cfg) (fe_cfg)->cfg.te_cfg.high_impedance_mode #define FE_ACTIVE_CH(fe_cfg) (fe_cfg)->cfg.te_cfg.active_ch #define FE_SIG_MODE(fe_cfg) (fe_cfg)->cfg.te_cfg.sig_mode +#define FE_RX_SLEVEL(fe_cfg) (fe_cfg)->cfg.te_cfg.rx_slevel + +#define GET_TE_START_CHANNEL(fe) \ + (IS_T1_FEMEDIA(fe) ? 1 : \ + IS_E1_FEMEDIA(fe) ? 0 :0) #define GET_TE_CHANNEL_RANGE(fe) \ (IS_T1_FEMEDIA(fe) ? NUM_OF_T1_CHANNELS :\ @@ -359,7 +349,7 @@ (FE_LBO(fe_cfg) == WAN_T1_133_266) ? "133-266ft" : \ (FE_LBO(fe_cfg) == WAN_T1_266_399) ? "266-399ft" : \ (FE_LBO(fe_cfg) == WAN_T1_399_533) ? "399-533ft" : \ - (FE_LBO(fe_cfg) == WAN_T1_533_655) ? "533-599ft": \ + (FE_LBO(fe_cfg) == WAN_T1_533_655) ? "5330-599ft": \ (FE_LBO(fe_cfg) == WAN_E1_120) ? "120OH" : \ (FE_LBO(fe_cfg) == WAN_E1_75) ? "75OH" : \ "Unknown" @@ -381,7 +371,7 @@ #define WAN_FE_SET_DEBUG_MODE (WAN_FE_UDP_CMD_START + 4) #define WAN_FE_TX_MODE (WAN_FE_UDP_CMD_START + 5) -/* FE interrupt types */ +/* FE interrupt types bit-map */ #define WAN_TE_INTR_NONE 0x00 #define WAN_TE_INTR_GLOBAL 0x01 #define WAN_TE_INTR_BASIC 0x02 @@ -398,9 +388,10 @@ typedef struct sdla_te_cfg { u_int32_t active_ch; u_int32_t te_rbs_ch; u_int8_t high_impedance_mode; - int rx_slevel; + int rx_slevel; /* only for high_impedance_mode=YES */ u_int8_t te_ref_clock; u_int8_t sig_mode; + u_int8_t ignore_yel_alarm; } sdla_te_cfg_t; /* Performamce monitor counters */ @@ -582,13 +573,15 @@ typedef struct { unsigned char xlpg_scale; u_int16_t status_cnt; - + int reg_dbg_busy; int reg_dbg_ready; unsigned char reg_dbg_value; wan_ticks_t crit_alarm_start; unsigned int lb_mode; + + int tx_yel_alarm; } sdla_te_param_t; @@ -601,8 +594,8 @@ typedef struct { EXTERN int sdla_te_default_cfg(void* pfe, void* fe_cfg, int media); EXTERN int sdla_te_copycfg(void* pfe, void* fe_cfg); -EXTERN int sdla_te_iface_init(void *p_fe_iface); -EXTERN int sdla_ds_te1_iface_init(void *p_fe_iface); +EXTERN int sdla_te_iface_init(void *p_fe, void *p_fe_iface); +EXTERN int sdla_ds_te1_iface_init(void *p_fe, void *p_fe_iface); #endif /* WAN_KERNEL */ diff --git a/patches/kdrivers/include/sdla_te1_ds.h b/patches/kdrivers/include/sdla_te1_ds.h index 57bf6cb..975401f 100644 --- a/patches/kdrivers/include/sdla_te1_ds.h +++ b/patches/kdrivers/include/sdla_te1_ds.h @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: sdla_te1_ds.h,v 1.9 2007/01/04 20:16:01 sangoma Exp $ + * $Id: sdla_te1_ds.h,v 1.15 2008/02/06 19:32:19 sangoma Exp $ */ /***************************************************************************** @@ -68,6 +68,7 @@ #define DEVICE_ID_DS26524 0x0C #define DEVICE_ID_DS26522 0x0D #define DEVICE_ID_DS26521 0x0E +#define DEVICE_ID_BAD 0x00 #define DEVICE_ID_SHIFT 3 #define DEVICE_ID_MASK 0x1F #define DEVICE_ID_DS(dev_id) ((dev_id) >> DEVICE_ID_SHIFT) & DEVICE_ID_MASK @@ -94,6 +95,13 @@ #define REG_RSIGC 0x13 #define BIT_RSIGC_CASMS 0x10 +#define REG_T1RCR2 0x14 +#define BIT_T1RCR2_RSLC96 0x10 +#define BIT_T1RCR2_OOF2 0x08 +#define BIT_T1RCR2_OOF1 0x04 +#define BIT_T1RCR2_RAIIE 0x02 +#define BIT_T1RCR2_RD4RM 0x01 + #define REG_RS1 0x40 #define BIT_RS_A 0x08 #define BIT_RS_B 0x04 @@ -348,6 +356,8 @@ #define BIT_RIM5_RNES 0x01 #define REG_RIM7 0xA6 +#define BIT_RIM7_RSLC96 0x08 +#define BIT_RIM7_RFDLF 0x04 #define REG_RSCSE1 0xA8 #define BITS_RSCSE1_ALL 0xFF @@ -536,10 +546,10 @@ #define BIT_TCR1_E1_TCRC4 0x01 #define REG_TCR2 0x182 -#define BIT_TCR2_T1_TD4RM 0x04 -#define BIT_TCR2_T1_TSLC96 0x40 #define BIT_TCR2_T1_TFDLS 0x80 -#define BIT_TCR2_E1_AEBE 0x80 +#define BIT_TCR2_T1_TSLC96 0x40 +#define BIT_TCR2_T1_TD4RM 0x04 +#define BIT_TCR2_E1_AEBE 0x80 /* EBIT */ #define REG_TCR3 0x183 #define BIT_TCR3_ODF 0x80 diff --git a/patches/kdrivers/include/sdla_te1_pmc.h b/patches/kdrivers/include/sdla_te1_pmc.h index 4ea68ed..a15ddbc 100644 --- a/patches/kdrivers/include/sdla_te1_pmc.h +++ b/patches/kdrivers/include/sdla_te1_pmc.h @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: sdla_te1_pmc.h,v 1.3 2006/10/03 16:45:59 sangoma Exp $ + * $Id: sdla_te1_pmc.h,v 1.4 2007/04/25 21:23:03 sangoma Exp $ */ /***************************************************************************** @@ -225,11 +225,13 @@ #define BIT_SIGX_CHANCFG_RDEBE 0x01 #define REG_T1_XBAS_CFG 0x54 -#define BIT_T1_XBAS_ZCS0 0x01 -#define BIT_T1_XBAS_ZCS1 0x02 #define BIT_T1_XBAS_JPN 0x40 #define BIT_T1_XBAS_B8ZS 0x20 #define BIT_T1_XBAS_ESF 0x10 +#define BIT_T1_XBAS_FMS1 0x08 +#define BIT_T1_XBAS_FMS0 0x04 +#define BIT_T1_XBAS_ZCS1 0x02 +#define BIT_T1_XBAS_ZCS0 0x01 #define REG_T1_XBAS_ALARM_TX 0x55 #define BIT_T1_XBAS_ALARM_TX_XYEL 0x02 diff --git a/patches/kdrivers/include/sdla_te3.h b/patches/kdrivers/include/sdla_te3.h index 988d1a0..f8638ef 100644 --- a/patches/kdrivers/include/sdla_te3.h +++ b/patches/kdrivers/include/sdla_te3.h @@ -21,7 +21,6 @@ #ifndef __SDLA_TE3_H # define __SDLA_TE3_H - #define WAN_TE3_LIU_LB_NORMAL 0x00 #define WAN_TE3_LIU_LB_ANALOG 0x01 #define WAN_TE3_LIU_LB_REMOTE 0x02 @@ -40,7 +39,6 @@ ((mode) == WAN_TE3_DEACTIVATE_LB) ? "Deactivate" :\ "Unknown" - #define WAN_TE3_RDEVICE_NONE 0x00 #define WAN_TE3_RDEVICE_ADTRAN 0x01 #define WAN_TE3_RDEVICE_DIGITALLINK 0x02 diff --git a/patches/kdrivers/include/sdla_te3.h~ b/patches/kdrivers/include/sdla_te3.h~ deleted file mode 100644 index 3863c03..0000000 --- a/patches/kdrivers/include/sdla_te3.h~ +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************************** - * - * sdla_te3.h Sangoma T3/E3 front end definitions. - * - * Alex Feldman - * - * Copyright Sangoma Technologies Inc. 1999, 2000, 2001, 2002, 2003, 2004 - * - * This program is provided subject to the Software License included in - * this package in the file license.txt. By using this program you agree - * to be bound bythe terms of this license. - * - * Should you not have a copy of the file license.txt, or wish to obtain - * a hard copy of the Software License, please contact Sangoma - * technologies Corporation. - * - * Contact: Sangoma Technologies Inc. 905-474-1990, info@sangoma.com - * - *****************************************************************************/ - -#ifndef __SDLA_TE3_H -# define __SDLA_TE3_H - - -#define WAN_TE3_LIU_LB_NORMAL 0x00 -#define WAN_TE3_LIU_LB_ANALOG 0x01 -#define WAN_TE3_LIU_LB_REMOTE 0x02 -#define WAN_TE3_LIU_LB_DIGITAL 0x03 -#define WAN_TE3_LB_TYPE_DECODE(type) \ - ((type) == WAN_TE3_LIU_LB_ANALOG) ? "Analog" : \ - ((type) == WAN_TE3_LIU_LB_REMOTE) ? "Remote" : \ - ((type) == WAN_TE3_LIU_LB_DIGITAL) ? "Digital Local" : \ - "Unknown" - -/* Line loopback activate/deactive modes */ -#define WAN_TE3_ACTIVATE_LB 0x01 -#define WAN_TE3_DEACTIVATE_LB 0x02 -#define WAN_TE3_LB_MODE_DECODE(mode) \ - ((mode) == WAN_TE3_ACTIVATE_LB) ? "Activate" : \ - ((mode) == WAN_TE3_DEACTIVATE_LB) ? "Deactivate" :\ - "Unknown" - - -#define WAN_TE3_RDEVICE_NONE 0x00 -#define WAN_TE3_RDEVICE_ADTRAN 0x01 -#define WAN_TE3_RDEVICE_DIGITALLINK 0x02 -#define WAN_TE3_RDEVICE_KENTROX 0x03 -#define WAN_TE3_RDEVICE_LARSCOM 0x04 -#define WAN_TE3_RDEVICE_VERILINK 0x05 - -#define WAN_TE3_BIT_LOS_ALARM 0x0001 -#define WAN_TE3_BIT_OOF_ALARM 0x0002 -#define WAN_TE3_BIT_AIS_ALARM 0x0004 -#define WAN_TE3_BIT_AIC_ALARM 0x0008 -#define WAN_TE3_BIT_YEL_ALARM 0x0010 -#define WAN_TE3_BIT_LOF_ALARM 0x0020 - -#define RDEVICE_DECODE(rdevice) \ - (rdevice == WAN_TE3_RDEVICE_NONE) ? "None" : \ - (rdevice == WAN_TE3_RDEVICE_ADTRAN) ? "ADTRAN" : \ - (rdevice == WAN_TE3_RDEVICE_DIGITALLINK) ? "DIGITALLINK" : \ - (rdevice == WAN_TE3_RDEVICE_KENTROX) ? "KENTROX" : \ - (rdevice == WAN_TE3_RDEVICE_LARSCOM) ? "LARSCOM" : \ - (rdevice == WAN_TE3_RDEVICE_VERILINK) ? "VERLINK" : \ - "Unknown" - -typedef struct { - int rx_equal; /* receive equalization enable (TRUE/FALSE) */ - int taos; /* transmit all ones select (TRUE/FALSE) */ - int lb_mode; /* loopback modes */ - int tx_lbo; /* transmit line build-out (TRUE/FALSE) */ -} sdla_te3_liu_cfg_t; - -typedef struct { - sdla_te3_liu_cfg_t liu_cfg; - int fractional; - int rdevice_type; - int fcs; - int clock; - unsigned char lcode; -} sdla_te3_cfg_t; - -typedef struct { - u_int32_t pmon_lcv; - u_int32_t pmon_framing; - u_int32_t pmon_parity; - u_int32_t pmon_febe; - u_int32_t pmon_cpbit; -} sdla_te3_pmon_t; - -#define IS_DS3(cfg) ((cfg)->media == WAN_MEDIA_DS3) -#define IS_E3(cfg) ((cfg)->media == WAN_MEDIA_E3) -#define IS_TE3(cfg) ( \ - (cfg)->media == WAN_MEDIA_DS3 || \ - (cfg)->media == WAN_MEDIA_E3) - - -#define WAN_TE3_ALARM(alarm, bit) ((alarm) & (bit)) ? "ON" : "OFF" - -#define WAN_TE3_LOS_ALARM(alarm) WAN_TE3_ALARM(alarm, WAN_TE3_BIT_LOS_ALARM) -#define WAN_TE3_OOF_ALARM(alarm) WAN_TE3_ALARM(alarm, WAN_TE3_BIT_OOF_ALARM) -#define WAN_TE3_AIS_ALARM(alarm) WAN_TE3_ALARM(alarm, WAN_TE3_BIT_AIS_ALARM) -#define WAN_TE3_AIC_ALARM(alarm) WAN_TE3_ALARM(alarm, WAN_TE3_BIT_AIC_ALARM) -#define WAN_TE3_YEL_ALARM(alarm) WAN_TE3_ALARM(alarm, WAN_TE3_BIT_YEL_ALARM) -#define WAN_TE3_LOF_ALARM(alarm) WAN_TE3_ALARM(alarm, WAN_TE3_BIT_LOF_ALARM) - -#if defined(WAN_KERNEL) - -typedef struct { - int dummy; -} sdla_te3_param_t; - -int sdla_te3_iface_init(void *p_fe_iface); -#endif /* WAN_KERNEL */ - -#endif /* __SDLA_TE3_H */ diff --git a/patches/kdrivers/include/sdla_x25.h b/patches/kdrivers/include/sdla_x25.h index b71ba8e..5a1d645 100644 --- a/patches/kdrivers/include/sdla_x25.h +++ b/patches/kdrivers/include/sdla_x25.h @@ -59,16 +59,16 @@ */ typedef struct X25Cmd { - unsigned char command ; /* command code */ - unsigned short length ; /* transfer data length */ - unsigned char result ; /* return code */ - unsigned char pf ; /* P/F bit */ - unsigned short lcn ; /* logical channel */ - unsigned char qdm ; /* Q/D/M bits */ - unsigned char cause ; /* cause field */ - unsigned char diagn ; /* diagnostics */ - unsigned char pktType ; /* packet type */ - unsigned char resrv[4] ; /* reserved */ + unsigned char command ; /* command code */ + unsigned short length ; /* transfer data length */ + unsigned char result ; /* return code */ + unsigned char pf ; /* P/F bit */ + unsigned short lcn ; /* logical channel */ + unsigned char qdm ; /* Q/D/M bits */ + unsigned char cause ; /* cause field */ + unsigned char diagn ; /* diagnostics */ + unsigned char pktType ; /* packet type */ + unsigned char resrv[4] ; /* reserved */ } TX25Cmd; /* @@ -237,9 +237,9 @@ typedef struct X25Cmd */ typedef struct X25Mbox { - unsigned char opflag ; /* 00h: execution flag */ - TX25Cmd cmd ; /* 01h: command block */ - unsigned char data[1] ; /* 10h: data buffer */ + unsigned char opflag ; /* 00h: execution flag */ + TX25Cmd cmd ; /* 01h: command block */ + unsigned char data[1] ; /* 10h: data buffer */ } TX25Mbox; /*---------------------------------------------------------------------------- @@ -247,11 +247,11 @@ typedef struct X25Mbox */ typedef struct X25TimeStamp { - unsigned char month ; - unsigned char date ; - unsigned char sec ; - unsigned char min ; - unsigned char hour ; + unsigned char month ; + unsigned char date ; + unsigned char sec ; + unsigned char min ; + unsigned char hour ; } TX25TimeStamp; /*---------------------------------------------------------------------------- @@ -261,16 +261,16 @@ typedef struct X25TimeStamp */ typedef struct X25Status { - unsigned short pvc_map ; /* 00h: PVC map */ - unsigned short icc_map ; /* 02h: Incomming Chan. map */ - unsigned short twc_map ; /* 04h: Two-way Cnan. map */ - unsigned short ogc_map ; /* 06h: Outgoing Chan. map */ - TX25TimeStamp tstamp ; /* 08h: timestamp (BCD) */ - unsigned char iflags ; /* 0Dh: interrupt flags */ - unsigned char imask ; /* 0Eh: interrupt mask */ - unsigned char resrv ; /* 0Eh: */ - unsigned char gflags ; /* 10h: misc. HDLC/X25 flags */ - unsigned char cflags[X25_MAX_CHAN] ; /* channel status bytes */ + unsigned short pvc_map ; /* 00h: PVC map */ + unsigned short icc_map ; /* 02h: Incomming Chan. map */ + unsigned short twc_map ; /* 04h: Two-way Cnan. map */ + unsigned short ogc_map ; /* 06h: Outgoing Chan. map */ + TX25TimeStamp tstamp ; /* 08h: timestamp (BCD) */ + unsigned char iflags ; /* 0Dh: interrupt flags */ + unsigned char imask ; /* 0Eh: interrupt mask */ + unsigned char resrv ; /* 0Eh: */ + unsigned char gflags ; /* 10h: misc. HDLC/X25 flags */ + unsigned char cflags[X25_MAX_CHAN] ; /* channel status bytes */ } TX25Status; /* @@ -308,9 +308,9 @@ typedef struct X25Status */ typedef struct X25GlobalVars { - unsigned char resrv ; /* 00h: reserved */ - unsigned char dtrCtl ; /* 01h: DTR control code */ - unsigned char resErr ; /* 01h: '1' - reset modem error */ + unsigned char resrv ; /* 00h: reserved */ + unsigned char dtrCtl ; /* 01h: DTR control code */ + unsigned char resErr ; /* 01h: '1' - reset modem error */ } TX25GlobalVars; /* @@ -324,7 +324,7 @@ typedef struct X25GlobalVars */ typedef struct X25ModemStatus { - unsigned char status ; /* 00h: modem status */ + unsigned char status ; /* 00h: modem status */ } TX25ModemStatus; /* @@ -338,11 +338,11 @@ typedef struct X25ModemStatus */ typedef struct X25LinkStatus { - unsigned char txQueued ; /* 00h: queued Tx I-frames*/ - unsigned char rxQueued ; /* 01h: queued Rx I-frames*/ - unsigned char station ; /* 02h: DTE/DCE config. */ - unsigned char reserved ; /* 03h: reserved */ - unsigned char sfTally ; /* 04h: supervisory frame tally */ + unsigned char txQueued ; /* 00h: queued Tx I-frames*/ + unsigned char rxQueued ; /* 01h: queued Rx I-frames*/ + unsigned char station ; /* 02h: DTE/DCE config. */ + unsigned char reserved ; /* 03h: reserved */ + unsigned char sfTally ; /* 04h: supervisory frame tally */ } TX25LinkStatus; /* @@ -356,23 +356,23 @@ typedef struct X25LinkStatus */ typedef struct HdlcStats { /* a number of ... */ - unsigned short rxIFrames ; /* 00h: ready Rx I-frames */ - unsigned short rxNoseq ; /* 02h: frms out-of-sequence */ - unsigned short rxNodata ; /* 04h: I-frms without data */ - unsigned short rxDiscarded ; /* 06h: discarded frames */ - unsigned short rxTooLong ; /* 08h: frames too long */ - unsigned short rxBadAddr ; /* 0Ah: frms with inval.addr*/ - unsigned short txAcked ; /* 0Ch: acknowledged I-frms */ - unsigned short txRetransm ; /* 0Eh: re-transmit. I-frms */ - unsigned short t1Timeout ; /* 10h: T1 timeouts */ - unsigned short rxSABM ; /* 12h: received SABM frames */ - unsigned short rxDISC ; /* 14h: received DISC frames */ - unsigned short rxDM ; /* 16h: received DM frames */ - unsigned short rxFRMR ; /* 18h: FRMR frames received */ - unsigned short txSABM ; /* 1Ah: transm. SABM frames*/ - unsigned short txDISC ; /* 1Ch: transm. DISC frames*/ - unsigned short txDM ; /* 1Eh: transm. DM frames */ - unsigned short txFRMR ; /* 20h: transm. FRMR frames*/ + unsigned short rxIFrames ; /* 00h: ready Rx I-frames */ + unsigned short rxNoseq ; /* 02h: frms out-of-sequence */ + unsigned short rxNodata ; /* 04h: I-frms without data */ + unsigned short rxDiscarded ; /* 06h: discarded frames */ + unsigned short rxTooLong ; /* 08h: frames too long */ + unsigned short rxBadAddr ; /* 0Ah: frms with inval.addr*/ + unsigned short txAcked ; /* 0Ch: acknowledged I-frms */ + unsigned short txRetransm ; /* 0Eh: re-transmit. I-frms */ + unsigned short t1Timeout ; /* 10h: T1 timeouts */ + unsigned short rxSABM ; /* 12h: received SABM frames */ + unsigned short rxDISC ; /* 14h: received DISC frames */ + unsigned short rxDM ; /* 16h: received DM frames */ + unsigned short rxFRMR ; /* 18h: FRMR frames received */ + unsigned short txSABM ; /* 1Ah: transm. SABM frames*/ + unsigned short txDISC ; /* 1Ch: transm. DISC frames*/ + unsigned short txDM ; /* 1Eh: transm. DM frames */ + unsigned short txFRMR ; /* 20h: transm. FRMR frames*/ } THdlcStats; /* --------------------------------------------------------------------------- @@ -380,16 +380,16 @@ typedef struct HdlcStats */ typedef struct HdlcCommErr { /* a number of ... */ - unsigned char rxOverrun ; /* 00h: Rx overrun errors */ - unsigned char rxBadCrc ; /* 01h: Rx CRC errors */ - unsigned char rxAborted ; /* 02h: Rx aborted frames */ - unsigned char rxDropped ; /* 03h: frames lost */ - unsigned char txAborted ; /* 04h: Tx aborted frames */ - unsigned char txUnderrun ; /* 05h: Tx underrun errors */ - unsigned char txMissIntr ; /* 06h: missed underrun ints */ - unsigned char reserved ; /* 07h: reserved */ - unsigned char droppedDCD ; /* 08h: times DCD dropped */ - unsigned char droppedCTS ; /* 09h: times CTS dropped */ + unsigned char rxOverrun ; /* 00h: Rx overrun errors */ + unsigned char rxBadCrc ; /* 01h: Rx CRC errors */ + unsigned char rxAborted ; /* 02h: Rx aborted frames */ + unsigned char rxDropped ; /* 03h: frames lost */ + unsigned char txAborted ; /* 04h: Tx aborted frames */ + unsigned char txUnderrun ; /* 05h: Tx underrun errors */ + unsigned char txMissIntr ; /* 06h: missed underrun ints */ + unsigned char reserved ; /* 07h: reserved */ + unsigned char droppedDCD ; /* 08h: times DCD dropped */ + unsigned char droppedCTS ; /* 09h: times CTS dropped */ } THdlcCommErr; /* --------------------------------------------------------------------------- @@ -397,44 +397,44 @@ typedef struct HdlcCommErr */ typedef struct X25Config { -unsigned char baudRate ; /* 00h: */ - unsigned char t1 ; /* 01h: */ - unsigned char t2 ; /* 02h: */ - unsigned char n2 ; /* 03h: */ - unsigned short hdlcMTU ; /* 04h: */ - unsigned char hdlcWindow ; /* 06h: */ - unsigned char t4 ; /* 07h: */ - unsigned char autoModem ; /* 08h: */ - unsigned char autoHdlc ; /* 09h: */ - unsigned char hdlcOptions ; /* 0Ah: */ - unsigned char station ; /* 0Bh: */ - unsigned char pktWindow ; /* 0Ch: */ - unsigned short defPktSize ; /* 0Dh: */ - unsigned short pktMTU ; /* 0Fh: */ - unsigned short loPVC ; /* 11h: */ - unsigned short hiPVC ; /* 13h: */ - unsigned short loIncommingSVC ; /* 15h: */ - unsigned short hiIncommingSVC ; /* 17h: */ - unsigned short loTwoWaySVC ; /* 19h: */ - unsigned short hiTwoWaySVC ; /* 1Bh: */ - unsigned short loOutgoingSVC ; /* 1Dh: */ - unsigned short hiOutgoingSVC ; /* 1Fh: */ - unsigned short options ; /* 21h: */ - unsigned char responseOpt ; /* 23h: */ - unsigned short facil1 ; /* 24h: */ - unsigned short facil2 ; /* 26h: */ - unsigned short ccittFacil ; /* 28h: */ - unsigned short otherFacil ; /* 2Ah: */ - unsigned short ccittCompat ; /* 2Ch: */ - unsigned char t10t20 ; /* 2Eh: */ - unsigned char t11t21 ; /* 2Fh: */ - unsigned char t12t22 ; /* 30h: */ - unsigned char t13t23 ; /* 31h: */ - unsigned char t16t26 ; /* 32H: */ - unsigned char t28 ; /* 33h: */ - unsigned char r10r20 ; /* 34h: */ - unsigned char r12r22 ; /* 35h: */ - unsigned char r13r23 ; /* 36h: */ +unsigned char baudRate ; /* 00h: */ + unsigned char t1 ; /* 01h: */ + unsigned char t2 ; /* 02h: */ + unsigned char n2 ; /* 03h: */ + unsigned short hdlcMTU ; /* 04h: */ + unsigned char hdlcWindow ; /* 06h: */ + unsigned char t4 ; /* 07h: */ + unsigned char autoModem ; /* 08h: */ + unsigned char autoHdlc ; /* 09h: */ + unsigned char hdlcOptions ; /* 0Ah: */ + unsigned char station ; /* 0Bh: */ + unsigned char pktWindow ; /* 0Ch: */ + unsigned short defPktSize ; /* 0Dh: */ + unsigned short pktMTU ; /* 0Fh: */ + unsigned short loPVC ; /* 11h: */ + unsigned short hiPVC ; /* 13h: */ + unsigned short loIncommingSVC ; /* 15h: */ + unsigned short hiIncommingSVC ; /* 17h: */ + unsigned short loTwoWaySVC ; /* 19h: */ + unsigned short hiTwoWaySVC ; /* 1Bh: */ + unsigned short loOutgoingSVC ; /* 1Dh: */ + unsigned short hiOutgoingSVC ; /* 1Fh: */ + unsigned short options ; /* 21h: */ + unsigned char responseOpt ; /* 23h: */ + unsigned short facil1 ; /* 24h: */ + unsigned short facil2 ; /* 26h: */ + unsigned short ccittFacil ; /* 28h: */ + unsigned short otherFacil ; /* 2Ah: */ + unsigned short ccittCompat ; /* 2Ch: */ + unsigned char t10t20 ; /* 2Eh: */ + unsigned char t11t21 ; /* 2Fh: */ + unsigned char t12t22 ; /* 30h: */ + unsigned char t13t23 ; /* 31h: */ + unsigned char t16t26 ; /* 32H: */ + unsigned char t28 ; /* 33h: */ + unsigned char r10r20 ; /* 34h: */ + unsigned char r12r22 ; /* 35h: */ + unsigned char r13r23 ; /* 36h: */ } TX25Config; #define X25_PACKET_WINDOW 0x02 /* Default value for Window Size */ @@ -443,21 +443,21 @@ unsigned char baudRate ; /* 00h: */ */ typedef struct X25ChanAlloc /*----- Channel allocation -*/ { - unsigned short loPVC ; /* 00h: lowest PVC number */ - unsigned short hiPVC ; /* 02h: highest PVC number */ - unsigned short loIncommingSVC ; /* 04h: lowest incoming SVC */ - unsigned short hiIncommingSVC ; /* 06h: highest incoming SVC */ - unsigned short loTwoWaySVC ; /* 08h: lowest two-way SVC */ - unsigned short hiTwoWaySVC ; /* 0Ah: highest two-way SVC */ - unsigned short loOutgoingSVC ; /* 0Ch: lowest outgoing SVC */ - unsigned short hiOutgoingSVC ; /* 0Eh: highest outgoing SVC */ + unsigned short loPVC ; /* 00h: lowest PVC number */ + unsigned short hiPVC ; /* 02h: highest PVC number */ + unsigned short loIncommingSVC ; /* 04h: lowest incoming SVC */ + unsigned short hiIncommingSVC ; /* 06h: highest incoming SVC */ + unsigned short loTwoWaySVC ; /* 08h: lowest two-way SVC */ + unsigned short hiTwoWaySVC ; /* 0Ah: highest two-way SVC */ + unsigned short loOutgoingSVC ; /* 0Ch: lowest outgoing SVC */ + unsigned short hiOutgoingSVC ; /* 0Eh: highest outgoing SVC */ } TX25ChanAlloc; typedef struct X25ChanCfg /*------ Channel configuration -----*/ { - unsigned char type ; /* 00h: channel type */ - unsigned char txConf ; /* 01h: Tx packet and window sizes */ - unsigned char rxConf ; /* 01h: Rx packet and window sizes */ + unsigned char type ; /* 00h: channel type */ + unsigned char txConf ; /* 01h: Tx packet and window sizes */ + unsigned char rxConf ; /* 01h: Rx packet and window sizes */ } TX25ChanCfg; /* @@ -473,38 +473,38 @@ typedef struct X25ChanCfg /*------ Channel configuration -----*/ */ typedef struct X25Stats { /* number of packets Tx/Rx'ed */ - unsigned short txRestartRqst ; /* 00h: Restart Request */ - unsigned short rxRestartRqst ; /* 02h: Restart Request */ - unsigned short txRestartConf ; /* 04h: Restart Confirmation */ - unsigned short rxRestartConf ; /* 06h: Restart Confirmation */ - unsigned short txResetRqst ; /* 08h: Reset Request */ - unsigned short rxResetRqst ; /* 0Ah: Reset Request */ - unsigned short txResetConf ; /* 0Ch: Reset Confirmation */ - unsigned short rxResetConf ; /* 0Eh: Reset Confirmation */ - unsigned short txCallRequest ; /* 10h: Call Request */ - unsigned short rxCallRequest ; /* 12h: Call Request */ - unsigned short txCallAccept ; /* 14h: Call Accept */ - unsigned short rxCallAccept ; /* 16h: Call Accept */ - unsigned short txClearRqst ; /* 18h: Clear Request */ - unsigned short rxClearRqst ; /* 1Ah: Clear Request */ - unsigned short txClearConf ; /* 1Ch: Clear Confirmation */ - unsigned short rxClearConf ; /* 1Eh: Clear Confirmation */ - unsigned short txDiagnostic ; /* 20h: Diagnostic */ - unsigned short rxDiagnostic ; /* 22h: Diagnostic */ - unsigned short txRegRqst ; /* 24h: Registration Request */ - unsigned short rxRegRqst ; /* 26h: Registration Request */ - unsigned short txRegConf ; /* 28h: Registration Confirm.*/ - unsigned short rxRegConf ; /* 2Ah: Registration Confirm.*/ - unsigned short txInterrupt ; /* 2Ch: Interrupt */ - unsigned short rxInterrupt ; /* 2Eh: Interrupt */ - unsigned short txIntrConf ; /* 30h: Interrupt Confirm. */ - unsigned short rxIntrConf ; /* 32h: Interrupt Confirm. */ - unsigned short txData ; /* 34h: Data */ - unsigned short rxData ; /* 36h: Data */ - unsigned short txRR ; /* 38h: RR */ - unsigned short rxRR ; /* 3Ah: RR */ - unsigned short txRNR ; /* 3Ch: RNR */ - unsigned short rxRNR ; /* 3Eh: RNR */ + unsigned short txRestartRqst ; /* 00h: Restart Request */ + unsigned short rxRestartRqst ; /* 02h: Restart Request */ + unsigned short txRestartConf ; /* 04h: Restart Confirmation */ + unsigned short rxRestartConf ; /* 06h: Restart Confirmation */ + unsigned short txResetRqst ; /* 08h: Reset Request */ + unsigned short rxResetRqst ; /* 0Ah: Reset Request */ + unsigned short txResetConf ; /* 0Ch: Reset Confirmation */ + unsigned short rxResetConf ; /* 0Eh: Reset Confirmation */ + unsigned short txCallRequest ; /* 10h: Call Request */ + unsigned short rxCallRequest ; /* 12h: Call Request */ + unsigned short txCallAccept ; /* 14h: Call Accept */ + unsigned short rxCallAccept ; /* 16h: Call Accept */ + unsigned short txClearRqst ; /* 18h: Clear Request */ + unsigned short rxClearRqst ; /* 1Ah: Clear Request */ + unsigned short txClearConf ; /* 1Ch: Clear Confirmation */ + unsigned short rxClearConf ; /* 1Eh: Clear Confirmation */ + unsigned short txDiagnostic ; /* 20h: Diagnostic */ + unsigned short rxDiagnostic ; /* 22h: Diagnostic */ + unsigned short txRegRqst ; /* 24h: Registration Request */ + unsigned short rxRegRqst ; /* 26h: Registration Request */ + unsigned short txRegConf ; /* 28h: Registration Confirm.*/ + unsigned short rxRegConf ; /* 2Ah: Registration Confirm.*/ + unsigned short txInterrupt ; /* 2Ch: Interrupt */ + unsigned short rxInterrupt ; /* 2Eh: Interrupt */ + unsigned short txIntrConf ; /* 30h: Interrupt Confirm. */ + unsigned short rxIntrConf ; /* 32h: Interrupt Confirm. */ + unsigned short txData ; /* 34h: Data */ + unsigned short rxData ; /* 36h: Data */ + unsigned short txRR ; /* 38h: RR */ + unsigned short rxRR ; /* 3Ah: RR */ + unsigned short txRNR ; /* 3Ch: RNR */ + unsigned short rxRNR ; /* 3Eh: RNR */ } TX25Stats; /*---------------------------------------------------------------------------- @@ -512,12 +512,12 @@ typedef struct X25Stats */ typedef struct X25EventLog { - unsigned char type ; /* 00h: transaction type */ - unsigned short lcn ; /* 01h: logical channel num */ - unsigned char packet ; /* 03h: async packet type */ - unsigned char cause ; /* 04h: X.25 cause field */ - unsigned char diag ; /* 05h: X.25 diag field */ - TX25TimeStamp ts ; /* 06h: time stamp */ + unsigned char type ; /* 00h: transaction type */ + unsigned short lcn ; /* 01h: logical channel num */ + unsigned char packet ; /* 03h: async packet type */ + unsigned char cause ; /* 04h: X.25 cause field */ + unsigned char diag ; /* 05h: X.25 diag field */ + TX25TimeStamp ts ; /* 06h: time stamp */ } TX25EventLog; /* @@ -551,8 +551,8 @@ typedef struct X25EventLog */ typedef struct X25TraceCfg { - unsigned char flags ; /* 00h: trace configuration flags */ - unsigned char timeout ; /* 01h: timeout for trace delay mode*/ + unsigned char flags ; /* 00h: trace configuration flags */ + unsigned char timeout ; /* 01h: timeout for trace delay mode*/ } TX25TraceCfg; /* @@ -572,12 +572,12 @@ typedef struct X25TraceCfg */ typedef struct X25Trace /*----- Trace data structure -------*/ { - unsigned short length ; /* 00h: trace data length */ - unsigned char type ; /* 02h: trace type */ - unsigned char lost_cnt ; /* 03h: N of traces lost */ - TX25TimeStamp tstamp ; /* 04h: mon/date/sec/min/hour */ - unsigned short millisec ; /* 09h: ms time stamp */ - unsigned char data[0] ; /* 0Bh: traced frame */ + unsigned short length ; /* 00h: trace data length */ + unsigned char type ; /* 02h: trace type */ + unsigned char lost_cnt ; /* 03h: N of traces lost */ + TX25TimeStamp tstamp ; /* 04h: mon/date/sec/min/hour */ + unsigned short millisec ; /* 09h: ms time stamp */ + unsigned char data[0] ; /* 0Bh: traced frame */ } TX25Trace; /* @@ -602,17 +602,17 @@ typedef struct X25Trace /*----- Trace data structure -------*/ typedef struct HDLCFrame /*----- DHLC Frame Format ----------*/ { - unsigned char addr ; /* address field */ - unsigned char cntl ; /* control field */ - unsigned char data[0] ; + unsigned char addr ; /* address field */ + unsigned char cntl ; /* control field */ + unsigned char data[0] ; } THDLCFrame; typedef struct X25Pkt /*----- X.25 Paket Format ----------*/ { - unsigned char lcn_hi ; /* 4 MSB of Logical Channel Number */ - unsigned char lcn_lo ; /* 8 LSB of Logical Channel Number */ - unsigned char type ; - unsigned char data[0] ; + unsigned char lcn_hi ; /* 4 MSB of Logical Channel Number */ + unsigned char lcn_lo ; /* 8 LSB of Logical Channel Number */ + unsigned char type ; + unsigned char data[0] ; } TX25Pkt; /* @@ -646,29 +646,29 @@ typedef struct X25Pkt /*----- X.25 Paket Format ----------*/ typedef struct { - TX25Cmd cmd ; - char data[X25_MAX_DATA] ; + TX25Cmd cmd ; + char data[X25_MAX_DATA] ; } mbox_cmd_t; #if 0 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] ; + 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_hdr_t hdr ; + char data[X25_MAX_DATA] ; }x25api_t; #endif @@ -688,74 +688,72 @@ typedef struct { #if 0 typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* command code */ - unsigned short length ; /* transfer data length */ - unsigned char result ; /* return code */ - unsigned char pf ; /* P/F bit */ - unsigned short lcn ; /* logical channel */ - unsigned char qdm ; /* Q/D/M bits */ - unsigned char cause ; /* cause field */ - unsigned char diagn ; /* diagnostics */ - unsigned char pktType ; /* packet type */ - unsigned char resrv[4] ; /* reserved */ + unsigned char opp_flag ; /* the opp flag */ + unsigned char command ; /* command code */ + unsigned short length ; /* transfer data length */ + unsigned char result ; /* return code */ + unsigned char pf ; /* P/F bit */ + unsigned short lcn ; /* logical channel */ + unsigned char qdm ; /* Q/D/M bits */ + unsigned char cause ; /* cause field */ + unsigned char diagn ; /* diagnostics */ + unsigned char pktType ; /* packet type */ + unsigned char resrv[4] ; /* reserved */ } cblock_t; typedef struct { - ip_pkt_t ip_pkt ; - udp_pkt_t udp_pkt ; - wp_mgmt_t wp_mgmt ; - cblock_t cblock ; - unsigned char data[4080] ; + ip_pkt_t ip_pkt ; + udp_pkt_t udp_pkt ; + wp_mgmt_t wp_mgmt ; + cblock_t cblock ; + unsigned char data[4080] ; } x25_udp_pkt_t; #endif typedef struct read_hdlc_stat { - unsigned short inf_frames_rx_ok ; - unsigned short inf_frames_rx_out_of_seq ; - unsigned short inf_frames_rx_no_data ; - unsigned short inf_frames_rx_dropped ; - unsigned short inf_frames_rx_data_too_long ; - unsigned short inf_frames_rx_invalid_addr ; - unsigned short inf_frames_tx_ok ; - unsigned short inf_frames_tx_retransmit ; - unsigned short T1_timeouts ; - unsigned short SABM_frames_rx ; - unsigned short DISC_frames_rx ; - unsigned short DM_frames_rx ; - unsigned short FRMR_frames_rx ; - unsigned short SABM_frames_tx ; - unsigned short DISC_frames_tx ; - unsigned short DM_frames_tx ; - unsigned short FRMR_frames_tx ; + unsigned short inf_frames_rx_ok ; + unsigned short inf_frames_rx_out_of_seq ; + unsigned short inf_frames_rx_no_data ; + unsigned short inf_frames_rx_dropped ; + unsigned short inf_frames_rx_data_too_long ; + unsigned short inf_frames_rx_invalid_addr ; + unsigned short inf_frames_tx_ok ; + unsigned short inf_frames_tx_retransmit ; + unsigned short T1_timeouts ; + unsigned short SABM_frames_rx ; + unsigned short DISC_frames_rx ; + unsigned short DM_frames_rx ; + unsigned short FRMR_frames_rx ; + unsigned short SABM_frames_tx ; + unsigned short DISC_frames_tx ; + unsigned short DM_frames_tx ; + unsigned short FRMR_frames_tx ; } read_hdlc_stat_t; typedef struct read_comms_err_stats{ - unsigned char overrun_err_rx ; - unsigned char CRC_err ; - unsigned char abort_frames_rx ; - unsigned char frames_dropped_buf_full ; - unsigned char abort_frames_tx ; - unsigned char transmit_underruns ; - unsigned char missed_tx_underruns_intr ; - unsigned char reserved ; - unsigned char DCD_drop ; - unsigned char CTS_drop ; + unsigned char overrun_err_rx ; + unsigned char CRC_err ; + unsigned char abort_frames_rx ; + unsigned char frames_dropped_buf_full ; + unsigned char abort_frames_tx ; + unsigned char transmit_underruns ; + unsigned char missed_tx_underruns_intr ; + unsigned char reserved ; + unsigned char DCD_drop ; + unsigned char CTS_drop ; } read_comms_err_stats_t; typedef struct trace_data { - unsigned short length ; - unsigned char type ; - unsigned char trace_dropped ; - unsigned char reserved[5] ; - unsigned short timestamp ; - unsigned int sec ; - unsigned int usec ; - unsigned char data[0] ; + unsigned short length ; + unsigned char type ; + unsigned char trace_dropped ; + unsigned char reserved[5] ; + unsigned short timestamp ; + unsigned int sec ; + unsigned int usec ; + unsigned char data[0] ; } trace_data_t; -#pragma pack() - enum {UDP_XPIPE_TYPE}; #define XPIPE_ENABLE_TRACING 0x14 @@ -786,5 +784,6 @@ enum {UDP_XPIPE_TYPE}; #define TRACE_ALL_HDLC_FRMS 0x40 #define TRACE_DATA_FRMS 0x08 +#pragma pack() #endif /* _SDLA_X25_H */ diff --git a/patches/kdrivers/include/sdla_xilinx.h b/patches/kdrivers/include/sdla_xilinx.h index ff24743..c56e9f7 100644 --- a/patches/kdrivers/include/sdla_xilinx.h +++ b/patches/kdrivers/include/sdla_xilinx.h @@ -926,8 +926,10 @@ typedef struct { } api_tx_element_t; #pragma pack() +#if !defined(__WINDOWS__)/* use 'wan_udphdr_aft_data'! */ #undef wan_udphdr_data #define wan_udphdr_data wan_udphdr_u.aft.data +#endif /*========================================== * Board CPLD Interface Section @@ -1005,7 +1007,8 @@ enum { TX_DMA_BUF_INIT =0, TX_DMA_BUF_USED }; - + +#if !defined(__WINDOWS__) enum { ROUTER_UP_TIME = 0x50, ENABLE_TRACING, @@ -1023,6 +1026,7 @@ enum { AFT_HWEC_STATUS, DIGITAL_LOOPTEST }; +#endif #define UDPMGMT_SIGNATURE "AFTPIPEA" @@ -1044,6 +1048,9 @@ typedef struct wp_rx_element unsigned int reg; unsigned int align; unsigned char pkt_error; +#if defined(__WINDOWS__) + api_header_t rx_info; +#endif }wp_rx_element_t; @@ -1102,23 +1109,30 @@ static __inline void set_channel_timeslot_sync(u32 *reg,unsigned int timeslot) static __inline unsigned short xilinx_valid_mtu(unsigned short mtu) { + unsigned short new_mtu = 0; if (mtu <= 128){ - return 128; + new_mtu = 128; }else if (mtu <= 256){ - return 256; + new_mtu = 256; }else if (mtu <= 512){ - return 512; + new_mtu = 512; }else if (mtu <= 1024){ - return 1024; + new_mtu = 1024; }else if (mtu <= 2048){ - return 2048; + new_mtu = 2048; }else if (mtu <= 4096){ - return 4096; + new_mtu = 4096; }else if (mtu <= 8188){ - return 8188; + new_mtu = 8188; }else{ return 0; } +#if defined(__FreeBSD__) + if (new_mtu > MCLBYTES - 16){ + new_mtu = MCLBYTES-16; + } +#endif + return new_mtu; } static __inline unsigned short xilinx_dma_buf_bits(unsigned short dma_bufs) diff --git a/patches/kdrivers/include/sdladrv.h b/patches/kdrivers/include/sdladrv.h index c3c593a..7657e48 100644 --- a/patches/kdrivers/include/sdladrv.h +++ b/patches/kdrivers/include/sdladrv.h @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: sdladrv.h,v 1.69 2007/03/23 15:10:01 sangoma Exp $ + * $Id: sdladrv.h,v 1.93 2008/03/06 14:02:42 sangoma Exp $ */ /***************************************************************************** @@ -38,7 +38,11 @@ * Author: Alex Feldman * * ============================================================================ + * Nov 27, 2007 David Rokhvarg Implemented functions/definitions for + * Sangoma MS Windows Driver and API. + * * Dec 06, 1999 Alex Feldman Updated to FreeBSD 3.2 + * * Dec 06, 1995 Gene Kozin Initial version. ***************************************************************************** */ @@ -51,6 +55,10 @@ # define EXTERN extern #endif +#if defined(__LINUX__) +# define WAN_ISA_SUPPORT +#endif + /* ****************************************************************** ** I N C L U D E S ** @@ -60,13 +68,19 @@ # include # include #elif defined(__FreeBSD__) -# ifdef __SDLADRV__ -# include +# if defined(__SDLADRV__) +# if defined(SDLA_AUTO_PROBE) +# include +# else +# include +# endif # endif #elif defined(__OpenBSD__) || defined(__NetBSD__) # ifdef __SDLADRV__ # include # endif +#elif defined(__WINDOWS__) +# include #endif /* @@ -74,13 +88,6 @@ ** D E F I N E S ** ****************************************************************** */ -#if defined(__LINUX__) -#ifdef CONFIG_ISA -# define WAN_ISA_SUPPORT -#else -# undef WAN_ISA_SUPPORT -#endif -#endif #define SDLADRV_MAGIC 0x414C4453L /* signature: 'SDLA' reversed */ @@ -90,33 +97,39 @@ #define SDLA_WINDOWSIZE 0x2000 /* default dual-port memory window size */ /* */ -#define SDLA_MEMBASE 0x01 -#define SDLA_MEMEND 0x02 -#define SDLA_MEMSIZE 0x03 -#define SDLA_IRQ 0x04 -#define SDLA_ADAPTERTYPE 0x05 -#define SDLA_CPU 0x06 -#define SDLA_SLOT 0x07 -#define SDLA_IOPORT 0x08 -#define SDLA_IORANGE 0x09 -#define SDLA_CARDTYPE 0x0A -#define SDLA_DMATAG 0x0B -#define SDLA_MEMORY 0x0C -#define SDLA_PCIEXTRAVER 0x0D -#define SDLA_HWTYPE 0x0E -#define SDLA_BUS 0x0F -#define SDLA_BASEADDR 0x10 -#define SDLA_COREREV 0x11 -#define SDLA_USEDCNT 0x12 -#define SDLA_ADAPTERSUBTYPE 0x13 -#define SDLA_HWEC_NO 0x14 -#define SDLA_COREID 0x15 - +#define SDLA_MEMBASE 0x01 +#define SDLA_MEMEND 0x02 +#define SDLA_MEMSIZE 0x03 +#define SDLA_IRQ 0x04 +#define SDLA_ADAPTERTYPE 0x05 +#define SDLA_CPU 0x06 +#define SDLA_SLOT 0x07 +#define SDLA_IOPORT 0x08 +#define SDLA_IORANGE 0x09 +#define SDLA_CARDTYPE 0x0A +#define SDLA_DMATAG 0x0B +#define SDLA_MEMORY 0x0C +#define SDLA_PCIEXTRAVER 0x0D +#define SDLA_HWTYPE 0x0E +#define SDLA_BUS 0x0F +#define SDLA_BASEADDR 0x10 +#define SDLA_COREREV 0x11 +#define SDLA_HWCPU_USEDCNT 0x12 +#define SDLA_ADAPTERSUBTYPE 0x13 +#define SDLA_HWEC_NO 0x14 +#define SDLA_COREID 0x15 +#define SDLA_PCIEXPRESS 0x16 +#define SDLA_PORTS_NO 0x17 +#define SDLA_HWPORTUSED 0x18 +#define SDLA_HWPORTREG 0x19 +#define SDLA_PORT_MAP 0x1A +#define SDLA_RECOVERY_CLOCK_FLAG 0x1B +#define SDLA_HWPORTREGMAP 0x1C #define SDLA_MAX_CPUS 2 - /* Serial card - 2, A104 - 4, A108 - 8, A200 - 1 */ -#define SDLA_MAX_PORTS 8 +/* Serial card - 2, A104 - 4, A108 - 8, A200/A400 - 1, A500-24 */ +#define SDLA_MAX_PORTS 24 /* Status values */ #define SDLA_MEM_RESERVED 0x0001 @@ -131,7 +144,9 @@ # define PCI_DMA_TODEVICE 2 #endif -#define SDLA_MAGIC(hw) WAN_ASSERT(hw->magic != SDLADRV_MAGIC) +#define SDLA_MAGIC(hw) WAN_ASSERT((hw)->magic != SDLADRV_MAGIC) +#define SDLA_MAGIC_RC(hw,rc) WAN_ASSERT_RC((hw)->magic != SDLADRV_MAGIC, (rc)) +#define SDLA_MAGIC_VOID(hw) WAN_ASSERT_VOID((hw)->magic != SDLADRV_MAGIC) /* ****************************************************************** @@ -145,8 +160,8 @@ typedef bus_addr_t sdla_base_addr_t; typedef bus_addr_t sdla_dma_addr_t; typedef pcici_t sdla_pci_dev_t; # else -typedef uint32_t sdla_base_addr_t; -typedef uint32_t sdla_dma_addr_t; +typedef bus_addr_t sdla_base_addr_t; +typedef bus_addr_t sdla_dma_addr_t; typedef struct device* sdla_pci_dev_t; # endif #elif defined(__OpenBSD__) @@ -168,6 +183,13 @@ typedef void * sdla_mem_handle_t; typedef unsigned long sdla_base_addr_t; typedef dma_addr_t sdla_dma_addr_t; typedef struct pci_dev* sdla_pci_dev_t; +#elif defined(__WINDOWS__) +typedef void * sdla_mem_handle_t; +typedef unsigned long sdla_base_addr_t; +/* Dma addresses are 32-bits wide!!! */ +typedef u32 dma_addr_t; +typedef dma_addr_t sdla_dma_addr_t; +typedef struct pci_dev* sdla_pci_dev_t; #else # warning "Undefined types sdla_mem_handle_t/sdla_base_addr_t!" #endif @@ -178,7 +200,11 @@ typedef struct pci_dev* sdla_pci_dev_t; ****************************************************************** */ #if defined(__FreeBSD__) -# define virt_to_phys(x) kvtop((caddr_t)x) +# if defined(__i386__) +# define virt_to_phys(x) kvtop((caddr_t)x) +# else +# define virt_to_phys(x) (sdla_dma_addr_t)(x) +# endif # define phys_to_virt(x) (sdla_mem_handle_t)x #elif defined(__OpenBSD__) # define virt_to_phys(x) kvtop((caddr_t)x) @@ -186,7 +212,9 @@ typedef struct pci_dev* sdla_pci_dev_t; #elif defined(__NetBSD__) # define virt_to_phys(x) kvtop((caddr_t)x) # define phys_to_virt(x) (bus_space_handle_t)x -#elif defined(__LINUX__) +#elif defined(__LINUX__) +#elif defined(__WINDOWS__) +# define phys_to_virt(x) NULL #else # warning "Undefined virt_to_phys/phys_to_virt macros!" #endif @@ -207,19 +235,92 @@ typedef struct pci_dev* sdla_pci_dev_t; ** S T R U C T U R E S ** ****************************************************************** */ -typedef struct sdla_hw_probe { +/* DMA structure */ +#define SDLA_DMA_FLAG_READY 0 +#define SDLA_DMA_FLAG_INIT 1 +#define SDLA_DMA_FLAG_ALLOC 2 + +#if defined(__FreeBSD__) +# define SDLA_DMA_POSTREAD BUS_DMASYNC_POSTREAD +# define SDLA_DMA_PREREAD BUS_DMASYNC_PREREAD +# define SDLA_DMA_POSTWRITE BUS_DMASYNC_POSTWRITE +# define SDLA_DMA_PREWRITE BUS_DMASYNC_PREWRITE +#elif defined(__LINUX__) +# define SDLA_DMA_POSTREAD PCI_DMA_FROMDEVICE +# define SDLA_DMA_PREREAD PCI_DMA_FROMDEVICE +# define SDLA_DMA_POSTWRITE PCI_DMA_TODEVICE +# define SDLA_DMA_PREWRITE PCI_DMA_TODEVICE +#else +# define SDLA_DMA_POSTREAD 1 +# define SDLA_DMA_PREREAD 2 +# define SDLA_DMA_POSTWRITE 3 +# define SDLA_DMA_PREWRITE 4 +#endif +typedef struct wan_dma_descr_ +{ + unsigned long init; + unsigned long flag; + u32 alignment; + u32 max_len; + + sdla_dma_addr_t dma_addr; /* physical address */ + u32 dma_len; /* total dma data len */ + u32 dma_map_len; /* actual dma mapped len (address range) */ + netskb_t *skb; + u32 index; + + u32 dma_descr; + u32 len_align; + u32 reg; + + u8 pkt_error; + void* dma_virt; + u32 dma_offset; + u32 dma_toggle; +#if defined(__FreeBSD__) + bus_dma_tag_t dmat; + bus_dmamap_t dmam; +#elif defined(__OpenBSD__) + bus_dma_tag_t dmat; + bus_dma_segment_t dmaseg; + int rsegs; +#elif defined(__NetBSD__) + bus_dma_tag_t dmat; + bus_dma_segment_t dmaseg; + int rsegs; +#elif defined(__WINDOWS__) + void* vAddr; + PHYSICAL_ADDRESS physicalAddr; +#endif +} wan_dma_descr_t; + + +typedef struct sdla_hw_probe +{ + int internal_used; int used; unsigned char hw_info[100]; unsigned char hw_info_verbose[500]; WAN_LIST_ENTRY(sdla_hw_probe) next; } sdla_hw_probe_t; +/*------------------------------------------------------------- + * + */ +#if 0 +typedef struct sdlahw_port +{ + int used; + char *devname; + sdla_hw_probe_t *hwprobe; +} sdlahw_port_t; +#endif /* * This structure keeps common parameters per physical card. */ typedef struct sdlahw_card { - int used; + int internal_used; unsigned int hw_type; /* ISA/PCI */ unsigned int type; /* S50x/S514/ADSL/SDLA_AFT */ unsigned char cfg_type; /* Config card type WANOPT_XXX */ @@ -232,6 +333,7 @@ typedef struct sdlahw_card { unsigned int slot_no; unsigned int bus_no; unsigned int ioport; + unsigned int recovery_clock_flag; /* 1 - already used, 0 - not used */ #if defined(__LINUX__) sdla_pci_dev_t pci_dev; /* PCI config header info */ #else @@ -242,35 +344,32 @@ typedef struct sdlahw_card { sdla_pci_dev_t pci_dev; /* PCI config header info */ #endif sdla_pci_dev_t pci_bridge_dev; /* PCI Bridge config header info */ + unsigned int pci_bridge_slot;/* PCI Bridge slot number */ + unsigned int pci_bridge_bus; /* PCI Bridge bus number */ wan_spinlock_t pcard_lock; /* lock per physical card for FE */ wan_spinlock_t pcard_ec_lock; /* lock per physical card for EC */ wan_smp_flag_t fe_rw_flag; unsigned char adptr_security; /* Adapter security (AFT cards) */ u16 hwec_chan_no; /* max hwec channels number */ - int rm_mod_type[MAX_REMORA_MODULES]; - void *port_ptr_isr_array[SDLA_MAX_PORTS]; + int hwec_ind; /* hwec index */ WAN_LIST_ENTRY(sdlahw_card) next; + +#if defined(__WINDOWS__) + int rm_mod_type[MAX_REMORA_MODULES]; +#endif + } sdlahw_card_t; -/*------------------------------------------------------------- - * - */ -typedef struct sdlahw_port -{ - int used; - char *devname; - sdla_hw_probe_t *hwprobe; -} sdlahw_port_t; - /*---------------------------------------------------------------------------- * Adapter hardware configuration. Pointer to this structure is passed to all * APIs. */ -typedef struct sdlahw +struct sdlahw_port; +typedef struct sdlahw_cpu { + int internal_used; int used; - char *devname; u16 status; unsigned fwid; /* firmware ID */ #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -282,14 +381,13 @@ typedef struct sdlahw void* irqh[SDLA_MAX_PORTS]; #endif unsigned int cpu_no; /* PCI CPU Number */ - unsigned int line_no; /* PCI CPU Number */ char auto_pci_cfg; /* Auto PCI configuration */ sdla_mem_handle_t dpmbase; /* dual-port memory base */ sdla_base_addr_t mem_base_addr; unsigned dpmsize; /* dual-port memory size */ unsigned pclk; /* CPU clock rate, kHz */ unsigned long memory; /* memory size */ - sdla_mem_handle_t vector; /* local offset of the DPM window */ + sdla_mem_handle_t vector; /* local offset of the DPM window */ unsigned io_range; /* I/O port range */ unsigned char regs[SDLA_MAXIORANGE]; /* was written to registers */ @@ -298,12 +396,37 @@ typedef struct sdlahw /* */ unsigned magic; - void* dev; /* used only for FreeBSD/OpenBSD */ +# if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + void *sdla_dev; /* used only for FreeBSD/OpenBSD */ +# endif u16 configured; - int max_ports; - sdlahw_port_t hwport[SDLA_MAX_PORTS]; - sdlahw_card_t* hwcard; - WAN_LIST_ENTRY(sdlahw) next; + + int max_ports; /* number of ports */ + u_int32_t port_map; /* installed modules for A200/A400/ISDN */ + int reg_port[SDLA_MAX_PORTS]; + u_int32_t reg_port_map; /* configured port */ + struct sdlahw_port *hwport[SDLA_MAX_PORTS]; + + void *port_ptr_isr_array[SDLA_MAX_PORTS]; + + sdlahw_card_t *hwcard; + WAN_LIST_ENTRY(sdlahw_cpu) next; +} sdlahw_cpu_t; + +typedef struct sdlahw_port +{ + int internal_used; + int used; + char *devname; + unsigned magic; + unsigned int port_no; /* Port number per CPU */ + sdla_hw_probe_t *hwprobe; + sdlahw_cpu_t* hwcpu; + + WAN_LIST_ENTRY(sdlahw_port) next; +#if defined(__WINDOWS__) + void *p_sdla; +#endif } sdlahw_t; typedef struct sdlahw_iface @@ -318,6 +441,7 @@ typedef struct sdlahw_iface int (*mapmem)(void*, unsigned long); int (*check_mismatch)(void*, unsigned char); int (*getcfg)(void*, int, void*); + int (*setcfg)(void*, int, void*); int (*isa_read_1)(void* hw, unsigned int offset, u8*); int (*isa_write_1)(void* hw, unsigned int offset, u8); int (*io_write_1)(void* hw, unsigned int offset, u8); @@ -335,7 +459,9 @@ typedef struct sdlahw_iface int (*pci_read_config_word)(void* hw, int reg, u16* value); int (*pci_read_config_dword)(void* hw, int reg, u32* value); int (*pci_bridge_write_config_dword)(void* hw, int reg, u32 value); + int (*pci_bridge_write_config_byte)(void* hw, int reg, u_int8_t value); int (*pci_bridge_read_config_dword)(void* hw, int reg, u32* value); + int (*pci_bridge_read_config_byte)(void* hw, int reg, u_int8_t* value); int (*cmd)(void* phw, unsigned long offset, wan_mbox_t* mbox); int (*peek)(void*,unsigned long, void*,unsigned); int (*poke)(void*,unsigned long, void*,unsigned); @@ -352,7 +478,9 @@ typedef struct sdlahw_iface int (*hw_lock)(void *phw, wan_smp_flag_t *flag); int (*hw_ec_unlock)(void *phw, wan_smp_flag_t *flag); int (*hw_ec_lock)(void *phw, wan_smp_flag_t *flag); + int (*hw_ec_trylock)(void *phw, wan_smp_flag_t *flag); int (*hw_same)(void *phw1, void *phw2); + int (*hwcpu_same)(void *phw1, void *phw2); int (*fe_test_and_set_bit)(void *phw, int value); int (*fe_test_bit)(void *phw,int value); int (*fe_set_bit)(void *phw,int value); @@ -363,6 +491,25 @@ typedef struct sdlahw_iface int (*write_cpld)(void *phw, u16, u8); int (*fe_write)(void*, ...); u_int8_t (*fe_read)(void*, ...); + u_int8_t (*__fe_read)(void*, ...); + wan_dma_descr_t* (*busdma_descr_alloc)(void *phw, int); + void (*busdma_descr_free)(void *phw, wan_dma_descr_t*); + int (*busdma_tag_create)(void *phw, wan_dma_descr_t*, u32, u32, int); + int (*busdma_tag_destroy)(void *phw, wan_dma_descr_t*, int); + int (*busdma_create)(void *phw, wan_dma_descr_t*); + int (*busdma_destroy)(void *phw, wan_dma_descr_t*); + int (*busdma_alloc)(void *phw, wan_dma_descr_t*); + void (*busdma_free)(void *phw, wan_dma_descr_t*); + int (*busdma_load)(void *phw, wan_dma_descr_t*, u32); + void (*busdma_unload)(void *phw, wan_dma_descr_t*); + void (*busdma_map)(void *phw, wan_dma_descr_t*, void *buf, int len, int map_len, int dir); + void (*busdma_unmap)(void *phw, wan_dma_descr_t*, int dir); + void (*busdma_sync)(void *phw, wan_dma_descr_t*, int ndescr, int single, int dir); + char* (*hwec_name)(void *phw); + int (*get_hwec_index)(void *phw); +#if defined(__WINDOWS__) + sdlahw_t *hw; +#endif } sdlahw_iface_t; typedef struct sdla_hw_type_cnt @@ -377,10 +524,12 @@ typedef struct sdla_hw_type_cnt unsigned char aft108_adapters; unsigned char aft_isdn_adapters; unsigned char aft_56k_adapters; + unsigned char aft_serial_adapters; unsigned char aft_x_adapters; }sdla_hw_type_cnt_t; + /****** Function Prototypes *************************************************/ EXTERN unsigned int sdla_hw_probe(void); @@ -394,21 +543,26 @@ EXTERN int sdla_unregister (void**, char*); static __inline unsigned int sdla_get_pci_bus(sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) - return pci_get_bus(card->pci_dev); + return pci_get_bus(hwcard->pci_dev); # else - return card->pci_dev->bus; + return hwcard->pci_dev->bus; # endif #elif defined(__NetBSD__) || defined(__OpenBSD__) - return card->pci_dev->pa_bus; + return hwcard->pci_dev->pa_bus; #elif defined(__LINUX__) - return ((struct pci_bus*)card->pci_dev->bus)->number; + return ((struct pci_bus*)hwcard->pci_dev->bus)->number; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # warning "sdla_get_pci_bus: Not supported yet!" #endif @@ -417,21 +571,26 @@ static __inline unsigned int sdla_get_pci_bus(sdlahw_t* hw) static __inline unsigned int sdla_get_pci_slot(sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) - return pci_get_slot(card->pci_dev); + return pci_get_slot(hwcard->pci_dev); # else - return card->pci_dev->slot; + return hwcard->pci_dev->slot; # endif #elif defined(__NetBSD__) || defined(__OpenBSD__) - return card->pci_dev->pa_device; + return hwcard->pci_dev->pa_device; #elif defined(__LINUX__) - return ((card->pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK); + return ((hwcard->pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # warning "sdla_get_pci_slot: Not supported yet!" #endif @@ -441,17 +600,32 @@ static __inline unsigned int sdla_get_pci_slot(sdlahw_t* hw) static __inline int sdla_bus_space_map(sdlahw_t* hw, int reg, int size, sdla_mem_handle_t* handle) { - int err = 0; + sdlahw_cpu_t *hwcpu; + int err = 0; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); #if defined(__FreeBSD__) - *handle = (sdla_mem_handle_t)pmap_mapdev(hw->mem_base_addr + reg, size); + *handle = (sdla_mem_handle_t)pmap_mapdev(hwcpu->mem_base_addr + reg, size); #elif defined(__NetBSD__) || defined(__OpenBSD__) - err = bus_space_map(hw->hwcard->memt, - hw->mem_base_addr+reg, + err = bus_space_map(hwcpu->hwcard->memt, + hwcpu->mem_base_addr+reg, size, 0, handle); #elif defined(__LINUX__) - *handle = (sdla_mem_handle_t)ioremap(hw->mem_base_addr+reg, size); + *handle = (sdla_mem_handle_t)ioremap(hwcpu->mem_base_addr+reg, size); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + /* + *handle = (sdla_mem_handle_t)MmMapIoSpace( + ((PHYSICAL_ADDRESS)(hwcpu->mem_base_addr+reg)), (ULONG)size, MmNonCached); + if(*handle == NULL){ + err = 1; + } + */ #else # warning "sdla_bus_space_map: Not supported yet!" #endif @@ -462,6 +636,12 @@ sdla_bus_space_map(sdlahw_t* hw, int reg, int size, sdla_mem_handle_t* handle) static __inline void sdla_bus_space_unmap(sdlahw_t* hw, sdla_mem_handle_t offset, int size) { + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT_VOID(hw == NULL); + WAN_ASSERT_VOID(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT_VOID(hwcpu->hwcard == NULL); #if defined(__FreeBSD__) int i = 0; for (i = 0; i < size; i += PAGE_SIZE){ @@ -469,9 +649,12 @@ sdla_bus_space_unmap(sdlahw_t* hw, sdla_mem_handle_t offset, int size) } kmem_free(kernel_map, (vm_offset_t)offset, size); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_unmap(hw->hwcard->memt, offset, size); + bus_space_unmap(hwcpu->hwcard->memt, offset, size); #elif defined(__LINUX__) iounmap((void*)offset); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + /*MmUnmapIoSpace((void*)offset, size);*/ #else # warning "sdla_bus_space_unmap: Not supported yet!" #endif @@ -482,12 +665,20 @@ sdla_bus_space_unmap(sdlahw_t* hw, sdla_mem_handle_t offset, int size) static __inline void sdla_bus_set_region_1(sdlahw_t* hw, unsigned int offset, unsigned char val, unsigned int cnt) { + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT_VOID(hw == NULL); + WAN_ASSERT_VOID(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT_VOID(hwcpu->hwcard == NULL); #if defined(__FreeBSD__) return; #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_set_region_1(hw->hwcard->memt, hw->dpmbase, offset, val, cnt); + bus_space_set_region_1(hwcpu->hwcard->memt, hw->dpmbase, offset, val, cnt); #elif defined(__LINUX__) - wp_memset_io(hw->dpmbase + offset, val, cnt); + wp_memset_io(hwcpu->dpmbase + offset, val, cnt); +#elif defined(__WINDOWS__) + wp_memset_io(((u8*)hwcpu->dpmbase) + offset, val, cnt); #else # warning "sdla_bus_set_region_1: Not supported yet!" #endif @@ -506,6 +697,9 @@ sdla_request_mem_region(sdlahw_t* hw, sdla_base_addr_t base_addr, unsigned int l } *pres = resource; return 0; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else # warning "sdla_request_mem_region: Not supported yet!" return 0; @@ -519,6 +713,8 @@ sdla_release_mem_region(sdlahw_t* hw, sdla_base_addr_t base_addr, unsigned int l return; #elif defined(__LINUX__) release_mem_region(base_addr, len); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # warning "sdla_release_mem_region: Not supported yet!" #endif @@ -528,14 +724,22 @@ static __inline int sdla_pci_enable_device(sdlahw_t* hw) { sdlahw_card_t* card; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; +#if defined(__FreeBSD__) + return pci_enable_io(card->pci_dev, SYS_RES_MEMORY); +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) return 0; #elif defined(__LINUX__) return pci_enable_device(card->pci_dev); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else # warning "sdla_release_mem_region: Not supported yet!" return -EINVAL; @@ -546,15 +750,23 @@ static __inline int sdla_pci_disable_device(sdlahw_t* hw) { sdlahw_card_t* card; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; +#if defined(__FreeBSD__) + return pci_disable_io(card->pci_dev, SYS_RES_MEMORY); +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) return 0; #elif defined(__LINUX__) pci_disable_device(card->pci_dev); return 0; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else # warning "sdla_release_mem_region: Not supported yet!" return -EINVAL; @@ -567,14 +779,21 @@ static __inline void sdla_pci_set_master(sdlahw_t* hw) { sdlahw_card_t* card; + sdlahw_cpu_t *hwcpu; WAN_ASSERT1(hw == NULL); - WAN_ASSERT1(hw->hwcard == NULL); - card = hw->hwcard; -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + WAN_ASSERT1(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT1(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; +#if defined(__FreeBSD__) + pci_enable_busmaster(card->pci_dev); +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) return; #elif defined(__LINUX__) pci_set_master(card->pci_dev); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # warning "sdla_pci_set_master: Not supported yet!" #endif @@ -585,10 +804,13 @@ static __inline void sdla_get_pci_base_resource_addr(sdlahw_t* hw, int pci_offset, sdla_base_addr_t *base_addr) { sdlahw_card_t* card; + sdlahw_cpu_t *hwcpu; WAN_ASSERT1(hw == NULL); - WAN_ASSERT1(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT1(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT1(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) @@ -599,12 +821,13 @@ sdla_get_pci_base_resource_addr(sdlahw_t* hw, int pci_offset, sdla_base_addr_t * #elif defined(__NetBSD__) || defined(__OpenBSD__) *base_addr = (sdla_base_addr_t)pci_conf_read(card->pci_dev->pa_pc, card->pci_dev->pa_tag, pci_offset); #elif defined(__LINUX__) - if (pci_offset == PCI_IO_BASE_DWORD){ *base_addr = (sdla_base_addr_t)pci_resource_start(card->pci_dev,0); }else{ *base_addr = (sdla_base_addr_t)pci_resource_start(card->pci_dev,1); } +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # warning "sdla_get_pci_base_resource_addr: Not supported yet!" #endif @@ -616,27 +839,35 @@ sdla_get_pci_base_resource_addr(sdlahw_t* hw, int pci_offset, sdla_base_addr_t * static __inline int __sdla_bus_read_4(void* phw, unsigned int offset, u32* value) { sdlahw_t* hw = (sdlahw_t*)phw; - int retry=5; - WAN_ASSERT2(hw == NULL, 0); - WAN_ASSERT2(hw->dpmbase == 0, 0); - SDLA_MAGIC(hw); + sdlahw_cpu_t *hwcpu; + unsigned int retry=3; + WAN_ASSERT2(hw == NULL, 0); + WAN_ASSERT2(hw->hwcpu == NULL, 0); + hwcpu = hw->hwcpu; + WAN_ASSERT2(hwcpu->hwcard == NULL, 0); + WAN_ASSERT2(hwcpu->dpmbase == 0, 0); + SDLA_MAGIC(hwcpu); + + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; do { #if defined(__FreeBSD__) - *value = readl(((u8*)hw->dpmbase + offset)); + *value = readl(((u8*)hw->hwcpu->dpmbase + offset)); #elif defined(__NetBSD__) || defined(__OpenBSD__) - *value = bus_space_read_4(hw->hwcard->memt, hwcpu->dpmbase, offset); + *value = bus_space_read_4(hw->hwcard->memt, hwcpu->hwcpu->dpmbase, offset); #elif defined(__LINUX__) - *value = wp_readl((unsigned char*)hw->dpmbase + offset); + *value = wp_readl((unsigned char*)hw->hwcpu->dpmbase + offset); +#elif defined(__WINDOWS__) + *value = READ_REGISTER_ULONG((PULONG)((PUCHAR)hw->hwcpu->dpmbase + offset)); #else *value = 0; # warning "sdla_bus_read_4: Not supported yet!" #endif if (offset == 0x40 && *value == (u32)-1) { if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%d: Error: Illegal Register read: 0x%04X = 0x%08X\n", + DEBUG_EVENT("%s:%d: wanpipe PCI Error: Illegal Register read: 0x%04X = 0x%08X\n", __FUNCTION__,__LINE__,offset,*value); } } else { @@ -652,16 +883,22 @@ static __inline int __sdla_bus_read_4(void* phw, unsigned int offset, u32* value static __inline int __sdla_bus_write_4(void* phw, unsigned int offset, u32 value) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; - WAN_ASSERT(hw == NULL); - SDLA_MAGIC(hw); - if (!(hw->status & SDLA_MEM_MAPPED)) return 0; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + SDLA_MAGIC(hwcpu); + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; #if defined(__FreeBSD__) - writel(((u8*)hw->dpmbase + offset), value); + writel(((u8*)hwcpu->dpmbase + offset), value); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_write_4(hw->hwcard->memt, hw->dpmbase, offset, value); + bus_space_write_4(hwcpu->hwcard->memt, hwcpu->dpmbase, offset, value); #elif defined(__LINUX__) - wp_writel(value,(u8*)hw->dpmbase + offset); + wp_writel(value,(u8*)hwcpu->dpmbase + offset); +#elif defined(__WINDOWS__) + WRITE_REGISTER_ULONG((PULONG)((PUCHAR)hwcpu->dpmbase + offset), value); #else # warning "sdla_bus_write_4: Not supported yet!" #endif @@ -670,39 +907,61 @@ static __inline int __sdla_bus_write_4(void* phw, unsigned int offset, u32 value static __inline int __sdla_is_same_hwcard(void* phw1, void *phw2) { - if (((sdlahw_t*)phw1)->hwcard == ((sdlahw_t*)phw2)->hwcard){ + sdlahw_cpu_t *hwcpu1, *hwcpu2; + + WAN_ASSERT_RC(phw1 == NULL, 0); + WAN_ASSERT_RC(phw2 == NULL, 0); + WAN_ASSERT_RC(((sdlahw_t*)phw1)->hwcpu == NULL, 0); + WAN_ASSERT_RC(((sdlahw_t*)phw2)->hwcpu == NULL, 0); + hwcpu1 = ((sdlahw_t*)phw1)->hwcpu; + hwcpu2 = ((sdlahw_t*)phw2)->hwcpu; + if (hwcpu1->hwcard == hwcpu2->hwcard){ return 1; } return 0; } -static __inline void **__sdla_get_ptr_isr_array(void *phw1) +static __inline void **__sdla_get_ptr_isr_array(void *phw) { - return &((sdlahw_t*)phw1)->hwcard->port_ptr_isr_array[0]; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT_RC(hw == NULL, 0); + WAN_ASSERT_RC(hw->hwcpu == NULL, 0); + hwcpu = hw->hwcpu; + return &hwcpu->port_ptr_isr_array[0]; } -static __inline void __sdla_push_ptr_isr_array(void *phw1, void *card, int line) +static __inline void __sdla_push_ptr_isr_array(void *phw, void *card, int line) { + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT_VOID(hw == NULL); + WAN_ASSERT_VOID(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; if (line >= SDLA_MAX_PORTS) { return; - } - - ((sdlahw_t*)phw1)->hwcard->port_ptr_isr_array[line]=card; + } + hwcpu->port_ptr_isr_array[line]=card; } -static __inline void __sdla_pull_ptr_isr_array(void *phw1, void *card, int line) +static __inline void __sdla_pull_ptr_isr_array(void *phw, void *card, int line) { + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT_VOID(hw == NULL); + WAN_ASSERT_VOID(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; if (line >= SDLA_MAX_PORTS) { return; } - ((sdlahw_t*)phw1)->hwcard->port_ptr_isr_array[line]=NULL; - + hwcpu->port_ptr_isr_array[line]=NULL; return; } - - #undef EXTERN #endif /* _SDLADRV_H */ diff --git a/patches/kdrivers/include/sdlapci.h b/patches/kdrivers/include/sdlapci.h index 41c0e7a..272b0b8 100644 --- a/patches/kdrivers/include/sdlapci.h +++ b/patches/kdrivers/include/sdlapci.h @@ -25,15 +25,25 @@ #define PCI_DEV_SLOT_MASK 0x1F /* mask for slot numbering */ #define PCI_IRQ_NOT_ALLOCATED 0xFF /* interrupt line for no IRQ */ -/* Definition for identifying and finding XILINX PCI adapters */ +/* Vendor id lisr for Sangoma cards */ #define SANGOMA_PCI_VENDOR 0x1923 /* Old value -> 0x11B0 */ #define SANGOMA_PCI_VENDOR_OLD 0x10EE /* Old value -> 0x11B0 */ + +/* Device id list for Sangoma cards */ #define SANGOMA_PCI_DEVICE 0x0300 /* Old value -> 0x0200 */ #define SANGOMA_PCI_4_DEVICE 0x0400 /* */ +#define SANGOMA_S2E_300_PCI_DEVICE 0x0030 /* Xilinx-300 SPARTAN-2e */ +#define SANGOMA_S3_400_PCI_DEVICE 0x0040 /* Xilinx-400 SPARTAN-3 */ +#define SANGOMA_S3_1000_PCI_DEVICE 0x0100 /* Xilinx-1000 SPARTAN-3 */ +#define SANGOMA_S3E_250_PCI_DEVICE 0x0025 /* Xilinx-250 SPARTAN-3e */ +#define SANGOMA_S3E_500_PCI_DEVICE 0x0050 /* Xilinx-500 SPARTAN-3e */ +#define SANGOMA_S3E_1200_PCI_DEVICE 0x0120 /* Xilinx-1200 SPARTAN-3e */ +#define SANGOMA_GP_ADSL_PCI_DEVICE 0x0001 /* Globe-Span ADSL */ #if defined(__WINDOWS__) #define SANGOMA_PCI_4_SHARK_DEVICE 0x0100 /* A104D */ #define SANGOMA_PCI_A200_SHARK_DEVICE 0x0040 /* A200 (D) */ +#define SANGOMA_PCI_A056_SHARK_DEVICE 0x0020 /* A056 */ #endif /* Definition for identifying and finding PLX PCI bridge adapters */ @@ -41,13 +51,9 @@ #define PLX_DEVICE_ID 0x8111 /* PLX device ID number */ #define PLX2_DEVICE_ID 0x8112 /* PLX device ID number rev 2 */ -#define TUNDRA_VENDOR_ID 0x10E3 /* TUNDRA vendor ID number */ -#define TUNDRA_DEVICE_ID 0x8111 /* TUNDRA device ID number */ - #define PLX_EEPROM_ENABLE 0x5A #define PLX_EEPROM_VENDOR_OFF 0xFC /* 2 bytes for Card vendor id */ - #define A101_1TE1_SUBSYS_VENDOR 0xA010 /* A101 with T1/E1 1 line */ #define A101_2TE1_SUBSYS_VENDOR 0xA011 /* A101 with T1/E1 2 lines */ #define A104_4TE1_SUBSYS_VENDOR 0xA013 /* A104 with T1/E1 4 lines */ @@ -66,6 +72,11 @@ #define AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR 0xA500 /* AFT-ISDN BRI SHARK board */ #define AFT_56K_SHARK_SUBSYS_VENDOR 0xA056 /* AFT-56K SHARK board */ +#define AFT_2SERIAL_V35X21_SUBSYS_VENDOR 0xA031 /* AFT-A142 2 Port V.35/X.21 board */ +#define AFT_4SERIAL_V35X21_SUBSYS_VENDOR 0xA032 /* AFT-A144 4 Port V.35/X.21 board */ +#define AFT_2SERIAL_RS232_SUBSYS_VENDOR 0xA033 /* AFT-A142 2 Port RS232 board */ +#define AFT_4SERIAL_RS232_SUBSYS_VENDOR 0xA034 /* AFT-A144 4 Port RS232 board */ + #define AFT_CORE_ID_MASK 0x00FF #define AFT_CORE_REV_MASK 0xFF00 #define AFT_CORE_REV_SHIFT 8 @@ -160,7 +171,7 @@ #define PCI_VENDOR_ID_GSI 0x14BC #define PCI_DEVICE_ID_GSI_PULSAR 0xD002 #define PCI_DEVICE_ID_GSI_ADSL PCI_DEVICE_ID_GSI_PULSAR -#define PCI_DEVICE_ID_GSI_ADSL_OTHER 0xD001 +#define PCI_DEVICE_ID_GSI_ADSL_V2 0xD001 #endif /* _SDLAPCI_H */ diff --git a/patches/kdrivers/include/sdlasfm.h b/patches/kdrivers/include/sdlasfm.h index d31b513..bd63cf6 100644 --- a/patches/kdrivers/include/sdlasfm.h +++ b/patches/kdrivers/include/sdlasfm.h @@ -159,6 +159,11 @@ typedef struct sfm /* SDLA firmware file structire */ #define AFT_ADPTR_56K_MASK 0x2000 /* AFT 56K board mask */ #define AFT_ADPTR_56K 0x2001 /* AFT 56K board */ +#define AFT_ADPTR_SERIAL_MASK 0x4000 /* AFT Serial base board mask */ +#define AFT_ADPTR_2SERIAL_V35X21 0x4001 /* AFT-A142 2 Port V.35/X.21 board */ +#define AFT_ADPTR_4SERIAL_V35X21 0x4002 /* AFT-A144 4 Port V.35/X.21 board */ +#define AFT_ADPTR_2SERIAL_RS232 0x4003 /* AFT-A142 2 Port RS232 board */ +#define AFT_ADPTR_4SERIAL_RS232 0x4004 /* AFT-A144 4 Port RS232 board */ #define OPERATE_T1E1_AS_SERIAL 0x8000 /* For bitstreaming only * Allow the applicatoin to @@ -180,7 +185,7 @@ typedef struct sfm /* SDLA firmware file structire */ /* CPLD interface */ #define AFT_MCPU_INTERFACE_ADDR 0x46 -#define AFT_MCPU_INTERFACE 0x44 +#define AFT_MCPU_INTERFACE 0x44 #define AFT56K_MCPU_INTERFACE_ADDR 0x46 #define AFT56K_MCPU_INTERFACE 0x44 @@ -202,6 +207,11 @@ typedef struct sfm /* SDLA firmware file structire */ #define AFT8_BIT_DEV_ADDR_CPLD 0x800 #define AFT8_BIT_DEV_MAXIM_ADDR_CPLD 0x1000 +/* Aft Serial CPLD definitions */ +#define AFT_SERIAL_BIT_DEV_ADDR_CLEAR 0x1800 /* QUAD */ +#define AFT_SERIAL_BIT_DEV_ADDR_CPLD 0x800 +#define AFT_SERIAL_BIT_DEV_MAXIM_ADDR_CPLD 0x1000 + #define AFT3_BIT_DEV_ADDR_EXAR_CLEAR 0x600 #define AFT3_BIT_DEV_ADDR_EXAR_CPLD 0x400 @@ -234,6 +244,10 @@ typedef struct sfm /* SDLA firmware file structire */ #define A108_SECURITY_256_ECCHAN 0x04 #define A108_SECURITY_0_ECCHAN 0x05 +#define A500_SECURITY_32_ECCHAN 0x00 +#define A500_SECURITY_64_ECCHAN 0x01 +#define A500_SECURITY_0_ECCHAN 0x05 + #define A104_ECCHAN(val) \ ((val) == A104_SECURITY_32_ECCHAN) ? 32 : \ ((val) == A104_SECURITY_64_ECCHAN) ? 64 : \ @@ -249,6 +263,10 @@ typedef struct sfm /* SDLA firmware file structire */ ((val) == A108_SECURITY_128_ECCHAN) ? 128 : \ ((val) == A108_SECURITY_256_ECCHAN) ? 256 : 0 +#define A500_ECCHAN(val) \ + ((val) == A500_SECURITY_32_ECCHAN) ? 32 : \ + ((val) == A500_SECURITY_64_ECCHAN) ? 64 : 0 + #define AFT_RM_SECURITY_16_ECCHAN 0x00 #define AFT_RM_SECURITY_32_ECCHAN 0x01 #define AFT_RM_SECURITY_0_ECCHAN 0x05 @@ -257,7 +275,6 @@ typedef struct sfm /* SDLA firmware file structire */ ((val) == AFT_RM_SECURITY_32_ECCHAN) ? 32 : 0 - #define SDLA_ADPTR_NAME(adapter_type) \ (adapter_type == S5141_ADPTR_1_CPU_SERIAL) ? "S514-1-PCI" : \ (adapter_type == S5142_ADPTR_2_CPU_SERIAL) ? "S514-2-PCI" : \ @@ -275,24 +292,12 @@ typedef struct sfm /* SDLA firmware file structire */ (adapter_type == A400_ADPTR_ANALOG) ? "AFT-A400" : \ (adapter_type == AFT_ADPTR_ISDN) ? "AFT-A500" : \ (adapter_type == AFT_ADPTR_56K) ? "AFT-A056" : \ + (adapter_type == AFT_ADPTR_2SERIAL_V35X21) ? "AFT-A142" : \ + (adapter_type == AFT_ADPTR_4SERIAL_V35X21) ? "AFT-A144" : \ + (adapter_type == AFT_ADPTR_2SERIAL_RS232) ? "AFT-A142" : \ + (adapter_type == AFT_ADPTR_4SERIAL_RS232) ? "AFT-A144" : \ "UNKNOWN" - -#if 0 -#define SDLA_ADPTR_DECODE(adapter_type) \ - (adapter_type == S5141_ADPTR_1_CPU_SERIAL) ? "S514-1-PCI" : \ - (adapter_type == S5142_ADPTR_2_CPU_SERIAL) ? "S514-2-PCI" : \ - (adapter_type == S5143_ADPTR_1_CPU_FT1) ? "S514-3-PCI" : \ - (adapter_type == S5144_ADPTR_1_CPU_T1E1) ? "S514-4-PCI" : \ - (adapter_type == S5145_ADPTR_1_CPU_56K) ? "S514-5-PCI" : \ - (adapter_type == S5147_ADPTR_2_CPU_T1E1) ? "S514-7-PCI" : \ - (adapter_type == S518_ADPTR_1_CPU_ADSL) ? "S518-PCI " : \ - (adapter_type == A101_ADPTR_1TE1) ? "AFT-A101 " : \ - (adapter_type == A101_ADPTR_2TE1) ? "AFT-A102 " : \ - (adapter_type == A104_ADPTR_4TE1) ? "AFT-A104 " : \ - (adapter_type == A300_ADPTR_U_1TE3) ? "AFT-A301 " : \ - "UNKNOWN " -#endif - + #define AFT_GET_SECURITY(security) \ ((security >> AFT_SECURITY_CPLD_SHIFT) & AFT_SECURITY_CPLD_MASK) @@ -313,11 +318,24 @@ typedef struct sfm /* SDLA firmware file structire */ (adptr_subtype == AFT_SUBTYPE_SHARK) ? "SHARK" : "" #define AFT_PCITYPE_DECODE(hwcard) \ - ((hwcard)->pci_bridge_dev) ? "PCIe" : "PCI" - -#define AFT_PCIEXPRESS_DECODE AFT_PCITYPE_DECODE + ((hwcard)->pci_bridge_dev) ? " PCIe" : " PCI" +#if defined(__WINDOWS__) +#define DECODE_CARD_SUBTYPE(card_sub_type) \ + (card_sub_type == A101_1TE1_SUBSYS_VENDOR) ? "A101" : \ + (card_sub_type == AFT_1TE1_SHARK_SUBSYS_VENDOR) ? "A101D" : \ + (card_sub_type == A101_2TE1_SUBSYS_VENDOR) ? "A102" : \ + (card_sub_type == AFT_2TE1_SHARK_SUBSYS_VENDOR) ? "A102D" : \ + (card_sub_type == A104_4TE1_SUBSYS_VENDOR) ? "A104" : \ + (card_sub_type == AFT_4TE1_SHARK_SUBSYS_VENDOR) ? "A104D" : \ + (card_sub_type == AFT_8TE1_SHARK_SUBSYS_VENDOR) ? "A108D" : \ + (card_sub_type == A200_REMORA_SHARK_SUBSYS_VENDOR)? "A200" : "Unknown" +#define SDLA_CARD_TYPE_DECODE(cardtype) \ + ((cardtype == SDLA_S514) ? "S514" : \ + (cardtype == SDLA_ADSL) ? "S518-ADSL" : \ + (cardtype == SDLA_AFT) ? "AFT" : "Invalid card") +#endif/* __WINDOWS__ */ #endif /* _SDLASFM_H */ diff --git a/patches/kdrivers/include/ss7_linux.h b/patches/kdrivers/include/ss7_linux.h index c135b15..78f96f9 100644 --- a/patches/kdrivers/include/ss7_linux.h +++ b/patches/kdrivers/include/ss7_linux.h @@ -24,12 +24,11 @@ Descripiton: #ifndef _SS7_LINUX_H #define _SS7_LINUX_H +#pragma pack(1) #include #include -#pragma pack(1) - enum { SIOCC_PC_RESERVED = (SIOC_WANPIPE_DEVPRIVATE), SIOCS_GENERAL_CMD, @@ -45,64 +44,35 @@ enum { typedef struct { - unsigned char status ; - unsigned char data_avail ; - unsigned short real_length ; - unsigned short time_stamp ; - unsigned char data[1] ; + unsigned char status ; + unsigned char data_avail ; + unsigned short real_length ; + unsigned short time_stamp ; + unsigned char data[1] ; } trace_pkt_t; typedef struct { - unsigned char SIO ; - unsigned short time_stamp ; - unsigned char reserved[13] ; + unsigned char SIO ; + unsigned short time_stamp ; + unsigned char reserved[13] ; } api_rx_hdr_t; typedef struct { - api_rx_hdr_t api_rx_hdr ; - void * data ; + api_rx_hdr_t api_rx_hdr ; + void * data ; } api_rx_element_t; typedef struct { - unsigned char SIO ; - unsigned char reserved[15] ; + unsigned char SIO ; + unsigned char reserved[15] ; } api_tx_hdr_t; typedef struct { - api_tx_hdr_t api_tx_hdr ; - void * data ; + api_tx_hdr_t api_tx_hdr ; + void * data ; } api_tx_element_t; -/* The embedded control block for UDP mgmt - This is essentially a mailbox structure, without the large data field */ -#if 0 -typedef struct { - unsigned char opp_flag ; /* the opp flag */ - unsigned char command ; /* the user command */ - unsigned short buffer_length ; /* the data length */ - unsigned char return_code ; /* the return code */ - unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] ; /* reserved for later */ -} cblock_t; - - -typedef struct { - unsigned char num_frames ; - unsigned char ismoredata ; -} trace_info_t; - -typedef struct { - ip_pkt_t ip_pkt ; - udp_pkt_t udp_pkt ; - wp_mgmt_t wp_mgmt ; - cblock_t cblock ; - trace_info_t trace_info ; - unsigned char data[SIZEOF_MB_DATA_BFR] ; -} ss7_udp_pkt_t; -#endif - -#pragma pack() - /* modem status changes */ #define DCD_HIGH 0x08 #define CTS_HIGH 0x20 @@ -129,5 +99,7 @@ typedef struct { #define UDPMGMT_SIGNATURE "CTPIPEAB" /* "STPIPEAB" */ +#pragma pack() + #endif diff --git a/patches/kdrivers/include/wanec_iface.h b/patches/kdrivers/include/wanec_iface.h new file mode 120000 index 0000000..bcd03df --- /dev/null +++ b/patches/kdrivers/include/wanec_iface.h @@ -0,0 +1 @@ +../wanec/wanec_iface.h \ No newline at end of file diff --git a/patches/kdrivers/include/wanpipe.h b/patches/kdrivers/include/wanpipe.h index c685769..d2464cf 100644 --- a/patches/kdrivers/include/wanpipe.h +++ b/patches/kdrivers/include/wanpipe.h @@ -13,6 +13,9 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* Nov 27, 2007 David Rokhvarg Implemented functions/definitions for +* Sangoma MS Windows Driver and API. +* * Nov 3, 2000 Nenad Corbic Added config_id to sdla_t structure. * Used to determine the protocol running. * Jul 13, 2000 Nenad Corbic Added SyncPPP Support @@ -47,6 +50,14 @@ #include #include # include +#elif defined(__WINDOWS__) +#include +#include +#include +#include +#include +#include +#include #elif defined(__LINUX__) || defined (__KERNEL__) #include #include @@ -89,6 +100,7 @@ #endif /* Defines */ + #define WANPIPE_MAGIC 0x414C4453L /* signature: 'SDLA' reversed */ /* IOCTL numbers (up to 16) */ @@ -307,10 +319,21 @@ typedef struct { # include # include # include +#elif defined(__WINDOWS__) +# include +# include +# include /* SDLA firmware module definitions */ +# include /* SDLA support module API definitions */ +# include #endif #define MAX_E1_CHANNELS 32 + +#if defined(__WINDOWS__) +#define MAX_FR_CHANNELS MAX_NUMBER_OF_PROTOCOL_INTERFACES /*1023*/ +#else #define MAX_FR_CHANNELS (1007+1) +#endif #define WAN_ENABLE 0x01 #define WAN_DISABLE 0x02 @@ -366,7 +389,7 @@ typedef struct wan_x25_conf_t x25_conf; atomic_t tx_interrupt_cmd; struct sk_buff_head trace_queue; - unsigned long trace_timeout; + wan_ticks_t trace_timeout; unsigned short trace_lost_cnt; unsigned long card_ready; @@ -694,19 +717,20 @@ typedef struct unsigned char state_change_exit_isr; unsigned long active_ch_map; unsigned long fifo_addr_map; + unsigned long fifo_addr_map_l2; wan_timer_t led_timer; unsigned char tdmv_sync; unsigned int chip_cfg_status; wan_taskq_t port_task; unsigned int port_task_cmd; unsigned long wdt_rx_cnt; - unsigned long wdt_tx_cnt; + wan_ticks_t wdt_tx_cnt; unsigned int security_id; unsigned int security_cnt; unsigned char firm_ver; unsigned char firm_id; unsigned int chip_security_cnt; - unsigned long rx_timeout,gtimeout; + wan_ticks_t rx_timeout,gtimeout; unsigned int comm_enabled; unsigned int lcfg_reg; unsigned int tdmv_master_if_up; @@ -731,14 +755,10 @@ typedef struct unsigned short tdm_tx_dma_toggle; unsigned int tdm_logic_ch_map; - unsigned long sec_chk_cnt; - + wan_ticks_t sec_chk_cnt; wan_skb_queue_t rtp_tap_list; - unsigned int rx_errors_hist; - unsigned int rx_errors_over_cnt; - unsigned long rx_errors_timeout; - unsigned long rx_errors_down_timeout; - + unsigned int serial_status; + } sdla_xilinx_t; @@ -759,20 +779,26 @@ typedef struct unsigned long status; } sdla_debug_t; + /* Adapter Data Space. * This structure is needed because we handle multiple cards, otherwise * static data would do it. */ typedef struct sdla { +#if defined(__WINDOWS__) + u8 device_type; /* must be first member of sdla_t structure! */ + struct _win_sdla_data; +#endif/* __WINDOWS__ */ + char devname[WAN_DRVNAME_SZ+1]; /* card name */ void* hw; /* hardware configuration */ wan_device_t wandev; /* WAN device data space */ - unsigned open_cnt; /* number of open interfaces */ - unsigned long state_tick; /* link state timestamp */ - unsigned intr_mode; /* Type of Interrupt Mode */ - unsigned long in_isr; /* interrupt-in-service flag */ + unsigned open_cnt; /* number of open interfaces */ + wan_ticks_t state_tick; /* link state timestamp */ + unsigned intr_mode; /* Type of Interrupt Mode */ + unsigned long in_isr; /* interrupt-in-service flag */ char buff_int_mode_unbusy; /* flag for carrying out dev_tint */ char dlci_int_mode_unbusy; /* flag for carrying out dev_tint */ unsigned long configured; /* flag for previous configurations */ @@ -821,8 +847,13 @@ typedef struct sdla struct sk_buff_head tty_rx_empty; struct sk_buff_head tty_rx_full; wan_taskq_t tty_task_queue; -#endif +#endif + +#if defined(__WINDOWS__) + struct +#else union +#endif { #if defined(__LINUX__) sdla_x25_t x; @@ -862,8 +893,8 @@ typedef struct sdla unsigned long update_comms_stats; sdla_fe_t fe; /* front end structures */ - u8 fe_no_intr; /* do not enable global fe intr */ - + u8 fe_no_intr; /* set to 0x01 if not FE interrupt should enabled */ + unsigned int rCount; /* Wanpipe Socket Interface */ @@ -899,9 +930,11 @@ typedef struct sdla # if defined(NETGRAPH) int running; /* something is attached so we are running */ /* ---netgraph bits --- */ - int datahooks; /* number of data hooks attached */ + int upperhooks; /* number of upper hooks attached */ + int lowerhooks; /* number of lower hooks attached */ node_p node; /* netgraph node */ - hook_p hook; /* data hook */ + hook_p upper; /* upper layer */ + hook_p lower; /* lower layer */ hook_p debug_hook; # if defined(ALTQ) struct ifaltq xmitq_hipri; /* hi-priority transmit queue */ @@ -921,6 +954,8 @@ typedef struct sdla u_long inrate, outrate; /* highest rate seen */ u_long inlast; /* last input N secs ago */ u_long out_deficit; /* output since last input */ + u_char promisc; /* promiscuous mode enabled */ + u_char autoSrcAddr; /* always overwrite source address */ void (*wan_down)(struct sdla*); int (*wan_up)(struct sdla*); void (*wan_start)(struct sdla*); @@ -931,9 +966,11 @@ typedef struct sdla u_long opackets, ipackets; #endif /* __FreeBSD__ */ - /* This value is used for detecting TDM Voice - * rsync timeout, it should be long */ - unsigned long rsync_timeout; + + /* This value is used for detecting TDM Voice + * rsync timeout, it should be long */ + wan_ticks_t rsync_timeout; + } sdla_t; /****** Public Functions ****************************************************/ @@ -963,6 +1000,8 @@ int wp_xilinx_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Suppor int wp_aft_te1_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */ int wp_aft_56k_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */ int wp_aft_analog_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */ +int wp_aft_bri_init(sdla_t* card, wandev_conf_t* conf); /* BRI Hardware Support */ +int wp_aft_serial_init(sdla_t* card, wandev_conf_t* conf); /* Serial Hardware Support */ int wp_adccp_init(sdla_t* card, wandev_conf_t* conf); int wp_xilinx_if_init(sdla_t* card, netdevice_t* dev); int wp_aft_te3_init(sdla_t* card, wandev_conf_t* conf); /* AFT TE3 Hardware Support */ @@ -1022,8 +1061,14 @@ void *atm_tx_skb_dequeue(void* wp_tx_pending_list, void *tx_idle_skb, char *if_n #if defined(__FreeBSD__) && defined(NETGRAPH) -int wan_ng_init(sdla_t*); -int wan_ng_remove(sdla_t*); +int wan_ng_init_old(sdla_t*); +int wan_ng_remove_old(sdla_t*); +#endif + +#if defined(__WINDOWS__) +extern int connect_to_interrupt_line(sdla_t *card); +extern void disconnect_from_interrupt_line(sdla_t *card); +int wp_aft_firmware_up_init(sdla_t* card, wandev_conf_t* conf); /* AFT Firmware Update support */ #endif #endif /* __KERNEL__ */ diff --git a/patches/kdrivers/include/wanpipe.h~ b/patches/kdrivers/include/wanpipe.h~ deleted file mode 100644 index 012c2f0..0000000 --- a/patches/kdrivers/include/wanpipe.h~ +++ /dev/null @@ -1,1014 +0,0 @@ -/***************************************************************************** -* wanpipe.h WANPIPE(tm) Multiprotocol WAN Link Driver. -* User-level API definitions. -* -* Author: Nenad Corbic -* Alex Feldman -* Gideon Hack -* -* 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. -* ============================================================================ -* Nov 3, 2000 Nenad Corbic Added config_id to sdla_t structure. -* Used to determine the protocol running. -* Jul 13, 2000 Nenad Corbic Added SyncPPP Support -* Feb 24, 2000 Nenad Corbic Added support for x25api driver -* Oct 04, 1999 Nenad Corbic New CHDLC and FRAME RELAY code, SMP support -* Jun 02, 1999 Gideon Hack Added 'update_call_count' for Cisco HDLC -* support -* Jun 26, 1998 David Fong Added 'ip_mode' in sdla_t.u.p for dynamic IP -* routing mode configuration -* Jun 12, 1998 David Fong Added Cisco HDLC union member in sdla_t -* Dec 08, 1997 Jaspreet Singh Added 'authenticator' in union of 'sdla_t' -* Nov 26, 1997 Jaspreet Singh Added 'load_sharing' structure. Also added -* 'devs_struct','dev_to_devtint_next' to 'sdla_t' -* Nov 24, 1997 Jaspreet Singh Added 'irq_dis_if_send_count', -* 'irq_dis_poll_count' to 'sdla_t'. -* Nov 06, 1997 Jaspreet Singh Added a define called 'INTR_TEST_MODE' -* Oct 20, 1997 Jaspreet Singh Added 'buff_intr_mode_unbusy' and -* 'dlci_intr_mode_unbusy' to 'sdla_t' -* Oct 18, 1997 Jaspreet Singh Added structure to maintain global driver -* statistics. -* Jan 15, 1997 Gene Kozin Version 3.1.0 -* o added UDP management stuff -* Jan 02, 1997 Gene Kozin Version 3.0.0 -*****************************************************************************/ -#ifndef _WANPIPE_H -#define _WANPIPE_H - -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -#include -#include -#include -#include -#include -# include -#elif defined(__LINUX__) || defined (__KERNEL__) -#include -#include -#include -#include -#include -#include -#else -# error "No OS Specified" -#endif - -/* Due to changes between 2.4.9 and 2.4.13, - * I decided to write my own min() and max() - * functions */ - -#define wp_min(x,y) \ - ({ unsigned int __x = (x); unsigned int __y = (y); __x < __y ? __x: __y; }) -#define wp_max(x,y) \ - ({ unsigned int __x = (x); unsigned int __y = (y); __x > __y ? __x: __y; }) - - -#if defined(__LINUX__) || defined (__KERNEL__) -# if defined(LINUX_2_4)||defined(LINUX_2_6) -# ifndef AF_WANPIPE -# define AF_WANPIPE 25 -# ifndef PF_WANPIPE -# define PF_WANPIPE AF_WANPIPE -# endif -# endif -# else -# ifndef AF_WANPIPE -# define AF_WANPIPE 24 -# ifndef PF_WANPIPE -# define PF_WANPIPE AF_WANPIPE -# endif -# endif -# endif -# define AF_ANNEXG_WANPIPE AF_WANPIPE -# define PF_ANNEXG_WANPIPE AF_ANNEXG_WANPIPE -#endif - -/* Defines */ -#define WANPIPE_MAGIC 0x414C4453L /* signature: 'SDLA' reversed */ - -/* IOCTL numbers (up to 16) */ -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -# define WANPIPE_DUMP _IOW(ROUTER_IOCTL, 16, wan_conf_t) -# define WANPIPE_EXEC _IOWR(ROUTER_IOCTL, 17, wan_conf_t) -#elif defined(__LINUX__) -# define WANPIPE_DUMP (ROUTER_USER+0) /* dump adapter's memory */ -# define WANPIPE_EXEC (ROUTER_USER+1) /* execute firmware command */ -#endif - -#if 0 -#define WAN_HWCALL(func, (x)) \ - if (card->hw_iface.##func){ \ - card->hw_iface.##func(x); \ - } -#endif - -#define TRACE_ALL 0x00 -#define TRACE_PROT 0x01 -#define TRACE_DATA 0x02 - -/* values for request/reply byte */ -#define UDPMGMT_REQUEST 0x01 -#define UDPMGMT_REPLY 0x02 -#define UDP_OFFSET 12 - -#define MAX_CMD_BUFF 10 -#define MAX_X25_LCN 255 /* Maximum number of x25 channels */ -#define MAX_LCN_NUM 4095 /* Maximum lcn number */ -#define MAX_FT1_RETRY 100 - -#define TX_TIMEOUT 5*HZ - - -/* General Critical Flags */ -enum { - SEND_CRIT, - PERI_CRIT, - RX_CRIT, - PRIV_CRIT -}; - -/* TE timer critical flags */ -/* #define LINELB_TIMER_RUNNING 0x04 - define in sdla_te1_pmc.h */ - -/* Bit maps for dynamic interface configuration - * DYN_OPT_ON : turns this option on/off - * DEV_DOWN : device was shutdown by the driver not - * by user - */ -#define DYN_OPT_ON 0x00 -#define DEV_DOWN 0x01 -#define WAN_DEV_READY 0x02 - -/* - * Data structures for IOCTL calls. - */ - -typedef struct sdla_dump /* WANPIPE_DUMP */ -{ - unsigned long magic; /* for verification */ - unsigned long offset; /* absolute adapter memory address */ - unsigned long length; /* block length */ - void* ptr; /* -> buffer */ -} sdla_dump_t; - -typedef struct sdla_exec /* WANPIPE_EXEC */ -{ - unsigned long magic; /* for verification */ - void* cmd; /* -> command structure */ - void* data; /* -> data buffer */ -} sdla_exec_t; - -typedef struct wan_procfs -{ - unsigned long magic; /* for verification */ - int cmd; - unsigned long max_len; - unsigned long offs; - int is_more; - void* data; -} wan_procfs_t; - -/* UDP management stuff */ -typedef struct wum_header -{ - unsigned char signature[8]; /* 00h: signature */ - unsigned char type; /* 08h: request/reply */ - unsigned char command; /* 09h: commnand */ - unsigned char reserved[6]; /* 0Ah: reserved */ -} wum_header_t; - -/************************************************************************* - Data Structure for global statistics -*************************************************************************/ - -typedef struct global_stats -{ - unsigned long isr_entry; - unsigned long isr_already_critical; - unsigned long isr_rx; - unsigned long isr_tx; - unsigned long isr_intr_test; - unsigned long isr_spurious; - unsigned long isr_enable_tx_int; - unsigned long rx_intr_corrupt_rx_bfr; - unsigned long rx_intr_on_orphaned_DLCI; - unsigned long rx_intr_dev_not_started; - unsigned long tx_intr_dev_not_started; - unsigned long poll_entry; - unsigned long poll_already_critical; - unsigned long poll_processed; - unsigned long poll_tbusy_bad_status; - unsigned long poll_host_disable_irq; - unsigned long poll_host_enable_irq; - -} global_stats_t; - -/************************************************************************* - Data Structure for if_send statistics -*************************************************************************/ -typedef struct if_send_stat{ - unsigned long if_send_entry; - unsigned long if_send_skb_null; - unsigned long if_send_broadcast; - unsigned long if_send_multicast; - unsigned long if_send_critical_ISR; - unsigned long if_send_critical_non_ISR; - unsigned long if_send_tbusy; - unsigned long if_send_tbusy_timeout; - unsigned long if_send_PIPE_request; - unsigned long if_send_wan_disconnected; - unsigned long if_send_dlci_disconnected; - unsigned long if_send_no_bfrs; - unsigned long if_send_adptr_bfrs_full; - unsigned long if_send_bfr_passed_to_adptr; - unsigned long if_send_protocol_error; - unsigned long if_send_bfr_not_passed_to_adptr; - unsigned long if_send_tx_int_enabled; - unsigned long if_send_consec_send_fail; -} if_send_stat_t; - -typedef struct rx_intr_stat{ - unsigned long rx_intr_no_socket; - unsigned long rx_intr_dev_not_started; - unsigned long rx_intr_PIPE_request; - unsigned long rx_intr_bfr_not_passed_to_stack; - unsigned long rx_intr_bfr_passed_to_stack; -} rx_intr_stat_t; - -typedef struct pipe_mgmt_stat{ - unsigned long UDP_PIPE_mgmt_kmalloc_err; - unsigned long UDP_PIPE_mgmt_direction_err; - unsigned long UDP_PIPE_mgmt_adptr_type_err; - unsigned long UDP_PIPE_mgmt_adptr_cmnd_OK; - unsigned long UDP_PIPE_mgmt_adptr_cmnd_timeout; - unsigned long UDP_PIPE_mgmt_adptr_send_passed; - unsigned long UDP_PIPE_mgmt_adptr_send_failed; - unsigned long UDP_PIPE_mgmt_not_passed_to_stack; - unsigned long UDP_PIPE_mgmt_passed_to_stack; - unsigned long UDP_PIPE_mgmt_no_socket; - unsigned long UDP_PIPE_mgmt_passed_to_adptr; -} pipe_mgmt_stat_t; - - -typedef struct { - struct sk_buff *skb; -} bh_data_t, cmd_data_t; - -#define MAX_LGTH_UDP_MGNT_PKT WAN_MAX_DATA_SIZE - - -/* This is used for interrupt testing */ -#define INTR_TEST_MODE 0x02 - -#define WUM_SIGNATURE_L 0x50495046 -#define WUM_SIGNATURE_H 0x444E3845 - -#define WUM_KILL 0x50 -#define WUM_EXEC 0x51 - - - -#if defined(WAN_KERNEL) -/****** Kernel Interface ****************************************************/ - -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -# include /* WANPIPE Debugging messages */ -# include -# include -# include -# include -#elif defined(__LINUX__) -# include -# ifndef KERNEL_VERSION -# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -# endif -# include -# include /* SDLA firmware module definitions */ -# include /* SDLA support module API definitions */ - -# if defined(LINUX_2_6) -# include -# elif defined(LINUX_2_4) -# include -# endif - -# include -# if defined(LINUX_2_4) || defined(LINUX_2_6) -# include -# include -# include -# include -# endif -# include -# include -# include -#endif - -#define MAX_E1_CHANNELS 32 -#define MAX_FR_CHANNELS (1007+1) - -#define WAN_ENABLE 0x01 -#define WAN_DISABLE 0x02 - -#ifndef min -#define min(a,b) (((a)<(b))?(a):(b)) -#endif -#ifndef max -#define max(a,b) (((a)>(b))?(a):(b)) -#endif - -#define is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0) -#define is_alpha(ch) ((((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'z')||\ - ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'Z'))?1:0) -#define is_hex_digit(ch) ((((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')||\ - ((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'f')||\ - ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'F'))?1:0) - - -/****** Data Structures *****************************************************/ - -#if defined(__LINUX__) -typedef struct -{ /****** X.25 specific data **********/ - netdevice_t *svc_to_dev_map[MAX_X25_LCN]; - netdevice_t *pvc_to_dev_map[MAX_X25_LCN]; - netdevice_t *tx_dev; - netdevice_t *cmd_dev; - u32 no_dev; - unsigned long hdlc_buf_status_off; - atomic_t tx_interrupts_pending; - - /* FIXME: Move this out of the union */ - u16 timer_int_enabled; - netdevice_t *poll_device; - atomic_t command_busy; - - u32 udp_type; - u8 udp_pkt_src; - u32 udp_lcn; - netdevice_t * udp_dev; - wan_udp_pkt_t udp_pkt_data; - atomic_t udp_pkt_len; - - u8 LAPB_hdlc; /* Option to turn off X25 and run only LAPB */ - u8 logging; /* Option to log call messages */ - u8 oob_on_modem; /* Option to send modem status to the api */ - u16 num_of_ch; /* Number of channels configured by the user */ - wan_taskq_t x25_poll_task; - struct timer_list x25_timer; - /* Proc fs */ - wan_x25_conf_t x25_adm_conf; - wan_x25_conf_t x25_conf; - atomic_t tx_interrupt_cmd; - struct sk_buff_head trace_queue; - unsigned long trace_timeout; - unsigned short trace_lost_cnt; - - unsigned long card_ready; -} sdla_x25_t; -#endif - -typedef struct -{ /****** frame relay specific data ***/ - unsigned long rxmb_base_off; /* -> first Rx buffer */ - unsigned long rxmb_last_off; /* -> last Rx buffer */ - unsigned long rx_base_off; /* S508 receive buffer base */ - unsigned long rx_top_off; /* S508 receive buffer end */ - unsigned short node_dlci[100]; - unsigned short dlci_num; - netdevice_t* dlci_to_dev_map[MAX_FR_CHANNELS]; - atomic_t tx_interrupts_pending; - - /* FIXME: Move this out of the union */ - unsigned short timer_int_enabled; - - int udp_type; - char udp_pkt_src; - unsigned udp_dlci; - wan_udp_pkt_t udp_pkt_data; - atomic_t udp_pkt_len; - void* trc_el_base; /* first trace element */ - void* trc_el_last; /* last trace element */ - void* curr_trc_el; /* current trace element */ - unsigned short trc_bfr_space; /* trace buffer space */ - netdevice_t* arp_dev; -#if defined(__LINUX__) - spinlock_t if_send_lock; -#endif - unsigned char issue_fs_on_startup; - /* Proc fs */ - unsigned short t391; - unsigned short t392; - unsigned short n391; - unsigned short n392; - unsigned short n393; - void* update_dlci; - unsigned char auto_dlci_cfg; -} sdla_fr_t; - -typedef struct -{ /****** PPP-specific data ***********/ - char if_name[WAN_IFNAME_SZ+1]; /* interface name */ - unsigned long txbuf_off; /* -> current Tx buffer */ - unsigned long txbuf_base_off; /* -> first Tx buffer */ - unsigned long txbuf_last_off; /* -> last Tx buffer */ - unsigned long txbuf_next_off; /* Next Tx buffer to use */ - unsigned long rxbuf_base_off; /* -> first Rx buffer */ - unsigned long rxbuf_last_off; /* -> last Rx buffer */ - unsigned long rx_base_off; /* S508 receive buffer base */ - unsigned long rx_top_off; /* S508 receive buffer end */ - unsigned long rxbuf_next_off; /* Next Rx buffer to use */ - char ip_mode; /* STATIC/HOST/PEER IP Mode */ - char authenticator; /* Authenticator for PAP/CHAP */ - /* FIXME: Move this out of the union */ - unsigned char comm_enabled; /* Is comm enabled or not */ - unsigned char peer_route; /* Process Peer Route */ -} sdla_ppp_t; - -typedef struct -{ /* Cisco HDLC-specific data */ - char if_name[WAN_IFNAME_SZ+1]; /* interface name */ - int comm_port;/* Communication Port O or 1 */ - unsigned char usedby; /* Used by WANPIPE or API */ - unsigned long rxmb_off; /* Receive mail box */ - /*unsigned long flags_off;*/ /* flags */ - unsigned long txbuf_off; /* -> current Tx buffer */ - unsigned long txbuf_base_off; /* -> first Tx buffer */ - unsigned long txbuf_last_off; /* -> last Tx buffer */ - unsigned long rxbuf_base_off; /* -> first Rx buffer */ - unsigned long rxbuf_last_off; /* -> last Rx buffer */ - unsigned long rx_base_off; /* S508 receive buffer base */ - unsigned long rx_top_off; /* S508 receive buffer end */ - void* tx_status; /* Tx status element */ - void* rx_status; /* Rx status element */ - unsigned char receive_only; /* high speed receivers */ - unsigned short protocol_options; - unsigned short kpalv_tx; /* Tx kpalv timer */ - unsigned short kpalv_rx; /* Rx kpalv timer */ - unsigned short kpalv_err; /* Error tolerance */ - unsigned short slarp_timer; /* SLARP req timer */ - unsigned state; /* state of the link */ - unsigned char api_status; - unsigned char update_call_count; - unsigned short api_options; /* for async config */ - unsigned char async_mode; - unsigned short tx_bits_per_char; - unsigned short rx_bits_per_char; - unsigned short stop_bits; - unsigned short parity; - unsigned short break_timer; - unsigned short inter_char_timer; - unsigned short rx_complete_length; - unsigned short xon_char; - unsigned short xoff_char; - /* FIXME: Move this out of the union */ - unsigned char comm_enabled; /* Is comm enabled or not */ - /* FIXME: Move this out of the union */ - unsigned char backup; - int TracingEnabled; /* For enabling Tracing */ - unsigned long curr_trace_addr; /* Used for Tracing */ - unsigned long start_trace_addr; - unsigned long end_trace_addr; - unsigned long base_addr_trace_buffer; - unsigned long end_addr_trace_buffer; - unsigned short number_trace_elements; - unsigned available_buffer_space; - unsigned long router_start_time; - unsigned char route_status; - unsigned char route_removed; - unsigned long tick_counter; - /* FIXME: Move this out of the union */ - unsigned short timer_int_enabled; - unsigned long router_up_time; -#if defined(__LINUX__) - spinlock_t if_send_lock; -#endif - void * prot; -} sdla_chdlc_t; - -typedef struct -{ - void* tx_status; /* Tx status element */ - void* rx_status; /* Rx status element */ - void* trace_status; /* Trace status element */ - void* txbuf; /* -> current Tx buffer */ - void* txbuf_base; /* -> first Tx buffer */ - void* txbuf_last; /* -> last Tx buffer */ - void* rxbuf_base; /* -> first Rx buffer */ - void* rxbuf_last; /* -> last Rx buffer */ - void* tracebuf; /* -> current Trace buffer */ - void* tracebuf_base; /* -> current Trace buffer */ - void* tracebuf_last; /* -> current Trace buffer */ - unsigned rx_base; /* receive buffer base */ - unsigned rx_end; /* receive buffer end */ - unsigned trace_base; /* trace buffer base */ - unsigned trace_end; /* trace buffer end */ -} sdla_hdlc_t; - -#if defined(__LINUX__) -typedef struct -{ - char if_name[WAN_IFNAME_SZ+1]; /* interface name */ - int comm_port;/* Communication Port O or 1 */ - unsigned char usedby; /* Used by WANPIPE or API */ - unsigned long rxmb_off; /* Receive mail box */ - /* unsigned long flags_off; */ /* flags */ - unsigned long txbuf_off; /* -> current Tx buffer */ - unsigned long txbuf_base_off; /* -> first Tx buffer */ - unsigned long txbuf_last_off; /* -> last Tx buffer */ - unsigned long rxbuf_base_off; /* -> first Rx buffer */ - unsigned long rxbuf_last_off; /* -> last Rx buffer */ - unsigned long rx_base_off; /* S508 receive buffer base */ - unsigned long rx_top_off; /* S508 receive buffer end */ - void* tx_status; /* FIXME: Not used Tx status element */ - void* rx_status; /* FIXME: Not used Rx status element */ - unsigned short protocol_options; - unsigned state; /* state of the link */ - unsigned char api_status; - unsigned char update_call_count; - unsigned short api_options; /* for async config */ - unsigned short tx_bits_per_char; - unsigned short rx_bits_per_char; - unsigned short stop_bits; - unsigned short parity; - - unsigned long tq_working; - void *time_slot_map[MAX_E1_CHANNELS]; - struct tasklet_struct wanpipe_rx_task; - struct tasklet_struct wanpipe_tx_task; - unsigned char time_slots; - unsigned char tx_scratch_buf[MAX_E1_CHANNELS*50]; - unsigned short tx_scratch_buf_len; - atomic_t tx_interrupts; - unsigned short tx_chan_multiple; - unsigned int wait_for_buffers; - struct sdla *sw_card; - struct sk_buff_head rx_isr_queue; - struct sk_buff_head rx_isr_free_queue; - - /* FIXME: Move this out of the union */ - unsigned short timer_int_enabled; - unsigned long tx_idle_off; - unsigned long rx_discard_off; - - wan_bitstrm_conf_t cfg; - - unsigned char rbs_sig[32]; - unsigned char serial; - -} sdla_bitstrm_t; -#endif - -typedef struct -{ - char if_name[WAN_IFNAME_SZ+1]; /* interface name */ - int comm_port;/* Communication Port O or 1 */ - unsigned char usedby; /* Used by WANPIPE or API */ - unsigned char state; - /* unsigned long flags_off; */ /* flags */ - unsigned long rxmb_off; /* Receive mail box */ - unsigned long txbuf_off; /* -> current Tx buffer */ - unsigned long txbuf_base_off; /* -> first Tx buffer */ - unsigned long txbuf_last_off; /* -> last Tx buffer */ - unsigned long rxbuf_base_off; /* -> first Rx buffer */ - unsigned long rxbuf_last_off; /* -> last Rx buffer */ - unsigned long rx_base_off; /* S508 receive buffer base */ - unsigned long rx_top_off; /* S508 receive buffer end */ - void* tx_status; /* Tx status element */ - void* rx_status; /* Rx status element */ - - unsigned int line_cfg_opt; - unsigned int modem_cfg_opt; - unsigned int modem_status_timer; - unsigned int api_options; - unsigned int protocol_options; - unsigned int protocol_specification; - unsigned int stats_history_options; - unsigned int max_length_msu_sif; - unsigned int max_unacked_tx_msus; - unsigned int link_inactivity_timer; - unsigned int t1_timer; - unsigned int t2_timer; - unsigned int t3_timer; - unsigned int t4_timer_emergency; - unsigned int t4_timer_normal; - unsigned int t5_timer; - unsigned int t6_timer; - unsigned int t7_timer; - unsigned int t8_timer; - unsigned int n1; - unsigned int n2; - unsigned int tin; - unsigned int tie; - unsigned int suerm_error_threshold; - unsigned int suerm_number_octets; - unsigned int suerm_number_sus; - unsigned int sie_interval_timer; - unsigned int sio_interval_timer; - unsigned int sios_interval_timer; - unsigned int fisu_interval_timer; -} sdla_ss7_t; - -typedef struct -{ - char if_name[WAN_IFNAME_SZ+1]; /* interface name */ - int comm_port;/* Communication Port O or 1 */ - unsigned char usedby; /* Used by WANPIPE or API */ - unsigned char state; - /*FIXME: Move this out of the union */ - unsigned char comm_enabled; -} sdla_sdlc_t; - -typedef struct -{ - void *adapter; - unsigned char EncapMode; -} sdla_adsl_t; - -#if defined(__LINUX__) -typedef struct -{ - unsigned long rxmb_off; /* Receive mail box */ - /* unsigned long flags_off; */ /* flags */ - unsigned long txbuf_off; /* -> current Tx buffer */ - unsigned long txbuf_base_off; /* -> first Tx buffer */ - unsigned long txbuf_last_off; /* -> last Tx buffer */ - unsigned long rxbuf_base_off; /* -> first Rx buffer */ - unsigned long rxbuf_last_off; /* -> last Rx buffer */ - unsigned long rx_base_off; /* S508 receive buffer base */ - void* tx_status; /* Tx status element */ - void* rx_status; /* Rx status element */ - wan_tasklet_t wanpipe_rx_task; - struct sk_buff_head wp_rx_free_list; - struct sk_buff_head wp_rx_used_list; - struct sk_buff_head wp_rx_data_list; - struct sk_buff_head wp_tx_prot_list; - unsigned char state; - wan_timer_t atm_timer; - void *tx_dev; - void *trace_info; - void *atm_device; - wan_atm_conf_t atm_cfg; -} sdla_atm_t; -#endif - -#if defined(__LINUX__) -typedef struct -{ - void* rxmb; /* Receive mail box */ - void* flags; /* flags */ - void* tx_status; /* Tx status element */ - void* rx_status; /* Rx status element */ - void* txbuf; /* -> current Tx buffer */ - void* txbuf_base; /* -> first Tx buffer */ - void* txbuf_last; /* -> last Tx buffer */ - void* rxbuf_base; /* -> first Rx buffer */ - void* rxbuf_last; /* -> last Rx buffer */ - unsigned rx_base; /* S508 receive buffer base */ - wan_tasklet_t wanpipe_rx_task; - struct sk_buff_head wp_rx_free_list; - struct sk_buff_head wp_rx_used_list; - unsigned char state; -} sdla_pos_t; -#endif - -typedef struct -{ - unsigned long time_slot_map; - unsigned long logic_ch_map; - unsigned char num_of_time_slots; - unsigned char top_logic_ch; - unsigned long bar; - void *trace_info; - void *dev_to_ch_map[MAX_E1_CHANNELS]; - void *rx_dma_ptr; - void *tx_dma_ptr; - wan_xilinx_conf_t cfg; - unsigned long dma_mtu_off; - unsigned short dma_mtu; - unsigned char state_change_exit_isr; - unsigned long active_ch_map; - unsigned long fifo_addr_map; - wan_timer_t led_timer; - unsigned char tdmv_sync; - unsigned int chip_cfg_status; - wan_taskq_t port_task; - unsigned int port_task_cmd; - unsigned long wdt_rx_cnt; - unsigned long wdt_tx_cnt; - unsigned int security_id; - unsigned int security_cnt; - unsigned char firm_ver; - unsigned char firm_id; - unsigned int chip_security_cnt; - unsigned long rx_timeout,gtimeout; - unsigned int comm_enabled; - unsigned int lcfg_reg; - unsigned int tdmv_master_if_up; - unsigned int tdmv_mtu; - unsigned int tdmv_zaptel_cfg; - netskb_t *tdmv_api_rx; - netskb_t *tdmv_api_tx; - wan_skb_queue_t tdmv_api_tx_list; - - unsigned int tdmv_dchan_cfg_on_master; - unsigned int tdmv_chan; - unsigned int tdmv_dchan; - unsigned int tdmv_dchan_active_ch; - void *tdmv_chan_ptr; - - unsigned char tdmv_hw_dtmf; - - unsigned char led_ctrl; - unsigned int tdm_intr_status; - void *bar_virt; - unsigned short tdm_rx_dma_toggle; - unsigned short tdm_tx_dma_toggle; - unsigned int tdm_logic_ch_map; - - unsigned long sec_chk_cnt; - - wan_skb_queue_t rtp_tap_list; -} sdla_xilinx_t; - -typedef struct -{ - unsigned long current_offset; - unsigned long total_len; - unsigned long total_num; - unsigned long status; -} sdla_debug_t; - -/* Adapter Data Space. - * This structure is needed because we handle multiple cards, otherwise - * static data would do it. - */ -typedef struct sdla -{ - char devname[WAN_DRVNAME_SZ+1]; /* card name */ - void* hw; /* hardware configuration */ - wan_device_t wandev; /* WAN device data space */ - - unsigned open_cnt; /* number of open interfaces */ - unsigned long state_tick; /* link state timestamp */ - unsigned intr_mode; /* Type of Interrupt Mode */ - unsigned long in_isr; /* interrupt-in-service flag */ - char buff_int_mode_unbusy; /* flag for carrying out dev_tint */ - char dlci_int_mode_unbusy; /* flag for carrying out dev_tint */ - unsigned long configured; /* flag for previous configurations */ - - unsigned short irq_dis_if_send_count; /* Disabling irqs in if_send*/ - unsigned short irq_dis_poll_count; /* Disabling irqs in poll routine*/ - unsigned short force_enable_irq; - char TracingEnabled; /* flag for enabling trace */ - global_stats_t statistics; /* global statistics */ - unsigned long mbox_off; /* -> mailbox offset */ - wan_mbox_t wan_mbox; /* mailbox structure */ - unsigned long rxmb_off; /* -> receive mailbox */ - wan_mbox_t wan_rxmb; /* rx mailbox structure */ - unsigned long flags_off; /* -> adapter status flags */ - unsigned long fe_status_off; /* FE status structure offset */ -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - unsigned char rx_data[MAX_PACKET_SIZE]; /* Rx buffer */ - unsigned int rx_len; /* Rx data len */ - unsigned char tx_data[MAX_PACKET_SIZE]; /* Tx buffer */ - unsigned int tx_len; /* Tx data len */ -#endif - WAN_IRQ_RETVAL (*isr)(struct sdla* card); /* interrupt service routine */ - void (*poll)(struct sdla* card); /* polling routine */ - int (*exec)(struct sdla* card, void* u_cmd, void* u_data); - /* Used by the listen() system call */ -#if defined(__LINUX__) - /* Wanpipe Socket Interface */ - int (*func) (netskb_t*, struct sock *); - struct sock *sk; -#endif - - /* Shutdown function */ - void (*disable_comm) (struct sdla *card); - - /* Secondary Port Device: Piggibacking */ - struct sdla *next; - struct sdla *list; - -#if defined(__LINUX__) - /* TTY driver variables */ - unsigned char tty_opt; - struct tty_struct *tty; - unsigned int tty_minor; - unsigned int tty_open; - unsigned char *tty_buf; - struct sk_buff_head tty_rx_empty; - struct sk_buff_head tty_rx_full; - wan_taskq_t tty_task_queue; -#endif - union - { -#if defined(__LINUX__) - sdla_x25_t x; - sdla_bitstrm_t b; - sdla_atm_t atm; - sdla_pos_t pos; -#endif - sdla_fr_t f; - sdla_ppp_t p; - sdla_chdlc_t c; - sdla_hdlc_t h; - sdla_ss7_t s; - sdla_sdlc_t sdlc; - sdla_adsl_t adsl; - sdla_xilinx_t aft; - sdla_debug_t debug; - } u; - unsigned char irq_equalize; - - /*????????????????*/ - /*Should be in wandev */ - unsigned int type; /* card type */ - unsigned int adptr_type; /* adapter type */ - unsigned char adptr_subtype; /* adapter subtype */ - wan_tasklet_t debug_task; - wan_timer_t debug_timer; - unsigned long debug_running; - unsigned char wan_debugging_state; /* WAN debugging state */ - int wan_debug_last_msg; /* Last WAN debug message */ - int (*wan_debugging)(struct sdla*);/* link debugging routine */ - unsigned long (*get_crc_frames)(struct sdla*);/* get no of CRC frames */ - unsigned long (*get_abort_frames)(struct sdla*);/* get no of Abort frames */ - unsigned long (*get_tx_underun_frames)(struct sdla*);/* get no of TX underun frames */ - unsigned short timer_int_enabled; - unsigned char backup; - unsigned long comm_enabled; - unsigned long update_comms_stats; - - sdla_fe_t fe; /* front end structures */ - - unsigned int rCount; - - /* Wanpipe Socket Interface */ - int (*get_snmp_data)(struct sdla*, netdevice_t*, void*); - - unsigned long intr_perm_off; - unsigned long intr_type_off; - - /* Hardware interface function pointers */ - sdlahw_iface_t hw_iface; - - int (*bind_api_to_svc)(struct sdla*, void *sk_id); - - unsigned long spurious; - - unsigned long intcount; - - wan_tdmv_conf_t tdmv_conf; -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) - wan_tdmv_iface_t tdmv_iface; - wan_tdmv_t wan_tdmv; -#endif - - wan_hwec_conf_t hwec_conf; - wan_rtp_conf_t rtp_conf; - -#if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - struct sdla* same_card; -#endif - - -#if defined(__FreeBSD__) -# if defined(NETGRAPH) - int running; /* something is attached so we are running */ - /* ---netgraph bits --- */ - int datahooks; /* number of data hooks attached */ - node_p node; /* netgraph node */ - hook_p hook; /* data hook */ - hook_p debug_hook; -# if defined(ALTQ) - struct ifaltq xmitq_hipri; /* hi-priority transmit queue */ - struct ifaltq xmitq; /* transmit queue */ -# else - struct ifqueue xmitq_hipri; /* hi-priority transmit queue */ - struct ifqueue xmitq; /* transmit queue */ -# endif - int flags; /* state */ -# define WAN_RUNNING 0x01 /* board is active */ -# define WAN_OACTIVE 0x02 /* output is active */ - int out_dog; /* watchdog cycles output count-down */ -# if ( __FreeBSD__ >= 3 ) - struct callout_handle handle; /* timeout(9) handle */ -# endif - u_long lastinbytes, lastoutbytes; /* a second ago */ - u_long inrate, outrate; /* highest rate seen */ - u_long inlast; /* last input N secs ago */ - u_long out_deficit; /* output since last input */ - void (*wan_down)(struct sdla*); - int (*wan_up)(struct sdla*); - void (*wan_start)(struct sdla*); -# endif /* NETGRAPH */ - /* per card statistics */ - u_long inbytes, outbytes; /* stats */ - u_long oerrors, ierrors; - u_long opackets, ipackets; -#endif /* __FreeBSD__ */ - - /* This value is used for detecting TDM Voice - * rsync timeout, it should be long */ - unsigned long rsync_timeout; -} sdla_t; - -/****** Public Functions ****************************************************/ - -void wanpipe_open (sdla_t* card); /* wpmain.c */ -void wanpipe_close (sdla_t* card); /* wpmain.c */ - -int wpx_init (sdla_t* card, wandev_conf_t* conf); /* wpx.c */ -int wpf_init (sdla_t* card, wandev_conf_t* conf); /* wpf.c */ -int wpp_init (sdla_t* card, wandev_conf_t* conf); /* wpp.c */ -int wpc_init (sdla_t* card, wandev_conf_t* conf); /* Cisco HDLC */ -int wp_asyhdlc_init (sdla_t* card, wandev_conf_t* conf); /* Async HDLC */ -int wpbsc_init (sdla_t* card, wandev_conf_t* conf); /* BSC streaming */ -int wph_init(sdla_t* card, wandev_conf_t* conf); /* HDLC support */ -int wpft1_init (sdla_t* card, wandev_conf_t* conf); /* FT1 Config support */ -int wp_mprot_init(sdla_t* card, wandev_conf_t* conf); /* Sync PPP on top of RAW CHDLC */ -int wpbit_init (sdla_t* card, wandev_conf_t* conf); /* Bit Stream driver */ -int wpedu_init(sdla_t* card, wandev_conf_t* conf); /* Educational driver */ -int wpss7_init(sdla_t* card, wandev_conf_t* conf); /* SS7 driver */ -int wp_bscstrm_init(sdla_t* card, wandev_conf_t* conf); /* BiSync Streaming Nasdaq */ -int wp_hdlc_fr_init(sdla_t* card, wandev_conf_t* conf); /* Frame Relay over HDLC RAW Streaming */ -int wp_adsl_init(sdla_t* card, wandev_conf_t* conf); /* ADSL Driver */ -int wp_sdlc_init(sdla_t* card, wandev_conf_t* conf); /* SDLC Driver */ -int wp_atm_init(sdla_t* card, wandev_conf_t* conf); /* ATM Driver */ -int wp_pos_init(sdla_t* card, wandev_conf_t* conf); /* POS Driver */ -int wp_xilinx_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */ -int wp_aft_te1_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */ -int wp_aft_56k_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */ -int wp_aft_analog_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */ -int wp_adccp_init(sdla_t* card, wandev_conf_t* conf); -int wp_xilinx_if_init(sdla_t* card, netdevice_t* dev); -int wp_aft_te3_init(sdla_t* card, wandev_conf_t* conf); /* AFT TE3 Hardware Support */ -int wp_aft_te1_ss7_init(sdla_t* card, wandev_conf_t* conf); /* AFT TE1 SS7 Hardware Support */ -int aft_global_hw_device_init(void); - -int wanpipe_globals_util_init(void); /* Initialize All Global Tables */ - -#if defined(__LINUX__) -extern int wanpipe_queue_tq (wan_taskq_t *); -extern int wanpipe_mark_bh (void); -extern int change_dev_flags (netdevice_t *, unsigned); -extern unsigned long get_ip_address (netdevice_t *dev, int option); -extern void add_gateway(sdla_t *, netdevice_t *); - -#if 0 -extern void fastcall wp_tasklet_hi_schedule_per_cpu(struct tasklet_struct *t, int cpu_no); -extern void wp_tasklet_per_cpu_init (void); -#endif - -//FIXME: Take it out -//extern int wan_reply_udp( unsigned char *data, unsigned int mbox_len, int trace_opt); -//extern int wan_udp_pkt_type(sdla_t* card,unsigned char *data); - -extern int wan_ip_udp_setup(void* card_id, - wan_rtp_conf_t *rtp_conf, - u32 chan, - unsigned char *data, unsigned int mbox_len); - -extern int wanpipe_sdlc_unregister(netdevice_t *dev); -extern int wanpipe_sdlc_register(netdevice_t *dev, void *wp_sdlc_reg); -//ALEX_TODAY extern int check_conf_hw_mismatch(sdla_t *card, unsigned char media); -#endif - -void adsl_vcivpi_update(sdla_t* card, wandev_conf_t* conf); - -#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG -extern struct wanpipe_lapb_register_struct lapb_protocol; -#endif - -int wan_snmp_data(sdla_t* card, netdevice_t* dev, int cmd, struct ifreq* ifr); - -int wan_capture_trace_packet(sdla_t *card, wan_trace_t* trace_info, netskb_t *skb, char direction); -int wan_capture_trace_packet_offset(sdla_t *card, wan_trace_t* trace_info, netskb_t *skb, int off,char direction); - -#if defined(__LINUX__) -int wan_verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode); -int wan_memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); -int wan_memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); -#endif - -/* LIP ATM prototypes */ -int init_atm_idle_buffer(unsigned char *buff, int buff_len, char *if_name, char hardware_flip); -int atm_add_data_to_skb(void* skb, void *data, int data_len, char *if_name); -int atm_pad_idle_cells_in_tx_skb(void *skb, void *tx_idle_skb, char *if_name); -void *atm_tx_skb_dequeue(void* wp_tx_pending_list, void *tx_idle_skb, char *if_name); - - -#if defined(__FreeBSD__) && defined(NETGRAPH) -int wan_ng_init(sdla_t*); -int wan_ng_remove(sdla_t*); -#endif - -#endif /* __KERNEL__ */ -#endif /* _WANPIPE_H */ diff --git a/patches/kdrivers/include/wanpipe_abstr.h b/patches/kdrivers/include/wanpipe_abstr.h index ee02e5b..47f8988 100644 --- a/patches/kdrivers/include/wanpipe_abstr.h +++ b/patches/kdrivers/include/wanpipe_abstr.h @@ -1,13 +1,18 @@ /***************************************************************************** -* wanpipe_abstr.c WANPIPE(tm) Kernel Abstraction Layer. +* wanpipe_abstr.h WANPIPE(tm) Kernel Abstraction Layer. * * Authors: Nenad Corbic -* Alex Feldman +* David Rokhvarg * * Copyright: (c) 2003 Sangoma Technologies Inc. * * ============================================================================ * Jan 20, 2003 Nenad Corbic Initial version +* +* Nov 27, 2007 David Rokhvarg Implemented functions/definitions for +* Sangoma MS Windows Driver and API. +* * ============================================================================ * 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 @@ -19,12 +24,25 @@ #ifndef _WANPIPE_ABSTR_H #define _WANPIPE_ABSTR_H +#if defined(__LINUX__) +# include +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# include +#elif defined(__WINDOWS__) +# include +#endif + extern unsigned char* wpabs_skb_data(void* skb); extern unsigned char* wpabs_skb_tail(void* skb); extern int wpabs_skb_len(void* skb); extern void* wpabs_skb_alloc(unsigned int len); extern void wpabs_skb_free(void* skb); -extern void wpabs_skb_copyback(void* skb, int off, int len, unsigned long cp); +#if defined(__WINDOWS__) || defined(__FreeBSD__) +extern void wpabs_skb_copyback(void*, int, int, caddr_t); +#else +extern void wpabs_skb_copyback(void*, int, int, unsigned long); +#endif + extern void wpabs_skb_copyback_user(void* skb, int off, int len, unsigned long cp); extern unsigned char* wpabs_skb_pull(void* skb, int len); extern unsigned char* wpabs_skb_put(void* skb, int len); @@ -64,7 +82,13 @@ extern int wpabs_netif_dev_up(void*); extern void wpabs_netif_wake_queue(void* dev); extern void* wpabs_timer_alloc(void); -extern void wpabs_init_timer(void*, void*, unsigned long); +extern void wpabs_init_timer(void*, void*, +#if defined(__WINDOWS__) + wan_timer_arg_t); +#else + unsigned long); +#endif + extern void wpabs_del_timer(void*); extern void wpabs_add_timer(void*,unsigned long); @@ -86,7 +110,7 @@ extern void* wpabs_spinlock_alloc(void); extern void wpabs_spinlock_free(void*); extern void wpabs_spin_lock_irqsave(void*,unsigned long*); extern void wpabs_spin_unlock_irqrestore(void*,unsigned long*); -extern void wpabs_spin_lock_init(void*); +extern void wpabs_spin_lock_init(void*, char*); extern void wpabs_rwlock_init (void*); extern void wpabs_read_rw_lock(void*); @@ -94,7 +118,6 @@ extern void wpabs_read_rw_unlock(void*); extern void wpabs_write_rw_lock_irq(void*,unsigned long*); extern void wpabs_write_rw_unlock_irq(void*,unsigned long*); - extern void wpabs_debug_event(const char * fmt, ...); extern void wpabs_debug_init(const char * fmt, ...); extern void wpabs_debug_cfg(const char * fmt, ...); @@ -109,7 +132,7 @@ extern int wpabs_test_bit(int bit, void *ptr); extern int wpabs_test_and_set_bit(int bit, void *ptr); extern int wpabs_clear_bit(int bit, void *ptr); -extern unsigned long wpabs_get_systemticks(void); +extern wan_ticks_t wpabs_get_systemticks(void); extern unsigned long wpabs_get_hz(void); extern unsigned short wpabs_htons(unsigned short data); extern unsigned short wpabs_ntohs(unsigned short); @@ -176,9 +199,6 @@ extern int wpabs_dma_free(void*, void*); extern unsigned long* wpabs_dma_get_vaddr(void*, void*); extern unsigned long wpabs_dma_get_paddr(void*, void*); -#define TRC_INCOMING_FRM 0x00 -#define TRC_OUTGOING_FRM 0x01 - extern int wpabs_trace_queue_len(void *trace_ptr); extern int wpabs_tracing_enabled(void*); extern int wpabs_trace_enqueue(void*, void*); @@ -190,16 +210,4 @@ extern unsigned char wpabs_get_last_trace_direction(void *trace_ptr); extern int wpabs_bpf_report(void *dev, void *skb, int,int); -#pragma pack(1) -typedef struct { - unsigned char status; - unsigned char data_avail; - unsigned short real_length; - unsigned short time_stamp; - unsigned long sec; - unsigned long usec; - unsigned char data[0]; -} wan_trace_pkt_t; -#pragma pack() - #endif diff --git a/patches/kdrivers/include/wanpipe_abstr_types.h b/patches/kdrivers/include/wanpipe_abstr_types.h new file mode 100644 index 0000000..797800f --- /dev/null +++ b/patches/kdrivers/include/wanpipe_abstr_types.h @@ -0,0 +1,36 @@ +/************************************************************************* +* wanpipe_abstr_types.h WANPIPE(tm) * +* * +* Wanpipe Kernel Abstraction type definitions * +* * +* * +* Author: Alex Feldman * +*========================================================================* +* Jan 24, 2008 Alex Feldman Initial version * +*************************************************************************/ + +#ifndef __WANPIPE_ABSTR_TYPES_H +# define __WANPIPE_ABSTR_TYPES_H + + + +#if defined(__FreeBSD__) +/******************* F R E E B S D ******************************/ +typedef int wan_ticks_t; +#elif defined(__OpenBSD__) +/******************* O P E N B S D ******************************/ +typedef int wan_ticks_t; +#elif defined(__NetBSD__) +/******************* N E T B S D ******************************/ +typedef int wan_ticks_t; +#elif defined(__LINUX__) +/*********************** L I N U X ******************************/ +typedef unsigned long wan_ticks_t; +#elif defined(__WINDOWS__) +/******************* W I N D O W S ******************************/ +typedef unsigned long wan_ticks_t; +#endif + + + +#endif /* __WANPIPE_ABSTR_TYPES_H */ diff --git a/patches/kdrivers/include/wanpipe_cfg.h b/patches/kdrivers/include/wanpipe_cfg.h index 8f9b833..358fcc6 100644 --- a/patches/kdrivers/include/wanpipe_cfg.h +++ b/patches/kdrivers/include/wanpipe_cfg.h @@ -1,19 +1,31 @@ #ifndef _WANPIPE_CFG_H_ #define _WANPIPE_CFG_H_ - #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) # include # include # include # include +# include +# include # include #elif defined(__LINUX__) # include # include # include # include +# include +# include # include +#elif defined(__WINDOWS__) +# include +# include +# include +# include +# include +# include +# include +# include #else # error "No OS Defined!" #endif @@ -23,12 +35,46 @@ #define LAN_INTERFACE 1 /* Miscellaneous */ +#if defined(__WINDOWS__) +#define WAN_IFNAME_SZ IFNAMSIZ/* max length of the interface name */ +#define WAN_DRVNAME_SZ IFNAMSIZ/* max length of the link driver name */ +#define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */ + +#define WAN_AUTHNAMELEN 64 +/* +This is the maximum number of interfaces that any protocol may have. +For example: a number of DLCIs. +*/ +#define MAX_NUMBER_OF_PROTOCOL_INTERFACES (1007+16) + +/********** compilation flags ************/ +/* compile protocols in the LIP layer */ +#define CONFIG_PRODUCT_WANPIPE_FR +#define CONFIG_PRODUCT_WANPIPE_CHDLC +#define CONFIG_PRODUCT_WANPIPE_PPP +#define CONFIG_PRODUCT_WANPIPE_LAPB + +/* compile AFT T1/E1 code */ +#define CONFIG_PRODUCT_WANPIPE_AFT +/* compile AFT A200 Analog code */ +#define CONFIG_PRODUCT_WANPIPE_AFT_RM +/* compile HWEC code */ +#define CONFIG_WANPIPE_HWEC +/* compile ADSL code */ +#define CONFIG_PRODUCT_WANPIPE_ADSL +/* compile TDM API code */ +#define AFT_TDM_API_SUPPORT +/********** end of compilation flags ************/ + + +#else #define WAN_IFNAME_SZ 15 /* max length of the interface name */ #define WAN_DRVNAME_SZ 15 /* max length of the link driver name */ #define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */ #define USED_BY_FIELD 30 /* max length of the used by field */ #define WAN_AUTHNAMELEN 64 +#endif /* Defines for UDP PACKET TYPE */ #define UDP_PTPIPE_TYPE 0x01 @@ -77,6 +123,7 @@ #define WANOPT_AFT_ISDN 11 #define WANOPT_AFT_56K 12 #define WANOPT_AFT101 13 +#define WANOPT_AFT_SERIAL 14 /* * Configuration options defines. @@ -87,6 +134,8 @@ #define WANOPT_NO 0 #define WANOPT_YES 1 +#define WANOPT_SIM 2 + /* intercace options */ #define WANOPT_RS232 0 #define WANOPT_V35 1 @@ -204,6 +253,10 @@ #define WANOPT_FE_OSC_CLOCK 0x00 #define WANOPT_FE_LINE_CLOCK 0x01 +#define WANOPT_NETWORK_SYNC_OUT 0x00 +#define WANOPT_NETWORK_SYNC_IN 0x01 + + enum wan_codec_format{ WP_NONE, @@ -224,10 +277,17 @@ enum { TDM_VOICE, TDM_VOICE_DCHAN, TDM_VOICE_API, +#if defined(__WINDOWS__) + /* has to be here to keep backward compatibility! */ + LIB_SANGOMA_API, + TDM_VOICE_API_V2, +#endif TDM_API, + WP_NETGRAPH, TRUNK }; + /* POS protocols */ enum { IBM4680, @@ -315,6 +375,7 @@ enum { (card_type == WANOPT_AFT_ANALOG) ? "A200/400" : \ (card_type == WANOPT_AFT_ISDN) ? "A500" : \ (card_type == WANOPT_AFT_56K) ? "A056" : \ + (card_type == WANOPT_AFT_SERIAL) ? "A14x" : \ "Unknown" #define COMPORT_DECODE(port) (port == WANOPT_PRI) ? "PRI" : "SEC" @@ -354,6 +415,8 @@ enum { #define FR_STATION_DECODE(station) \ (station == WANOPT_CPE) ? "CPE" : "Node" +#define DEFAULT_TE_RX_SLEVEL 120 + typedef char devname_t[WAN_DRVNAME_SZ+1]; typedef enum { @@ -415,6 +478,12 @@ typedef struct wan_adsl_conf unsigned short mtu; unsigned char atm_watchdog; + /* Number of cells received on each interrupt. Recommended values: 5 - 40. + Higher values for higher line speeds. + + */ + unsigned short RxCellCount; + }wan_adsl_conf_t; @@ -521,6 +590,12 @@ typedef struct wan_x25_conf /*---------------------------------------------------------------------------- * Frame relay specific link-level configuration. */ +#if defined(__WINDOWS__) +# define DLCI_LIST_LEN MAX_NUMBER_OF_PROTOCOL_INTERFACES +#else +# define DLCI_LIST_LEN 100 +#endif + typedef struct wan_fr_conf { unsigned int signalling; /* local in-channel signalling type */ @@ -530,11 +605,14 @@ typedef struct wan_fr_conf unsigned int n392; /* error threshold counter */ unsigned int n393; /* monitored events counter */ unsigned int dlci_num; /* number of DLCs (access node) */ - unsigned int dlci[100]; /* List of all DLCIs */ + unsigned int dlci[DLCI_LIST_LEN];/* List of all DLCIs */ unsigned char issue_fs_on_startup; unsigned char station; /* Node or CPE */ unsigned int eek_cfg; /* EEK Request Reply Mode */ unsigned int eek_timer; /* EEK Request Reply Timer */ +#if defined(__WINDOWS__) + unsigned char auto_dlci; /* 1 - yes, 0 - no */ +#endif } wan_fr_conf_t; /* used by wanpipemon to get DLCI status */ @@ -549,7 +627,6 @@ typedef struct wan_lip_fr_dlci unsigned char type; } wan_fr_dlci_t; - typedef struct wan_rtp_conf { unsigned int rtp_ip; @@ -561,31 +638,20 @@ typedef struct wan_rtp_conf unsigned char rtp_local_mac[WAN_IFNAME_SZ+1]; }wan_rtp_conf_t; - typedef struct wan_xilinx_conf { unsigned short dma_per_ch; /* DMA buffers per logic channel */ unsigned short mru; /* MRU of transparent channels */ unsigned int rbs; /* Robbit signalling support */ unsigned int data_mux_map; /* Data mux map */ - //unsigned int tdmv_span_no; - //unsigned int tdmv_dchan; /* hwHDLC: PRI SIG */ - //unsigned char tdmv_hw_dtmf; /* TDMV Enable/Disable HW DTMF */ unsigned int rx_crc_bytes; -// unsigned int ec_clk_src; /* Octasic Clock Source Port */ -// unsigned int ec_persist_disable; /* HW EC Persist */ - - -#if 0 - unsigned int rtp_ip; - unsigned short rtp_port; - unsigned short rtp_sample; - char rtp_devname[WAN_IFNAME_SZ+1]; +#if defined(__WINDOWS__) + unsigned short num_of_ch; /* Number of logical channels */ + unsigned int tdmv_span_no; + unsigned char tdmv_hwec; + unsigned int fe_ref_clock; + unsigned int tdmv_dchan; #endif - unsigned int err_throttle_period; - unsigned int err_throttle_timeout; - - } wan_xilinx_conf_t; typedef struct wan_xilinx_conf_if @@ -601,10 +667,14 @@ typedef struct wan_xilinx_conf_if unsigned char ss7_mode; unsigned char ss7_lssu_size; unsigned char tdmv_master_if; -// unsigned char tdmv_hwec; /* Enable/Disable HW EC */ - unsigned char rbs_cas_idle; /* Initial RBS/CAS value */ -// unsigned char hwec_dtmf; /* Enable/Disable HW DTMF */ +/* unsigned char tdmv_hwec; */ /* Enable/Disable HW EC */ + unsigned char rbs_cas_idle; /* Initial RBS/CAS value */ +/* unsigned char hwec_dtmf; */ /* Enable/Disable HW DTMF */ /* unsigned char tdmv_hwec_map[50];*/ /* Enable/Disable HW EC */ + unsigned char hdlc_repeat; +#if defined(__WINDOWS__) + unsigned char tdmv_hwec; +#endif }wan_xilinx_conf_if_t; @@ -796,7 +866,11 @@ typedef struct sppp_parms_struct { unsigned char ppp_prot; /* CHDLC */ +#if defined(__WINDOWS__) + unsigned int sppp_max_keepalive_count; +#else unsigned int keepalive_err_margin; +#endif }wan_sppp_if_conf_t; @@ -912,6 +986,22 @@ typedef struct wan_hwec_conf_ } wan_hwec_conf_t; +#define MAX_PARAM_LEN 50 +#define MAX_VALUE_LEN 50 +typedef struct wan_custom_param_ +{ + char name[MAX_PARAM_LEN+1]; + char sValue[MAX_VALUE_LEN+1]; + unsigned int dValue; +} wan_custom_param_t; + +typedef struct wan_custom_conf_ +{ + unsigned int param_no; + wan_custom_param_t *params; +} wan_custom_conf_t; + + /*---------------------------------------------------------------------------- * WAN device configuration. Passed to ROUTER_SETUP IOCTL. */ @@ -934,7 +1024,7 @@ typedef struct wandev_conf unsigned udp_port; /* UDP port for management */ unsigned char ttl; /* Time To Live for UDP security */ unsigned char ft1; /* FT1 Configurator Option */ - char interface; /* RS-232/V.35, etc. */ + char electrical_interface; /* RS-232/V.35, etc. */ char clocking; /* external/internal */ char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */ char connection; /* permanent/switched/on-demand */ @@ -951,9 +1041,11 @@ typedef struct wandev_conf /****** arbitrary data ***************/ unsigned data_size; /* data buffer size */ void* data; /* data buffer, e.g. firmware */ - +#if defined(__WINDOWS__) + struct{ +#else union{ /****** protocol-specific ************/ - +#endif wan_x25_conf_t x25; /* X.25 configuration */ wan_ppp_conf_t ppp; /* PPP configuration */ wan_fr_conf_t fr; /* frame relay configuration */ @@ -969,23 +1061,21 @@ typedef struct wandev_conf } u; /* No new variables are allowed above */ - - char card_type; /* Supported Sangoma Card type */ - unsigned pci_bus_no; /* S514 PCI bus number */ + unsigned int card_type; /* Supported Sangoma Card type */ + unsigned int pci_bus_no; /* S514 PCI bus number */ sdla_fe_cfg_t fe_cfg; /* Front end configurations */ - wan_tdmv_conf_t tdmv_conf; - wan_hwec_conf_t hwec_conf; - wan_rtp_conf_t rtp_conf; - + wan_tdmv_conf_t tdmv_conf; + wan_hwec_conf_t hwec_conf; + wan_rtp_conf_t rtp_conf; + wan_custom_conf_t oct_conf; unsigned char line_idle; /* IDLE FLAG/ IDLE MARK */ unsigned char ignore_front_end_status; unsigned int max_trace_queue; unsigned int max_rx_queue; - #if 0 /* Bitstreaming options */ unsigned int sync_options; @@ -998,7 +1088,10 @@ typedef struct wandev_conf unsigned int max_trace_queue; unsigned int max_rx_queue; #endif - + +#if defined(__WINDOWS__) + u16 card_sub_type; /* "S" 5141/5142/5143 or "A" 101/102/104/108/200/056 */ +#endif/* __WINDOWS__ */ } wandev_conf_t; /* 'config_id' definitions */ @@ -1030,15 +1123,17 @@ typedef struct wandev_conf #define WANCONFIG_LAPB 125 /* LIP LAPB Protocol Support */ #define WANCONFIG_XDLC 126 /* LIP XDLC Protocol Support */ #define WANCONFIG_TTY 127 /* LIP TTY Support */ -#define WANCONFIG_AFT_TE1 128 /* AFT Quad Hardware Support */ +#define WANCONFIG_AFT_TE1 128 /* AFT A1/2/4/8 Hardware Support */ #define WANCONFIG_XMTP2 129 /* LIP XMTP2 Protocol Support */ #define WANCONFIG_ASYHDLC 130 /* S514 ASY HDLC API Support */ #define WANCONFIG_LIP_ATM 131 /* ATM in LIP layer */ #define WANCONFIG_AFT_ANALOG 132 /* AFT Analog Driver */ #define WANCONFIG_ZAP 133 /* Used in wanpipemon when working with Zaptel driver */ #define WANCONFIG_LAPD 134 /* LIP LAPD Q921 Protocol Support */ -#define WANCONFIG_LIP_KATM 135 /* Kernel ATM Stack Support */ +#define WANCONFIG_LIP_KATM 135 /* Kernel ATM Stack Support */ #define WANCONFIG_AFT_56K 136 /* AFT 56K Support */ +#define WANCONFIG_AFT_ISDN_BRI 137 /* AFT ISDN BRI Driver */ +#define WANCONFIG_AFT_SERIAL 138 /* AFT Serial V32/RS232 Driver */ /*FIXME: This should be taken out, I just //used it so I don't break the apps that are @@ -1076,7 +1171,12 @@ typedef struct wandev_conf (protocol == WANCONFIG_GENERIC) ? "WANPIPE Generic driver": \ (protocol == WANCONFIG_MPCHDLC) ? "CHDLC": \ (protocol == WANCONFIG_ZAP) ? "ZAP": \ - (protocol == WANCONFIG_TTY) ? "TTY": "Unknown Protocol" + (protocol == WANCONFIG_AFT_56K) ? "AFT 56K": \ + (protocol == WANCONFIG_AFT_ISDN_BRI) ? "ISDN BRI": \ + (protocol == WANCONFIG_AFT_SERIAL) ? "Serial V35/RS232": \ + (protocol == WANCONFIG_AFT_ANALOG) ? "Analog FXO/FXS": \ + (protocol == WANCONFIG_AFT_TE1) ? "AFT A1/2/4/8" : \ + (protocol == WANCONFIG_TTY) ? "TTY" : "Unknown Protocol" typedef struct wan_tdmv_if_conf @@ -1140,7 +1240,12 @@ typedef struct wanif_conf unsigned keepalive_err_margin; /* keepalive_error_tolerance */ unsigned slarp_timer; /* SLARP request timer */ unsigned char ttl; /* Time To Live for UDP security */ +#if defined(__WINDOWS__) + /* 'interface' is reserved for C++ compiler!! */ + char electrical_interface; /* RS-232/V.35, etc. */ +#else char interface; /* RS-232/V.35, etc. */ +#endif char clocking; /* external/internal */ unsigned bps; /* data transfer rate */ unsigned mtu; /* maximum transmit unit size */ @@ -1191,13 +1296,19 @@ typedef struct wanif_conf wan_tdmv_if_conf_t tdmv; wan_hwec_if_conf_t hwec; - //unsigned char tdmv_echo_off; /* TDMV echo disable */ - //unsigned char tdmv_codec; /* TDMV codec */ + wan_custom_conf_t ec_conf; + /*unsigned char tdmv_echo_off; */ /* TDMV echo disable */ + /*unsigned char tdmv_codec; */ /* TDMV codec */ unsigned char single_tx_buf; /* Used in low latency applications */ unsigned char lip_prot; +#if defined(__WINDOWS__) + DEVICE_CONFIGURATION device_cfg; + struct { +#else union { +#endif wan_atm_conf_if_t atm; /* per interface configuration */ wan_x25_if_conf_t x25; wan_lapb_if_conf_t lapb; @@ -1207,7 +1318,11 @@ typedef struct wanif_conf wan_xilinx_conf_if_t aft; wan_xdlc_conf_t xdlc; wan_sppp_if_conf_t ppp; +#if defined(__WINDOWS__) + wan_sppp_if_conf_t chdlc; +#else wan_chdlc_conf_t chdlc; +#endif }u; } wanif_conf_t; @@ -1297,4 +1412,97 @@ enum { WPLIP_LAPD }; +#define TRC_INCOMING_FRM 0x00 +#define TRC_OUTGOING_FRM 0x01 +#pragma pack(1) +typedef struct { + unsigned char status; + unsigned char data_avail; + unsigned short real_length; + unsigned short time_stamp; + unsigned long sec; + unsigned long usec; + unsigned char data[0]; +} wan_trace_pkt_t; +#pragma pack() + +#if defined(__WINDOWS__) + +#define ACU_MTU 2048 +#define MODE_OPTION_HDLC "HDLC" +#define MODE_OPTION_BITSTRM "BitStream" + +#define SDLA_DECODE_USEDBY_FIELD(usedby) \ + (usedby == WANPIPE) ? "WANPIPE" : \ + (usedby == API) ? "API" : \ + (usedby == BRIDGE) ? "BRIDGE" : \ + (usedby == BRIDGE_NODE) ? "BRIDGE_NODE" : \ + (usedby == SWITCH) ? "SWITCH" : \ + (usedby == STACK) ? "STACK" : \ + (usedby == TDM_VOICE_API) ? "TDM VOICE API" : \ + (usedby == TDM_VOICE_DCHAN) ? "TDM VOICE DCHAN" : \ + (usedby == LIB_SANGOMA_API) ? "LIB SANGOMA API" : \ + (usedby == TDM_VOICE_API_V2) ? "TDM VOICE API V2" : \ + (usedby == ANNEXG) ? "ANNEXG" : "Unknown" + +#define CARD_WANOPT_DECODE(cardtype) \ + ((cardtype == WANOPT_S50X) ? "WANOPT_S50X" : \ + (cardtype == WANOPT_S51X) ? "WANOPT_S51X" : \ + (cardtype == WANOPT_ADSL) ? "WANOPT_ADSL" : \ + (cardtype == WANOPT_AFT) ? "WANOPT_AFT": \ + (cardtype == WANOPT_AFT102) ? "WANOPT_AFT102": \ + (cardtype == WANOPT_AFT104) ? "WANOPT_AFT104": \ + (cardtype == WANOPT_AFT108) ? "WANOPT_AFT108": \ + (cardtype == WANOPT_AFT_ANALOG) ? "WANOPT_AFT_ANALOG": \ + (cardtype == WANOPT_AFT_56K) ? "WANOPT_AFT_56K": \ + (cardtype == WANOPT_AFT300) ? "WANOPT_AFT300": "Invalid card") + +#if 1 + +typedef struct _buffer_settings{ + /* Number of received blocks of data before Receive event is indicated to API caller. */ + u16 buffer_multiplier_factor; + + /* Number of buffers for receiving or transmitting data on an API interface. */ + /* EACH buffer will contain 'buffer_multiplier_factor' blocks of data before + Receive event is indicated to API caller. + */ + u16 number_of_buffers_per_api_interface; +}buffer_settings_t; + +#define MIN_BUFFER_MULTIPLIER_FACTOR 1 +#define MAX_BUFFER_MULTIPLIER_FACTOR 7 + +#define MIN_NUMBER_OF_BUFFERS_PER_API_INTERFACE 50 +#define MAX_NUMBER_OF_BUFFERS_PER_API_INTERFACE 100 + +/* structure used with IoctlDriverConfigurationCommand*/ +typedef struct { + unsigned char command_code; + unsigned int return_code; + /* Port configuration */ + wandev_conf_t wandev_conf; + + /* + Per-Interface configuration. + For AFT card maximum NUM_OF_E1_CHANNELS (31) logic channels. + Configuration of each logic channel ('active_ch', HDLC or Transparent...) + */ + wanif_conf_t if_cfg[NUM_OF_E1_CHANNELS]; + + buffer_settings_t buffer_settings; +}driver_cfg_t; +#endif + +#define DRV_MODE_NORMAL 0 +#define DRV_MODE_AFTUP 1 + +/* cpecial id - when driver installed, it is "not configured". +user has to select the protocol.*/ +#define WANCONFIG_NONE 10 +/* special id - for AFT firmware update */ +#define WANCONFIG_AFT_FIRMWARE_UPDATE 11 + +#endif/* __WINDOWS__) */ + #endif diff --git a/patches/kdrivers/include/wanpipe_codec_iface.h b/patches/kdrivers/include/wanpipe_codec_iface.h index 8de17e2..d5d8301 100644 --- a/patches/kdrivers/include/wanpipe_codec_iface.h +++ b/patches/kdrivers/include/wanpipe_codec_iface.h @@ -1,5 +1,5 @@ /************************************************************************** - * wanpipe_codec_iface.c + * wanpipe_codec_iface.h * WANPIPE(tm) Multiprotocol WAN Link Driver. * TDM voice board configuration. * diff --git a/patches/kdrivers/include/wanpipe_common.h b/patches/kdrivers/include/wanpipe_common.h index 9b44e4d..4338af3 100644 --- a/patches/kdrivers/include/wanpipe_common.h +++ b/patches/kdrivers/include/wanpipe_common.h @@ -2,7 +2,7 @@ * Copyright (c) 2002 * Alex Feldman . All rights reserved. * - * $Id: wanpipe_common.h,v 1.175 2007/02/24 00:17:14 sangoma Exp $ + * $Id: wanpipe_common.h,v 1.213 2008/02/21 19:39:18 sangoma Exp $ */ /**************************************************************************** @@ -11,23 +11,26 @@ * Author: Alex Feldman * * ========================================================================== + * Nov 27, 2007 David Rokhvarg Implemented functions/definitions for + * Sangoma MS Windows Driver and API. + * * July 17, 2002 Alex Feldman Initial Version **************************************************************************** */ #ifndef __WANPIPE_COMMON_H -# define __WANPIPE_COMMON_H +# define __WANPIPE_COMMON_H -#ifdef __LINUX__ +#if defined(__LINUX__) # include +#elif defined(__WINDOWS__) +# include +# include +# include #else # include #endif -#ifdef WAN_DEBUG_MEM -extern atomic_t wan_debug_mem; -#endif - /**************************************************************************** ** D E F I N E S ****************************************************************************/ @@ -39,6 +42,8 @@ extern atomic_t wan_debug_mem; ((unsigned char *)&addr)[3] #endif +#define NAME_PLACEHOLDER + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) # define WAN_LIST_HEAD(name, type) LIST_HEAD(name, type) @@ -95,6 +100,42 @@ extern atomic_t wan_debug_mem; #elif defined(__LINUX__) /* ********* L I N U X *****************/ +# define WAN_LIST_HEAD(name, type) struct name { struct type * lh_first; } +# define WAN_LIST_HEAD_INITIALIZER(head) { NULL } +# define WAN_LIST_ENTRY(type) struct { struct type *le_next; struct type **le_prev; } +# define WAN_LIST_FIRST(head) ((head)->lh_first) +# define WAN_LIST_END(head) NULL +# define WAN_LIST_EMPTY(head) (WAN_LIST_FIRST(head) == WAN_LIST_END(head)) +# define WAN_LIST_NEXT(elm, field) ((elm)->field.le_next) +# define WAN_LIST_FOREACH(var, head, field) for((var) = WAN_LIST_FIRST(head); \ + (var); \ + (var) = WAN_LIST_NEXT(var, field)) +# define WAN_LIST_INIT(head) do { WAN_LIST_FIRST(head) = NULL;}\ + while(0) + +#define WAN_LIST_INSERT_HEAD(head, elm, field) do { \ + if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_FIRST((head))) != NULL) \ + WAN_LIST_FIRST((head))->field.le_prev = &WAN_LIST_NEXT((elm), field);\ + WAN_LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &WAN_LIST_FIRST((head)); \ +} while (0) +#define WAN_LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_NEXT((listelm), field)) != NULL)\ + WAN_LIST_NEXT((listelm), field)->field.le_prev = \ + &WAN_LIST_NEXT((elm), field); \ + WAN_LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &WAN_LIST_NEXT((listelm), field); \ +} while (0) +#define WAN_LIST_REMOVE(elm, field) do { \ + if (WAN_LIST_NEXT((elm), field) != NULL) \ + WAN_LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = WAN_LIST_NEXT((elm), field); \ +} while (0) + +#elif defined(__WINDOWS__) + + # define WAN_LIST_HEAD(name, type) struct name { struct type * lh_first; } # define WAN_LIST_HEAD_INITIALIZER(head) { NULL } # define WAN_LIST_ENTRY(type) struct { struct type *le_next; struct type **le_prev; } @@ -134,186 +175,15 @@ extern atomic_t wan_debug_mem; #if defined(WAN_KERNEL) -#if defined(__FreeBSD__) -# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrhead) -# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_link) -#elif defined (__OpenBSD__) -# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrlist) -# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_list) -#elif defined (__NetBSD__) -# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrlist) -# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_list) -#elif defined(__LINUX__) -#elif defined(__SOLARIS__) -#elif defined(__WINDOWS__) -#else -# error "WAN_TAILQ_x macros doesn't supported yet!" -#endif - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# if defined(__FreeBSD__) -# define WAN_PKTATTR_DECL(pktattr) -# else -# define WAN_PKTATTR_DECL(pktattr) struct altq_pktattr pktattr -# endif -# define WAN_IFQ_SET_READY IFQ_SET_READY -# define WAN_IFQ_IS_EMPTY IFQ_IS_EMPTY -# define WAN_IFQ_INC_LEN IFQ_INC_LEN -# define WAN_IFQ_DEC_LEN IFQ_DEC_LEN -# define WAN_IFQ_INC_DROPS IFQ_INC_DROPS -# define WAN_IFQ_SET_MAXLEN IFQ_SET_MAXLEN -# define WAN_IFQ_PURGE IFQ_PURGE -# if (__FreeBSD_version > 503000) -# define WAN_IFQ_ENQUEUE(ifq, m, pattr, err) IFQ_ENQUEUE((ifq),(m),(err)) -# else -# define WAN_IFQ_ENQUEUE IFQ_ENQUEUE -# endif -# define WAN_IFQ_DEQUEUE IFQ_DEQUEUE -# define WAN_IFQ_POLL IFQ_POLL -# define WAN_IFQ_CLASSIFY IFQ_CLASSIFY -# define WAN_IFQ_INIT IFQ_INIT -# define WAN_IFQ_LEN IFQ_LEN -#elif defined(__LINUX__) -# define WAN_IFQ_INIT(ifq, max_pkt) skb_queue_head_init((ifq)) -# define WAN_IFQ_PURGE(ifq) skb_queue_purge((ifq)) -# define WAN_IFQ_ENQUEUE(ifq, skb, arg, err) skb_queue_tail((ifq), (skb)) -# define WAN_IFQ_LEN(ifq) skb_queue_len((ifq)) -#elif defined(__WINDOWS__) -#else -# error "Undefined IFQ_x macros!" -#endif - -#if defined(__FreeBSD__) -# if (__FreeBSD_version < 410000) -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - (task)->task_func = func; (task)->data = arg -# define WAN_TASKLET_SCHEDULE(task) \ - if (!wan_test_bit(0, &(task)->running)){ \ - wan_set_bit(0, &(task)->running); \ - (task)->task_func((task)->data, 0); \ +static __inline void WP_MDELAY (u32 ms) { + /* wait for "milliseconds * 1/1000" of sec */ + for (; ms > 0; --ms){ + WP_DELAY(1000); } -# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) +} -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -# define WAN_TASKLET_KILL(task) -# else -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - TASK_INIT(&(task)->task_id, priority, func, (void*)arg) -# define WAN_TASKLET_SCHEDULE(task) \ - if (!wan_test_bit(0, &(task)->running)){ \ - wan_set_bit(0, &(task)->running); \ - taskqueue_enqueue(taskqueue_swi, &(task)->task_id); \ - } -# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) - -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -/* taskqueue_run(taskqueue_swi); \*/ -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_KILL(task) -# endif -#elif defined(__OpenBSD__) || defined(__NetBSD__) -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - (task)->task_func = func; (task)->data = arg -# define WAN_TASKLET_SCHEDULE(task) \ - if (!wan_test_bit(0, &(task)->running)){ \ - wan_set_bit(0, &(task)->running); \ - (task)->task_func((task)->data, 0); \ - } - -# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) - -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_KILL(task) - - -#elif defined(__LINUX__) - -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - tasklet_init(&(task)->task_id,func,(unsigned long)arg) - -# define WAN_TASKLET_SCHEDULE(task) \ - wan_set_bit(0, &(task)->running); \ - tasklet_schedule(&(task)->task_id); - -#if 0 -# define WAN_WP_TASKLET_SCHEDULE_PER_CPU(task,cpu) \ - wan_set_bit(0, &(task)->running); \ - wp_tasklet_hi_schedule_per_cpu(&(task)->task_id,cpu); -#endif - -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_KILL(task) tasklet_kill(&(task)->task_id) - - -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_TASKLET_x macro!" -#endif - -#if defined(__FreeBSD__) -# if (__FreeBSD_version < 410000) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - (task)->tfunc = func; task->data = arg -# else -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - TASK_INIT(&task->tqueue, priority, func, arg) -# endif -#elif defined(__OpenBSD__) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - (task)->tfunc = func; task->data = arg -#elif defined(__NetBSD__) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - (task)->tfunc = func; task->data = arg -#elif defined(__LINUX__) -/* Due to 2.6.20 kernel the wan_taskq_t is now a direct - * workqueue struct not an abstracted structure */ -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - INIT_WORK((task),func,arg) -# else -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - INIT_WORK((task),func) -# endif - -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_TASKQ_INIT macro!" -#endif - -#if defined(__FreeBSD__) && (__FreeBSD_version >= 410000) -# define WAN_IS_TASKQ_SCHEDULE -# define WAN_TASKQ_SCHEDULE(task) \ - taskqueue_enqueue(taskqueue_swi, &task->tqueue);\ - taskqueue_run(taskqueue_swi) -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# define WAN_IS_TASKQ_SCHEDULE -# define WAN_TASKQ_SCHEDULE(task) \ - task->tfunc(task->data, 0) -#elif defined(__LINUX__) -# define WAN_IS_TASKQ_SCHEDULE -# define WAN_TASKQ_SCHEDULE(task) \ - wan_schedule_task(task) -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_TASKQ_SCHEDULE macro!" -#endif +#define WAN_STIMEOUT(start, timeout) \ + ((SYSTEM_TICKS - (start)) > ((timeout) * HZ)) #if defined(__LINUX__) # define WAN_COPY_FROM_USER(k,u,l) copy_from_user(k,u,l) @@ -322,6 +192,7 @@ extern atomic_t wan_debug_mem; # define WAN_COPY_FROM_USER(k,u,l) copyin(u,k,l) # define WAN_COPY_TO_USER(u,k,l) copyout(k,u,l) #elif defined(__WINDOWS__) + #else # error "Undefined WAN_COPY_FROM_USER/WAN_COPY_TO_USER macros!" #endif @@ -371,15 +242,15 @@ extern atomic_t wan_debug_mem; # define WAN_NET_RATELIMIT net_ratelimit #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# define WAN_NETIF_QUEUE_STOPPED(dev) (dev)->if_flags & IFF_DRV_OACTIVE -# define WAN_NETIF_WAKE_QUEUE(dev) (dev)->if_flags &= ~IFF_DRV_OACTIVE +# define WAN_NETIF_QUEUE_STOPPED(dev) ((dev)->if_drv_flags & IFF_DRV_OACTIVE) +# define WAN_NETIF_WAKE_QUEUE(dev) ((dev)->if_drv_flags &= ~IFF_DRV_OACTIVE) #if 0 # define WAN_NETIF_STOP_QUEUE(dev) # define WAN_NETIF_START_QUEUE(dev) #endif -# define WAN_NETIF_STOP_QUEUE(dev) (dev)->if_flags |= IFF_DRV_OACTIVE -# define WAN_NETIF_START_QUEUE(dev) (dev)->if_flags &= ~IFF_DRV_OACTIVE -# define WAN_NETIF_RUNNING(dev) 1 +# define WAN_NETIF_STOP_QUEUE(dev) (dev)->if_drv_flags |= IFF_DRV_OACTIVE +# define WAN_NETIF_START_QUEUE(dev) (dev)->if_drv_flags &= ~IFF_DRV_OACTIVE +# define WAN_NETIF_RUNNING(dev) ((dev)->if_drv_flags&IFF_DRV_RUNNING) # define WAN_NETIF_UP(dev) ((dev)->if_flags&IFF_UP) # define WAN_NETDEVICE_STOP(dev) # define WAN_NETDEVICE_START(dev) @@ -393,41 +264,147 @@ extern atomic_t wan_debug_mem; # define WAN_NETIF_CARRIER_OK(dev) 1 #elif defined(__WINDOWS__) +# define WAN_NET_RATELIMIT() 1 +# define WAN_NETIF_QUEUE_STOPPED(dev) test_bit(0,&dev->tbusy) +# define WAN_NETIF_UP(dev) ((dev)->flags&IFF_UP) +# define WAN_NETIF_WAKE_QUEUE(dev) netif_wake_queue(dev) +# define WAN_NETIF_START_QUEUE(dev) netif_wake_queue(dev) +# define WAN_NETIF_CARRIER_OFF(dev) FUNC_NOT_IMPL +# define WAN_NETIF_STOP_QUEUE(dev) FUNC_NOT_IMPL +# define WAN_IFQ_LEN(ifqueue) skb_queue_len(ifqueue) + #else # error "Undefined WAN_NETIF_x macros!" #endif +/* Update Network Interface statistics */ +#if defined(__LINUX__) + +# define WAN_NETIF_STATS_INC_RX_PACKETS(common) (common)->if_stats.rx_packets++ +# define WAN_NETIF_STATS_INC_TX_PACKETS(common) (common)->if_stats.tx_packets++ +# define WAN_NETIF_STATS_RX_PACKETS(common) ((common)->if_stats.rx_packets) +# define WAN_NETIF_STATS_TX_PACKETS(common) ((common)->if_stats.tx_packets) +# define WAN_NETIF_STATS_INC_RX_BYTES(common,len) (common)->if_stats.rx_bytes+=(len) +# define WAN_NETIF_STATS_INC_TX_BYTES(common,len) (common)->if_stats.tx_bytes+=(len) +# define WAN_NETIF_STATS_INC_RX_ERRORS(common) (common)->if_stats.rx_errors++ +# define WAN_NETIF_STATS_INC_TX_ERRORS(common) (common)->if_stats.tx_errors++ +# define WAN_NETIF_STATS_INC_RX_DROPPED(common) (common)->if_stats.rx_dropped++ +# define WAN_NETIF_STATS_RX_DROPPED(common) (common)->if_stats.rx_dropped +# define WAN_NETIF_STATS_INC_TX_DROPPED(common) (common)->if_stats.tx_dropped++ +# define WAN_NETIF_STATS_INC_MULTICAST(common) (common)->if_stats.multicast++ +# define WAN_NETIF_STATS_INC_COLLISIONS(common) (common)->if_stats.collisions++ +# define WAN_NETIF_STATS_INC_RX_LENGTH_ERRORS(common) (common)->if_stats.rx_length_errors++ +# define WAN_NETIF_STATS_INC_RX_OVER_ERRORS(common) (common)->if_stats.rx_over_errors++ +# define WAN_NETIF_STATS_INC_RX_CRC_ERRORS(common) (common)->if_stats.rx_crc_errors++ +# define WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(common) (common)->if_stats.rx_frame_errors++ +# define WAN_NETIF_STATS_INC_RX_FIFO_ERRORS(common) (common)->if_stats.rx_fifo_errors++ +# define WAN_NETIF_STATS_INC_RX_MISSED_ERRORS(common) (common)->if_stats.rx_missed_errors++ +# define WAN_NETIF_STATS_INC_TX_ABORTED_ERRORS(common) (common)->if_stats.tx_aborted_errors++ +# define WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(common) (common)->if_stats.tx_carrier_errors++ +# define WAN_NETIF_STATS_TX_CARRIER_ERRORS(common) (common)->if_stats.tx_carrier_errors +# define WAN_NETIF_STATS_INC_TX_FIFO_ERRORS(common) (common)->if_stats.tx_fifo_errors++ +# define WAN_NETIF_STATS_INC_TX_HEARTBEAT_ERRORS(common) (common)->if_stats.tx_heartbeat_errors++ +# define WAN_NETIF_STATS_INC_TX_WINDOW_ERRORS(common) (common)->if_stats.tx_window_errors++ +# define WAN_NETIF_STATS_INC_RX_COMPRESSED(common) (common)->if_stats.rx_compressed++ +# define WAN_NETIF_STATS_INC_TX_COMPRESSED(common) (common)->if_stats.tx_compressed++ + +#elif defined(__FreeBSD__) || defined(__OpenBSD__) + +# define WAN_NETIF_STATS_INC_RX_PACKETS(common) if ((common)->dev) (common)->dev->if_ipackets++ +# define WAN_NETIF_STATS_INC_TX_PACKETS(common) if ((common)->dev) (common)->dev->if_opackets++ +# define WAN_NETIF_STATS_RX_PACKETS(common) ((common)->dev) ? (common)->dev->if_ipackets : 0 +# define WAN_NETIF_STATS_TX_PACKETS(common) ((common)->dev) ? (common)->dev->if_opackets : 0 +# define WAN_NETIF_STATS_INC_RX_BYTES(common,len) if ((common)->dev) (common)->dev->if_ibytes+=(len) +# define WAN_NETIF_STATS_INC_TX_BYTES(common,len) if ((common)->dev) (common)->dev->if_obytes+=(len) +# define WAN_NETIF_STATS_INC_RX_ERRORS(common) if ((common)->dev) (common)->dev->if_ierrors++ +# define WAN_NETIF_STATS_INC_TX_ERRORS(common) if ((common)->dev) (common)->dev->if_oerrors++ +# define WAN_NETIF_STATS_INC_RX_DROPPED(common) if ((common)->dev) (common)->dev->if_iqdrops++ +# define WAN_NETIF_STATS_RX_DROPPED(common) if ((common)->dev) (common)->dev->if_iqdrops +# define WAN_NETIF_STATS_INC_TX_DROPPED(common) +# define WAN_NETIF_STATS_INC_MULTICAST(common) if ((common)->dev) (common)->dev->if_omcasts++ +# define WAN_NETIF_STATS_INC_COLLISIONS(common) if ((common)->dev) (common)->dev->if_collisions++ +# define WAN_NETIF_STATS_INC_RX_LENGTH_ERRORS(common) if ((common)->dev) (common)->dev->if_ierrors++ +# define WAN_NETIF_STATS_INC_RX_OVER_ERRORS(common) if ((common)->dev) (common)->dev->if_ierrors++ +# define WAN_NETIF_STATS_INC_RX_CRC_ERRORS(common) if ((common)->dev) (common)->dev->if_ierrors++ +# define WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(common) if ((common)->dev) (common)->dev->if_ierrors++ +# define WAN_NETIF_STATS_INC_RX_FIFO_ERRORS(common) if ((common)->dev) (common)->dev->if_ierrors++ +# define WAN_NETIF_STATS_INC_RX_MISSED_ERRORS(common) if ((common)->dev) (common)->dev->if_ierrors++ +# define WAN_NETIF_STATS_INC_TX_ABORTED_ERRORS(common) if ((common)->dev) (common)->dev->if_oerrors++ +# define WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(common) if ((common)->dev) (common)->dev->if_oerrors++ +# define WAN_NETIF_STATS_TX_CARRIER_ERRORS(common) if ((common)->dev) (common)->dev->if_oerrors +# define WAN_NETIF_STATS_INC_TX_FIFO_ERRORS(common) if ((common)->dev) (common)->dev->if_oerrors++ +# define WAN_NETIF_STATS_INC_TX_HEARTBEAT_ERRORS(common) if ((common)->dev) (common)->dev->if_oerrors++ +# define WAN_NETIF_STATS_INC_TX_WINDOW_ERRORS(common) if ((common)->dev) (common)->dev->if_oerrors++ +# define WAN_NETIF_STATS_INC_RX_COMPRESSED(common) +# define WAN_NETIF_STATS_INC_TX_COMPRESSED(common) + +#elif defined(__WINDOWS__) + +# define WAN_NETIF_STATS_INC_RX_PACKETS(common) (common)->if_stats.rx_packets++ +# define WAN_NETIF_STATS_INC_TX_PACKETS(common) (common)->if_stats.tx_packets++ +# define WAN_NETIF_STATS_RX_PACKETS(common) ((common)->if_stats.rx_packets) +# define WAN_NETIF_STATS_TX_PACKETS(common) ((common)->if_stats.tx_packets) +# define WAN_NETIF_STATS_INC_RX_BYTES(common,len) (common)->if_stats.rx_bytes+=(len) +# define WAN_NETIF_STATS_INC_TX_BYTES(common,len) (common)->if_stats.tx_bytes+=(len) +# define WAN_NETIF_STATS_INC_RX_ERRORS(common) (common)->if_stats.rx_errors++ +# define WAN_NETIF_STATS_INC_TX_ERRORS(common) (common)->if_stats.tx_errors++ +# define WAN_NETIF_STATS_INC_RX_DROPPED(common) (common)->if_stats.rx_dropped++ +# define WAN_NETIF_STATS_RX_DROPPED(common) (common)->if_stats.rx_dropped +# define WAN_NETIF_STATS_INC_TX_DROPPED(common) (common)->if_stats.tx_dropped++ +# define WAN_NETIF_STATS_INC_MULTICAST(common) (common)->if_stats.multicast++ +# define WAN_NETIF_STATS_INC_COLLISIONS(common) (common)->if_stats.collisions++ +# define WAN_NETIF_STATS_INC_RX_LENGTH_ERRORS(common) (common)->if_stats.rx_length_errors++ +# define WAN_NETIF_STATS_INC_RX_OVER_ERRORS(common) (common)->if_stats.rx_over_errors++ +# define WAN_NETIF_STATS_INC_RX_CRC_ERRORS(common) (common)->if_stats.rx_crc_errors++ +# define WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(common) (common)->if_stats.rx_frame_errors++ +# define WAN_NETIF_STATS_INC_RX_FIFO_ERRORS(common) (common)->if_stats.rx_fifo_errors++ +# define WAN_NETIF_STATS_INC_RX_MISSED_ERRORS(common) (common)->if_stats.rx_missed_errors++ +# define WAN_NETIF_STATS_INC_TX_ABORTED_ERRORS(common) (common)->if_stats.tx_aborted_errors++ +# define WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(common) (common)->if_stats.tx_carrier_errors++ +# define WAN_NETIF_STATS_TX_CARRIER_ERRORS(common) (common)->if_stats.tx_carrier_errors +# define WAN_NETIF_STATS_INC_TX_FIFO_ERRORS(common) (common)->if_stats.tx_fifo_errors++ +# define WAN_NETIF_STATS_INC_TX_HEARTBEAT_ERRORS(common) (common)->if_stats.tx_heartbeat_errors++ +# define WAN_NETIF_STATS_INC_TX_WINDOW_ERRORS(common) (common)->if_stats.tx_window_errors++ +# define WAN_NETIF_STATS_INC_RX_COMPRESSED(common) (common)->if_stats.rx_compressed++ +# define WAN_NETIF_STATS_INC_TX_COMPRESSED(common) (common)->if_stats.tx_compressed++ + +#else + +# error "Undefined WAN_NETIF_STATSx macro!" +# define WAN_NETIF_STATS_INC_RXPACKETS(common) +# define WAN_NETIF_STATS_INC_TXPACKETS(common) +# define WAN_NETIF_STATS_INC_RXBYTES(common) +# define WAN_NETIF_STATS_INC_TXBYTES(common) +# define WAN_NETIF_STATS_INC_RXERRORS(common) +# define WAN_NETIF_STATS_INC_TXERRORS(common) +# define WAN_NETIF_STATS_INC_RXDROPPED(common) +# define WAN_NETIF_STATS_INC_TXDROPPED(common) +# define WAN_NETIF_STATS_INC_MULTICAST(common) +# define WAN_NETIF_STATS_INC_COLLISIONS(common) +# define WAN_NETIF_STATS_INC_RXLENGTHERRORS(common) +# define WAN_NETIF_STATS_INC_RXOVERERRORS(common) +# define WAN_NETIF_STATS_INC_RXCRCERRORS(common) +# define WAN_NETIF_STATS_INC_RXFRAMESERRORS(common) +# define WAN_NETIF_STATS_INC_RXFIFOERRORS(common) +# define WAN_NETIF_STATS_INC_RXMISSEDERRORS(common) + +# define WAN_NETIF_STATS_INC_TXABORTEDERRORS(common) +# define WAN_NETIF_STATS_INC_TXCARRIERERRORS(common) +# define WAN_NETIF_STATS_INC_TXFIFOERRORS(common) +# define WAN_NETIF_STATS_INC_TXHEARTBEATERRORS(common) +# define WAN_NETIF_STATS_INC_TXWINDOWERRORS(common) + +# define WAN_NETIF_STATS_INC_RXCOMPRESSED(common) +# define WAN_NETIF_STATS_INC_TXCOMPRESSED(common) +#endif + #if defined(__LINUX__) # define WAN_BPF_DIR_IN (1<<0) # define WAN_BPF_DIR_OUT (1<<1) # define WAN_BPF_REPORT(dev,m) #elif defined(__FreeBSD__) -# define WAN_BPF_DIR_IN (1<<0) -# define WAN_BPF_DIR_OUT (1<<1) -# if (__FreeBSD_version > 500000) -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)) -# else -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev), (m)) -# endif #elif defined(__OpenBSD__) -# if (OpenBSD < 200611) -# define WAN_BPF_DIR_IN (1<<0) -# define WAN_BPF_DIR_OUT (1<<1) -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)); -# else -# define WAN_BPF_DIR_IN BPF_DIRECTION_IN -# define WAN_BPF_DIR_OUT BPF_DIRECTION_OUT -# define WAN_BPF_REPORT(dev,m,d) \ - if (dir == WAN_BPF_DIR_IN){ \ - bpf_mtap((dev)->if_bpf, (m), BPF_DIRECTION_IN); \ - }else{ \ - bpf_mtap((dev)->if_bpf, (m), BPF_DIRECTION_OUT); \ - } -# endif #elif defined(__NetBSD__) -# define WAN_BPF_DIR_IN (1<<0) -# define WAN_BPF_DIR_OUT (1<<1) -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)); #elif defined(__WINDOWS__) #else # error "Undefined WAN_BPF_REPORT macro!" @@ -461,6 +438,12 @@ extern atomic_t wan_debug_mem; } # define WAN_HOLD(str) str->refcnt++ #elif defined(__WINDOWS__) + +# define WAN_DEV_PUT(dev) wan_atomic_dec(&(dev)->refcnt) +# define WAN_DEV_HOLD(dev) wan_atomic_inc(&(dev)->refcnt) +# define __WAN_PUT(str) wan_atomic_dec(&(str)->refcnt) + +# define WAN_HOLD(str) wan_atomic_inc(&(str)->refcnt) #else # warning "Undefined WAN_HOLD/WAN_PUT macro!" #endif @@ -512,6 +495,15 @@ typedef char *va_list; #define WAN_VA_END(ap) (void) 0 #endif +/* String library definitions */ +#if defined(__LINUX__) +# define strncasecmp strnicmp +#elif defined(__WINDOWS__) +# define strlcpy strncpy +# define strncasecmp _strnicmp +# define snprintf _snprintf +# define vsnprintf _vsnprintf +#endif /**************************************************************************** ** T Y P E D E F S @@ -578,7 +570,25 @@ void wanpipe_debugging (void* data, int pending); #else void wanpipe_debugging (unsigned long data); #endif -static __inline int wan_skb_tailroom(void* skb); + + + + + +/**************************************************************************** +** MEMORY DEBUG F U N C T I O N S +****************************************************************************/ + +#ifdef WAN_DEBUG_MEM + +int sdla_memdbg_push(void *mem, char *func_name, int line, int len); +int sdla_memdbg_pull(void *mem, char *func_name, int line); + +#endif + + + + /**************************************************************************** ** I N L I N E F U N C T I O N S @@ -587,50 +597,60 @@ static __inline int wan_skb_tailroom(void* skb); /* ** wan_malloc - */ + +#ifdef WAN_DEBUG_MEM + +#define wan_malloc(size) __wan_malloc(size,(char*)__FUNCTION__,(int)__LINE__) +static __inline void* __wan_malloc(int size, char *func_name, int line) +#else static __inline void* wan_malloc(int size) +#endif { void* ptr = NULL; #if defined(__LINUX__) ptr = kmalloc(size, GFP_ATOMIC); - if (ptr){ - DEBUG_ADD_MEM(size); - } #elif defined(__SOLARIS__) ptr=kmem_alloc(size,KM_NOSLEEP); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) ptr = malloc(size, M_DEVBUF, M_NOWAIT); #elif defined(__WINDOWS__) - ptr = ExAllocatePool(NonPagedPool, size); + ptr = kmalloc(size); #else # error "wan_malloc() function is not supported yet!" #endif if (ptr){ memset(ptr, 0, size); - DEBUG_ADD_MEM(size); +#ifdef WAN_DEBUG_MEM + sdla_memdbg_push(ptr, func_name, line, size); +#endif } return ptr; } +#ifdef WAN_DEBUG_MEM +#define wan_kmalloc(size) __wan_kmalloc(size,(char*)__FUNCTION__,(int)__LINE__) +static __inline void* __wan_kmalloc(int size, char *func_name, int line) +#else static __inline void* wan_kmalloc(int size) +#endif { void* ptr = NULL; #if defined(__LINUX__) ptr = kmalloc(size, GFP_KERNEL); - if (ptr){ - DEBUG_ADD_MEM(size); - } #elif defined(__SOLARIS__) ptr=kmem_alloc(size,KM_NOSLEEP); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) ptr = malloc(size, M_DEVBUF, M_NOWAIT); #elif defined(__WINDOWS__) - ptr = ExAllocatePool(NonPagedPool, size); + ptr = kmalloc(size); #else # error "wan_malloc() function is not supported yet!" #endif if (ptr){ memset(ptr, 0, size); - DEBUG_ADD_MEM(size); +#ifdef WAN_DEBUG_MEM + sdla_memdbg_push(ptr, func_name, line, size); +#endif } return ptr; } @@ -638,13 +658,22 @@ static __inline void* wan_kmalloc(int size) /* ** wan_free - */ +#ifdef WAN_DEBUG_MEM +#define wan_free(ptr) __wan_free(ptr,(char*)__FUNCTION__,(int)__LINE__) +static __inline void __wan_free(void* ptr, char *func_name, int line) +#else static __inline void wan_free(void* ptr) +#endif { if (!ptr){ DEBUG_EVENT("wan_free: NULL PTR !!!!!\n"); return; } +#ifdef WAN_DEBUG_MEM + sdla_memdbg_pull(ptr, func_name, line); +#endif + #if defined(__LINUX__) kfree(ptr); #elif defined(__SOLARIS__) @@ -653,25 +682,28 @@ static __inline void wan_free(void* ptr) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) return free(ptr, M_DEVBUF); #elif defined(__WINDOWS__) - ExFreePool(ptr); + kfree(ptr); #else # error "wan_free() function is not supported yet!" #endif } + +#ifdef WAN_DEBUG_MEM +#define wan_vmalloc(size) __wan_vmalloc(size,(char*)__FUNCTION__,(int)__LINE__) +static __inline void* __wan_vmalloc(int size, char *func_name, int line) +#else static __inline void* wan_vmalloc(int size) +#endif { void* ptr = NULL; #if defined(__LINUX__) ptr = vmalloc(size); - if (ptr){ - DEBUG_ADD_MEM(size); - } #elif defined(__FreeBSD__) ptr = (caddr_t)kmem_alloc(kernel_map, size + sizeof(vm_size_t)); if (ptr){ vm_size_t *ptr1 = (vm_size_t*)ptr; - bzero(ptr, size); + bzero(ptr, size + sizeof(vm_size_t)); *ptr1 = size + sizeof(vm_size_t); ptr = ptr1++; } @@ -685,12 +717,15 @@ static __inline void* wan_vmalloc(int size) } #elif defined(__SOLARIS__) #elif defined(__WINDOWS__) + ptr = kmalloc(size); #else # error "wan_vmalloc() function is not supported yet!" #endif if (ptr){ memset(ptr, 0, size); - DEBUG_ADD_MEM(size); +#ifdef WAN_DEBUG_MEM + sdla_memdbg_push(ptr, func_name, line, size); +#endif } return ptr; } @@ -698,12 +733,25 @@ static __inline void* wan_vmalloc(int size) /* ** wan_vfree - */ + + +#ifdef WAN_DEBUG_MEM +#define wan_vfree(ptr) __wan_vfree(ptr,(char*)__FUNCTION__,(int)__LINE__) +static __inline void __wan_vfree(void* ptr, char *func_name, int line) +#else static __inline void wan_vfree(void* ptr) +#endif + { if (!ptr){ DEBUG_EVENT("wan_vfree: NULL PTR !!!!!\n"); return; } + +#ifdef WAN_DEBUG_MEM + sdla_memdbg_pull(ptr, func_name, line); +#endif + #if defined(__LINUX__) vfree(ptr); #elif defined(__FreeBSD__) @@ -720,6 +768,7 @@ static __inline void wan_vfree(void* ptr) } #elif defined(__SOLARIS__) #elif defined(__WINDOWS__) + kfree(ptr); #else # error "wan_free() function is not supported yet!" #endif @@ -740,6 +789,8 @@ static __inline unsigned long wan_virt2bus(unsigned long* ptr) #elif defined(__OpenBSD__) || defined(__NetBSD__) return vtophys((vaddr_t)ptr); #elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else # error "wan_virt2bus() function is not supported yet!" #endif @@ -755,6 +806,8 @@ static __inline unsigned long* wan_bus2virt(unsigned long virt_addr) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) return (unsigned long*)virt_addr; #elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else # error "wan_bus2virt() function is not supported yet!" #endif @@ -767,7 +820,7 @@ static __inline unsigned long* wan_bus2virt(unsigned long virt_addr) ** wan_dma_alloc */ static __inline int -wan_dma_alloc(void* hw, wan_dma_descr_t* dma_descr) +wan_dma_alloc_org(void* hw, wan_dma_descr_org_t* dma_descr) { int err = 0; #if defined(__FreeBSD__) @@ -842,6 +895,7 @@ wan_dma_alloc(void* hw, wan_dma_descr_t* dma_descr) err = -ENOMEM; } #elif defined(__WINDOWS__) + FUNC_NOT_IMPL return -EINVAL; #else # error "wan_dma_alloc() function is not supported yet!" @@ -853,7 +907,7 @@ wan_dma_alloc(void* hw, wan_dma_descr_t* dma_descr) ** wan_dma_free */ static __inline int -wan_dma_free(void* hw, wan_dma_descr_t* dma_descr) +wan_dma_free_org(void* hw, wan_dma_descr_org_t* dma_descr) { #if defined(__FreeBSD__) bus_dmamem_free(dma_descr->dmat, dma_descr->vAddr, dma_descr->dmamap); @@ -872,6 +926,7 @@ wan_dma_free(void* hw, wan_dma_descr_t* dma_descr) dma_descr->vAddr = NULL; dma_descr->pAddr = 0; #elif defined(__WINDOWS__) + FUNC_NOT_IMPL return -EINVAL; #else # error "wan_dma_free() function is not supported yet!" @@ -879,12 +934,12 @@ wan_dma_free(void* hw, wan_dma_descr_t* dma_descr) return 0; } -static __inline unsigned long* wan_dma_get_vaddr(void* card, wan_dma_descr_t* dma) +static __inline unsigned long* wan_dma_get_vaddr(void* card, wan_dma_descr_org_t* dma) { return dma->vAddr; } -static __inline unsigned long wan_dma_get_paddr(void* card, wan_dma_descr_t* dma) +static __inline unsigned long wan_dma_get_paddr(void* card, wan_dma_descr_org_t* dma) { return wan_virt2bus(dma->vAddr); } @@ -904,17 +959,18 @@ static __inline int wan_getcurrenttime(unsigned long *sec, unsigned long *usec) if (sec) *sec = tv.tv_sec; if (usec) *usec = tv.tv_usec; return 0; -#elif defined(__WINDOWS__) - LARGE_INTEGER tv; - NdisGetCurrentSystemTime(&tv); - if (sec) *sec = (unsigned long)tv.QuadPart; - return 0; #elif defined(__LINUX__) struct timeval tv; do_gettimeofday(&tv); if (sec) *sec = tv.tv_sec; if (usec) *usec = tv.tv_usec; return 0; +#elif defined(__WINDOWS__) + struct timeval tv; + do_gettimeofday(&tv); + if (sec) *sec = tv.tv_sec; + if (usec) *usec = tv.tv_usec; + return 0; #else # error "wan_getcurrenttime() function is not supported yet!" #endif @@ -944,6 +1000,12 @@ wan_init_timer(wan_timer_t* wan_timer, wan_timer_func_t timer_func, wan_timer_ar wan_timer->timer_func = timer_func; wan_timer->timer_arg = arg; #elif defined(__WINDOWS__) + wan_timer->timer_func = timer_func; + wan_timer->timer_arg = arg; + KeInitializeDpc(&wan_timer->timer_info.TimerDpcObject, + wan_timer->timer_func, + wan_timer->timer_arg); + KeInitializeTimer(&wan_timer->timer_info.Timer); #else # error "wan_init_timer() function is not supported yet!" #endif /* linux */ @@ -974,6 +1036,8 @@ wan_del_timer(wan_timer_t* wan_timer) timeout_del(&wan_timer->timer_info); #elif defined(__NetBSD__) callout_stop(&wan_timer->timer_info); +#elif defined(__WINDOWS__) + KeCancelTimer(&wan_timer->timer_info.Timer); #else # error "wan_del_timer() function is not supported yet!" #endif /* linux */ @@ -1002,7 +1066,7 @@ wan_add_timer(wan_timer_t* wan_timer, unsigned long delay) timeout(wan_timer->timer_func, (void*)wan_timer->timer_arg, delay); - WAN_ASSERT1(wan_timer->timer_info.callout == NULL); + WAN_ASSERT(wan_timer->timer_info.callout == NULL); #elif defined(__OpenBSD__) timeout_add(&wan_timer->timer_info, delay); #elif defined(__NetBSD__) @@ -1011,6 +1075,19 @@ wan_add_timer(wan_timer_t* wan_timer, unsigned long delay) delay, wan_timer->timer_func, wan_timer->timer_arg); +#elif defined(__WINDOWS__) + LARGE_INTEGER large_int_delay; + + if(0)DEBUG_TIMER("%s(): delay: %u\n", __FUNCTION__, delay); + + /* The 'delay' is in milliseconds + RtlConvertLongToLargeInteger(-10000000L * 1) - this is 1 second. + Converted to milliseconds: + */ + large_int_delay = RtlConvertLongToLargeInteger(-10000L * delay); + + KeSetTimer(&wan_timer->timer_info.Timer, large_int_delay, + &wan_timer->timer_info.TimerDpcObject); #else # error "wan_add_timer() function is not supported yet!" #endif /* linux */ @@ -1030,6 +1107,8 @@ static __inline unsigned char* wan_skb_data(void* skb) return mtod((struct mbuf*)skb, caddr_t); #elif defined(__SOLARIS__) return ((netskb_t*)mp)->b_rptr; +#elif defined(__WINDOWS__) + return dev_skb_data(skb); #else # error "wan_skb_data() function is not supported yet!" #endif @@ -1042,11 +1121,13 @@ static __inline unsigned char* wan_skb_data(void* skb) static __inline unsigned char* wan_skb_tail(void* skb) { #if defined(__LINUX__) - return wan_skb_tail_pointer((struct sk_buff*)skb); + return __wan_skb_tail_pointer(skb); #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) return mtod((struct mbuf*)skb, caddr_t) + ((struct mbuf*)skb)->m_len; #elif defined(__SOLARIS__) return ((netskb_t*)mp)->b_wptr; +#elif defined(__WINDOWS__) + return dev_skb_tail(skb); #else # error "wan_skb_tail() function is not supported yet!" #endif @@ -1066,6 +1147,8 @@ static __inline void wan_skb_append(void* skbprev, void *skb, void *list) # endif #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) m_cat (skbprev, skb); +#elif defined(__WINDOWS__) + skb_append(skbprev,skb); #else # error "wan_skb_append() function is not supported yet!" #endif @@ -1091,6 +1174,8 @@ static __inline int wan_skb_len(void* skb) tmp = tmp->b_cont; } return len; +#elif defined(__WINDOWS__) + return dev_skb_len(skb); #else # error "wan_skb_len() function is not supported yet!" #endif @@ -1098,19 +1183,29 @@ static __inline int wan_skb_len(void* skb) /* ** wan_skb_free() - -** Free kernel memory buffer. +** Free kernel memory buffer. */ + +#ifdef WAN_DEBUG_MEM +#define wan_skb_free(ptr) __wan_skb_free(ptr,(char*)__FUNCTION__,(int)__LINE__) +static __inline void __wan_skb_free(void* skb, char *func_name, int line) +#else static __inline void wan_skb_free(void* skb) -{ -#if defined(__LINUX__) -#if defined(WAN_DEBUG_MEM) - DEBUG_SUB_MEM(((struct sk_buff*)skb)->truesize); #endif +{ + +#if defined(WAN_DEBUG_MEM) + sdla_memdbg_pull(skb, func_name, line); +#endif + +#if defined(__LINUX__) dev_kfree_skb_any(skb); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) m_freem(skb); #elif defined(__SOLARIS__) freemsg(skb); +#elif defined(__WINDOWS__) + dev_kfree_skb_any(skb); #else # error "wan_skb_free() function is not supported yet!" #endif @@ -1162,43 +1257,57 @@ static __inline int wan_skb_mark(void* pskb) ** wan_skb_alloc() - ** Allocate kernel buffer with len. */ +#if defined(WAN_DEBUG_MEM) +#define wan_skb_alloc(size) __wan_skb_alloc(size,(char*)__FUNCTION__,(int)__LINE__) +static __inline void* __wan_skb_alloc(unsigned int len, char *func_name, int line) +#else static __inline void* wan_skb_alloc(unsigned int len) +#endif { #if defined(__LINUX__) #if defined(WAN_DEBUG_MEM) struct sk_buff *skb=dev_alloc_skb(len); if (skb){ - DEBUG_ADD_MEM(skb->truesize); + sdla_memdbg_push(skb, func_name,line,skb->truesize); } return (void*)skb; #else return (void*)dev_alloc_skb(len); #endif #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf *new = NULL; + struct mbuf *nm = NULL; - if (len){ - MGETHDR(new, M_DONTWAIT, MT_DATA); - }else{ - MGET(new, M_DONTWAIT, MT_DATA); +# if 1 + nm = m_getcl(M_DONTWAIT,MT_DATA,M_PKTHDR); + if (nm != NULL){ + nm->m_data += 16; + wan_skb_set_mark(nm); } - if (new){ - if (new->m_flags & M_PKTHDR){ - new->m_pkthdr.len = 0; + return nm; +# else + int s = splimp(); + MGETHDR(nm, M_DONTWAIT, MT_DATA); + if (nm){ + if (nm->m_flags & M_PKTHDR){ + nm->m_pkthdr.len = 0; } - new->m_len = 0; - MCLGET(new, M_DONTWAIT); - if ((new->m_flags & M_EXT) == 0){ - wan_skb_free(new); + nm->m_len = 0; + MCLGET(nm, M_DONTWAIT); + if ((nm->m_flags & M_EXT) == 0){ + wan_skb_free(nm); + splx(s); return NULL; } /* Always reserve extra 16 bytes (as Linux) ** for the header */ - new->m_data += 16; - wan_skb_set_mark(new); - return (void*)new; + nm->m_data += 16; + wan_skb_set_mark(nm); + splx(s); + return (void*)nm; } + splx(s); return NULL; +# endif #elif defined (__SOLARIS__) mblk_t *mp=allocb(ROUNDUP(len+16, IOC_LINESIZE), BPRI_MED); if (mp){ @@ -1206,48 +1315,65 @@ static __inline void* wan_skb_alloc(unsigned int len) mp->b_rptr=(uchar_t *)ptr+16; } return mp; +#elif defined(__WINDOWS__) + return (void*)dev_alloc_skb(len); #else # error "wan_skb_alloc() function is not supported yet!" #endif } + +#if defined(WAN_DEBUG_MEM) +#define wan_skb_kalloc(size) __wan_skb_kalloc(size,(char*)__FUNCTION__,(int)__LINE__) +static __inline void* __wan_skb_kalloc(unsigned int len, char *func_name, int line) +#else static __inline void* wan_skb_kalloc(unsigned int len) +#endif { #if defined(__LINUX__) #if defined(WAN_DEBUG_MEM) struct sk_buff *skb=__dev_alloc_skb(len,GFP_KERNEL); if (skb){ - DEBUG_ADD_MEM(skb->truesize); + sdla_memdbg_push(skb, func_name,line,skb->truesize); } return (void*)skb; #else return (void*)__dev_alloc_skb(len,GFP_KERNEL); #endif #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf *new = NULL; + struct mbuf *nm = NULL; - if (len){ - MGETHDR(new, M_DONTWAIT, MT_DATA); - }else{ - MGET(new, M_DONTWAIT, MT_DATA); +# if 1 + nm = m_getcl(M_DONTWAIT,MT_DATA,M_PKTHDR); + if (nm != NULL){ + nm->m_data += 16; + wan_skb_set_mark(nm); } - if (new){ - if (new->m_flags & M_PKTHDR){ - new->m_pkthdr.len = 0; + return nm; +# else + int s = splimp(); + MGETHDR(nm, M_DONTWAIT, MT_DATA); + if (nm){ + if (nm->m_flags & M_PKTHDR){ + nm->m_pkthdr.len = 0; } - new->m_len = 0; - MCLGET(new, M_DONTWAIT); - if ((new->m_flags & M_EXT) == 0){ - wan_skb_free(new); + nm->m_len = 0; + MCLGET(nm, M_DONTWAIT); + if ((nm->m_flags & M_EXT) == 0){ + wan_skb_free(nm); + splx(s); return NULL; } /* Always reserve extra 16 bytes (as Linux) ** for the header */ - new->m_data += 16; - wan_skb_set_mark(new); - return (void*)new; + nm->m_data += 16; + wan_skb_set_mark(nm); + splx(s); + return (void*)nm; } + splx(s); return NULL; +# endif #elif defined (__SOLARIS__) mblk_t *mp=allocb(ROUNDUP(len+16, IOC_LINESIZE), BPRI_MED); if (mp){ @@ -1255,6 +1381,8 @@ static __inline void* wan_skb_kalloc(unsigned int len) mp->b_rptr=(uchar_t *)ptr+16; } return mp; +#elif defined(__WINDOWS__) + return (void*)dev_alloc_skb(len); #else # error "wan_skb_kalloc() function is not supported yet!" #endif @@ -1274,9 +1402,13 @@ static __inline void wan_skb_set_dev(void* pskb, void* dev) } #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) netskb_t* m = (netskb_t*)pskb; + WAN_SKBCRITASSERT(m); if (m){ m->m_pkthdr.rcvif = dev; } +#elif defined(__WINDOWS__) + struct sk_buff *skb = (struct sk_buff*)pskb; + skb->dev = dev; #else # error "wan_skb_set_dev() function is not supported yet!" #endif @@ -1292,10 +1424,14 @@ static __inline void wan_skb_set_protocol(void* pskb, unsigned int protocol) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf *mbuf = (struct mbuf*)pskb; if (protocol == ETH_P_IPX){ - mbuf->m_flags |= M_PROTO1; + mbuf->m_flags |= WAN_MFLAG_IPX; } +#elif defined(__WINDOWS__) + struct sk_buff *skb = (struct sk_buff*)pskb; + /* RtlUshortByteSwap converts a USHORT from + little-endian to big-endian, and vice versa. */ + skb->protocol = RtlUshortByteSwap(protocol); #else - # warning "wan_skb_set_protocol() function is not supported yet!" #endif } @@ -1305,16 +1441,48 @@ static __inline void wan_skb_set_raw(void* pskb) #if defined(__LINUX__) struct sk_buff *skb = (struct sk_buff*)pskb; if (skb){ - wan_skb_reset_mac_header(skb); - wan_skb_reset_network_header(skb); + __wan_skb_reset_mac_header(skb); + __wan_skb_reset_network_header(skb); } #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__WINDOWS__) + struct sk_buff *skb = (struct sk_buff*)pskb; + /* skb->mac.raw = skb->data; */ + FUNC_NOT_IMPL #else # warning "wan_skb_set_raw() function is not supported yet!" #endif } +static __inline void wan_skb_reset_mac_header(void* pskb) +{ +#if defined(__LINUX__) + struct sk_buff *skb = (struct sk_buff*)pskb; + if (skb){ + __wan_skb_reset_mac_header(skb); + } +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "wan_skb_reset_mac_hdr() function is not supported yet!" +#endif +} +static __inline void wan_skb_reset_network_header(void* pskb) +{ +#if defined(__LINUX__) + struct sk_buff *skb = (struct sk_buff*)pskb; + if (skb){ + __wan_skb_reset_network_header(skb); + } +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "wan_skb_reset_network_hdr() function is not supported yet!" +#endif +} /* ** wan_skb_set_csum() - @@ -1338,9 +1506,13 @@ static __inline void wan_skb_set_csum(void* skb, unsigned int csum) } #elif defined(__NetBSD__) || defined(__FreeBSD__) netskb_t* m = (netskb_t*)skb; + WAN_SKBCRITASSERT(m); if (m){ m->m_pkthdr.csum_data = csum; } +#elif defined(__WINDOWS__) + struct sk_buff *sk = (struct sk_buff*)skb; + sk->csum = csum; #else # error "wan_skb_set_csum() function is not supported yet!" #endif @@ -1357,6 +1529,7 @@ static __inline unsigned int wan_skb_csum(void* skb) return (sk) ? sk->csum : 0; #elif defined(__NetBSD__) || defined(__FreeBSD__) netskb_t* m = (netskb_t*)skb; + WAN_SKBCRITASSERT(m); return (m) ? m->m_pkthdr.csum_data : 0; #elif defined(__OpenBSD__) netskb_t* m = (netskb_t*)skb; @@ -1365,8 +1538,11 @@ static __inline unsigned int wan_skb_csum(void* skb) # else return (m) ? m->m_pkthdr.csum : 0; # endif +#elif defined(__WINDOWS__) + struct sk_buff *sk = (struct sk_buff*)skb; + return sk->csum; #else -# error "wan_skb_set_dev() function is not supported yet!" +# error "wan_skb_csum() function is not supported yet!" #endif } @@ -1380,10 +1556,13 @@ static __inline int wan_skb_check(void* skb) return 0; #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) netskb_t* m = (netskb_t*)skb; + WAN_SKBCRITASSERT(m); if (m->m_pkthdr.len != m->m_len){ return 1; } return 0; +#elif defined(__WINDOWS__) + return 0; #else # error "wan_skb_check() function is not supported yet!" #endif @@ -1401,6 +1580,8 @@ static __inline void wan_skb_reserve(void* skb, unsigned int len) struct mbuf *m = (struct mbuf*)skb; m->m_data += len; +#elif defined(__WINDOWS__) + skb_reserve(skb, len); #else # error "wan_skb_free() function is not supported yet!" #endif @@ -1418,9 +1599,11 @@ static __inline void wan_skb_copyback(void* skb, int off, int len, caddr_t cp) struct sk_buff* sk = (struct sk_buff*)skb; unsigned char* data = NULL; if (off == wan_skb_len(skb)){ - if (wan_skb_tail_pointer(sk) + len > wan_skb_end_pointer(sk)){ - DEBUG_EVENT("wan_skb_copyback: Internal Error (off=%d,len=%d,skb_len=%d)!\n", - off, len, wan_skb_len(skb)); + if (sk->tail + len > sk->end){ + DEBUG_EVENT( + "%s:%d: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + __FUNCTION__,__LINE__, + off, len, wan_skb_len(skb)); return; }else{ data = skb_put(skb, len); @@ -1433,13 +1616,48 @@ static __inline void wan_skb_copyback(void* skb, int off, int len, caddr_t cp) skb_trim(skb, off + len); } } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__FreeBSD__) + struct mbuf* m = (struct mbuf*)skb; + caddr_t data = mtod(m, caddr_t); + + WAN_SKBCRITASSERT(m); + if (off + len > m->m_ext.ext_size){ + panic("%s:%d: Buffer is too small (%d:%d;%d)!", + __FUNCTION__,__LINE__, + off,len,m->m_ext.ext_size); + return; + } + bcopy(cp, &data[off], len); + m->m_len = off + len; + m->m_pkthdr.len = off + len; +#elif defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf* m = (struct mbuf*)skb; caddr_t data = mtod(m, caddr_t); bcopy(cp, &data[off], len); m->m_len = off + len; m->m_pkthdr.len = off + len; +#elif defined(__WINDOWS__) + struct sk_buff* sk = (struct sk_buff*)skb; + unsigned char* data = NULL; + if (off == wan_skb_len(skb)){ + if (sk->tail + len > sk->end){ + DEBUG_EVENT( + "%s:%d: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + __FUNCTION__,__LINE__, + off, len, wan_skb_len(skb)); + return; + }else{ + data = skb_put(skb, len); + memcpy(data, cp, len); + } + }else{ + if (off + len > wan_skb_len(skb)){ + data = skb_put(skb, len); + memcpy(data + off, cp, len); + skb_trim(skb, off + len); + } + } #else # error "wan_skb_copyback() function is not supported yet!" #endif @@ -1459,14 +1677,18 @@ static __inline int wan_skb_copyback_user(void* skb, int off, int len, caddr_t c struct sk_buff* sk = (struct sk_buff*)skb; unsigned char* data = NULL; if (off == wan_skb_len(skb)){ - if (wan_skb_tail_pointer(sk) + len > wan_skb_end_pointer(sk)){ - DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + if (__wan_skb_tail_pointer(sk) + len > sk->end){ + DEBUG_EVENT( + "%s:%d: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + __FUNCTION__,__LINE__, off, len, wan_skb_len(skb)); return -EINVAL; }else{ data = skb_put(skb, len); if (WAN_COPY_FROM_USER(data, cp, len)){ - DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + DEBUG_EVENT( + "%s:%d: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + __FUNCTION__,__LINE__, off, len, wan_skb_len(skb)); return -EFAULT; } @@ -1475,7 +1697,9 @@ static __inline int wan_skb_copyback_user(void* skb, int off, int len, caddr_t c if (off + len > wan_skb_len(skb)){ data = skb_put(skb, len); if (WAN_COPY_FROM_USER(data+off, cp, len)){ - DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + DEBUG_EVENT( + "%s:%d: Internal Error (off=%d,len=%d,skb_len=%d)!\n", + __FUNCTION__,__LINE__, off, len, wan_skb_len(skb)); return -EFAULT; } @@ -1487,9 +1711,17 @@ static __inline int wan_skb_copyback_user(void* skb, int off, int len, caddr_t c struct mbuf* m = (struct mbuf*)skb; caddr_t data = mtod(m, caddr_t); + WAN_SKBCRITASSERT(m); + if (off + len > m->m_ext.ext_size){ + panic("%s:%d: Buffer is too small (%d:%d:%d)!\n", + __FUNCTION__,__LINE__, off,len,m->m_ext.ext_size); + return 0; + } WAN_COPY_FROM_USER(cp, &data[off], len); m->m_len = off + len; m->m_pkthdr.len = off + len; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # error "wan_skb_copyback_user() function is not supported yet!" #endif @@ -1506,15 +1738,21 @@ static __inline void wan_skb_copydata(void* skb, int off, int len, caddr_t cp) { #if defined(__LINUX__) if (off + len > wan_skb_len(skb)){ - DEBUG_EVENT("wan_skb_copydata: Internal error (off=%d, len=%d, skb_len=%d)!\n", + DEBUG_EVENT( + "%s:%d: Internal error (off=%d, len=%d, skb_len=%d)!\n", + __FUNCTION__,__LINE__, off, len, wan_skb_len(skb)); return; } memcpy(cp, wan_skb_data(skb), len); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# if (__FreeBSD_version >= 502000) + m_copydata(skb, off, len, cp); +# else caddr_t data = mtod((struct mbuf*)skb, caddr_t); bcopy(cp, &data[off], len); +# endif #elif defined(__SOLARIS__) mblk_t* tmp = (mblk_t*)skb; unsigned char* ptr = NULL; @@ -1526,6 +1764,15 @@ static __inline void wan_skb_copydata(void* skb, int off, int len, caddr_t cp) i += num; tmp = tmp->b_cont; } +#elif defined(__WINDOWS__) + if (off + len > wan_skb_len(skb)){ + DEBUG_EVENT( + "%s:%d: Internal error (off=%d, len=%d, skb_len=%d)!\n", + __FUNCTION__,__LINE__, + off, len, wan_skb_len(skb)); + return; + } + memcpy(cp, wan_skb_data(skb), len); #else # error "wan_skb_copydata() function is not supported yet!" #endif @@ -1540,6 +1787,8 @@ static __inline void * wan_skb_copy(void *skb) return skb_copy(skb,GFP_ATOMIC); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) return m_copym(skb, 0, wan_skb_len(skb), M_DONTWAIT); +#elif defined(__WINDOWS__) + return skb_copy(skb,GFP_ATOMIC); #else # error "wan_skb_copy() function is not supported yet" #endif @@ -1555,6 +1804,8 @@ static __inline void * wan_skb_clone(void *skb) return skb_clone(skb,GFP_ATOMIC); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) return m_copym(skb, 0, wan_skb_len(skb), M_DONTWAIT); +#elif defined(__WINDOWS__) + return skb_clone(skb,GFP_ATOMIC); #else # error "wan_skb_clone() function is not supported yet" #endif @@ -1562,9 +1813,6 @@ static __inline void * wan_skb_clone(void *skb) } - - - /* ** wan_skb2buffer() - ** Correct skb block. @@ -1575,23 +1823,29 @@ static __inline int wan_skb2buffer(void** skb) return 0; #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) netskb_t *m = (netskb_t*)(*skb); - netskb_t *new = NULL; + netskb_t *nm = NULL; + int s; - new = wan_skb_alloc(0); - if (new){ + s = splnet(); + nm = wan_skb_alloc(1); + if (nm){ struct mbuf *tmp = m; - char *buffer = new->m_data; + char *buffer = nm->m_data; for( ; tmp; tmp = tmp->m_next) { bcopy(mtod(tmp, caddr_t), buffer, tmp->m_len); buffer += tmp->m_len; - new->m_len += tmp->m_len; + nm->m_len += tmp->m_len; } wan_skb_free(m); - *skb = new; + *skb = nm; + splx(s); return 0; } + splx(s); return -EINVAL; +#elif defined(__WINDOWS__) + return 0; #else # error "wan_skb_correct() function is not supported yet!" #endif @@ -1606,6 +1860,15 @@ static __inline unsigned char* wan_skb_pull(void* skb, int len) #if defined(__LINUX__) return skb_pull((struct sk_buff*)skb, len); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + struct mbuf *m = (struct mbuf*)skb; + + WAN_SKBCRITASSERT(m); + if (len > m->m_ext.ext_size){ + panic("%s:%d: Buffer is too small (%d:%d)!\n", + __FUNCTION__,__LINE__, + len,m->m_ext.ext_size); + return NULL; + } m_adj(skb, len); #if 0 struct mbuf* m = (struct mbuf*)skb; @@ -1614,6 +1877,8 @@ static __inline unsigned char* wan_skb_pull(void* skb, int len) m->m_len = m->m_pkthdr.len; #endif return wan_skb_data(skb); +#elif defined(__WINDOWS__) + return skb_pull((struct sk_buff*)skb, len); #else # error "wan_skb_pull() function is not supported yet!" #endif @@ -1632,6 +1897,14 @@ static __inline unsigned char* wan_skb_put(void* skb, int len) int org_len = wan_skb_len(skb); unsigned char* data = wan_skb_data(skb); + WAN_SKBCRITASSERT(m); + if (org_len + len > m->m_ext.ext_size){ + panic("%s:%d: Buffer is too small (%d:%d:%d)!\n", + __FUNCTION__,__LINE__, + org_len,len,m->m_ext.ext_size); + return NULL; + } + m->m_len = org_len + len; m->m_pkthdr.len = org_len + len; /*Alex Sep27,2004 last tail but not data pointer return wan_skb_data(skb);*/ @@ -1641,6 +1914,8 @@ static __inline unsigned char* wan_skb_put(void* skb, int len) unsigned char *wptr=mp->b_wptr; mp->b_wptr += len; return mp->b_wptr; +#elif defined(__WINDOWS__) + return skb_put((struct sk_buff*)skb, len); #else # error "wan_skb_put() function is not supported yet!" #endif @@ -1658,29 +1933,34 @@ static __inline unsigned char* wan_skb_push(void* skb, int len) struct mbuf *m = (struct mbuf*)skb; int org_len = wan_skb_len(skb); + WAN_SKBCRITASSERT(m); if (m->m_flags & M_EXT){ if ((m->m_data - len) < m->m_ext.ext_buf){ - DEBUG_EVENT("Can't push %d bytes!\n", len); - return wan_skb_data(skb); + panic("%s:%d: Can't push %d bytes (%p:%p)!\n", + __FUNCTION__,__LINE__, + len,m->m_data,m->m_ext.ext_buf); + return NULL; } }else{ if ((m->m_data - len) < m->m_pktdat){ - DEBUG_EVENT("Can't push %d bytes!\n", len); - return wan_skb_data(skb); + panic("%s:%d: Can't push %d bytes (%p:%p)!\n", + __FUNCTION__,__LINE__, + len,m->m_data,m->m_pktdat); + return NULL; } } m->m_data -= len; m->m_len = org_len + len; m->m_pkthdr.len = org_len + len; return wan_skb_data(skb); +#elif defined(__WINDOWS__) + return skb_push((struct sk_buff*)skb, len); #else # error "wan_skb_push() function is not supported yet!" #endif } - - /* ** wan_skb_tailroom() - Tail room ** @@ -1693,10 +1973,13 @@ static __inline int wan_skb_tailroom(void* skb) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf* m = (struct mbuf*)skb; + WAN_SKBCRITASSERT(m); if (m->m_flags & M_EXT){ - return (MCLBYTES - m->m_len); + return (m->m_ext.ext_size/*MCLBYTES*/ - m->m_len); } return (MHLEN - m->m_len); +#elif defined(__WINDOWS__) + return skb_tailroom(skb); #else # error "wan_skb_tailroom() function is not supported yet!" #endif @@ -1714,10 +1997,13 @@ static __inline int wan_skb_headroom(void* skb) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf* m = (struct mbuf*)skb; + WAN_SKBCRITASSERT(m); if (m->m_flags & M_EXT){ return (m->m_data - m->m_ext.ext_buf); } return (m->m_data - m->m_pktdat); +#elif defined(__WINDOWS__) + return skb_headroom(skb); #else # error "wan_skb_headroom() function is not supported yet!" #endif @@ -1736,14 +2022,12 @@ static __inline void wan_skb_trim(void* skb, unsigned int len) skb_trim(skb, len); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf* m = (struct mbuf*)skb; -#if 0 - /* Trim only moves tail to head+len (Oct13) */ - if (len == 0){ - m->m_data = m->m_ext.ext_buf; - } -#endif + + WAN_SKBCRITASSERT(m); m->m_pkthdr.len = len; m->m_len = m->m_pkthdr.len; +#elif defined(__WINDOWS__) + skb_trim(skb, len); #else # error "wan_skb_trim() function is not supported yet!" #endif @@ -1759,12 +2043,27 @@ static __inline void wan_skb_init(void* pskb, unsigned int len) #if defined(__LINUX__) struct sk_buff* skb = (struct sk_buff*)pskb; skb->data = skb->head + len; - wan_skb_reset_tail_pointer(skb); + __wan_skb_reset_tail_pointer(skb); skb->len = 0; skb->data_len = 0; + #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) struct mbuf* m = (struct mbuf*)pskb; - m->m_data = m->m_ext.ext_buf + len; + + WAN_SKBCRITASSERT(m); + if (m->m_ext.ext_buf == NULL){ + panic("wan_skb_init: Invalid mbuf ext_buf pointer!\n"); + return; + } + m->m_data = m->m_ext.ext_buf + len; + m->m_pkthdr.len = 0; //was len + m->m_len = 0; //was len +#elif defined(__WINDOWS__) + struct sk_buff* skb = (struct sk_buff*)pskb; + skb->data = skb->head + len; + skb->tail = skb->data; + skb->len = 0; + skb->data_len = 0; #else # error "wan_skb_init() function is not supported yet!" #endif @@ -1788,17 +2087,25 @@ static __inline int wan_skb_print(void* skb) int len = m->m_pkthdr.len, i; unsigned char *data = wan_skb_data(skb); - if (m->m_type & M_PKTHDR) - DEBUG_EVENT("M_PKTHDR flag set (%d)!\n", - m->m_pkthdr.len); - if (m->m_type & M_EXT) - DEBUG_EVENT("M_EXT flag set (%d)!\n", - m->m_pkthdr.len); DEBUG_EVENT("Packet %d bytes: ", len); - for(i=0;im_type & M_PKTHDR) + DEBUG_EVENT("M_PKTHDR flag set (%d)!\n", + m->m_pkthdr.len); + if (m->m_type & M_EXT) + DEBUG_EVENT("M_EXT flag set (%d)!\n", + m->m_pkthdr.len); + data = mtod(m, unsigned char*); + len = wan_skb_len(m); + DEBUG_EVENT("mbuf chain %d bytes: ", len); + for(i=0;im_next; + } +#elif defined(__WINDOWS__) + dev_print_skb(skb); #endif return 0; } @@ -1826,6 +2133,8 @@ static __inline void wan_skb_unlink(void* pskb) skb_unlink((struct sk_buff*)pskb); # endif #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # error "wan_skb_unlink() function is not supported yet!" #endif @@ -1842,6 +2151,8 @@ static __inline void wan_skb_queue_init(void *list) skb_queue_head_init(list); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) WAN_IFQ_INIT((wan_skb_queue_t*)list, IFQ_MAXLEN); +#elif defined(__WINDOWS__) + skb_queue_head_init(list); #else # error "wan_skb_queue_init() function is not supported yet!" #endif @@ -1861,6 +2172,8 @@ static __inline void wan_skb_queue_purge(void *list) } #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) WAN_IFQ_PURGE(((wan_skb_queue_t*)list)); +#elif defined(__WINDOWS__) + skb_queue_purge(list); #else # error "wan_skb_queue_purge() function is not supported yet!" #endif @@ -1876,6 +2189,8 @@ static __inline void wan_skb_queue_tail(void* list, void* newsk) skb_queue_tail(list, newsk); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) IF_ENQUEUE((wan_skb_queue_t*)list, (struct mbuf*)newsk); +#elif defined(__WINDOWS__) + skb_queue_tail(list, newsk); #else # error "wan_skb_queue_tail() function is not supported yet!" #endif @@ -1891,6 +2206,8 @@ static __inline void wan_skb_queue_head(void* list, void* newsk) skb_queue_head(list, newsk); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) IF_PREPEND((wan_skb_queue_t*)list, (struct mbuf*)newsk); +#elif defined(__WINDOWS__) + skb_queue_head(list, newsk); #endif } @@ -1906,6 +2223,8 @@ static __inline int wan_skb_queue_len(void* list) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) wan_skb_queue_t* ifqueue = (wan_skb_queue_t*)list; return WAN_IFQ_LEN(ifqueue); +#elif defined(__WINDOWS__) + return skb_queue_len(list); #else # error "wan_skb_queue_len() function is not supported yet!" #endif @@ -1923,8 +2242,10 @@ static __inline void *wan_skb_dequeue(void* list) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) netskb_t* newsk = NULL; - IF_DEQUEUE((wan_skb_queue_t*)list, newsk); + IFQ_DEQUEUE((wan_skb_queue_t*)list, newsk); return (void*)newsk; +#elif defined(__WINDOWS__) + return skb_dequeue(list); #else # error "wan_skb_dequeue() function is not supported yet!" #endif @@ -1987,6 +2308,8 @@ static __inline int wan_netif_init(netdevice_t* dev, char* ifname) # else strcpy(dev->name, ifname); # endif +#elif defined(__WINDOWS__) + strncpy(dev->name, ifname, IFNAMSIZ); #else # error "wan_netif_init() function is not supported yet!" #endif @@ -2008,6 +2331,8 @@ static __inline int wan_netif_del(netdevice_t* dev) /* Do nothing */ #elif defined(__LINUX__) /* Do nothing */ +#elif defined(__WINDOWS__) + /* Do nothing */ #else # error "wan_netif_del() function is not supported yet!" #endif @@ -2018,7 +2343,6 @@ static __inline int wan_netif_del(netdevice_t* dev) #if defined(__LINUX__) static __inline void wan_netif_fake_init(netdevice_t *d) { - #ifdef LINUX_FEAT_2624 d->header_ops = NULL; #else @@ -2119,6 +2443,18 @@ wan_netif_alloc(unsigned char *devname, int ifType, int *err) } } return ifp; +#elif defined(__WINDOWS__) + netdevice_t *dev=wan_malloc(sizeof(netdevice_t)); + *err=0; + + if (!dev){ + *err=-ENOMEM; + return NULL; + } + memset(dev, 0, sizeof(netdevice_t)); + + strncpy(dev->name,devname,IFNAMSIZ); + return dev; #else # error "wan_netif_alloc() unsupported" #endif @@ -2143,6 +2479,8 @@ static __inline void wan_netif_free(netdevice_t *dev) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) wan_netif_del(dev); IFFREE(dev); /*wan_free(dev);*/ +#elif defined(__WINDOWS__) + wan_free(dev); #else #error "wan_netif_free() not supported!" #endif @@ -2164,6 +2502,8 @@ static __inline char* wan_netif_name(netdevice_t* dev) # endif #elif defined(__OpenBSD__) || defined(__NetBSD__) sprintf(ifname, "%s", dev->if_xname); +#elif defined(__WINDOWS__) + strcpy(ifname, dev->name); #else # error "wan_get_ifname() function is not supported yet!" #endif @@ -2177,6 +2517,8 @@ static __inline void* wan_netif_priv(netdevice_t* dev) return dev->priv; #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) return dev->if_softc; +#elif defined(__WINDOWS__) + return dev->priv; #else # error "wan_netif_priv() function is not supported yet!" #endif @@ -2189,6 +2531,8 @@ static __inline int wan_netif_up(netdevice_t* dev) return WAN_NETIF_UP(dev); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) return WAN_NETIF_UP(dev); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # error "wan_netif_up() function is not supported yet!" #endif @@ -2202,6 +2546,8 @@ static __inline void wan_netif_set_priv(netdevice_t* dev, void* priv) dev->priv = priv; #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) dev->if_softc = priv; +#elif defined(__WINDOWS__) + dev->priv = priv; #else # error "wan_netif_priv() function is not supported yet!" #endif @@ -2215,6 +2561,8 @@ static __inline short wan_netif_flags(netdevice_t* dev) return dev->flags; #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) return dev->if_flags; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # error "wan_netif_flags() function is not supported yet!" #endif @@ -2228,6 +2576,8 @@ static __inline int wan_netif_mcount(netdevice_t* dev) return dev->if_amcount; #elif defined(__OpenBSD__) || defined(__NetBSD__) return 0; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # error "wan_netif_mcount() function is not supported yet!" #endif @@ -2238,6 +2588,8 @@ static __inline int wan_netif_set_ticks(netdevice_t* dev, unsigned long ticks) #if defined(__LINUX__) dev->trans_start = ticks; #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__WINDOWS__) + dev->trans_start = ticks; #else # error "wan_netif_set_ticks() function is not supported yet!" #endif @@ -2249,6 +2601,8 @@ static __inline int wan_netif_set_mtu(netdevice_t* dev, unsigned long mtu) #if defined(__LINUX__) #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) dev->if_mtu = mtu; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # error "wan_netif_set_mtu() function is not supported yet!" #endif @@ -2264,7 +2618,7 @@ wan_bpf_report(netdevice_t* dev, void* pkt, int flag, int dir) /* Do nothing */ #elif defined(__FreeBSD__) if (dev->if_bpf != NULL){ /* BF-0002 */ - WAN_BPF_REPORT(dev, pkt); + WAN_BPF_REPORT(dev, pkt, dir); } #elif defined(__OpenBSD__) || defined(__NetBSD__) if (dev->if_bpf != NULL){ /* BF-0002 */ @@ -2279,6 +2633,9 @@ wan_bpf_report(netdevice_t* dev, void* pkt, int flag, int dir) WAN_BPF_REPORT(dev, pkt, dir); } } +#elif defined(__WINDOWS__) + /* Do nothing */ + FUNC_NOT_IMPL #else # error "wan_bpf_report() function is not supported yet!" #endif @@ -2288,12 +2645,35 @@ wan_bpf_report(netdevice_t* dev, void* pkt, int flag, int dir) -static __inline void wan_spin_lock_init(void *lock) +static __inline void wan_spin_lock_init(void *lock, char *name) { #if defined(__LINUX__) spin_lock_init(((spinlock_t*)lock)); #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) /*(*(wan_smp_flag_t*)flag) = 0;*/ +#if defined(SPINLOCK_OLD) +#else + mtx_init((struct mtx*)lock, name, MTX_NETWORK_LOCK, MTX_DEF); +#endif +#elif defined(__WINDOWS__) + spin_lock_init((wan_spinlock_t*)lock); +#else +# warning "wan_spin_lock_init() function is not supported yet!" +#endif +} + +static __inline void wan_spin_lock_irq_init(void *lock, char *name) +{ +#if defined(__LINUX__) + spin_lock_init(((spinlock_t*)lock)); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + /*(*(wan_smp_flag_t*)flag) = 0;*/ +#if defined(SPINLOCK_OLD) +#else + mtx_init((struct mtx*)lock, name, MTX_NETWORK_LOCK, MTX_SPIN); +#endif +#elif defined(__WINDOWS__) + spin_lock_init((wan_spinlock_t*)lock); #else # warning "wan_spin_lock_init() function is not supported yet!" #endif @@ -2302,15 +2682,21 @@ static __inline void wan_spin_lock_init(void *lock) static __inline int wan_spin_is_locked(void *lock) { #if defined(__LINUX__) - return spin_is_locked((spinlock_t*)lock); + return spin_is_locked(((spinlock_t*)lock)); #elif defined(__NetBSD__) || defined(__OpenBSD__) return 0;/*((*(wan_smp_flag_t*)flag) & imask[IPL_NET]);*/ #elif defined(__FreeBSD__) # if (__FreeBSD_version > 500000) +# if defined(SPINLOCK_OLD) return 0; +# else + return mtx_owned((struct mtx*)lock); +# endif # else return 0;/*((*(wan_smp_flag_t*)flag) & net_imask);*/ # endif +#elif defined(__WINDOWS__) + return 0;/* always returns 'unlocked' */ #else # warning "wan_spin_is_lock() function is not supported yet!" #endif @@ -2323,7 +2709,16 @@ static __inline void wan_spin_lock_irq(void *lock, wan_smp_flag_t *flag) #elif defined(__FreeBSD__) /* Feb 10, 2005 Change splnet to splimp ** (i think it was cause to system crash) */ - *flag = splimp(); +#if defined(SPINLOCK_OLD) + *flag = splhigh(); /*splimp();*/ +#else + if (!mtx_initialized((struct mtx*)lock)){ + DEBUG_EVENT( + "INTERNAL ERROR: Spin Lock IRQ is no initialized!\n"); + return; + } + mtx_lock_spin((struct mtx*)lock); +#endif #elif defined(__OpenBSD__) *flag = splnet(); #elif defined(__NetBSD__) @@ -2332,6 +2727,8 @@ static __inline void wan_spin_lock_irq(void *lock, wan_smp_flag_t *flag) # else *flag = splimp(); # endif +#elif defined(__WINDOWS__) + spin_lock_irqsave((wan_spinlock_t*)lock); #else # warning "wan_spin_lock_irq() function is not supported yet!" #endif @@ -2339,14 +2736,45 @@ static __inline void wan_spin_lock_irq(void *lock, wan_smp_flag_t *flag) static __inline void wan_spin_unlock_irq(void *lock, wan_smp_flag_t *flag) { #if defined(__LINUX__) - spin_unlock_irqrestore(((spinlock_t*)lock),*flag); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + spin_unlock_irqrestore((spinlock_t*)lock,*flag); +#elif defined(__FreeBSD__) +#if defined(SPINLOCK_OLD) splx(*flag); +#else + if (!mtx_initialized((struct mtx*)lock)){ + DEBUG_EVENT( + "INTERNAL ERROR: Spin Lock IRQ is no initialized!\n"); + return; + } + mtx_unlock_spin((struct mtx*)lock); +#endif +#elif defined(__OpenBSD__) || defined(__NetBSD__) + splx(*flag); +#elif defined(__WINDOWS__) + spin_unlock_irqrestore((wan_spinlock_t*)lock); #else # warning "wan_spin_unlock_irq() function is not supported yet!" #endif } +static __inline int wan_spin_trylock(void *lock) +{ +#if defined(__LINUX__) + return spin_trylock(((spinlock_t*)lock)); +#elif defined(__FreeBSD__) + return mtx_trylock((struct mtx*)lock); +#elif defined(__OpenBSD__) + #warning "FIXME: Complete this code.!!!!!!!!!!!" +#elif defined(__NetBSD__) + #warning "FIXME: Complete this code.!!!!!!!!!!!" +#elif defined(__WINDOWS__) + return spin_trylock((wan_spinlock_t*)lock); +#else +# warning "wan_spin_trylock() function is not supported yet!" +#endif + return 0; +} + static __inline void wan_spin_lock(void *lock) { #if defined(__LINUX__) @@ -2354,7 +2782,16 @@ static __inline void wan_spin_lock(void *lock) #elif defined(__FreeBSD__) /* Feb 10, 2005 Change splnet to splimp ** (i think it was cause to system crash) */ +#if defined(SPINLOCK_OLD) *((wan_spinlock_t*)lock) = splimp(); +#else + if (!mtx_initialized((struct mtx*)lock)){ + DEBUG_EVENT( + "INTERNAL ERROR: Spin Lock IRQ is no initialized!\n"); + return; + } + mtx_lock((struct mtx*)lock); +#endif #elif defined(__OpenBSD__) *((wan_spinlock_t*)lock) = splnet(); #elif defined(__NetBSD__) @@ -2363,6 +2800,8 @@ static __inline void wan_spin_lock(void *lock) # else *((wan_spinlock_t*)lock) = splimp(); # endif +#elif defined(__WINDOWS__) + spin_lock((wan_spinlock_t*)lock); #else # warning "wan_spin_lock() function is not supported yet!" #endif @@ -2371,8 +2810,21 @@ static __inline void wan_spin_unlock(void *lock) { #if defined(__LINUX__) spin_unlock(((spinlock_t*)lock)); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__FreeBSD__) +#if defined(SPINLOCK_OLD) splx(*(wan_spinlock_t*)lock); +#else + if (!mtx_initialized((struct mtx*)lock)){ + DEBUG_EVENT( + "INTERNAL ERROR: Spin Lock IRQ is no initialized!\n"); + return; + } + mtx_unlock((struct mtx*)lock); +#endif +#elif defined(__OpenBSD__) || defined(__NetBSD__) + splx(*(wan_spinlock_t*)lock); +#elif defined(__WINDOWS__) + spin_unlock((wan_spinlock_t*)lock); #else # warning "wan_spin_unlock() function is not supported yet!" #endif @@ -2438,5 +2890,47 @@ static __inline void wan_write_bus_4(void *phw, void *virt, int offset, unsigned } #endif +#if defined(__WINDOWS__) + +# define WAN_SPIN_LOCK_INIT(pSpinLock) \ +{ \ + int rc=1; \ + VERIFY_PASSIVE_IRQL(rc); \ + if(rc == 0){ \ + KeInitializeSpinLock(pSpinLock); \ + } \ +} + +/////////////////////////////////////////////////////// +//for use at IRQL <= DISPATCH_LEVEL +# define WAN_SPIN_LOCK_IRQSAVE(pSpinLock) \ +{ \ + int rc=SILENT; \ + VERIFY_DISPATCH_IRQL(rc); \ + if(rc == 0){ \ + KeAcquireSpinLock(pSpinLock, &old_IRQL);\ + } \ +} + +# define WAN_SPIN_UNLOCK_IRQSAVE(pSpinLock) \ + KeReleaseSpinLock(pSpinLock, old_IRQL); + +//for use at IRQL == DISPATCH_LEVEL - more efficient +//when known to run in DPC +# define WAN_SPIN_LOCK_DPC(pSpinLock) \ +{ \ + int rc=1; \ + if(0)DBG_IRQLOCK("WAN_SPIN_LOCK_DPC: caller: %s\n",__FUNCTION__); \ + \ + VERIFY_IRQL_EQUAL_DISPATCH(rc); \ + if(rc == 0){ \ + KeAcquireSpinLockAtDpcLevel(pSpinLock); \ + } \ +} + +# define WAN_SPIN_UNLOCK_DPC(pSpinLock) \ + KeReleaseSpinLockFromDpcLevel(pSpinLock); +#endif + #endif /* WAN_KERNEL */ #endif /* __WANPIPE_COMMON_H */ diff --git a/patches/kdrivers/include/wanpipe_common.h~ b/patches/kdrivers/include/wanpipe_common.h~ deleted file mode 100644 index fa8d5a4..0000000 --- a/patches/kdrivers/include/wanpipe_common.h~ +++ /dev/null @@ -1,2442 +0,0 @@ -/* - * Copyright (c) 2002 - * Alex Feldman . All rights reserved. - * - * $Id: wanpipe_common.h,v 1.175 2007/02/24 00:17:14 sangoma Exp $ - */ - -/**************************************************************************** - * wanpipe_common.h WANPIPE(tm) Multiprotocol WAN Link Driver. - * - * Author: Alex Feldman - * - * ========================================================================== - * July 17, 2002 Alex Feldman Initial Version - **************************************************************************** - */ - -#ifndef __WANPIPE_COMMON_H -# define __WANPIPE_COMMON_H - -#ifdef __LINUX__ -# include -#else -# include -#endif - -#ifdef WAN_DEBUG_MEM -extern atomic_t wan_debug_mem; -#endif - -/**************************************************************************** -** D E F I N E S -****************************************************************************/ -#ifndef NIPQUAD -# define NIPQUAD(addr) \ - ((unsigned char *)&addr)[0], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[3] -#endif - -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - -# define WAN_LIST_HEAD(name, type) LIST_HEAD(name, type) -# define WAN_LIST_HEAD_INITIALIZER(head) LIST_HEAD_INITIALIZER(head) -# define WAN_LIST_ENTRY(type) LIST_ENTRY(type) -# define WAN_LIST_EMPTY(head) LIST_EMPTY(head) -# define WAN_LIST_FIRST(head) LIST_FIRST(head) -# define WAN_LIST_FOREACH(var, head, field) LIST_FOREACH(var, head, field) -# define WAN_LIST_INIT(head) LIST_INIT(head) -# define WAN_LIST_INSERT_AFTER(listelm, elm, field) LIST_INSERT_AFTER(listelm, elm, field) -/*# define WAN_LIST_INSERT_BEFORE(listelm, elm, field) LIST_INSERT_BEFORE(listelm, elm, field)*/ -# define WAN_LIST_INSERT_HEAD(head, elm, field) LIST_INSERT_HEAD(head, elm, field) -# define WAN_LIST_NEXT(elm, field) LIST_NEXT(elm, field) -# define WAN_LIST_REMOVE(elm, field) LIST_REMOVE(elm, field) - -#elif defined(__SOLARIS__) - -/* ********* S O L A R I S *****************/ - -# define WAN_LIST_HEAD(name, type) struct name { struct type * lh_first; } -# define WAN_LIST_HEAD_INITIALIZER(head) { NULL } -# define WAN_LIST_ENTRY(type) struct { struct type *le_next; struct type **le_prev; } -# define WAN_LIST_FIRST(head) ((head)->lh_first) -# define WAN_LIST_END(head) NULL -# define WAN_LIST_EMPTY(head) (WAN_LIST_FIRST(head) == WAN_LIST_END(head)) -# define WAN_LIST_NEXT(elm, field) ((elm)->field.le_next) -# define WAN_LIST_FOREACH(var, head, field) for((var) = WAN_LIST_FIRST(head); \ - (var); \ - (var) = WAN_LIST_NEXT(var, field)) -# define WAN_LIST_INIT(head) do { WAN_LIST_FIRST(head) = NULL;}\ - while(0) - -#define WAN_LIST_INSERT_HEAD(head, elm, field) do { \ - if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_FIRST((head))) != NULL) \ - WAN_LIST_FIRST((head))->field.le_prev = &WAN_LIST_NEXT((elm), field);\ - WAN_LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &WAN_LIST_FIRST((head)); \ -} while (0) -#define WAN_LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_NEXT((listelm), field)) != NULL)\ - WAN_LIST_NEXT((listelm), field)->field.le_prev = \ - &WAN_LIST_NEXT((elm), field); \ - WAN_LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &WAN_LIST_NEXT((listelm), field); \ -} while (0) -#define WAN_LIST_REMOVE(elm, field) do { \ - if (WAN_LIST_NEXT((elm), field) != NULL) \ - WAN_LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = WAN_LIST_NEXT((elm), field); \ -} while (0) - - -#elif defined(__LINUX__) -/* ********* L I N U X *****************/ - -# define WAN_LIST_HEAD(name, type) struct name { struct type * lh_first; } -# define WAN_LIST_HEAD_INITIALIZER(head) { NULL } -# define WAN_LIST_ENTRY(type) struct { struct type *le_next; struct type **le_prev; } -# define WAN_LIST_FIRST(head) ((head)->lh_first) -# define WAN_LIST_END(head) NULL -# define WAN_LIST_EMPTY(head) (WAN_LIST_FIRST(head) == WAN_LIST_END(head)) -# define WAN_LIST_NEXT(elm, field) ((elm)->field.le_next) -# define WAN_LIST_FOREACH(var, head, field) for((var) = WAN_LIST_FIRST(head); \ - (var); \ - (var) = WAN_LIST_NEXT(var, field)) -# define WAN_LIST_INIT(head) do { WAN_LIST_FIRST(head) = NULL;}\ - while(0) - -#define WAN_LIST_INSERT_HEAD(head, elm, field) do { \ - if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_FIRST((head))) != NULL) \ - WAN_LIST_FIRST((head))->field.le_prev = &WAN_LIST_NEXT((elm), field);\ - WAN_LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &WAN_LIST_FIRST((head)); \ -} while (0) -#define WAN_LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((WAN_LIST_NEXT((elm), field) = WAN_LIST_NEXT((listelm), field)) != NULL)\ - WAN_LIST_NEXT((listelm), field)->field.le_prev = \ - &WAN_LIST_NEXT((elm), field); \ - WAN_LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &WAN_LIST_NEXT((listelm), field); \ -} while (0) -#define WAN_LIST_REMOVE(elm, field) do { \ - if (WAN_LIST_NEXT((elm), field) != NULL) \ - WAN_LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = WAN_LIST_NEXT((elm), field); \ -} while (0) - -#else -# error "WAN_LISTx macros not supported yet!" -#endif - -#if defined(WAN_KERNEL) - -#if defined(__FreeBSD__) -# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrhead) -# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_link) -#elif defined (__OpenBSD__) -# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrlist) -# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_list) -#elif defined (__NetBSD__) -# define WAN_TAILQ_FIRST(ifp) TAILQ_FIRST(&ifp->if_addrlist) -# define WAN_TAILQ_NEXT(ifa) TAILQ_NEXT(ifa, ifa_list) -#elif defined(__LINUX__) -#elif defined(__SOLARIS__) -#elif defined(__WINDOWS__) -#else -# error "WAN_TAILQ_x macros doesn't supported yet!" -#endif - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# if defined(__FreeBSD__) -# define WAN_PKTATTR_DECL(pktattr) -# else -# define WAN_PKTATTR_DECL(pktattr) struct altq_pktattr pktattr -# endif -# define WAN_IFQ_SET_READY IFQ_SET_READY -# define WAN_IFQ_IS_EMPTY IFQ_IS_EMPTY -# define WAN_IFQ_INC_LEN IFQ_INC_LEN -# define WAN_IFQ_DEC_LEN IFQ_DEC_LEN -# define WAN_IFQ_INC_DROPS IFQ_INC_DROPS -# define WAN_IFQ_SET_MAXLEN IFQ_SET_MAXLEN -# define WAN_IFQ_PURGE IFQ_PURGE -# if (__FreeBSD_version > 503000) -# define WAN_IFQ_ENQUEUE(ifq, m, pattr, err) IFQ_ENQUEUE((ifq),(m),(err)) -# else -# define WAN_IFQ_ENQUEUE IFQ_ENQUEUE -# endif -# define WAN_IFQ_DEQUEUE IFQ_DEQUEUE -# define WAN_IFQ_POLL IFQ_POLL -# define WAN_IFQ_CLASSIFY IFQ_CLASSIFY -# define WAN_IFQ_INIT IFQ_INIT -# define WAN_IFQ_LEN IFQ_LEN -#elif defined(__LINUX__) -# define WAN_IFQ_INIT(ifq, max_pkt) skb_queue_head_init((ifq)) -# define WAN_IFQ_PURGE(ifq) skb_queue_purge((ifq)) -# define WAN_IFQ_ENQUEUE(ifq, skb, arg, err) skb_queue_tail((ifq), (skb)) -# define WAN_IFQ_LEN(ifq) skb_queue_len((ifq)) -#elif defined(__WINDOWS__) -#else -# error "Undefined IFQ_x macros!" -#endif - -#if defined(__FreeBSD__) -# if (__FreeBSD_version < 410000) -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - (task)->task_func = func; (task)->data = arg -# define WAN_TASKLET_SCHEDULE(task) \ - if (!wan_test_bit(0, &(task)->running)){ \ - wan_set_bit(0, &(task)->running); \ - (task)->task_func((task)->data, 0); \ - } -# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) - -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -# define WAN_TASKLET_KILL(task) -# else -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - TASK_INIT(&(task)->task_id, priority, func, (void*)arg) -# define WAN_TASKLET_SCHEDULE(task) \ - if (!wan_test_bit(0, &(task)->running)){ \ - wan_set_bit(0, &(task)->running); \ - taskqueue_enqueue(taskqueue_swi, &(task)->task_id); \ - } -# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) - -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -/* taskqueue_run(taskqueue_swi); \*/ -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_KILL(task) -# endif -#elif defined(__OpenBSD__) || defined(__NetBSD__) -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - (task)->task_func = func; (task)->data = arg -# define WAN_TASKLET_SCHEDULE(task) \ - if (!wan_test_bit(0, &(task)->running)){ \ - wan_set_bit(0, &(task)->running); \ - (task)->task_func((task)->data, 0); \ - } - -# define __WAN_TASKLET_SCHEDULE(task) WAN_TASKLET_SCHEDULE(task) - -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_KILL(task) - - -#elif defined(__LINUX__) - -# define WAN_TASKLET_INIT(task, priority, func, arg) \ - (task)->running = 0; \ - tasklet_init(&(task)->task_id,func,(unsigned long)arg) - -# define WAN_TASKLET_SCHEDULE(task) \ - wan_set_bit(0, &(task)->running); \ - tasklet_schedule(&(task)->task_id); - -#if 0 -# define WAN_WP_TASKLET_SCHEDULE_PER_CPU(task,cpu) \ - wan_set_bit(0, &(task)->running); \ - wp_tasklet_hi_schedule_per_cpu(&(task)->task_id,cpu); -#endif - -# define WAN_TASKLET_RUNNING(task) \ - wan_test_bit(0, &(task)->running) - -# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) -# define WAN_TASKLET_KILL(task) tasklet_kill(&(task)->task_id) - - -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_TASKLET_x macro!" -#endif - -#if defined(__FreeBSD__) -# if (__FreeBSD_version < 410000) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - (task)->tfunc = func; task->data = arg -# else -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - TASK_INIT(&task->tqueue, priority, func, arg) -# endif -#elif defined(__OpenBSD__) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - (task)->tfunc = func; task->data = arg -#elif defined(__NetBSD__) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - (task)->tfunc = func; task->data = arg -#elif defined(__LINUX__) -/* Due to 2.6.20 kernel the wan_taskq_t is now a direct - * workqueue struct not an abstracted structure */ -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - INIT_WORK((task),func,arg) -# else -# define WAN_TASKQ_INIT(task, priority, func, arg) \ - INIT_WORK((task),func) -# endif - -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_TASKQ_INIT macro!" -#endif - -#if defined(__FreeBSD__) && (__FreeBSD_version >= 410000) -# define WAN_IS_TASKQ_SCHEDULE -# define WAN_TASKQ_SCHEDULE(task) \ - taskqueue_enqueue(taskqueue_swi, &task->tqueue);\ - taskqueue_run(taskqueue_swi) -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# define WAN_IS_TASKQ_SCHEDULE -# define WAN_TASKQ_SCHEDULE(task) \ - task->tfunc(task->data, 0) -#elif defined(__LINUX__) -# define WAN_IS_TASKQ_SCHEDULE -# define WAN_TASKQ_SCHEDULE(task) \ - wan_schedule_task(task) -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_TASKQ_SCHEDULE macro!" -#endif - -#if defined(__LINUX__) -# define WAN_COPY_FROM_USER(k,u,l) copy_from_user(k,u,l) -# define WAN_COPY_TO_USER(u,k,l) copy_to_user(u,k,l) -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# define WAN_COPY_FROM_USER(k,u,l) copyin(u,k,l) -# define WAN_COPY_TO_USER(u,k,l) copyout(k,u,l) -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_COPY_FROM_USER/WAN_COPY_TO_USER macros!" -#endif - -#if defined(__LINUX__) -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) -# define WAN_NETIF_WAKE_QUEUE(dev) do { \ - clear_bit(0, &dev->tbusy); \ - mark_bh(NET_BH); \ - } while(0) -# define WAN_NETIF_START_QUEUE(dev) do { \ - dev->tbusy = 0; \ - dev->interrupt = 0; \ - dev->start = 1; \ - } while(0); -# define WAN_NETIF_STOP_QUEUE(dev) set_bit(0, &dev->tbusy) -# define WAN_NETIF_RUNNING(dev) dev->start -# define WAN_NETDEVICE_START(dev) dev->start = 1 -# define WAN_NETDEVICE_STOP(dev) dev->start = 0 -# define WAN_NETIF_QUEUE_STOPPED(dev) test_bit(0,&dev->tbusy) -# define WAN_NETIF_CARRIER_OFF(dev) -# define WAN_NETIF_CARRIER_ON(dev) -# define WAN_NETIF_CARRIER_OK(dev) 1 -# else -#if 0 -# define WAN_NETIF_WAKE_QUEUE(dev) do{ \ - if (((wanpipe_common_t *)dev->priv)->usedby == TDM_VOICE){ \ - DEBUG_EVENT("%s: TDM VOICE not waking but starting!!!!\n",dev->name); \ - netif_start_queue(dev); \ - }else{ \ - netif_wake_queue(dev); \ - } \ - }while(0) -#endif -# define WAN_NETIF_WAKE_QUEUE(dev) netif_wake_queue(dev); -# define WAN_NETIF_START_QUEUE(dev) netif_start_queue(dev) -# define WAN_NETIF_STOP_QUEUE(dev) netif_stop_queue(dev) -# define WAN_NETIF_RUNNING(dev) netif_running(dev) -# define WAN_NETDEVICE_START(dev) -# define WAN_NETDEVICE_STOP(dev) -# define WAN_NETIF_QUEUE_STOPPED(dev) netif_queue_stopped(dev) -# define WAN_NETIF_CARRIER_OFF(dev) netif_carrier_off(dev) -# define WAN_NETIF_CARRIER_ON(dev) netif_carrier_on(dev) -# define WAN_NETIF_CARRIER_OK(dev) netif_carrier_ok(dev) -# endif -# define WAN_NETIF_UP(dev) ((dev)->flags&IFF_UP) -# define WAN_NET_RATELIMIT net_ratelimit - -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# define WAN_NETIF_QUEUE_STOPPED(dev) (dev)->if_flags & IFF_DRV_OACTIVE -# define WAN_NETIF_WAKE_QUEUE(dev) (dev)->if_flags &= ~IFF_DRV_OACTIVE -#if 0 -# define WAN_NETIF_STOP_QUEUE(dev) -# define WAN_NETIF_START_QUEUE(dev) -#endif -# define WAN_NETIF_STOP_QUEUE(dev) (dev)->if_flags |= IFF_DRV_OACTIVE -# define WAN_NETIF_START_QUEUE(dev) (dev)->if_flags &= ~IFF_DRV_OACTIVE -# define WAN_NETIF_RUNNING(dev) 1 -# define WAN_NETIF_UP(dev) ((dev)->if_flags&IFF_UP) -# define WAN_NETDEVICE_STOP(dev) -# define WAN_NETDEVICE_START(dev) -# define NET_ADMIN_CHECK() -# define WAN_NET_RATELIMIT() 1 -# define MOD_INC_USE_COUNT -# define MOD_DEC_USE_COUNT - -# define WAN_NETIF_CARRIER_OFF(dev) -# define WAN_NETIF_CARRIER_ON(dev) -# define WAN_NETIF_CARRIER_OK(dev) 1 - -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_NETIF_x macros!" -#endif - -#if defined(__LINUX__) -# define WAN_BPF_DIR_IN (1<<0) -# define WAN_BPF_DIR_OUT (1<<1) -# define WAN_BPF_REPORT(dev,m) -#elif defined(__FreeBSD__) -# define WAN_BPF_DIR_IN (1<<0) -# define WAN_BPF_DIR_OUT (1<<1) -# if (__FreeBSD_version > 500000) -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)) -# else -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev), (m)) -# endif -#elif defined(__OpenBSD__) -# if (OpenBSD < 200611) -# define WAN_BPF_DIR_IN (1<<0) -# define WAN_BPF_DIR_OUT (1<<1) -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)); -# else -# define WAN_BPF_DIR_IN BPF_DIRECTION_IN -# define WAN_BPF_DIR_OUT BPF_DIRECTION_OUT -# define WAN_BPF_REPORT(dev,m,d) \ - if (dir == WAN_BPF_DIR_IN){ \ - bpf_mtap((dev)->if_bpf, (m), BPF_DIRECTION_IN); \ - }else{ \ - bpf_mtap((dev)->if_bpf, (m), BPF_DIRECTION_OUT); \ - } -# endif -#elif defined(__NetBSD__) -# define WAN_BPF_DIR_IN (1<<0) -# define WAN_BPF_DIR_OUT (1<<1) -# define WAN_BPF_REPORT(dev,m,d) bpf_mtap((dev)->if_bpf, (m)); -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_BPF_REPORT macro!" -#endif - - -#if defined (__LINUX__) -# define WAN_DEV_PUT(dev) wan_atomic_dec(&(dev)->refcnt) -# define WAN_DEV_HOLD(dev) wan_atomic_inc(&(dev)->refcnt) -# define __WAN_PUT(str) wan_atomic_dec(&(str)->refcnt) -# define WAN_PUT(str) if (atomic_dec_and_test(&(str)->refcnt)){ \ - wan_kfree(str); \ - } -# define WAN_HOLD(str) wan_atomic_inc(&(str)->refcnt) -#elif defined(__FreeBSD__) -# define WAN_DEV_PUT(dev) -# define WAN_DEV_HOLD(dev) -# define __WAN_PUT(str) wan_atomic_dec(&(str)->refcnt) -# define WAN_PUT(str) wan_atomic_dec(&str->refcnt); \ - if (str->refcnt){ \ - WAN_FREE(str); \ - } -# define WAN_HOLD(str) wan_atomic_inc(&(str)->refcnt) -#elif defined(__NetBSD__) || defined(__OpenBSD__) -# define WAN_DEV_PUT(dev) -# define WAN_DEV_HOLD(dev) -# define __WAN_PUT(str) str->refcnt-- -# define WAN_PUT(str) str->refcnt--; \ - if (str->refcnt){ \ - WAN_FREE(str); \ - } -# define WAN_HOLD(str) str->refcnt++ -#elif defined(__WINDOWS__) -#else -# warning "Undefined WAN_HOLD/WAN_PUT macro!" -#endif - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# ifdef ENABLE_SPPP -# define WAN_SPPP_ENABLED 1 -# define WAN_SPPP_ATTACH(ifp) sppp_attach(ifp) -# define WAN_SPPP_DETACH(ifp) sppp_detach(ifp) -# define WAN_SPPP_FLUSH(ifp) sppp_flush(ifp) -# define WAN_SPPP_PICK(ifp) sppp_pick(ifp) -# define WAN_SPPP_DEQUEUE(ifp) sppp_dequeue(ifp) -# define WAN_SPPP_ISEMPTY(ifp) sppp_isempty(ifp) -# define WAN_SPPP_INPUT(ifp,skb) sppp_input(ifp,skb) -# define WAN_SPPP_IOCTL(ifp,cmd,data) sppp_ioctl(ifp,cmd,data); -# else -# define WAN_SPPP_ENABLED 0 -# define WAN_SPPP_ATTACH(ifp) -# define WAN_SPPP_DETACH(ifp) -# define WAN_SPPP_FLUSH(ifp) -# define WAN_SPPP_PICK(ifp) NULL -# define WAN_SPPP_DEQUEUE(ifp) NULL -# define WAN_SPPP_ISEMPTY(ifp) 0 -# define WAN_SPPP_INPUT(ifp,skb) -# define WAN_SPPP_IOCTL(ifp,cmd,data) -EOPNOTSUPP -# endif -#elif defined(__LINUX__) -# define WAN_SPPP_ENABLED 1 -# define WAN_SPPP_IOCTL(ifp,cmd,data) -EOPNOTSUPP -#elif defined(__WINDOWS__) -#else -# error "Undefined WAN_SPPP_x macros!" -#endif - -#define WAN_MAX_TRACE_TIMEOUT (5*HZ) - -#if 0 -/* - * Variable argument list macro definitions - */ -#ifndef _VALIST -#define _VALIST -typedef char *va_list; -#endif /* _VALIST */ -#define _WAN_VA_SIZE(type) (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long)) - -#define WAN_VA_START(ap, A) ((ap) = (va_list) &(A) + _WAN_VA_SIZE(A)) -#define WAN_VA_ARG(ap, T) (*(T *)((ap) += _WAN_VA_SIZE(T),(ap) - _WAN_VA_SIZE (T))) -#define WAN_VA_END(ap) (void) 0 -#endif - - -/**************************************************************************** -** T Y P E D E F S -****************************************************************************/ -# if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -/* - * Ethernet statistics collection data - */ -struct net_device_stats -{ - unsigned long rx_packets; /* total packets received */ - unsigned long tx_packets; /* total packets transmited */ - unsigned long rx_bytes; /* total bytes received */ - unsigned long tx_bytes; /* total bytes transmited */ - unsigned long rx_errors; /* bad packet received */ - unsigned long tx_errors; /* packet transmit problems */ - unsigned long rx_dropped; /* no space in buffers */ - unsigned long tx_dropped; /* no space available */ - unsigned long multicast; /* multicast packet received */ - unsigned long collisions; - - /* detailed rx_errors */ - unsigned long rx_length_errors; - unsigned long rx_over_errors; /* receiver ring off buff overflow */ - unsigned long rx_crc_errors; /* recv'd pkt with crc error */ - unsigned long rx_frame_errors; /* recv'd frame alignment error */ - unsigned long rx_fifo_errors; /* recv'r fifo overrun */ - unsigned long rx_missed_errors; /* receiver missed packet */ - - /* detailed tx_errors */ - unsigned long tx_aborted_errors; - unsigned long tx_carrier_errors; - unsigned long tx_fifo_errors; - unsigned long tx_heartbeat_errors; - unsigned long tx_window_errors; - - /* for cslip etc */ - unsigned long rx_compressed; - unsigned long tx_compressed; -}; -#endif - -/**************************************************************************** -** F U N C T I O N P R O T O T Y P E S -****************************************************************************/ -unsigned int wan_dec2uint (unsigned char* str, int len); -char* wanpipe_get_state_string (void*); -void wanpipe_set_state (void*, int); -char wanpipe_get_state (void*); -void wanpipe_card_lock_irq (void *,unsigned long *); -void wanpipe_card_unlock_irq (void *,unsigned long *); -void wanpipe_set_baud(void*card,unsigned int baud); -unsigned long wan_get_ip_addr (void*, int); -int wan_udp_pkt_type (void*, caddr_t); -int wan_reply_udp (void*, unsigned char*, unsigned int); -unsigned short wan_calc_checksum(char *data, int len); -void wanpipe_debug_timer_init(void*); -void wan_trace_info_init(wan_trace_t *trace, int max_trace_queue); -int wan_trace_purge (wan_trace_t *trace); -int wan_trace_enqueue(wan_trace_t *trace, void *skb_ptr); -int wan_tracing_enabled(wan_trace_t *trace_info); -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -void wanpipe_debugging (void* data, int pending); -#else -void wanpipe_debugging (unsigned long data); -#endif -static __inline int wan_skb_tailroom(void* skb); - -/**************************************************************************** -** I N L I N E F U N C T I O N S -****************************************************************************/ -/******************* WANPIPE MALLOC/FREE FUNCTION ******************/ -/* -** wan_malloc - -*/ -static __inline void* wan_malloc(int size) -{ - void* ptr = NULL; -#if defined(__LINUX__) - ptr = kmalloc(size, GFP_ATOMIC); - if (ptr){ - DEBUG_ADD_MEM(size); - } -#elif defined(__SOLARIS__) - ptr=kmem_alloc(size,KM_NOSLEEP); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - ptr = malloc(size, M_DEVBUF, M_NOWAIT); -#elif defined(__WINDOWS__) - ptr = ExAllocatePool(NonPagedPool, size); -#else -# error "wan_malloc() function is not supported yet!" -#endif - if (ptr){ - memset(ptr, 0, size); - DEBUG_ADD_MEM(size); - } - return ptr; -} - -static __inline void* wan_kmalloc(int size) -{ - void* ptr = NULL; -#if defined(__LINUX__) - ptr = kmalloc(size, GFP_KERNEL); - if (ptr){ - DEBUG_ADD_MEM(size); - } -#elif defined(__SOLARIS__) - ptr=kmem_alloc(size,KM_NOSLEEP); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - ptr = malloc(size, M_DEVBUF, M_NOWAIT); -#elif defined(__WINDOWS__) - ptr = ExAllocatePool(NonPagedPool, size); -#else -# error "wan_malloc() function is not supported yet!" -#endif - if (ptr){ - memset(ptr, 0, size); - DEBUG_ADD_MEM(size); - } - return ptr; -} - -/* -** wan_free - -*/ -static __inline void wan_free(void* ptr) -{ - if (!ptr){ - DEBUG_EVENT("wan_free: NULL PTR !!!!!\n"); - return; - } - -#if defined(__LINUX__) - kfree(ptr); -#elif defined(__SOLARIS__) - kmem_free(ptr,sizeof(*ptr)); - DEBUG_EVENT("%s: Feeing Size %i\n",__FUNCTION__,sizeof(*ptr)); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return free(ptr, M_DEVBUF); -#elif defined(__WINDOWS__) - ExFreePool(ptr); -#else -# error "wan_free() function is not supported yet!" -#endif -} - -static __inline void* wan_vmalloc(int size) -{ - void* ptr = NULL; -#if defined(__LINUX__) - ptr = vmalloc(size); - if (ptr){ - DEBUG_ADD_MEM(size); - } -#elif defined(__FreeBSD__) - ptr = (caddr_t)kmem_alloc(kernel_map, size + sizeof(vm_size_t)); - if (ptr){ - vm_size_t *ptr1 = (vm_size_t*)ptr; - bzero(ptr, size); - *ptr1 = size + sizeof(vm_size_t); - ptr = ptr1++; - } -#elif defined(__OpenBSD__) || defined(__NetBSD__) - ptr = (caddr_t)uvm_km_alloc(kernel_map, size + sizeof(vsize_t)); - if (ptr){ - vsize_t *ptr1 = (vsize_t*)ptr; - bzero(ptr, size); - *ptr1 = size + sizeof(vsize_t); - ptr = ptr1++; - } -#elif defined(__SOLARIS__) -#elif defined(__WINDOWS__) -#else -# error "wan_vmalloc() function is not supported yet!" -#endif - if (ptr){ - memset(ptr, 0, size); - DEBUG_ADD_MEM(size); - } - return ptr; -} - -/* -** wan_vfree - -*/ -static __inline void wan_vfree(void* ptr) -{ - if (!ptr){ - DEBUG_EVENT("wan_vfree: NULL PTR !!!!!\n"); - return; - } -#if defined(__LINUX__) - vfree(ptr); -#elif defined(__FreeBSD__) - { - vm_size_t *ptr1 = (vm_size_t*)ptr; - ptr1 --; - kmem_free(kernel_map, (vm_offset_t)ptr1, (vm_size_t)*ptr1); - } -#elif defined(__OpenBSD__) || defined(__NetBSD__) - { - vsize_t *ptr1 = (vsize_t*)ptr; - ptr1 --; - uvm_km_free(kernel_map, (vaddr_t)ptr1, (vsize_t)*ptr1); - } -#elif defined(__SOLARIS__) -#elif defined(__WINDOWS__) -#else -# error "wan_free() function is not supported yet!" -#endif - return; -} - - -/******************* WANPIPE VIRT<->BUS SPACE FUNCTION ******************/ -/* -** wan_virt2bus -*/ -static __inline unsigned long wan_virt2bus(unsigned long* ptr) -{ -#if defined(__LINUX__) - return virt_to_bus(ptr); -#elif defined(__FreeBSD__) - return vtophys((vm_offset_t)ptr); -#elif defined(__OpenBSD__) || defined(__NetBSD__) - return vtophys((vaddr_t)ptr); -#elif defined(__WINDOWS__) -#else -# error "wan_virt2bus() function is not supported yet!" -#endif -} - -/* -** wan_bus2virt -*/ -static __inline unsigned long* wan_bus2virt(unsigned long virt_addr) -{ -#if defined(__LINUX__) - return bus_to_virt(virt_addr); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return (unsigned long*)virt_addr; -#elif defined(__WINDOWS__) -#else -# error "wan_bus2virt() function is not supported yet!" -#endif -} - - -/******************* WANPIPE DMA FUNCTION ******************/ - -/* -** wan_dma_alloc -*/ -static __inline int -wan_dma_alloc(void* hw, wan_dma_descr_t* dma_descr) -{ - int err = 0; -#if defined(__FreeBSD__) - err = bus_dma_tag_create(/*parent*/NULL, - /*alignemnt*/1, - /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/dma_descr->max_length, -# if (__FreeBSD_version >= 502000) - /*nsegments*/1, -# else - /*nsegments*/BUS_SPACE_UNRESTRICTED, -# endif - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, -# if (__FreeBSD_version >= 502000) - /*lockfunc*/NULL, /*lockfuncarg*/NULL, -# endif - &dma_descr->dmat); - if (err){ - DEBUG_EVENT("Failed create DMA tag (size=%ld)!\n", - dma_descr->max_length); - dma_descr->max_length = 0; - return err; - } - err = bus_dmamem_alloc(dma_descr->dmat, - (void**)&dma_descr->vAddr, - BUS_DMA_NOWAIT, - &dma_descr->dmamap); - if (err){ - DEBUG_EVENT("Failed allocate DMA (size=%ld)!\n", - dma_descr->max_length); - bus_dma_tag_destroy(dma_descr->dmat); - dma_descr->max_length = 0; - return err; - } -#elif defined(__OpenBSD__) || defined(__NetBSD__) - err = bus_dmamem_alloc(dma_descr->dmat, /* dma tag */ - dma_descr->max_length, /* size */ - PAGE_SIZE, /* alignment */ - 0, /* boundary */ - &dma_descr->dmaseg, /* serments */ - 1, /* num of segments */ - &dma_descr->rsegs, /* R num of segments */ - BUS_DMA_NOWAIT); - if (err){ - DEBUG_EVENT("Failed allocate DMA segment (size=%ld)!\n", - dma_descr->max_length); - dma_descr->max_length = 0; - return err; - } - err = bus_dmamem_map(dma_descr->dmat, /* dma tag */ - &dma_descr->dmaseg, /* segments */ - dma_descr->rsegs, /* return num of segments */ - dma_descr->max_length, /* size */ - (caddr_t*)&dma_descr->vAddr, /* kernel virtual address */ - BUS_DMA_NOWAIT); - if (err){ - DEBUG_EVENT("Failed map DMA segment (size=%ld)!\n", - dma_descr->max_length); - dma_descr->max_length = 0; - bus_dmamem_free(dma_descr->dmat, &dma_descr->dmaseg, dma_descr->rsegs); - return err; - } -#elif defined(__LINUX__) - dma_descr->vAddr = pci_alloc_consistent(NULL, - dma_descr->max_length, - (dma_addr_t *)&dma_descr->pAddr); - if (dma_descr->vAddr == NULL){ - err = -ENOMEM; - } -#elif defined(__WINDOWS__) - return -EINVAL; -#else -# error "wan_dma_alloc() function is not supported yet!" -#endif - return err; -} - -/* -** wan_dma_free -*/ -static __inline int -wan_dma_free(void* hw, wan_dma_descr_t* dma_descr) -{ -#if defined(__FreeBSD__) - bus_dmamem_free(dma_descr->dmat, dma_descr->vAddr, dma_descr->dmamap); - return bus_dma_tag_destroy(dma_descr->dmat); -#elif defined(__OpenBSD__) || defined(__NetBSD__) - bus_dmamem_unmap(dma_descr->dmat, (caddr_t)dma_descr->vAddr, dma_descr->max_length); - bus_dmamem_free(dma_descr->dmat, &dma_descr->dmaseg, dma_descr->rsegs); -#elif defined(__LINUX__) - - DEBUG_TEST("Freeing Pages 0x%p len=%li order=%i\n", - dma_descr->vAddr, - dma_descr->max_length, - get_order(dma_descr->max_length)); - - pci_free_consistent(NULL, dma_descr->max_length,dma_descr->vAddr,dma_descr->pAddr); - dma_descr->vAddr = NULL; - dma_descr->pAddr = 0; -#elif defined(__WINDOWS__) - return -EINVAL; -#else -# error "wan_dma_free() function is not supported yet!" -#endif - return 0; -} - -static __inline unsigned long* wan_dma_get_vaddr(void* card, wan_dma_descr_t* dma) -{ - return dma->vAddr; -} - -static __inline unsigned long wan_dma_get_paddr(void* card, wan_dma_descr_t* dma) -{ - return wan_virt2bus(dma->vAddr); -} - - - - - -/********************** WANPIPE TIMER FUNCTION **************************/ - - -static __inline int wan_getcurrenttime(unsigned long *sec, unsigned long *usec) -{ -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct timeval tv; - microtime(&tv); - if (sec) *sec = tv.tv_sec; - if (usec) *usec = tv.tv_usec; - return 0; -#elif defined(__WINDOWS__) - LARGE_INTEGER tv; - NdisGetCurrentSystemTime(&tv); - if (sec) *sec = (unsigned long)tv.QuadPart; - return 0; -#elif defined(__LINUX__) - struct timeval tv; - do_gettimeofday(&tv); - if (sec) *sec = tv.tv_sec; - if (usec) *usec = tv.tv_usec; - return 0; -#else -# error "wan_getcurrenttime() function is not supported yet!" -#endif -} - -/* -** wan_init_timer -*/ -static __inline void -wan_init_timer(wan_timer_t* wan_timer, wan_timer_func_t timer_func, wan_timer_arg_t arg) -{ -#if defined(__LINUX__) - init_timer(&wan_timer->timer_info); - wan_timer->timer_info.function = timer_func; - wan_timer->timer_info.data = arg; -#elif defined(__FreeBSD__) - /* FIXME_ADSL_TIMER */ - callout_handle_init(&wan_timer->timer_info); - wan_timer->timer_func = timer_func; - wan_timer->timer_arg = arg; -#elif defined(__OpenBSD__) - timeout_set(&wan_timer->timer_info, timer_func, (void*)arg); - wan_timer->timer_func = timer_func; - wan_timer->timer_arg = arg; -#elif defined(__NetBSD__) - callout_init(&wan_timer->timer_info); - wan_timer->timer_func = timer_func; - wan_timer->timer_arg = arg; -#elif defined(__WINDOWS__) -#else -# error "wan_init_timer() function is not supported yet!" -#endif /* linux */ -} - -/* -** wan_del_timer -*/ -static __inline void -wan_del_timer(wan_timer_t* wan_timer) -{ -#if defined(__LINUX__) - if (!wan_timer->timer_info.function){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%d Warning: WAN Timer del error: func=%p\n", - __FUNCTION__,__LINE__, - wan_timer->timer_info.function); - } - return; - } - del_timer(&wan_timer->timer_info); -#elif defined(__FreeBSD__) - untimeout(wan_timer->timer_func, - (void*)wan_timer->timer_arg, - wan_timer->timer_info); - callout_handle_init(&wan_timer->timer_info); -#elif defined(__OpenBSD__) - timeout_del(&wan_timer->timer_info); -#elif defined(__NetBSD__) - callout_stop(&wan_timer->timer_info); -#else -# error "wan_del_timer() function is not supported yet!" -#endif /* linux */ -} - -/* -** wan_add_timer -*/ -static __inline int -wan_add_timer(wan_timer_t* wan_timer, unsigned long delay) -{ -#if defined(__LINUX__) - if (timer_pending(&wan_timer->timer_info) || - !wan_timer->timer_info.function){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%d Warning: WAN Timer add error: pending or func=%p\n", - __FUNCTION__,__LINE__, - wan_timer->timer_info.function); - } - return -EINVAL; - } - wan_timer->timer_info.expires = SYSTEM_TICKS + delay; - add_timer(&wan_timer->timer_info); -#elif defined(__FreeBSD__) - wan_timer->timer_info = - timeout(wan_timer->timer_func, - (void*)wan_timer->timer_arg, - delay); - WAN_ASSERT1(wan_timer->timer_info.callout == NULL); -#elif defined(__OpenBSD__) - timeout_add(&wan_timer->timer_info, delay); -#elif defined(__NetBSD__) - wan_timer->timer_info.c_time = delay; - callout_reset(&wan_timer->timer_info, - delay, - wan_timer->timer_func, - wan_timer->timer_arg); -#else -# error "wan_add_timer() function is not supported yet!" -#endif /* linux */ - return 0; -} - -/********************** WANPIPE KERNEL BUFFER **************************/ -/* -** wan_skb_data() - -** Returns pointer to data. -*/ -static __inline unsigned char* wan_skb_data(void* skb) -{ -#if defined(__LINUX__) - return ((struct sk_buff*)skb)->data; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return mtod((struct mbuf*)skb, caddr_t); -#elif defined(__SOLARIS__) - return ((netskb_t*)mp)->b_rptr; -#else -# error "wan_skb_data() function is not supported yet!" -#endif -} - -/* -** wan_skb_tail() - -** Returns pointer to data. -*/ -static __inline unsigned char* wan_skb_tail(void* skb) -{ -#if defined(__LINUX__) - return wan_skb_tail_pointer((struct sk_buff*)skb); -#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - return mtod((struct mbuf*)skb, caddr_t) + ((struct mbuf*)skb)->m_len; -#elif defined(__SOLARIS__) - return ((netskb_t*)mp)->b_wptr; -#else -# error "wan_skb_tail() function is not supported yet!" -#endif -} - -/* -** wan_skb_append() - -** Returns pointer to data. -*/ -static __inline void wan_skb_append(void* skbprev, void *skb, void *list) -{ -#if defined(__LINUX__) -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) - skb_append(skbprev,skb); -# else - skb_append(skbprev,skb,list); -# endif -#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - m_cat (skbprev, skb); -#else -# error "wan_skb_append() function is not supported yet!" -#endif -} - - - -/* -** wan_skb_len() - -** Returns current kernel buffer length. -*/ -static __inline int wan_skb_len(void* skb) -{ -#if defined(__LINUX__) - return ((struct sk_buff*)skb)->len; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return ((struct mbuf*)skb)->m_len; -#elif defined(__SOLARIS__) - mblk_t* tmp = skb; - int len = 0; - while(tmp) { - len += (tmp->b_wptr - tmp->b_rptr); - tmp = tmp->b_cont; - } - return len; -#else -# error "wan_skb_len() function is not supported yet!" -#endif -} - -/* -** wan_skb_free() - -** Free kernel memory buffer. -*/ -static __inline void wan_skb_free(void* skb) -{ -#if defined(__LINUX__) -#if defined(WAN_DEBUG_MEM) - DEBUG_SUB_MEM(((struct sk_buff*)skb)->truesize); -#endif - dev_kfree_skb_any(skb); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - m_freem(skb); -#elif defined(__SOLARIS__) - freemsg(skb); -#else -# error "wan_skb_free() function is not supported yet!" -#endif -} - -/* -** wan_skb_set_mark() - -** Set mark for skb. -*/ -static __inline void wan_skb_set_mark(void* pskb) -{ -#if defined(__LINUX__) - return; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - ((netskb_t*)pskb)->m_flags |= WAN_MFLAG_PRV; -#endif - return; -} - -/* -** wan_skb_clear_mark() - -** Clear mark from skb. -*/ -static __inline void wan_skb_clear_mark(void* pskb) -{ -#if defined(__LINUX__) - return; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - ((netskb_t*)pskb)->m_flags &= ~WAN_MFLAG_PRV; -#endif - return; -} - -/* -** wan_skb_mark() - -** Return 1 if mark is set, otherwise 0. -*/ -static __inline int wan_skb_mark(void* pskb) -{ -#if defined(__LINUX__) - return 0; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return (((netskb_t*)pskb)->m_flags & WAN_MFLAG_PRV); -#endif - return 0; -} - -/* -** wan_skb_alloc() - -** Allocate kernel buffer with len. -*/ -static __inline void* wan_skb_alloc(unsigned int len) -{ -#if defined(__LINUX__) -#if defined(WAN_DEBUG_MEM) - struct sk_buff *skb=dev_alloc_skb(len); - if (skb){ - DEBUG_ADD_MEM(skb->truesize); - } - return (void*)skb; -#else - return (void*)dev_alloc_skb(len); -#endif -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf *new = NULL; - - if (len){ - MGETHDR(new, M_DONTWAIT, MT_DATA); - }else{ - MGET(new, M_DONTWAIT, MT_DATA); - } - if (new){ - if (new->m_flags & M_PKTHDR){ - new->m_pkthdr.len = 0; - } - new->m_len = 0; - MCLGET(new, M_DONTWAIT); - if ((new->m_flags & M_EXT) == 0){ - wan_skb_free(new); - return NULL; - } - /* Always reserve extra 16 bytes (as Linux) - ** for the header */ - new->m_data += 16; - wan_skb_set_mark(new); - return (void*)new; - } - return NULL; -#elif defined (__SOLARIS__) - mblk_t *mp=allocb(ROUNDUP(len+16, IOC_LINESIZE), BPRI_MED); - if (mp){ - caddr_t ptr= (caddr_t) ROUNDUP((long)mp->b_rptr, 1); - mp->b_rptr=(uchar_t *)ptr+16; - } - return mp; -#else -# error "wan_skb_alloc() function is not supported yet!" -#endif -} - -static __inline void* wan_skb_kalloc(unsigned int len) -{ -#if defined(__LINUX__) -#if defined(WAN_DEBUG_MEM) - struct sk_buff *skb=__dev_alloc_skb(len,GFP_KERNEL); - if (skb){ - DEBUG_ADD_MEM(skb->truesize); - } - return (void*)skb; -#else - return (void*)__dev_alloc_skb(len,GFP_KERNEL); -#endif -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf *new = NULL; - - if (len){ - MGETHDR(new, M_DONTWAIT, MT_DATA); - }else{ - MGET(new, M_DONTWAIT, MT_DATA); - } - if (new){ - if (new->m_flags & M_PKTHDR){ - new->m_pkthdr.len = 0; - } - new->m_len = 0; - MCLGET(new, M_DONTWAIT); - if ((new->m_flags & M_EXT) == 0){ - wan_skb_free(new); - return NULL; - } - /* Always reserve extra 16 bytes (as Linux) - ** for the header */ - new->m_data += 16; - wan_skb_set_mark(new); - return (void*)new; - } - return NULL; -#elif defined (__SOLARIS__) - mblk_t *mp=allocb(ROUNDUP(len+16, IOC_LINESIZE), BPRI_MED); - if (mp){ - caddr_t ptr= (caddr_t) ROUNDUP((long)mp->b_rptr, 1); - mp->b_rptr=(uchar_t *)ptr+16; - } - return mp; -#else -# error "wan_skb_kalloc() function is not supported yet!" -#endif -} - - -/* -** wan_skb_set_dev() - -** Set device point. -*/ -static __inline void wan_skb_set_dev(void* pskb, void* dev) -{ -#if defined(__LINUX__) - struct sk_buff *skb = (struct sk_buff*)pskb; - if (skb){ - skb->dev = dev; - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - netskb_t* m = (netskb_t*)pskb; - if (m){ - m->m_pkthdr.rcvif = dev; - } -#else -# error "wan_skb_set_dev() function is not supported yet!" -#endif -} - -static __inline void wan_skb_set_protocol(void* pskb, unsigned int protocol) -{ -#if defined(__LINUX__) - struct sk_buff *skb = (struct sk_buff*)pskb; - if (skb){ - skb->protocol = htons(protocol); - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf *mbuf = (struct mbuf*)pskb; - if (protocol == ETH_P_IPX){ - mbuf->m_flags |= M_PROTO1; - } -#else - -# warning "wan_skb_set_protocol() function is not supported yet!" -#endif -} - -static __inline void wan_skb_set_raw(void* pskb) -{ -#if defined(__LINUX__) - struct sk_buff *skb = (struct sk_buff*)pskb; - if (skb){ - wan_skb_reset_mac_header(skb); - wan_skb_reset_network_header(skb); - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -#else -# warning "wan_skb_set_raw() function is not supported yet!" -#endif -} - - - -/* -** wan_skb_set_csum() - -** Set checksum. -*/ -static __inline void wan_skb_set_csum(void* skb, unsigned int csum) -{ -#if defined(__LINUX__) - struct sk_buff *sk = (struct sk_buff*)skb; - if (sk){ - sk->csum = csum; - } -#elif defined(__OpenBSD__) - netskb_t* m = (netskb_t*)skb; - if (m){ -# if (OpenBSD >= 200511) - m->m_pkthdr.csum_flags = csum; -# else - m->m_pkthdr.csum = csum; -# endif - } -#elif defined(__NetBSD__) || defined(__FreeBSD__) - netskb_t* m = (netskb_t*)skb; - if (m){ - m->m_pkthdr.csum_data = csum; - } -#else -# error "wan_skb_set_csum() function is not supported yet!" -#endif -} - -/* -** wan_skb_csum() - -** Return checksum value. -*/ -static __inline unsigned int wan_skb_csum(void* skb) -{ -#if defined(__LINUX__) - struct sk_buff *sk = (struct sk_buff*)skb; - return (sk) ? sk->csum : 0; -#elif defined(__NetBSD__) || defined(__FreeBSD__) - netskb_t* m = (netskb_t*)skb; - return (m) ? m->m_pkthdr.csum_data : 0; -#elif defined(__OpenBSD__) - netskb_t* m = (netskb_t*)skb; -# if (OpenBSD >= 200511) - return (m) ? m->m_pkthdr.csum_flags : 0; -# else - return (m) ? m->m_pkthdr.csum : 0; -# endif -#else -# error "wan_skb_set_dev() function is not supported yet!" -#endif -} - -/* -** wan_skb_check() - -** Check if packet consists from one skb block. -*/ -static __inline int wan_skb_check(void* skb) -{ -#if defined(__LINUX__) - return 0; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - netskb_t* m = (netskb_t*)skb; - if (m->m_pkthdr.len != m->m_len){ - return 1; - } - return 0; -#else -# error "wan_skb_check() function is not supported yet!" -#endif -} - -/* -** wan_skb_reserve() - -** Reserve extra bytes before data -*/ -static __inline void wan_skb_reserve(void* skb, unsigned int len) -{ -#if defined(__LINUX__) - skb_reserve(skb, len); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf *m = (struct mbuf*)skb; - - m->m_data += len; -#else -# error "wan_skb_free() function is not supported yet!" -#endif -} - -/* -** wan_skb_copyback() - -** Copy data from a buffer back into the indicated mbuf chain, -** starting "off" bytes from the beginning, extending the mbuf -** chain if necessary. -*/ -static __inline void wan_skb_copyback(void* skb, int off, int len, caddr_t cp) -{ -#if defined(__LINUX__) - struct sk_buff* sk = (struct sk_buff*)skb; - unsigned char* data = NULL; - if (off == wan_skb_len(skb)){ - if (wan_skb_tail_pointer(sk) + len > wan_skb_end_pointer(sk)){ - DEBUG_EVENT("wan_skb_copyback: Internal Error (off=%d,len=%d,skb_len=%d)!\n", - off, len, wan_skb_len(skb)); - return; - }else{ - data = skb_put(skb, len); - memcpy(data, cp, len); - } - }else{ - if (off + len > wan_skb_len(skb)){ - data = skb_put(skb, len); - memcpy(data + off, cp, len); - skb_trim(skb, off + len); - } - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf* m = (struct mbuf*)skb; - caddr_t data = mtod(m, caddr_t); - - bcopy(cp, &data[off], len); - m->m_len = off + len; - m->m_pkthdr.len = off + len; -#else -# error "wan_skb_copyback() function is not supported yet!" -#endif -} - -/* -** wan_skb_copyback_user() - -** Copy data from a buffer back into the indicated mbuf chain, -** starting "off" bytes from the beginning, extending the mbuf -** chain if necessary. -** Data being copied is coming from user space, thus we must -** use a special function to copy it into kernel space. -*/ -static __inline int wan_skb_copyback_user(void* skb, int off, int len, caddr_t cp) -{ -#if defined(__LINUX__) - struct sk_buff* sk = (struct sk_buff*)skb; - unsigned char* data = NULL; - if (off == wan_skb_len(skb)){ - if (wan_skb_tail_pointer(sk) + len > wan_skb_end_pointer(sk)){ - DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", - off, len, wan_skb_len(skb)); - return -EINVAL; - }else{ - data = skb_put(skb, len); - if (WAN_COPY_FROM_USER(data, cp, len)){ - DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", - off, len, wan_skb_len(skb)); - return -EFAULT; - } - } - }else{ - if (off + len > wan_skb_len(skb)){ - data = skb_put(skb, len); - if (WAN_COPY_FROM_USER(data+off, cp, len)){ - DEBUG_EVENT("wan_skb_copyback_user: Internal Error (off=%d,len=%d,skb_len=%d)!\n", - off, len, wan_skb_len(skb)); - return -EFAULT; - } - skb_trim(skb, off + len); - } - } - return 0; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf* m = (struct mbuf*)skb; - caddr_t data = mtod(m, caddr_t); - - WAN_COPY_FROM_USER(cp, &data[off], len); - m->m_len = off + len; - m->m_pkthdr.len = off + len; -#else -# error "wan_skb_copyback_user() function is not supported yet!" -#endif - return 0; -} - - -/* -** wan_skb_copyback() - -** Copy data from an mbuf chain starting "off" bytes from the beginning, -** continuing for "len" bytes, into the indicated buffer. -*/ -static __inline void wan_skb_copydata(void* skb, int off, int len, caddr_t cp) -{ -#if defined(__LINUX__) - if (off + len > wan_skb_len(skb)){ - DEBUG_EVENT("wan_skb_copydata: Internal error (off=%d, len=%d, skb_len=%d)!\n", - off, len, wan_skb_len(skb)); - return; - } - memcpy(cp, wan_skb_data(skb), len); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - caddr_t data = mtod((struct mbuf*)skb, caddr_t); - - bcopy(cp, &data[off], len); -#elif defined(__SOLARIS__) - mblk_t* tmp = (mblk_t*)skb; - unsigned char* ptr = NULL; - unsigned i = 0, num = 0; - while(tmp != NULL) { - ptr = tmp->b_rptr; - num = tmp->b_wptr - tmp->b_rptr; - bcopy(ptr, &cp[i], num); - i += num; - tmp = tmp->b_cont; - } -#else -# error "wan_skb_copydata() function is not supported yet!" -#endif -} - -/* -** wan_skb_copy() -*/ -static __inline void * wan_skb_copy(void *skb) -{ -#if defined(__LINUX__) - return skb_copy(skb,GFP_ATOMIC); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return m_copym(skb, 0, wan_skb_len(skb), M_DONTWAIT); -#else -# error "wan_skb_copy() function is not supported yet" -#endif - -} - -/* -** wan_skb_clone() -*/ -static __inline void * wan_skb_clone(void *skb) -{ -#if defined(__LINUX__) - return skb_clone(skb,GFP_ATOMIC); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return m_copym(skb, 0, wan_skb_len(skb), M_DONTWAIT); -#else -# error "wan_skb_clone() function is not supported yet" -#endif - -} - - - - - -/* -** wan_skb2buffer() - -** Correct skb block. -*/ -static __inline int wan_skb2buffer(void** skb) -{ -#if defined(__LINUX__) - return 0; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - netskb_t *m = (netskb_t*)(*skb); - netskb_t *new = NULL; - - new = wan_skb_alloc(0); - if (new){ - struct mbuf *tmp = m; - char *buffer = new->m_data; - - for( ; tmp; tmp = tmp->m_next) { - bcopy(mtod(tmp, caddr_t), buffer, tmp->m_len); - buffer += tmp->m_len; - new->m_len += tmp->m_len; - } - wan_skb_free(m); - *skb = new; - return 0; - } - return -EINVAL; -#else -# error "wan_skb_correct() function is not supported yet!" -#endif -} - -/* -** wan_skb_pull() - -** -*/ -static __inline unsigned char* wan_skb_pull(void* skb, int len) -{ -#if defined(__LINUX__) - return skb_pull((struct sk_buff*)skb, len); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - m_adj(skb, len); -#if 0 - struct mbuf* m = (struct mbuf*)skb; - m->m_data += len; - m->m_pkthdr.len -= len; - m->m_len = m->m_pkthdr.len; -#endif - return wan_skb_data(skb); -#else -# error "wan_skb_pull() function is not supported yet!" -#endif -} - -/* -** wan_skb_put() - -** -*/ -static __inline unsigned char* wan_skb_put(void* skb, int len) -{ -#if defined(__LINUX__) - return skb_put((struct sk_buff*)skb, len); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf* m = (struct mbuf*)skb; - int org_len = wan_skb_len(skb); - unsigned char* data = wan_skb_data(skb); - - m->m_len = org_len + len; - m->m_pkthdr.len = org_len + len; -/*Alex Sep27,2004 last tail but not data pointer return wan_skb_data(skb);*/ - return data + org_len; -#elif defined(__SOLARIS__) - mblk_t mp=(mblk_t*)skb; - unsigned char *wptr=mp->b_wptr; - mp->b_wptr += len; - return mp->b_wptr; -#else -# error "wan_skb_put() function is not supported yet!" -#endif -} - -/* -** wan_skb_push() - -** -*/ -static __inline unsigned char* wan_skb_push(void* skb, int len) -{ -#if defined(__LINUX__) - return skb_push((struct sk_buff*)skb, len); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf *m = (struct mbuf*)skb; - int org_len = wan_skb_len(skb); - - if (m->m_flags & M_EXT){ - if ((m->m_data - len) < m->m_ext.ext_buf){ - DEBUG_EVENT("Can't push %d bytes!\n", len); - return wan_skb_data(skb); - } - }else{ - if ((m->m_data - len) < m->m_pktdat){ - DEBUG_EVENT("Can't push %d bytes!\n", len); - return wan_skb_data(skb); - } - } - m->m_data -= len; - m->m_len = org_len + len; - m->m_pkthdr.len = org_len + len; - return wan_skb_data(skb); -#else -# error "wan_skb_push() function is not supported yet!" -#endif -} - - - - -/* -** wan_skb_tailroom() - Tail room -** -** -*/ -static __inline int wan_skb_tailroom(void* skb) -{ -#if defined(__LINUX__) - return skb_tailroom(skb); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf* m = (struct mbuf*)skb; - - if (m->m_flags & M_EXT){ - return (MCLBYTES - m->m_len); - } - return (MHLEN - m->m_len); -#else -# error "wan_skb_tailroom() function is not supported yet!" -#endif -} - -/* -** wan_skb_tailroom() - Head room -** -** -*/ -static __inline int wan_skb_headroom(void* skb) -{ -#if defined(__LINUX__) - return skb_headroom(skb); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf* m = (struct mbuf*)skb; - - if (m->m_flags & M_EXT){ - return (m->m_data - m->m_ext.ext_buf); - } - return (m->m_data - m->m_pktdat); -#else -# error "wan_skb_headroom() function is not supported yet!" -#endif -} - - - -/* -** wan_skb_trim() - Trim from tail -** -** -*/ -static __inline void wan_skb_trim(void* skb, unsigned int len) -{ -#if defined(__LINUX__) - skb_trim(skb, len); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf* m = (struct mbuf*)skb; -#if 0 - /* Trim only moves tail to head+len (Oct13) */ - if (len == 0){ - m->m_data = m->m_ext.ext_buf; - } -#endif - m->m_pkthdr.len = len; - m->m_len = m->m_pkthdr.len; -#else -# error "wan_skb_trim() function is not supported yet!" -#endif -} - -/* -** wan_skb_init() - Setup skb data ptr -** -** -*/ -static __inline void wan_skb_init(void* pskb, unsigned int len) -{ -#if defined(__LINUX__) - struct sk_buff* skb = (struct sk_buff*)pskb; - skb->data = skb->head + len; - wan_skb_reset_tail_pointer(skb); - skb->len = 0; - skb->data_len = 0; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct mbuf* m = (struct mbuf*)pskb; - m->m_data = m->m_ext.ext_buf + len; -#else -# error "wan_skb_init() function is not supported yet!" -#endif -} - -static __inline int wan_skb_print(void* skb) -{ -#if defined(__LINUX__) - int len = wan_skb_len(skb); - unsigned char *data = wan_skb_data(skb); - int i; - - DEBUG_EVENT("DBG Packet %d bytes: ",len); - for(i=0;im_pkthdr.len, i; - unsigned char *data = wan_skb_data(skb); - - if (m->m_type & M_PKTHDR) - DEBUG_EVENT("M_PKTHDR flag set (%d)!\n", - m->m_pkthdr.len); - if (m->m_type & M_EXT) - DEBUG_EVENT("M_EXT flag set (%d)!\n", - m->m_pkthdr.len); - DEBUG_EVENT("Packet %d bytes: ", len); - for(i=0;i= '0') && (ifname[len] <= '9')){ - if (!base){ - int i=0; - base = 1; - for(i=0;i= 502000) - if_initname(dev, ifname, IF_DUNIT_NONE); -# else - dev->if_unit = ifunit; - if (dev->if_name == NULL){ - dev->if_name = wan_malloc(prefix_len+1); - if (dev->if_name == NULL){ - return -ENOMEM; - } - } - memcpy(dev->if_name, ifname, prefix_len); - dev->if_name[prefix_len] = '\0'; -# endif - WAN_IFQ_SET_MAXLEN(&dev->if_snd, ifqmaxlen); -#elif defined(__OpenBSD__) || defined(__NetBSD__) - if (strlen(ifname) >= IFNAMSIZ){ - return -ENOMEM; - } - bcopy(ifname, dev->if_xname, strlen(ifname)); - WAN_IFQ_SET_MAXLEN(&dev->if_snd, IFQ_MAXLEN); -#elif defined(__LINUX__) -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) - dev->name = ifname; -# else - strcpy(dev->name, ifname); -# endif -#else -# error "wan_netif_init() function is not supported yet!" -#endif - return 0; -} - -static __inline int wan_netif_del(netdevice_t* dev) -{ - WAN_ASSERT(dev == NULL); -#if defined(__FreeBSD__) - dev->if_init = NULL; -# if (__FreeBSD_version >= 502000) - dev->if_dname = NULL; -# elif (__FreeBSD_version > 400000) - /* Free interface name (only for FreeBSD-4.0) */ - free(dev->if_name, M_DEVBUF); -# endif -#elif defined(__OpenBSD__) || defined(__NetBSD__) - /* Do nothing */ -#elif defined(__LINUX__) - /* Do nothing */ -#else -# error "wan_netif_del() function is not supported yet!" -#endif - return 0; -} - - -#if defined(__LINUX__) -static __inline void wan_netif_fake_init(netdevice_t *d) -{ - -#ifdef LINUX_FEAT_2624 - d->hard_header = NULL; - d->rebuild_header = NULL; - d->header_cache_update = NULL; - d->hard_header_cache = NULL; -#else - d->header_ops = NULL; -#endif - - return; -} -#endif - -static __inline void* -wan_netif_alloc(unsigned char *devname, int ifType, int *err) -{ -#if defined(__LINUX__) -# if defined(LINUX_2_6) -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)) - return __dev_alloc(devname, err); -# else - return alloc_netdev(0,devname,wan_netif_fake_init); -# endif -# elif defined(LINUX_2_4) - netdevice_t *dev=wan_malloc(sizeof(netdevice_t)); - *err=0; - - if (!dev){ - *err=-ENOMEM; - } - memset(dev, 0, sizeof(netdevice_t)); - - strncpy(dev->name,devname,30); - return dev; -# else - netdevice_t *dev=wan_malloc(sizeof(netdevice_t)); - *err=0; - - if (!dev){ - *err=-ENOMEM; - } - memset(dev, 0, sizeof(netdevice_t)); - - dev->name=wan_malloc(35); - if (!dev->name){ - wan_free(dev); - dev=NULL; - *err=-ENOMEM; - return NULL; - } - strncpy(dev->name,devname,30); - return dev; -# endif -#elif defined(__FreeBSD__) && (__FreeBSD_version > 600000) - struct ifnet* ifp; - ifp = IFALLOC(ifType); - /*ifp = wan_malloc(sizeof(struct ifnet));*/ - if (ifp == NULL){ - *err = -ENOMEM; - return NULL; - } - if (devname){ - *err = wan_netif_init(ifp, devname); - if (*err){ - wan_netif_del(ifp); - return NULL; - } - } - return ifp; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - struct ifnet* ifp; - switch(ifType){ - case WAN_IFT_PPP: - ifp = (struct ifnet*)wan_malloc(sizeof(struct sppp)); - if (ifp) bzero((struct sppp*)ifp, sizeof(struct sppp)); - break; - case WAN_IFT_ETHER: - ifp = (struct ifnet*)wan_malloc(sizeof(wan_ethercom_t)); - if (ifp) bzero(WAN_IFP2AC(ifp), sizeof(wan_ethercom_t)); - break; - case WAN_IFT_OTHER: - default: - ifp = wan_malloc(sizeof(struct ifnet)); - if (ifp) bzero(ifp, sizeof(struct ifnet)); - break; - } - /*ifp = IFALLOC(ifType);*/ - /*ifp = wan_malloc(sizeof(struct ifnet));*/ - if (ifp == NULL){ - *err = -ENOMEM; - return NULL; - } - if (devname){ - *err = wan_netif_init(ifp, devname); - if (*err){ - wan_netif_del(ifp); - return NULL; - } - } - return ifp; -#else -# error "wan_netif_alloc() unsupported" -#endif - -} - -static __inline void wan_netif_free(netdevice_t *dev) -{ - -#if defined(__LINUX__) -# if defined(LINUX_2_6) - free_netdev(dev); -# elif defined(LINUX_2_4) - wan_free(dev); -# else - if (dev->name){ - wan_free(dev->name); - dev->name=NULL; - } - wan_free(dev); -# endif -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - wan_netif_del(dev); - IFFREE(dev); /*wan_free(dev);*/ -#else -#error "wan_netif_free() not supported!" -#endif - -} - - -static __inline char* wan_netif_name(netdevice_t* dev) -{ - static char ifname[IFNAMSIZ+1]; - WAN_ASSERT2(dev == NULL, NULL); -#if defined(__LINUX__) - strcpy(ifname, dev->name); -#elif defined(__FreeBSD__) -# if (__FreeBSD_version >= 502000) - strcpy(ifname, dev->if_xname); -# else - sprintf(ifname, "%s%d", dev->if_name, dev->if_unit); -# endif -#elif defined(__OpenBSD__) || defined(__NetBSD__) - sprintf(ifname, "%s", dev->if_xname); -#else -# error "wan_get_ifname() function is not supported yet!" -#endif - return ifname; -} - -static __inline void* wan_netif_priv(netdevice_t* dev) -{ - WAN_ASSERT2(dev == NULL, NULL); -#if defined(__LINUX__) - return dev->priv; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return dev->if_softc; -#else -# error "wan_netif_priv() function is not supported yet!" -#endif -} - -static __inline int wan_netif_up(netdevice_t* dev) -{ - WAN_ASSERT2(dev == NULL, -EINVAL); -#if defined(__LINUX__) - return WAN_NETIF_UP(dev); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return WAN_NETIF_UP(dev); -#else -# error "wan_netif_up() function is not supported yet!" -#endif -} - - -static __inline void wan_netif_set_priv(netdevice_t* dev, void* priv) -{ - WAN_ASSERT1(dev == NULL); -#if defined(__LINUX__) - dev->priv = priv; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - dev->if_softc = priv; -#else -# error "wan_netif_priv() function is not supported yet!" -#endif - return; -} - -static __inline short wan_netif_flags(netdevice_t* dev) -{ - WAN_ASSERT(dev == NULL); -#if defined(__LINUX__) - return dev->flags; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - return dev->if_flags; -#else -# error "wan_netif_flags() function is not supported yet!" -#endif -} - -static __inline int wan_netif_mcount(netdevice_t* dev) -{ -#if defined(__LINUX__) - return dev->mc_count; -#elif defined(__FreeBSD__) - return dev->if_amcount; -#elif defined(__OpenBSD__) || defined(__NetBSD__) - return 0; -#else -# error "wan_netif_mcount() function is not supported yet!" -#endif -} - -static __inline int wan_netif_set_ticks(netdevice_t* dev, unsigned long ticks) -{ -#if defined(__LINUX__) - dev->trans_start = ticks; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -#else -# error "wan_netif_set_ticks() function is not supported yet!" -#endif - return 0; -} - -static __inline int wan_netif_set_mtu(netdevice_t* dev, unsigned long mtu) -{ -#if defined(__LINUX__) -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - dev->if_mtu = mtu; -#else -# error "wan_netif_set_mtu() function is not supported yet!" -#endif - return 0; -} - - -static __inline void -wan_bpf_report(netdevice_t* dev, void* pkt, int flag, int dir) -{ - -#if defined(__LINUX__) - /* Do nothing */ -#elif defined(__FreeBSD__) - if (dev->if_bpf != NULL){ /* BF-0002 */ - WAN_BPF_REPORT(dev, pkt); - } -#elif defined(__OpenBSD__) || defined(__NetBSD__) - if (dev->if_bpf != NULL){ /* BF-0002 */ - if (flag){ - struct mbuf m0; - u_int32_t af = AF_INET; - m0.m_next = pkt; - m0.m_len = 4; - m0.m_data = (char*)⁡ - WAN_BPF_REPORT(dev, &m0, dir); - }else{ - WAN_BPF_REPORT(dev, pkt, dir); - } - } -#else -# error "wan_bpf_report() function is not supported yet!" -#endif -} - - - - - -static __inline void wan_spin_lock_init(void *lock) -{ -#if defined(__LINUX__) - spin_lock_init(((spinlock_t*)lock)); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - /*(*(wan_smp_flag_t*)flag) = 0;*/ -#else -# warning "wan_spin_lock_init() function is not supported yet!" -#endif -} - -static __inline int wan_spin_is_locked(void *lock) -{ -#if defined(__LINUX__) - return spin_is_locked((spinlock_t*)lock); -#elif defined(__NetBSD__) || defined(__OpenBSD__) - return 0;/*((*(wan_smp_flag_t*)flag) & imask[IPL_NET]);*/ -#elif defined(__FreeBSD__) -# if (__FreeBSD_version > 500000) - return 0; -# else - return 0;/*((*(wan_smp_flag_t*)flag) & net_imask);*/ -# endif -#else -# warning "wan_spin_is_lock() function is not supported yet!" -#endif -} - -static __inline void wan_spin_lock_irq(void *lock, wan_smp_flag_t *flag) -{ -#if defined(__LINUX__) - spin_lock_irqsave(((spinlock_t*)lock),*flag); -#elif defined(__FreeBSD__) - /* Feb 10, 2005 Change splnet to splimp - ** (i think it was cause to system crash) */ - *flag = splimp(); -#elif defined(__OpenBSD__) - *flag = splnet(); -#elif defined(__NetBSD__) -# if (__NetBSD_Version__ >= 106000200) - *flag = splvm(); -# else - *flag = splimp(); -# endif -#else -# warning "wan_spin_lock_irq() function is not supported yet!" -#endif -} -static __inline void wan_spin_unlock_irq(void *lock, wan_smp_flag_t *flag) -{ -#if defined(__LINUX__) - spin_unlock_irqrestore(((spinlock_t*)lock),*flag); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - splx(*flag); -#else -# warning "wan_spin_unlock_irq() function is not supported yet!" -#endif -} - -static __inline void wan_spin_lock(void *lock) -{ -#if defined(__LINUX__) - spin_lock(((spinlock_t*)lock)); -#elif defined(__FreeBSD__) - /* Feb 10, 2005 Change splnet to splimp - ** (i think it was cause to system crash) */ - *((wan_spinlock_t*)lock) = splimp(); -#elif defined(__OpenBSD__) - *((wan_spinlock_t*)lock) = splnet(); -#elif defined(__NetBSD__) -# if (__NetBSD_Version__ >= 106000200) - *((wan_spinlock_t*)lock) = splvm(); -# else - *((wan_spinlock_t*)lock) = splimp(); -# endif -#else -# warning "wan_spin_lock() function is not supported yet!" -#endif -} -static __inline void wan_spin_unlock(void *lock) -{ -#if defined(__LINUX__) - spin_unlock(((spinlock_t*)lock)); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - splx(*(wan_spinlock_t*)lock); -#else -# warning "wan_spin_unlock() function is not supported yet!" -#endif -} - - - -#if 0 -static __inline void wan_read_rw_lock(void *lock) -{ -#if defined(__LINUX__) - read_lock(((rwlock_t*)lock)); -#else -# warning "wan_read_rw_lock() function is not supported yet!" -#endif -} - -static __inline void wan_read_rw_unlock(void *lock) -{ -#if defined(__LINUX__) - read_unlock(((rwlock_t*)lock)); -#else -# warning "wan_read_rw_unlock() function is not supported yet!" -#endif -} - -static __inline void wan_write_rw_lock_irq(void *lock, unsigned long *flag) -{ -#if defined(__LINUX__) - write_lock_irqsave(((rwlock_t*)lock),flag); -#else -# warning "wan_read_rw_lock() function is not supported yet!" -#endif -} - -static __inline void wan_write_rw_unlock_irq(void *lock, unsigned long *flag) -{ -#if defined(__LINUX__) - write_unlock_irqrestore(((rwlock_t*)lock),flag); -#else -# warning "wan_read_rw_unlock() function is not supported yet!" -#endif -} -#endif - -#if 0 -static __inline void wan_read_bus_4(void *phw, void *virt, int offset, unsigned int *value) -{ -#if defined(__LINUX__) - *value = wp_readl((unsigned char*)virt + offset); -#else - sdla_bus_read_4(phw,offset,value); -#endif -} - -static __inline void wan_write_bus_4(void *phw, void *virt, int offset, unsigned int value) -{ -#if defined(__LINUX__) - wp_writel(value,(u8*)virt + offset); -#else - sdla_bus_write_4(phw,offset,value); -#endif -} -#endif - -#endif /* WAN_KERNEL */ -#endif /* __WANPIPE_COMMON_H */ diff --git a/patches/kdrivers/include/wanpipe_debug.h b/patches/kdrivers/include/wanpipe_debug.h index 990f8dd..ac22c60 100644 --- a/patches/kdrivers/include/wanpipe_debug.h +++ b/patches/kdrivers/include/wanpipe_debug.h @@ -19,6 +19,7 @@ #undef WAN_DEBUG_KERNEL #undef WAN_DEBUG_MOD #undef WAN_DEBUG_CFG +#undef WAN_DEBUG_REG #undef WAN_DEBUG_INIT_VAR #undef WAN_DEBUG_IOCTL #undef WAN_DEBUG_CMD @@ -39,24 +40,35 @@ #undef WAN_DEBUG_SNMP #undef WAN_DEBUG_TE3 #undef WAN_DEBUG_RM +#undef WAN_DEBUG_BRI #undef WAN_DEBUG_HWEC #undef WAN_DEBUG_TDMAPI #undef WAN_DEBUG_FE - +#undef WAN_DEBUG_NG #undef WAN_DEBUG_MEM +#undef WAN_DEBUG_BRI +#undef WAN_DEBUG_BRI_INIT +#undef WAN_DEBUG_FUNC #if defined (__WINDOWS__) -# define DEBUG_NONE if (0) DbgPrint -# define PRINT OutputLogString +void OutputLogString(PUCHAR pvFormat, ...); + +# define DEBUG_NONE +#if 1 +# define PRINT OutputLogString +#else +# define PRINT if(1)DbgPrint +#endif + # define DEBUG_PRINT DbgPrint -# define DEBUG_LIMIT DbgPrint # define _DEBUG_PRINT DbgPrint # define DEBUG_KERNEL DEBUG_NONE # define DEBUG_EVENT DEBUG_NONE # define DEBUG_MOD DEBUG_NONE # define DEBUG_CFG DEBUG_NONE +# define DEBUG_REG DEBUG_NONE # define DEBUG_INIT DEBUG_NONE # define DEBUG_IOCTL DEBUG_NONE # define DEBUG_CMD DEBUG_NONE @@ -71,6 +83,7 @@ # define DEBUG_TE1 DEBUG_NONE # define DEBUG_TE3 DEBUG_NONE # define DEBUG_56K DEBUG_NONE +# define DEBUG_BRI DEBUG_NONE # define DEBUG_PROCFS DEBUG_NONE # define DEBUG_TDMV DEBUG_NONE # define DEBUG_TEST DEBUG_NONE @@ -81,9 +94,11 @@ # define DEBUG_HWEC DEBUG_NONE # define DEBUG_TDMAPI DEBUG_NONE # define DEBUG_FE DEBUG_NONE +# define DEBUG_NG DEBUG_NONE # define WAN_DEBUG_FUNC_START DEBUG_NONE # define WAN_DEBUG_FUNC_END DEBUG_NONE # define WAN_DEBUG_FUNC_LINE DEBUG_NONE +# define DEBUG_BRI DEBUG_NONE # ifdef WAN_DEBUG_KERNEL # undef DEBUG_KERNEL @@ -101,6 +116,10 @@ # undef DEBUG_CFG # define DEBUG_CFG DEBUG_PRINT # endif +# ifdef WAN_DEBUG_REG +# undef DEBUG_REG +# define DEBUG_REG DEBUG_PRINT +# endif # ifdef WAN_DEBUG_INIT_VAR # undef DEBUG_INIT # define DEBUG_INIT DEBUG_PRINT @@ -155,6 +174,10 @@ # undef DEBUG_56K # define DEBUG_56K DEBUG_PRINT # endif +# ifdef WAN_DEBUG_BRI +# undef DEBUG_BRI +# define DEBUG_BRI DEBUG_PRINT +# endif # ifdef WAN_DEBUG_PROCFS # undef DEBUG_PROCFS # define DEBUG_PROCFS DEBUG_PRINT @@ -195,18 +218,107 @@ # undef DEBUG_TDMAPI # define DEBUG_TDMAPI DEBUG_PRINT # endif -# ifdef WAN_DEBUG_FE -# undef DEBUG_FE -# define DEBUG_FE DEBUG_PRINT +# ifdef WAN_DEBUG_NG +# undef DEBUG_NG +# define DEBUG_NG DEBUG_PRINT # endif +# ifdef WAN_DEBUG_BRI +# undef DEBUG_BRI +# define DEBUG_BRI DEBUG_PRINT +# endif +# ifdef WAN_DEBUG_BRI_INIT +# undef DEBUG_BRI_INIT +# define DEBUG_BRI_INIT DEBUG_PRINT +# endif + +# define DEBUG_ADD_MEM +# define DEBUG_SUB_MEM + +# define splimp() 0 +# define splx(l) + +#define ERR_DBG_OUT if(1)DbgPrint +#define DBG_NOT_IMPL if(0)DbgPrint +#define FUNC_NOT_IMPL if(0)DbgPrint("%s()-Not Implemented\n", __FUNCTION__); +#define DBG_DSL_NOT_IMPLD if(0)DbgPrint("%s()-Not Implemented\n", __FUNCTION__); + +/* debugging of wanpipe_kernel.h */ +#define DBG_KRN if(0)DbgPrint +#define DBG_8TE1 if(0)DbgPrint +#define DG_TDMCODEC if(0)DbgPrint +#define DBG_G3 if(0)DbgPrint + +#define DBG_FAST_TX if(0)DbgPrint +#define DBG_ACUAPI if(0)DbgPrint +#define DEBUG_IDLE_TX if(0)DbgPrint +#define DEBUG_SHARED_EVENT if(0)DbgPrint +#define DBG_ADSL_TX if(0)DbgPrint +#define DEBUG_NEW_TX if(0)DbgPrint +#define DBG_IRQLOCK if(0)DbgPrint +#define DBG_ADSL_FAST_TX if(0)DbgPrint +#define DBG_S514_INIT if(0)DbgPrint +#define DBG_SET_CFG if(0)DbgPrint +#define DBG_ADSL_INIT if(0)DbgPrint +#define DBG_HIGH_IMPED if(0)DbgPrint +#define DBG_LIP_OOB if(0)DbgPrint +#define DEBUG_AFT if(0)DbgPrint +#define DBG_TE1_INTERRUPT if(0)DbgPrint +#define DBG_BSTRM if(0)DbgPrint +#define DEBUG_FIRMWARE_UPDATE if(0)DbgPrint +#define DBG_ADSL_RX if(0)DbgPrint +#define DBG_8TE1_START if(0)DbgPrint +#define DBG_BITSTRM if(0)DbgPrint + +#define DBG_FE_LOCK if(0)DbgPrint + +/* sprotocol.sys */ +#define DEBUG_LIP if(0)DbgPrint +#define DBG_LIP_SKB if(0)DbgPrint +/* wanpipe.sys */ +#define DEBUG_REQUEST if(0)DbgPrint +#define DEBUG_IF_TX if(0)DbgPrint +#define DEBUG_COMMON if(0)DbgPrint +#define DEBUG_IF_RX if(0)DbgPrint +#define DEBUG_NET_IF if(0)DbgPrint + +/* These are defined in "sources" file of each driver */ +#if defined( VIRTUAL_IF_DRV ) + #define DRIVER_NAME "SDLADRV" +#elif defined( BUSENUM_DRV ) + #define DRIVER_NAME "SangBus" +#elif defined( NDIS_MINIPORT_DRIVER ) + #define DRIVER_NAME "WANPIPE" +#elif defined( SPROTOCOL ) + #define DRIVER_NAME "SPROTOCOL" +#endif + +#define DBG_BUFFER_LEN 512 + +static void my_func_dbg(char *drv_name, char *func, char *file, int line) +{ + DbgPrint("%s:%s(): File: %s, Line: %d.\n", drv_name, func, file, line); +} + +#define AFT_FUNC_DEBUG() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define TDM_FUNC_DBG() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define EC_FUNC_DEBUG() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define DBG_SET_CFG_FUNC() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define DBG_ACUAPI_FUNC() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define FUNC_DEBUG() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define TDM_FUNC_DBG() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define SKB_FUNC() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) +#define PROT_FUNC_DEBUG() if(0)my_func_dbg(DRIVER_NAME, __FUNCTION__, __FILE__, __LINE__) #else /* !__WINDOWS__*/ +/* L I N U X */ + # define DEBUG_KERNEL(format,msg...) # define DEBUG_EVENT(format,msg...) # define DEBUG_MOD(format,msg...) # define DEBUG_CFG(format,msg...) +# define DEBUG_REG(format,msg...) # define DEBUG_INIT(format,msg...) # define DEBUG_IOCTL(format,msg...) # define DEBUG_CMD(format,msg...) @@ -221,6 +333,7 @@ # define DEBUG_TE1(format,msg...) # define DEBUG_TE3(format,msg...) # define DEBUG_56K(format,msg...) +# define DEBUG_BRI(format,msg...) # define DEBUG_PROCFS(format,msg...) # define DEBUG_TDMV(format,msg...) # define DEBUG_TEST(format,msg...) @@ -233,21 +346,21 @@ # define DEBUG_HWEC(format,msg...) # define DEBUG_TDMAPI(format,msg...) # define DEBUG_FE(format,msg...) +# define DEBUG_NG(format,msg...) # define WAN_DEBUG_FUNC_START # define WAN_DEBUG_FUNC_END # define WAN_DEBUG_FUNC_LINE +# define DEBUG_BRI(format,msg...) +# define DEBUG_BRI_INIT(format,msg...) # if (defined __FreeBSD__) || (defined __OpenBSD__) || defined(__NetBSD__) # define DEBUG_PRINT(format,msg...) log(LOG_INFO, format, ##msg) -# define DEBUG_LIMIT(format,msg...) log(LOG_INFO, format, ##msg) # define _DEBUG_PRINT(format,msg...) log(LOG_INFO, format, ##msg) # else /* !__FreeBSD__ && !__OpenBSD__ */ # define DEBUG_PRINT(format,msg...) printk(KERN_INFO format, ##msg) -# define DEBUG_LIMIT(format,msg...) printk(KERN_INFO format, ##msg) -//# define DEBUG_LIMIT(format,msg...) if (WAN_NET_RATELIMIT()) printk(KERN_INFO format, ##msg) # define _DEBUG_PRINT(format,msg...) printk(format,##msg) # endif /* __FreeBSD__ || __OpenBSD__ */ @@ -270,6 +383,10 @@ # undef DEBUG_CFG # define DEBUG_CFG(format,msg...) DEBUG_PRINT(format,##msg) # endif +# ifdef WAN_DEBUG_REG +# undef DEBUG_REG +# define DEBUG_REG(format,msg...) DEBUG_PRINT(format,##msg) +# endif # ifdef WAN_DEBUG_INIT_VAR # undef DEBUG_INIT # define DEBUG_INIT(format,msg...) DEBUG_PRINT(format,##msg) @@ -324,6 +441,10 @@ # undef DEBUG_56K # define DEBUG_56K(format,msg...) DEBUG_PRINT(format,##msg) # endif +# ifdef WAN_DEBUG_BRI +# undef DEBUG_BRI +# define DEBUG_BRI(format,msg...) DEBUG_PRINT(format,##msg) +# endif # ifdef WAN_DEBUG_PROCFS # undef DEBUG_PROCFS # define DEBUG_PROCFS(format,msg...) DEBUG_PRINT(format,##msg) @@ -340,19 +461,24 @@ # undef DEBUG_DBG # define DEBUG_DBG(format,msg...) DEBUG_PRINT(format,##msg) # endif + +#if 0 # ifdef WAN_DEBUG_MEM +/* This is not used any more */ # undef DEBUG_ADD_MEM -# define DEBUG_ADD_MEM(a) /*DEBUG_EVENT("%s:%d MEM ADDING %d\n",__FUNCTION__,__LINE__,a);*/(atomic_add(a,&wan_debug_mem)) +# define DEBUG_ADD_MEM(a) # undef DEBUG_SUB_MEM -# define DEBUG_SUB_MEM(a) /*DEBUG_EVENT("%s:%d MEM SUBSTR %d\n",__FUNCTION__,__LINE__,a);*/(atomic_sub(a,&wan_debug_mem)) +# define DEBUG_SUB_MEM(a) #endif +#endif + # ifdef WAN_DEBUG_DMA # undef DEBUG_DMA # define DEBUG_DMA(format,msg...) DEBUG_PRINT(format,##msg) # endif # ifdef WAN_DEBUG_SNMP # undef DEBUG_SNMP -# define DEBUG_SNMP(format,msg...) DEBUG_PRINT(format,##msg) +# define DEBUG_SNMP(format,msg...) DEBUG_PRINT(format,##msg) # endif # ifdef WAN_DEBUG_RM # undef DEBUG_RM @@ -364,13 +490,24 @@ # endif # ifdef WAN_DEBUG_TDMAPI # undef DEBUG_TDMAPI -# define DEBUG_TDMAPI(format,msg...) DEBUG_PRINT(format,##msg) +# define DEBUG_TDMAPI(format,msg...) DEBUG_PRINT(format,##msg) # endif # ifdef WAN_DEBUG_FE # undef DEBUG_FE # define DEBUG_FE(format,msg...) DEBUG_PRINT(format,##msg) # endif - +# ifdef WAN_DEBUG_BRI +# undef DEBUG_BRI +# define DEBUG_BRI(format,msg...) DEBUG_PRINT(format,##msg) +# endif +# ifdef WAN_DEBUG_BRI_INIT +# undef DEBUG_BRI_INIT +# define DEBUG_BRI_INIT(format,msg...) DEBUG_PRINT(format,##msg) +# endif +# ifdef WAN_DEBUG_NG +# undef DEBUG_NG +# define DEBUG_NG(format,msg...) DEBUG_PRINT(format,##msg) +# endif #endif /* __WINDOWS__ */ @@ -379,14 +516,18 @@ #if defined(WAN_DEBUG_FUNC) # undef WAN_DEBUG_FUNC_START -# define WAN_DEBUG_FUNC_START DEBUG_EVENT("[%s]: %s:%d: Start (%ld)\n",\ - __FILE__,__FUNCTION__,__LINE__, SYSTEM_TICKS); +# define WAN_DEBUG_FUNC_START DEBUG_EVENT("[%s]: %s:%d: Start (%d)\n",\ + __FILE__,__FUNCTION__,__LINE__, (unsigned int)SYSTEM_TICKS); # undef WAN_DEBUG_FUNC_END -# define WAN_DEBUG_FUNC_END DEBUG_EVENT("[%s]: %s:%d: End (%ld)\n", \ - __FILE__,__FUNCTION__,__LINE__,SYSTEM_TICKS); +# define WAN_DEBUG_FUNC_END DEBUG_EVENT("[%s]: %s:%d: End (%d)\n", \ + __FILE__,__FUNCTION__,__LINE__,(unsigned int)SYSTEM_TICKS); # undef WAN_DEBUG_FUNC_LINE -# define WAN_DEBUG_FUNC_LINE DEBUG_EVENT("[%s]: %s:%d: (%ld)\n", \ - __FILE__,__FUNCTION__,__LINE__,SYSTEM_TICKS); +# define WAN_DEBUG_FUNC_LINE DEBUG_EVENT("[%s]: %s:%d: (%d)\n", \ + __FILE__,__FUNCTION__,__LINE__,(unsigned int)SYSTEM_TICKS); + +#define BRI_FUNC() if(1)DEBUG_EVENT("%s(): line:%d\n", __FUNCTION__, __LINE__) +#else +#define BRI_FUNC() #endif #define WAN_ASSERT(val) if (val){ \ @@ -425,6 +566,29 @@ } +#if defined(__FreeBSD__) +# ifndef WAN_SKBDEBUG +# define WAN_SKBDEBUG 0 +# endif +# define WAN_SKBCRITASSERT(mm) if (WAN_SKBDEBUG){ \ + if ((mm) == NULL){ \ + panic("%s:%d: MBUF is NULL!\n", \ + __FUNCTION__,__LINE__); \ + } \ + if (((mm)->m_flags & (M_PKTHDR|M_EXT)) != (M_PKTHDR|M_EXT)){ \ + panic("%s:%d: Invalid MBUF m_flags=%X (m=%p)\n", \ + __FUNCTION__,__LINE__, \ + (mm)->m_flags,(mm)); \ + } \ + if ((unsigned long)(mm)->m_data < 0x100){ \ + panic("%s:%d: Invalid MBUF m_data=%p (m=%p)\n", \ + __FUNCTION__,__LINE__, \ + (mm)->m_data,(mm)); \ + } \ +} +#else +# define WAN_SKBCRITASSERT(mm) +#endif #define WAN_MEM_INIT(id) unsigned long mem_in_used_##id = 0x0l #define WAN_MEM_INC(id,size) mem_in_used_##id += size diff --git a/patches/kdrivers/include/wanpipe_defines.h b/patches/kdrivers/include/wanpipe_defines.h index 465205a..cdb162a 100644 --- a/patches/kdrivers/include/wanpipe_defines.h +++ b/patches/kdrivers/include/wanpipe_defines.h @@ -1,16 +1,17 @@ - -/* - ************************************************************************ - * wanpipe_defines.h * - * WANPIPE(tm) Global definition for Sangoma * - * Mailbox/API/UDP structures. * - * * - * Author: Alex Feldman * - *======================================================================* - * May 10 2002 Alex Feldman Initial version * - * * - ************************************************************************ - */ +/************************************************************************* +* wanpipe_defines.h * +* WANPIPE(tm) Global definition for Sangoma * +* Mailbox/API/UDP structures. * +* * +* Author: Alex Feldman * +*========================================================================* +* May 10, 2002 Alex Feldman Initial version * +* * +* Nov 27, 2007 David Rokhvarg Implemented functions/definitions for * +* Sangoma MS Windows Driver and API. * +* * +* * +*************************************************************************/ #ifndef __WANPIPE_DEFINES_H # define __WANPIPE_DEFINES_H @@ -27,11 +28,21 @@ #if defined(__LINUX__) # include # include +# include #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) # include # if defined(WAN_KERNEL) # include # endif +# include +#elif defined(__WINDOWS__) +# include +# include /* Basic data types */ +# include +# if defined(WAN_KERNEL) +# include +# endif +# include #endif /************************************************ @@ -117,12 +128,6 @@ # define WANPIPE_SUB_VERSION WANPIPE_SUB_VERSION_NetBSD # define WANPIPE_LITE_VERSION WANPIPE_LITE_VERSION_NetBSD #elif defined(__WINDOWS__) -# undef WANPIPE_VERSION -# undef WANPIPE_VERSION_BETA -# undef WANPIPE_SUB_VERSION -# define WANPIPE_VERSION WANPIPE_VERSION_Windows -# define WANPIPE_VERSION_BETA WANPIPE_VERSION_BETA_Windows -# define WANPIPE_SUB_VERSION WANPIPE_SUB_VERSION_Windows #endif #define WANROUTER_MAJOR_VER 2 @@ -186,8 +191,41 @@ typedef struct tcphdr tcphdr_t; # define w_tcp_seq th_seq # define w_tcp_ack_seq th_ack #elif defined(__WINDOWS__) -typedef void* iphdr_t; -typedef void* udphdr_t; +/* Intel X86 */ +#define __LITTLE_ENDIAN_BITFIELD + +struct iphdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 ihl:4, + version:4; +#elif defined (__BIG_ENDIAN_BITFIELD) + __u8 version:4, + ihl:4; +#else +# error "unknown byteorder!" +#endif + __u8 tos; + __u16 tot_len; + __u16 id; + __u16 frag_off; + __u8 ttl; + __u8 protocol; + __u16 check; + __u32 saddr; + __u32 daddr; + /*The options start here. */ +}; + +struct udphdr { + __u16 source; + __u16 dest; + __u16 len; + __u16 check; +}; + +typedef struct iphdr iphdr_t; +typedef struct udphdr udphdr_t; + #else # error "Unknown OS system!" #endif @@ -212,9 +250,13 @@ typedef u_int64_t u64; ** GLOBAL SANGOMA MACROS ************************************************/ #if defined(__LINUX__) -# define strlcpy(d,s,l) strcpy(d,s) +# if !defined(strlcpy) +# define strlcpy(d,s,l) strcpy((d),(s)) +# endif #elif defined(__FreeBSD__) -# define strlcpy(d,s,l) strcpy(d,s) +# if !defined(strlcpy) +# define strlcpy(d,s,l) strcpy((d),(s)) +# endif #endif /************************************************ @@ -484,7 +526,11 @@ typedef struct { typedef struct { wan_api_rx_hdr_t api_rx_hdr; +#if defined(__WINDOWS__)/* zero-sized array does not comply to ANSI 'C' standard! */ + unsigned char data[1]; +#else unsigned char data[0]; +#endif #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 @@ -508,11 +554,16 @@ typedef struct { typedef struct { wan_api_tx_hdr_t api_tx_hdr; +#if defined(__WINDOWS__)/* zero-sized array does not comply to ANSI 'C' standard! */ + unsigned char data[1]; +#else unsigned char data[0]; +#endif }wan_api_tx_element_t; #pragma pack() +#if !defined(__WINDOWS__) enum { SIOC_WAN_READ_REG = 0x01, SIOC_WAN_WRITE_REG, @@ -532,6 +583,7 @@ enum { SIOC_WAN_WRITE_PCIBRIDGE_REG, SIOC_WAN_ALL_WRITE_PCIBRIDGE_REG }; +#endif typedef struct wan_cmd_api_ { @@ -625,7 +677,11 @@ typedef struct wan_udp_hdr{ #define wan_udphdr_aft_num_frames wan_udphdr_u.aft.trace_info.num_frames #define wan_udphdr_aft_ismoredata wan_udphdr_u.aft.trace_info.ismoredata #define wan_udphdr_aft_data wan_udphdr_u.aft.data -#define wan_udphdr_data wan_udphdr_u.data +#if defined(__WINDOWS__) +# define wan_udphdr_data wan_udphdr_aft_data +#else +# define wan_udphdr_data wan_udphdr_u.data +#endif } wan_udp_hdr_t; @@ -659,7 +715,6 @@ typedef struct wan_udp_hdr{ # define WP_DELAY DELAY # define WP_SCHEDULE(arg,name) tsleep(&(arg),PPAUSE,(name),(arg)) # define SYSTEM_TICKS ticks -typedef int wan_ticks_t; # define HZ hz # define RW_LOCK_UNLOCKED 0 # define ETH_P_IP AF_INET @@ -669,6 +724,8 @@ typedef int wan_ticks_t; # define WAN_IFT_ETHER IFT_ETHER # define WAN_IFT_PPP IFT_PPP # define WAN_MFLAG_PRV M_PROTO1 +# define WAN_MFLAG_IPX M_PROTO2 +typedef u_long wan_ioctl_cmd_t; #elif defined(__OpenBSD__) /******************* O P E N B S D ******************************/ # define WAN_MOD_LOAD LKM_E_LOAD @@ -676,7 +733,6 @@ typedef int wan_ticks_t; # define WP_DELAY DELAY # define WP_SCHEDULE(arg,name) tsleep(&(arg),PPAUSE,(name),(arg)) # define SYSTEM_TICKS ticks -typedef int wan_ticks_t; # define HZ hz # define RW_LOCK_UNLOCKED 0 # define ETH_P_IP AF_INET @@ -686,25 +742,26 @@ typedef int wan_ticks_t; # define WAN_IFT_ETHER IFT_ETHER # define WAN_IFT_PPP IFT_PPP # define WAN_MFLAG_PRV M_PROTO1 +# define WAN_MFLAG_IPX M_PROTO2 +typedef u_long wan_ioctl_cmd_t; #elif defined(__NetBSD__) /******************* N E T B S D ******************************/ # define WAN_MOD_LOAD LKM_E_LOAD # define WAN_MOD_UNLOAD LKM_E_UNLOAD # define WP_DELAY DELAY # define SYSTEM_TICKS tick -typedef int wan_ticks_t; # define HZ hz # define RW_LOCK_UNLOCKED 0 # define WAN_IFT_OTHER IFT_OTHER # define WAN_IFT_ETHER IFT_ETHER # define WAN_IFT_PPP IFT_PPP +typedef u_long wan_ioctl_cmd_t; #elif defined(__LINUX__) /*********************** L I N U X ******************************/ # define ETHER_ADDR_LEN ETH_ALEN # define WP_DELAY(usecs) udelay(usecs) # define atomic_set_int(name, val) atomic_set(name, val) # define SYSTEM_TICKS jiffies -typedef unsigned long wan_ticks_t; # define WP_SCHEDULE(arg,name) schedule() # define wan_atomic_read atomic_read # define wan_atomic_set atomic_set @@ -713,10 +770,27 @@ typedef unsigned long wan_ticks_t; # define WAN_IFT_OTHER 0x00 # define WAN_IFT_ETHER 0x00 # define WAN_IFT_PPP 0x00 +typedef int wan_ioctl_cmd_t; #elif defined(__WINDOWS__) /******************* W I N D O W S ******************************/ -# define EINVAL 22 -# define IFNAMESIZ 16 +# define ETHER_ADDR_LEN 6 +# define WP_DELAY(usecs) KeStallExecutionProcessor(usecs);/* usecs is in MicroSeconds */ +# define SYSTEM_TICKS get_systemticks() +# define jiffies SYSTEM_TICKS +# define wan_atomic_read atomic_read +# define wan_atomic_set atomic_set +# define wan_atomic_inc atomic_inc +# define wan_atomic_dec atomic_dec +# define RW_LOCK_UNLOCKED 0 +typedef int wan_ioctl_cmd_t; + +#define ONE_MILLISECOND_INTERVAL 1000 +/* this macro allowed only at IRQL = PASSIVE_LEVEL*/ +#define WP_MILLISECONDS_DELAY(ms_delay){ \ + LARGE_INTEGER Interval; \ + Interval.QuadPart = Int32x32To64(ONE_MILLISECOND_INTERVAL*ms_delay, -10);\ + KeDelayExecutionThread(KernelMode, FALSE, &Interval); \ +} #endif #if defined(__FreeBSD__) @@ -729,9 +803,9 @@ typedef unsigned long wan_ticks_t; int load_##name (module_t mod, int cmd, void *arg){ \ switch(cmd){ \ case WAN_MOD_LOAD: return mod_init((devsw)); \ - case WAN_MOD_UNLOAD: \ - case WAN_MOD_SHUTDOWN: return mod_exit((devsw));\ - case WAN_MOD_QUIESCE: return 0; \ + case WAN_MOD_UNLOAD: return mod_exit((devsw)); \ + case WAN_MOD_SHUTDOWN: return 0;\ + case WAN_MOD_QUIESCE: return 0; \ } \ return -EINVAL; \ } \ @@ -815,9 +889,12 @@ typedef unsigned long wan_ticks_t; ** T Y P E D E F ****************************************************************** */ + +#if !defined(__WINDOWS__) #if !defined(offsetof) # define offsetof(type, member) ((size_t)(&((type*)0)->member)) #endif +#endif #if defined(__LINUX__) typedef struct sk_buff netskb_t; @@ -838,9 +915,7 @@ typedef void (*wan_taskq_func_t)(struct work_struct *); typedef struct tq_struct wan_taskq_t; typedef void* virt_addr_t; -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) typedef unsigned long phys_addr_t; -#endif typedef spinlock_t wan_spinlock_t; typedef rwlock_t wan_rwlock_t; typedef unsigned long wan_smp_flag_t; @@ -877,7 +952,11 @@ typedef dev_t ttydriver_t; typedef struct tty ttystruct_t; typedef struct termios termios_t; typedef int (get_info_t)(char *, char **, off_t, int, int); +#if defined(SPINLOCK_OLD) typedef int wan_spinlock_t; +#else +typedef struct mtx wan_spinlock_t; +#endif typedef int wan_rwlock_t; typedef int wan_smp_flag_t; typedef int wan_rwlock_flag_t; @@ -946,22 +1025,39 @@ typedef void (wan_pci_ifunc_t)(void*); #elif defined(__SOLARIS__) typedef mblk_t netskb_t; - #elif defined(__WINDOWS__) -typedef UCHAR u8; -typedef UINT u16; -typedef USHORT u32; -typedef ULONG u64; -typedef char* caddr_t; -# if defined(NDIS_MINIPORT_DRIVER) -typedef NDIS_MINIPORT_TIMER wan_timer_info_t; -# else -typedef KTIMER wan_timer_info_t; -# endif -typedef void netdevice_t; -typedef void* wan_skb_queue_t; -typedef void (*wan_timer_func_t)(void*); +/*********************************************************************/ + +/*********************************************************************/ + +typedef struct sk_buff netskb_t; +typedef struct sk_buff_head wan_skb_queue_t; + +typedef struct +{ + u8 DestAddr[6]; + u8 SrcAddr[6]; + u16 EtherType; +} ethhdr_t; + +typedef void* wan_timer_arg_t; +typedef PKDEFERRED_ROUTINE wan_tasklet_func_t; +typedef PKDEFERRED_ROUTINE wan_taskq_func_t; + +typedef struct _wan_timer_info_t{ + KTIMER Timer; + KDPC TimerDpcObject; + LARGE_INTEGER TimerDueTime; +}wan_timer_info_t; + +typedef void (*wan_timer_func_t)(IN PKDPC Dpc, void* context, void * arg2, void * arg3); + +typedef struct { ULONG counter; } atomic_t; + +typedef int wan_rwlock_t; +typedef int wan_rwlock_flag_t; +typedef int pid_t; #endif /* @@ -1001,9 +1097,9 @@ typedef struct _wan_rwlock /* ** FIXME: Redefined from sdla_adsl.c -** DMA structure +** DMA structure for ADSL ONLY!!!!!!! */ -typedef struct _wan_dma_descr +typedef struct _wan_dma_descr_org { unsigned long* vAddr; unsigned long pAddr; @@ -1022,7 +1118,7 @@ typedef struct _wan_dma_descr int rsegs; #else /* other OS */ #endif -} wan_dma_descr_t;/*, *PDMA_DESCRIPTION;*/ +} wan_dma_descr_org_t;/*, *PDMA_DESCRIPTION;*/ /* ** TASK structure @@ -1037,6 +1133,8 @@ typedef struct _wan_tasklet void* data; #elif defined(__LINUX__) struct tasklet_struct task_id; +#elif defined(__WINDOWS__) + KDPC tqueue; #elif defined(__SOLARIS__) #error "wan_tasklet: not defined in solaris" #endif @@ -1060,6 +1158,8 @@ typedef struct _wan_taskq # else struct work_struct tqueue; # endif +#elif defined(__WINDOWS__) + KDPC tqueue; #elif defined(__SOLARIS__) #error "_wan_taskq: not defined in solaris" #endif @@ -1071,7 +1171,7 @@ typedef struct wan_trace { u_int32_t tracing_enabled; wan_skb_queue_t trace_queue; - unsigned long trace_timeout;/* WARNING: has to be 'unsigned long' !!!*/ + wan_ticks_t trace_timeout;/* WARNING: has to be 'unsigned long' !!!*/ unsigned int max_trace_queue; unsigned char last_trace_direction; u_int32_t missed_idle_rx_counter; @@ -1093,12 +1193,12 @@ typedef struct _wan_timer #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) wan_timer_func_t timer_func; #elif defined(__WINDOWS__) - KDPC TimerDpcObject; + wan_timer_func_t timer_func; #endif void* timer_arg; } wan_timer_t; -#if !defined(LINUX_2_6) +#if !defined(LINUX_2_6) && !defined(__WINDOWS__) /* Define this structure for BSDs and not Linux-2.6 */ struct seq_file { char* buf; /* pointer to buffer (buf)*/ @@ -1193,8 +1293,6 @@ typedef struct wan_udp_pkt { } wan_udp_pkt_t; - - #pragma pack(1) #if defined(WAN_BIG_ENDIAN) || (1) @@ -1244,6 +1342,7 @@ typedef struct wan_rtp_pkt { #pragma pack() + #endif /* KERNEL */ #endif /* __WANPIPE_DEFINES_H */ diff --git a/patches/kdrivers/include/wanpipe_ec_kernel.h b/patches/kdrivers/include/wanpipe_ec_kernel.h index 6a11279..6ca328f 100644 --- a/patches/kdrivers/include/wanpipe_ec_kernel.h +++ b/patches/kdrivers/include/wanpipe_ec_kernel.h @@ -21,18 +21,21 @@ # include #endif +#if defined(WAN_KERNEL) typedef struct wanec_iface_ { unsigned long init; - void* (*reg) (void*, int); + void* (*reg) (void*, u_int32_t, int, int, void*); int (*unreg) (void*, void*); int (*ioctl) (void); - int (*isr) (void*, void*); + int (*isr) (void*); int (*poll) (void*, void*); int (*event_ctrl) (void*, void*, wan_event_ctrl_t*); } wanec_iface_t; +#endif /* WAN_KERNEL */ + #endif /* __WANPIPE_EC_KERNEL_H */ diff --git a/patches/kdrivers/include/wanpipe_events.h b/patches/kdrivers/include/wanpipe_events.h index 07f2855..53b665b 100644 --- a/patches/kdrivers/include/wanpipe_events.h +++ b/patches/kdrivers/include/wanpipe_events.h @@ -24,11 +24,23 @@ (type == WAN_EC_TONE_STOP) ? "Stop" : \ "Unknown" +/* pcm law type (alaw or ulaw) */ +#define WAN_EC_PCM_U_LAW 0x01 +#define WAN_EC_PCM_A_LAW 0x02 +#define WAN_EC_DECODE_PCM_LAW(pcmlaw) \ + ((pcmlaw) == WAN_EC_PCM_U_LAW) ? "ULAW" : \ + ((pcmlaw) == WAN_EC_PCM_A_LAW) ? "ALAW" : "Unknown" + /* channel port (sout, rout, sin, rin) */ -#define WAN_EC_CHANNEL_PORT_SOUT 0x01 -#define WAN_EC_CHANNEL_PORT_SIN 0x02 -#define WAN_EC_CHANNEL_PORT_ROUT 0x03 -#define WAN_EC_CHANNEL_PORT_RIN 0x04 +#define WAN_EC_CHANNEL_PORT_SOUT 0x01 +#define WAN_EC_CHANNEL_PORT_SIN 0x02 +#define WAN_EC_CHANNEL_PORT_ROUT 0x04 +#define WAN_EC_CHANNEL_PORT_RIN 0x08 +#define WAN_EC_DECODE_CHANNEL_PORT(port) \ + ((port) == WAN_EC_CHANNEL_PORT_SOUT) ? "SOUT" : \ + ((port) == WAN_EC_CHANNEL_PORT_SIN) ? "SIN" : \ + ((port) == WAN_EC_CHANNEL_PORT_ROUT) ? "ROUT" : \ + ((port) == WAN_EC_CHANNEL_PORT_RIN) ? "RIN" : "Unknown" #define WAN_EVENT_RXHOOK_OFF 0x01 #define WAN_EVENT_RXHOOK_ON 0x02 @@ -77,9 +89,11 @@ #define WAN_EVENT_RM_ONHOOKTRANSFER 0x000E #define WAN_EVENT_RM_SETPOLARITY 0x000F #define WAN_EVENT_RM_SET_ECHOTUNE 0x0010 +#define WAN_EVENT_EC_CHAN_MODIFY 0x0011 +#define WAN_EVENT_EC_H100_REPORT 0x0012 #define WAN_EVENT_TYPE_DECODE(type) \ - ((type) == WAN_EVENT_EC_DTMF) ? "EC DTMF" : \ + ((type) == WAN_EVENT_EC_DTMF) ? "EC DTMF" : \ ((type) == WAN_EVENT_RM_POWER) ? "RM Power Alarm" : \ ((type) == WAN_EVENT_RM_LC) ? "RM Loop Closure" : \ ((type) == WAN_EVENT_RM_RING_TRIP) ? "RM Ring Trip" : \ @@ -95,6 +109,7 @@ ((type) == WAN_EVENT_RM_ONHOOKTRANSFER) ? "RM On-hook transfer" : \ ((type) == WAN_EVENT_RM_SETPOLARITY) ? "RM Set polarity" : \ ((type) == WAN_EVENT_RM_SET_ECHOTUNE) ? "RM Set echotune" : \ + ((type) == WAN_EVENT_EC_CHAN_MODIFY) ? "EC Chan Modify" : \ "(Unknown type)" /* tone type list */ @@ -130,7 +145,8 @@ typedef struct wan_event_ctrl_ { u_int16_t type; u_int8_t mode; - int mod_no; /* A200-Remora */ + int mod_no; /* A200-Remora */ + int channel; unsigned char ec_dtmf_port; /* EC DTMF: SOUT or ROUT */ unsigned long ts_map; u_int8_t tone; diff --git a/patches/kdrivers/include/wanpipe_fr_iface.h b/patches/kdrivers/include/wanpipe_fr_iface.h index bf75590..cdee472 100644 --- a/patches/kdrivers/include/wanpipe_fr_iface.h +++ b/patches/kdrivers/include/wanpipe_fr_iface.h @@ -66,7 +66,11 @@ extern int wp_fr_close_chan(void *chan_ptr); extern int wp_fr_ioctl (void *chan_ptr, int cmd, void *arg); extern int wp_fr_rx (void * prot_ptr, void *rx_pkt); +#if defined(__WINDOWS__) +extern int wp_fr_timer (void *prot_ptr, unsigned int *period); +#else extern int wp_fr_timer (void *prot_ptr, unsigned int *period, unsigned int carrier_reliable); +#endif extern int wp_fr_tx (void * chan_ptr, void *skb, int type); extern int wp_fr_pipemon(void *chan, int cmd, int dlci, unsigned char* data, unsigned int *len); extern int wp_fr_snmp(void* chan_ptr, void* data); diff --git a/patches/kdrivers/include/wanpipe_iface.h b/patches/kdrivers/include/wanpipe_iface.h index 8de4560..3368e13 100644 --- a/patches/kdrivers/include/wanpipe_iface.h +++ b/patches/kdrivers/include/wanpipe_iface.h @@ -94,23 +94,13 @@ struct if_settings /* WANPIPE Generic function interface */ # if defined(WAN_KERNEL) -/* ifType - SNMP */ -#if 0 -/* moved to wanpipe_defines.h */ -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -# define WAN_IFT_OTHER IFT_OTHER -# define WAN_IFT_ETHER IFT_ETHER -# define WAN_IFT_PPP IFT_PPP -#elif defined(__LINUX__) -# define WAN_IFT_OTHER 0x00 -# define WAN_IFT_ETHER 0x00 -# define WAN_IFT_PPP 0x00 -#endif -#endif - typedef struct { +#if defined(__WINDOWS__) + netdevice_t*(*alloc)(int); +#else netdevice_t*(*alloc)(int, int ifType); +#endif void(*free)(netdevice_t*); int(*attach)(netdevice_t*, char*, int); void(*detach)(netdevice_t*, int); diff --git a/patches/kdrivers/include/wanpipe_includes.h b/patches/kdrivers/include/wanpipe_includes.h index 8f589d3..273bbe4 100644 --- a/patches/kdrivers/include/wanpipe_includes.h +++ b/patches/kdrivers/include/wanpipe_includes.h @@ -5,7 +5,11 @@ * * * Author: Alex Feldman * *======================================================================* - * Aug 10 2002 Alex Feldman Initial version * + * * + * Nov 27, 2007 David Rokhvarg Added header files needed to compile * + * Sangoma MS Windows Driver and API. * + * * + * Aug 10, 2002 Alex Feldman Initial version * * * ************************************************************************ */ @@ -39,6 +43,7 @@ # endif # include # include +# include # include # include # include @@ -68,6 +73,7 @@ # include # include # endif +# include # include # include # include @@ -99,6 +105,7 @@ #ifdef NETGRAPH # include # include +# include #endif /* NETGRAPH */ # include # if (__FreeBSD_version < 500000) @@ -320,19 +327,43 @@ /* ** *** W I N D O W S *** */ -# if defined(__KERNEL__) -# include /* PCI configuration struct */ -# include /* NDIS functions */ -# include -# include -# include /* offsetof, etc. */ -# include /* bit manipulation macros */ -# include /* operation return codes */ -# include /* for 'wan_udp_hdr_t' */ -# include -# else -# include -# endif /* if defined(__WINDOWS__) */ + + +#if defined(WAN_KERNEL) || defined(__KERNEL__) +# include +# include /* clock_t */ + +# if defined(VIRTUAL_IF_DRV) || defined(SPROTOCOL) +# include +# include +# include +# include +# include +# include +# include +# include +# include /* API definitions */ +# include +# endif + +#if defined( NDIS_MINIPORT_DRIVER ) +# undef BINARY_COMPATIBLE +# define BINARY_COMPATIBLE 0 /* compile for Win2000 and later */ +# define NDIS50_MINIPORT 1 +# include +# include +# include +#endif + +/*# include - UINT*/ +#else +# include +#endif + +#include +#include +#include /* offsetof, etc. */ + #elif defined (__SOLARIS__) # include # include diff --git a/patches/kdrivers/include/wanpipe_kernel.h b/patches/kdrivers/include/wanpipe_kernel.h index 6238335..937df55 100644 --- a/patches/kdrivers/include/wanpipe_kernel.h +++ b/patches/kdrivers/include/wanpipe_kernel.h @@ -28,24 +28,26 @@ #else # define wp_ip_rt_ioctl(_cmd_,_rptr_) ip_rt_ioctl(_cmd_,_rptr_) # define wp_devinet_ioctl(_cmd_,_rptr_) devinet_ioctl(_cmd_,_rptr_) -#endif +#endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -#define wan_skb_reset_mac_header(skb) skb_reset_mac_header(skb) -#define wan_skb_reset_network_header(skb) skb_reset_network_header(skb) -#define wan_skb_end_pointer(skb) skb_end_pointer(skb) -#define wan_skb_tail_pointer(skb) skb_tail_pointer(skb) -#define wan_skb_reset_tail_pointer(skb) skb_reset_tail_pointer(skb) -#define wan_skb_set_tail_pointer(skb,offset) skb_set_tail_pointer(skb,offset) +#define __wan_skb_reset_mac_header(skb) skb_reset_mac_header(skb) +#define __wan_skb_reset_network_header(skb) skb_reset_network_header(skb) +#define __wan_skb_reset_tail_pointer(skb) skb_reset_tail_pointer(skb) +#define __wan_skb_tail_pointer(skb) skb_tail_pointer(skb) +#define __wan_skb_set_tail_pointer(skb,offset) skb_set_tail_pointer(skb,offset) +#define __wan_skb_end_pointer(skb) skb_end_pointer(skb) #else -#define wan_skb_reset_mac_header(skb) ((skb)->mac.raw = (skb)->data) -#define wan_skb_reset_network_header(skb) ((skb)->nh.raw = (skb)->data) -#define wan_skb_tail_pointer(skb) ((skb)->tail) -#define wan_skb_end_pointer(skb) ((skb)->end) -#define wan_skb_reset_tail_pointer(skb) ((skb)->tail = (skb)->data) -#define wan_skb_set_tail_pointer(skb,offset) ((skb)->tail = ((skb)->data + offset)) +#define __wan_skb_reset_mac_header(skb) (skb->mac.raw = skb->data) +#define __wan_skb_reset_network_header(skb) (skb->nh.raw = skb->data) +#define __wan_skb_reset_tail_pointer(skb) (skb->tail = skb->data) +#define __wan_skb_end_pointer(skb) ((skb)->end) +#define __wan_skb_tail_pointer(skb) ((netskb_t*)skb)->tail +#define __wan_skb_set_tail_pointer(skb,offset) ((skb)->tail = ((skb)->data + offset)) #endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) || defined(LINUX_FEAT_2624) # ifndef LINUX_FEAT_2624 # define LINUX_FEAT_2624 1 @@ -65,6 +67,10 @@ #endif +/*========================================================================== + KERNEL 2.6. + *==========================================================================*/ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* KERNEL 2.6.X */ @@ -91,19 +97,17 @@ { schedule_work(tq); } - + #define ADMIN_CHECK() {if (!capable(CAP_SYS_ADMIN)) {\ - if (WAN_NET_RATELIMIT()) { \ - DEBUG_EVENT("%s:%d: wanpipe: ADMIN_CHECK: Failed !\n",__FUNCTION__,__LINE__);\ - } \ + DEBUG_EVENT("wanpipe: ADMIN_CHECK: Failed Cap=0x%X Fsuid=0x%X Euid=0x%X\n", \ + current->cap_effective,current->fsuid,current->euid);\ return -EPERM; \ }\ } #define NET_ADMIN_CHECK() {if (!capable(CAP_NET_ADMIN)){\ - if (WAN_NET_RATELIMIT()) { \ - DEBUG_EVENT("%s:%d: wanpipe: NET_ADMIN_CHECK: Failed !\n",__FUNCTION__,__LINE__);\ - } \ + DEBUG_EVENT("wanpipe: NET_ADMIN_CHECK: Failed Cap=0x%X Fsuid=0x%X Euid=0x%X\n", \ + current->cap_effective,current->fsuid,current->euid);\ return -EPERM; \ }\ } @@ -160,6 +164,12 @@ #endif + + +/*========================================================================== + KERNEL 2.4.X + *==========================================================================*/ + #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /* -------------------------------------------------- * KERNEL 2.4.X @@ -247,6 +257,12 @@ + +/*========================================================================== + KERNEL 2.2.X + *==========================================================================*/ + + #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) /*----------------------------------------------------- * KERNEL 2.2.X @@ -496,7 +512,60 @@ static inline int open_dev_check(netdevice_t *dev) #endif } -#else +#define WAN_IFQ_INIT(ifq, max_pkt) skb_queue_head_init((ifq)) +#define WAN_IFQ_DESTROY(ifq) +#define WAN_IFQ_PURGE(ifq) wan_skb_queue_purge((ifq)) +#define WAN_IFQ_DMA_PURGE(ifq) \ + { netskb_t *skb; \ + while ((skb=wan_skb_dequeue((ifq))) != NULL) { \ + if (skb_shinfo(skb)->frag_list || skb_shinfo(skb)->nr_frags) { \ + DEBUG_EVENT("WARNING [%s:%d]: SKB Corruption!\n", \ + __FUNCTION__,__LINE__); \ + continue; \ + } \ + wan_skb_free(skb); \ + } \ + } + +#define WAN_IFQ_ENQUEUE(ifq, skb, arg, err) skb_queue_tail((ifq), (skb)) +#define WAN_IFQ_LEN(ifq) skb_queue_len((ifq)) + +# define WAN_TASKLET_INIT(task, priority, func, arg) \ + (task)->running = 0; \ + tasklet_init(&(task)->task_id,func,(unsigned long)arg) + +# define WAN_TASKLET_SCHEDULE(task) \ + wan_set_bit(0, &(task)->running); \ + tasklet_schedule(&(task)->task_id); +#if 0 +# define WAN_WP_TASKLET_SCHEDULE_PER_CPU(task,cpu) \ + wan_set_bit(0, &(task)->running); \ + wp_tasklet_hi_schedule_per_cpu(&(task)->task_id,cpu); +#endif + +# define WAN_TASKLET_RUNNING(task) \ + wan_test_bit(0, &(task)->running) + +# define WAN_TASKLET_END(task) wan_clear_bit(0, &(task)->running) + +# define WAN_TASKLET_KILL(task) tasklet_kill(&(task)->task_id) + +/* Due to 2.6.20 kernel the wan_taskq_t is now a direct + * workqueue struct not an abstracted structure */ +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + INIT_WORK((task),func,arg) +# else +# define WAN_TASKQ_INIT(task, priority, func, arg) \ + INIT_WORK((task),func) +# endif +# define WAN_IS_TASKQ_SCHEDULE +# define WAN_TASKQ_SCHEDULE(task) \ + wan_schedule_task(task) + + + +#else /* __KERNEL__ */ #include @@ -514,4 +583,7 @@ static inline int open_dev_check(netdevice_t *dev) #endif + #endif + + diff --git a/patches/kdrivers/include/wanpipe_kernel.h~ b/patches/kdrivers/include/wanpipe_kernel.h~ deleted file mode 100644 index c3f0180..0000000 --- a/patches/kdrivers/include/wanpipe_kernel.h~ +++ /dev/null @@ -1,513 +0,0 @@ - -#ifndef _WANPIPE_KERNEL_H -#define _WANPIPE_KERNEL_H - -#ifdef __KERNEL__ - -#include - -# if defined (__BIG_ENDIAN_BITFIELD) -# define WAN_BIG_ENDIAN 1 -# undef WAN_LITTLE_ENDIAN -# else -# undef WAN_BIG_ENDIAN -# define WAN_LITTLE_ENDIAN 1 -# endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) -# define MODULE_LICENSE(a) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) -# define snprintf(a,b,c,d...) sprintf(a,c,##d) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) -# define wp_ip_rt_ioctl(_cmd_,_rptr_) -EINVAL -# define wp_devinet_ioctl(_cmd_,_rptr_) -EINVAL -#else -# define wp_ip_rt_ioctl(_cmd_,_rptr_) ip_rt_ioctl(_cmd_,_rptr_) -# define wp_devinet_ioctl(_cmd_,_rptr_) devinet_ioctl(_cmd_,_rptr_) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -#define wan_skb_reset_mac_header(skb) skb_reset_mac_header(skb) -#define wan_skb_reset_network_header(skb) skb_reset_network_header(skb) -#define wan_skb_end_pointer(skb) skb_end_pointer(skb) -#define wan_skb_tail_pointer(skb) skb_tail_pointer(skb) -#define wan_skb_reset_tail_pointer(skb) skb_reset_tail_pointer(skb) -#define wan_skb_set_tail_pointer(skb,offset) skb_set_tail_pointer(skb,offset) -#else -#define wan_skb_reset_mac_header(skb) ((skb)->mac.raw = (skb)->data) -#define wan_skb_reset_network_header(skb) ((skb)->nh.raw = (skb)->data) -#define wan_skb_tail_pointer(skb) ((skb)->tail) -#define wan_skb_end_pointer(skb) ((skb)->end) -#define wan_skb_reset_tail_pointer(skb) ((skb)->tail = (skb)->data) -#define wan_skb_set_tail_pointer(skb,offset) ((skb)->tail = ((skb)->data + offset)) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -# define LINUX_FEAT_2624 1 -# define wan_dev_get_by_name(name) dev_get_by_name(&init_net,name) -# define wan_dev_get_by_index(idx) dev_get_by_index(&init_net,idx) -# define wan_init_net(name) init_net.name -#else -# define wan_dev_get_by_name(name) dev_get_by_name(name) -# define wan_dev_get_by_index(idx) dev_get_by_index(idx) -# define wan_init_net(name) name -#endif - - -#ifndef IRQF_SHARED -#define IRQF_SHARED SA_SHIRQ -#endif - - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -/* KERNEL 2.6.X */ - - #define LINUX_2_6 - #define netdevice_t struct net_device - - #define FREE_READ 1 - #define FREE_WRITE 0 - - #define stop_net_queue(a) netif_stop_queue(a) - #define start_net_queue(a) netif_start_queue(a) - #define is_queue_stopped(a) netif_queue_stopped(a) - #define wake_net_dev(a) netif_wake_queue(a) - #define is_dev_running(a) netif_running(a) - #define wan_dev_kfree_skb(a,b) dev_kfree_skb_any(a) - - #define tq_struct work_struct - - #define wan_call_usermodehelper(a,b,c) call_usermodehelper(a,b,c,0) - - #define pci_present() 1 - - static inline void wan_schedule_task(struct tq_struct *tq) - { - schedule_work(tq); - } - - #define ADMIN_CHECK() {if (!capable(CAP_SYS_ADMIN)) {\ - DEBUG_EVENT("wanpipe: ADMIN_CHECK: Failed Cap=0x%X Fsuid=0x%X Euid=0x%X\n", \ - current->cap_effective,current->fsuid,current->euid);\ - return -EPERM; \ - }\ - } - - #define NET_ADMIN_CHECK() {if (!capable(CAP_NET_ADMIN)){\ - DEBUG_EVENT("wanpipe: NET_ADMIN_CHECK: Failed Cap=0x%X Fsuid=0x%X Euid=0x%X\n", \ - current->cap_effective,current->fsuid,current->euid);\ - return -EPERM; \ - }\ - } - - #define WAN_IRQ_CALL(fn,args,ret) ret = fn args - #define WAN_IRQ_RETURN(a) return a - #define WAN_IRQ_RETVAL irqreturn_t - #define WAN_IRQ_RETVAL_DECL(ret) irqreturn_t ret = WAN_IRQ_NONE - #define WAN_IRQ_RETVAL_SET(ret, val) ret = val - #define WAN_IRQ_HANDLED IRQ_HANDLED - #define WAN_IRQ_NONE IRQ_NONE - - #define mark_bh(a) - - #define wan_clear_bit(a,b) clear_bit((a),(unsigned long*)(b)) - #define wan_set_bit(a,b) set_bit((a),(unsigned long*)(b)) - #define wan_test_bit(a,b) test_bit((a),(unsigned long*)(b)) - #define wan_test_and_set_bit(a,b) test_and_set_bit((a),(unsigned long*)(b)) - #define wan_test_and_clear_bit(a,b) test_and_clear_bit((a),(unsigned long*)(b)) - - #define dev_init_buffers(a) - - #define WP_PDE(_a) PDE(_a) - - - - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) - # define wp_rcu_read_lock(in_dev) rcu_read_lock() - # define wp_rcu_read_unlock(in_dev) rcu_read_unlock() - # define wp_readb(ptr) readb((void __iomem *)(ptr)) - # define wp_reads(ptr) reads((void __iomem *)(ptr)) - # define wp_readl(ptr) readl((void __iomem *)(ptr)) - # define wp_writeb(data,ptr) writeb(data,(void __iomem *)(ptr)) - # define wp_writew(data,ptr) writew(data,(void __iomem *)(ptr)) - # define wp_writel(data,ptr) writel(data,(void __iomem *)(ptr)) - # define wp_memset_io(ptr,data,len) memset_io((void __iomem *)(ptr),data,len) - #else - # define wp_rcu_read_lock(in_dev) read_lock_bh(&in_dev->lock) - # define wp_rcu_read_unlock(in_dev) read_unlock_bh(&in_dev->lock) - # define wp_readb(ptr) readb((ptr)) - # define wp_reads(ptr) reads((ptr)) - # define wp_readl(ptr) readl((ptr)) - # define wp_writeb(data,ptr) writeb(data,(ptr)) - # define wp_writew(data,ptr) writew(data,(ptr)) - # define wp_writel(data,ptr) writel(data,(ptr)) - # define wp_memset_io(ptr,data,len) memset_io((ptr),data,len) - #endif - - #if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,14) - #define htonl __constant_htonl - #define htons __constant_htons - #define ntohl __constant_ntohl - #define ntohs __constant_ntohs - #endif - - -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) -/* -------------------------------------------------- - * KERNEL 2.4.X - * -------------------------------------------------*/ - - #define LINUX_2_4 - #define netdevice_t struct net_device - - #define FREE_READ 1 - #define FREE_WRITE 0 - - #define stop_net_queue(a) netif_stop_queue(a) - #define start_net_queue(a) netif_start_queue(a) - #define is_queue_stopped(a) netif_queue_stopped(a) - #define wake_net_dev(a) netif_wake_queue(a) - #define is_dev_running(a) netif_running(a) - #define wan_dev_kfree_skb(a,b) dev_kfree_skb_any(a) - #define pci_get_device(a,b,c) pci_find_device(a,b,c) - - #define __dev_get(a) dev_get(a) - - static inline void wan_schedule_task(struct tq_struct *tq) - { - schedule_task(tq); - } - - #ifndef INIT_WORK - # define INIT_WORK INIT_TQUEUE - #endif - - #define wan_call_usermodehelper(a,b,c) call_usermodehelper(a,b,c) - - #define ADMIN_CHECK() {if (!capable(CAP_SYS_ADMIN)) {\ - DEBUG_EVENT("wanpipe: ADMIN_CHECK: Failed Cap=0x%X Fsuid=0x%X Euid=0x%X\n", \ - current->cap_effective,current->fsuid,current->euid);\ - return -EPERM; \ - }\ - } - - #define NET_ADMIN_CHECK() {if (!capable(CAP_NET_ADMIN)){\ - DEBUG_EVENT("wanpipe: NET_ADMIN_CHECK: Failed Cap=0x%X Fsuid=0x%X Euid=0x%X\n", \ - current->cap_effective,current->fsuid,current->euid);\ - return -EPERM; \ - }\ - } - - #define WAN_IRQ_CALL(fn,args,ret) fn args - #define WAN_IRQ_RETURN(a) return - #define WAN_IRQ_RETVAL void - #define WAN_IRQ_RETVAL_DECL(ret) - #define WAN_IRQ_RETVAL_SET(ret, val) - #ifndef WAN_IRQ_NONE - # define WAN_IRQ_NONE (0) - #endif - - #ifndef WAN_IRQ_HANDLED - # define WAN_IRQ_HANDLED (1) - #endif - - #define wan_clear_bit(a,b) clear_bit((a),(b)) - #define wan_set_bit(a,b) set_bit((a),(b)) - #define wan_test_bit(a,b) test_bit((a),(b)) - #define wan_test_and_set_bit(a,b) test_and_set_bit((a),(b)) - #define wan_test_and_clear_bit(a,b) test_and_clear_bit((a),(b)) - - static inline struct proc_dir_entry *WP_PDE(const struct inode *inode) - { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,21) - return (struct proc_dir_entry *)inode->u.generic_ip; - #else - return (struct proc_dir_entry *)inode->i_private; - #endif - } - - #define wp_rcu_read_lock(in_dev) read_lock_bh(&in_dev->lock) - #define wp_rcu_read_unlock(in_dev) read_unlock_bh(&in_dev->lock) - #define wp_readb(ptr) readb((ptr)) - #define wp_reads(ptr) reads((ptr)) - #define wp_readl(ptr) readl((ptr)) - - #define wp_writeb(data,ptr) writeb(data,(ptr)) - #define wp_writew(data,ptr) writew(data,(ptr)) - #define wp_writel(data,ptr) writel(data,(ptr)) - #define wp_memset_io(ptr,data,len) memset_io((ptr),data,len) - - - -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -/*----------------------------------------------------- - * KERNEL 2.2.X - * ---------------------------------------------------*/ - - #define LINUX_2_1 - #define net_device device - #define netdevice_t struct device - #define FREE_READ 1 - #define FREE_WRITE 0 - - #define S_IRUGO 0 - - #define __exit - - #ifndef get_order - # define get_order(x) __get_order(x) - #endif - - #define pci_get_device(a,b,c) pci_find_device(a,b,c) - #define wan_dev_kfree_skb(a,b) kfree_skb(a) - #define dev_kfree_skb_any(a) kfree_skb(a) - - #define netif_wake_queue(dev) do { \ - clear_bit(0, &(dev)->tbusy); \ - mark_bh(NET_BH); \ - } while(0) - #define netif_start_queue(dev) do { \ - (dev)->tbusy = 0; \ - (dev)->interrupt = 0; \ - (dev)->start = 1; \ - } while (0) - - #define netif_stop_queue(dev) (set_bit(0, &(dev)->tbusy)) - #define netif_running(dev) (dev)->start - #define netdevice_start(dev) (dev)->start = 1 - #define netdevice_stop(dev) (dev)->start = 0 - #define netif_queue_stopped(dev) (test_bit(0,&(dev)->tbusy)) - #define netif_set_tx_timeout(dev, tf, tm) - - #define stop_net_queue(dev) netif_stop_queue(dev) - #define start_net_queue(dev) netif_start_queue(dev) - #define is_queue_stopped(dev) netif_queue_stopped(dev) - #define wake_net_dev(dev) netif_wake_queue(dev) - #define is_dev_running(dev) netif_running(dev) - - #define dev_kfree_skb_irq(x) kfree_skb(x) - - #define tasklet_struct tq_struct - - #define __dev_get(a) dev_get(a) - - #ifndef DECLARE_WAITQUEUE - #define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = { current, NULL } - #endif - - #define tasklet_kill(a) { if ((a)->sync) {} } - - #define request_mem_region(addr, size, name) ((void *)1) - #define release_mem_region(addr, size) - #define pci_enable_device(x) (0) - #define pci_resource_start(dev, bar) dev->base_address[bar] - - #define wp_rcu_read_lock(in_dev) - #define wp_rcu_read_unlock(in_dev) - #define wp_readb(ptr) readb((ptr)) - #define wp_reads(ptr) reads((ptr)) - #define wp_readl(ptr) readl((ptr)) - #define wp_writeb(data,ptr) writeb(data,(ptr)) - #define wp_writew(data,ptr) writew(data,(ptr)) - #define wp_writel(data,ptr) writel(data,(ptr)) - #define wp_memset_io(ptr,data,len) memset_io((ptr),data,len) - - static inline void tasklet_hi_schedule(struct tasklet_struct *tasklet) - { - queue_task(tasklet, &tq_immediate); - mark_bh(IMMEDIATE_BH); - } - - static inline void tasklet_schedule(struct tasklet_struct *tasklet) - { - queue_task(tasklet, &tq_immediate); - mark_bh(IMMEDIATE_BH); - } - - static inline void tasklet_init(struct tasklet_struct *tasklet, - void (*func)(unsigned long), - unsigned long data) - { - tasklet->next = NULL; - tasklet->sync = 0; - tasklet->routine = (void (*)(void *))func; - tasklet->data = (void *)data; - } - - static inline void wan_schedule_task(struct tq_struct *tq) - { - queue_task(tq, &tq_scheduler); - } - - /* Setup Dma Memory size copied directly from 3c505.c */ - static inline int __get_order(unsigned long size) - { - int order; - - size = (size - 1) >> (PAGE_SHIFT - 1); - order = -1; - do { - size >>= 1; - order++; - } while (size); - return order; - } - - typedef int (get_info_t)(char *, char **, off_t, int, int); - - #define ADMIN_CHECK() {if (!capable(CAP_SYS_ADMIN)) return -EPERM;} - #define NET_ADMIN_CHECK() {if (!capable(CAP_NET_ADMIN)) return -EPERM;} - - #define WAN_IRQ_CALL(fn,args,ret) fn args - #define WAN_IRQ_RETURN(a) return - #define WAN_IRQ_RETVAL void - #define WAN_IRQ_RETVAL_DECL(ret) - #define WAN_IRQ_RETVAL_SET(ret, val) - #ifndef WAN_IRQ_NONE - # define WAN_IRQ_NONE (0) - #endif - - #ifndef WAN_IRQ_HANDLED - # define WAN_IRQ_HANDLED (1) - #endif - - typedef unsigned long mm_segment_t; - - #ifndef INIT_WORK - # define INIT_WORK INIT_TQUEUE - #endif - - #define wan_clear_bit(a,b) clear_bit((a),(b)) - #define wan_set_bit(a,b) set_bit((a),(b)) - #define wan_test_bit(a,b) test_bit((a),(b)) - #define wan_test_and_set_bit(a,b) test_and_set_bit((a),(b)) - #define wan_test_and_clear_bit(a,b) test_and_clear_bit((a),(b)) - - static inline struct proc_dir_entry *WP_PDE(const struct inode *inode) - { - #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) - return (struct proc_dir_entry *)inode->u.generic_ip; - #else - return (struct proc_dir_entry *)inode->i_private; - #endif - } - -#else -/* KERNEL 2.0.X */ - - - #define LINUX_2_0 - #define netdevice_t struct device - - static inline struct proc_dir_entry *WP_PDE(const struct inode *inode) - { - #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) - return (struct proc_dir_entry *)inode->i_private; - #else - return (struct proc_dir_entry *)inode->u.generic_ip; - #endif - } - - #define test_and_set_bit set_bit - #define net_ratelimit() 1 - - #define stop_net_queue(a) (set_bit(0, &a->tbusy)) - #define start_net_queue(a) (clear_bit(0,&a->tbusy)) - #define is_queue_stopped(a) (a->tbusy) - #define wake_net_dev(a) {clear_bit(0,&a->tbusy);mark_bh(NET_BH);} - #define is_dev_running(a) (test_bit(0,(void*)&a->start)) - #define wan_dev_kfree_skb(a,b) kfree_skb(a,b) - #define pci_get_device(a,b,c) pci_find_device(a,b,c) - #define spin_lock_init(a) - #define spin_lock(a) - #define spin_unlock(a) - - #define __dev_get(a) dev_get(a) - - #define netif_wake_queue(dev) do { \ - clear_bit(0, &dev->tbusy); \ - mark_bh(NET_BH); \ - } while(0) - #define netif_start_queue(dev) do { \ - dev->tbusy = 0; \ - dev->interrupt = 0; \ - dev->start = 1; \ - } while (0) - #define netif_stop_queue(dev) set_bit(0, &dev->tbusy) - #define netif_running(dev) dev->start - #define netdevice_start(dev) dev->start = 1 - #define netdevice_stop(dev) dev->start = 0 - #define netif_set_tx_timeout(dev, tf, tm) - #define dev_kfree_skb_irq(x) kfree_skb(x) - - typedef int (write_proc_t)(char *, char **, off_t, int, int); - - #define net_device_stats enet_statistics - - static inline int copy_from_user(void *a, void *b, int len){ - int err = verify_area(VERIFY_READ, b, len); - if (err) - return err; - - memcpy_fromfs (a, b, len); - return 0; - } - - static inline int copy_to_user(void *a, void *b, int len){ - int err = verify_area(VERIFY_WRITE, b, len); - if (err) - return err; - memcpy_tofs (a, b,len); - return 0; - } - - #define WAN_IRQ_CALL(fn,args,ret) fn args - #define WAN_IRQ_RETURN(a) return - #define WAN_IRQ_RETVAL void - #define WAN_IRQ_RETVAL_DECL(ret) - #define WAN_IRQ_RETVAL_SET(ret, val) - - #ifndef WAN_IRQ_NONE - # define WAN_IRQ_NONE (0) - #endif - - #ifndef WAN_IRQ_HANDLED - # define WAN_IRQ_HANDLED (1) - #endif - - typedef unsigned long mm_segment_t; - -#endif - -static inline int open_dev_check(netdevice_t *dev) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - return is_dev_running(dev); -#else - return 0; -#endif -} - -#else - -#include - -/* This file is not being included from kernel space - * we need to define what kersdladrv_pci_tblnel version we are - * running */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - #define LINUX_2_6 -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - #define LINUX_2_4 -#else - #define LINUX_2_4 -#endif - - -#endif -#endif diff --git a/patches/kdrivers/include/wanpipe_lapb_iface.h b/patches/kdrivers/include/wanpipe_lapb_iface.h index 8c15d44..afc62e0 100644 --- a/patches/kdrivers/include/wanpipe_lapb_iface.h +++ b/patches/kdrivers/include/wanpipe_lapb_iface.h @@ -46,7 +46,10 @@ extern int wp_lapb_close(void *lapb_ptr); extern int wp_lapb_rx(void *lapb_ptr, void *skb); extern int wp_lapb_bh(void *lapb_ptr); extern int wp_lapb_tx(void *lapb_ptr, void *skb, int type); +#if defined(__WINDOWS__) +extern int wp_lapb_timer(void *lapb_ptr, unsigned int *period); +#else extern int wp_lapb_timer(void *lapb_ptr, unsigned int *period, unsigned int); - +#endif #endif diff --git a/patches/kdrivers/include/wanpipe_lip.h b/patches/kdrivers/include/wanpipe_lip.h index 662691d..18c3e15 100644 --- a/patches/kdrivers/include/wanpipe_lip.h +++ b/patches/kdrivers/include/wanpipe_lip.h @@ -1,4 +1,4 @@ -/* $Header: /usr/local/cvsroot/wanpipe_common/include/wanpipe_lip.h,v 1.38 2007/02/21 18:46:09 sangoma Exp $ */ +/* $Header: /usr/local/cvsroot/wanpipe_common/include/wanpipe_lip.h,v 1.43 2008/01/09 17:45:29 sangoma Exp $ */ #ifndef _WANPIPE_LIP_HEADER_ #define _WANPIPE_LIP_HEADER_ @@ -25,6 +25,30 @@ # if defined(CONFIG_PRODUCT_WANPIPE_XDLC) # include # endif +#elif defined(__WINDOWS__) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# if defined(CONFIG_PRODUCT_WANPIPE_LAPB) || defined(CONFIG_PRODUCT_WANPIPE_LIP_LAPD) +# include +# endif +# if defined(CONFIG_PRODUCT_WANPIPE_XDLC) +# include +# endif +/* Prototypes for interface between LIP and 'sprotocol' code in virt_adap_enum.c: */ +int sdla_tx_down(void* dev, void *tx_skb); +int sdla_data_rx_up(void* sdla_net_dev, void *rx_skb); + #else # include # include @@ -155,7 +179,11 @@ enum { */ #define MAX_LCN 255 #define MAX_DECODE_BUF_SZ 1000 +#if defined(__WINDOWS__) +#define MAX_PROC_NAME WAN_IFNAME_SZ +#else #define MAX_PROC_NAME 10 +#endif #ifndef MAX_PROC_EVENTS #define MAX_PROC_EVENTS 20 @@ -166,7 +194,7 @@ enum { /*#define MAX_TX_BUF 10*/ #define MAX_TX_BUF 10 #define MAX_ATM_TX_BUF 35 -#define MAX_RX_Q 128 +#define MAX_RX_Q 32 #define WPLIP_MAGIC_LINK 0xDAFE1234 #define WPLIP_MAGIC_DEV 0xDAFE4321 @@ -199,7 +227,7 @@ typedef struct wplip_link * * Packet direction UP * */ - WAN_LIST_HEAD(,wplip_dev) list_head_ifdev; + WAN_LIST_HEAD(NAME_PLACEHOLDER,wplip_dev) list_head_ifdev; unsigned int dev_cnt; wan_rwlock_t dev_list_lock; @@ -212,7 +240,7 @@ typedef struct wplip_link * Eg. Load balancing over multiple * links */ - WAN_LIST_HEAD(,wplip_dev_list) list_head_tx_ifdev; + WAN_LIST_HEAD(NAME_PLACEHOLDER,wplip_dev_list) list_head_tx_ifdev; unsigned int tx_dev_cnt; wan_rwlock_t tx_dev_list_lock; @@ -221,7 +249,11 @@ typedef struct wplip_link unsigned char carrier_state; unsigned char prot_state; +#if defined(__WINDOWS__) + void *prot_obj; /* this is the pointer to protocol object */ +#else void *prot; +#endif wan_timer_t prot_timer; unsigned char protocol; @@ -247,6 +279,9 @@ typedef struct wplip_link wan_skb_queue_t tx_queue; wan_skb_queue_t rx_queue; wan_tasklet_t task; +#if defined(__FreeBSD__) && defined(WPLIP_TQ_THREAD) + struct taskqueue *tq; +#endif struct wplip_dev *cur_tx; @@ -269,6 +304,10 @@ typedef struct wplip_link wan_taskq_t prot_task; u32 latency_qlen; +#if defined(__WINDOWS__) + void *sdla_card; /* for wplip_link_callback_tx_down() */ +#endif + } wplip_link_t; @@ -298,8 +337,9 @@ typedef struct wplip_dev{ #if defined(__LINUX__) struct proc_dir_entry *dent; #endif +#if defined(__WINDOWS__) struct net_device_stats ifstats; - +#endif unsigned char used; unsigned char protocol; @@ -320,8 +360,9 @@ typedef struct wplip_dev{ unsigned int interface_down; unsigned int if_down; - wan_taskq_t if_task; + wan_taskq_t if_task; + } wplip_dev_t; typedef struct wplip_dev_list @@ -363,7 +404,11 @@ typedef struct wplip_prot_iface unsigned int *len); int (*rx) (void *prot_ptr, void *rx_pkt); +#if defined(__WINDOWS__) + int (*timer) (void *prot_ptr, unsigned int *period); +#else int (*timer) (void *prot_ptr, unsigned int *period, unsigned int); +#endif int (*bh) (void *); int (*snmp) (void *, void *); int (*task) (void *prot_ptr); @@ -417,6 +462,12 @@ extern int wplip_link_callback_tx_down(void *lip_link, void *skb); extern int wplip_callback_kick_prot_task(void *lip_link); extern int wplip_set_hw_idle_frame (void *liplink_ptr, unsigned char *data, int len); +#if defined(__WINDOWS__) +extern wplip_reg_t wplip_protocol; +extern int wanpipe_lip_init(void); +extern int wanpipe_lip_exit(void); +#endif + /* wanpipe_lip_sub.c */ extern wplip_link_t* wplip_create_link(char *devname); extern void wplip_remove_link(wplip_link_t *lip_link); @@ -486,6 +537,7 @@ extern int wplip_lipdev_prot_change_state(void *wplip_id, int state, unsigned char*,int); + extern int wplip_lipdev_prot_update_state_change(wplip_dev_t *wplip_id,unsigned char*,int); @@ -523,7 +575,11 @@ static __inline int wplip_trigger_bh(wplip_link_t *lip_link) } if (wan_skb_queue_len(&lip_link->rx_queue)){ +#if defined(__LINUX__) || !defined(WPLIP_TQ_THREAD) WAN_TASKLET_SCHEDULE((&lip_link->task)); +#else + WAN_TASKQUEUE_SCHEDULE(lip_link->tq,&lip_link->task); +#endif return 0; } @@ -540,14 +596,22 @@ static __inline int wplip_trigger_bh(wplip_link_t *lip_link) #if 0 gdbg_flag=0; #endif +#if defined(__LINUX__) || !defined(WPLIP_TQ_THREAD) WAN_TASKLET_SCHEDULE((&lip_link->task)); +#else + WAN_TASKQUEUE_SCHEDULE(lip_link->tq,&lip_link->task); +#endif return 0; } static __inline int wplip_kick_trigger_bh(wplip_link_t *lip_link) { wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); +#if defined(__LINUX__) || !defined(WPLIP_TQ_THREAD) WAN_TASKLET_SCHEDULE((&lip_link->task)); +#else + WAN_TASKQUEUE_SCHEDULE(lip_link->tq,&lip_link->task); +#endif return 0; } @@ -603,6 +667,22 @@ static __inline int wplip_decode_protocol(wplip_dev_t *lip_dev, void *ptr) return WPLIP_IPX; } + return WPLIP_IP; +#elif defined(__WINDOWS__) + struct sk_buff *skb=(struct sk_buff*)ptr; + + DEBUG_LIP("wplip_decode_protocol()\n"); + + switch (wpabs_htons(skb->protocol)){ + + case ETH_P_IP: + return WPLIP_IP; + case ETH_P_IPV6: + return WPLIP_IPV6; + case ETH_P_IPX: + return WPLIP_IPX; + } + return WPLIP_IP; #else # error ("wplip_decode_protocol: Unknown Protocol!\n"); @@ -626,12 +706,145 @@ static __inline void wp_lip_config_bridge_mode(wplip_dev_t *lip_dev) } #endif +#if defined(__WINDOWS__) +#define PACKET_TYPE_DECODE(type) \ + ((type == WPLIP_RAW) ? "WPLIP_RAW" : \ + (type == WPLIP_IP) ? "WPLIP_IP" : \ + (type == WPLIP_IPV6) ? "WPLIP_IPV6" : \ + (type == WPLIP_IPX) ? "WPLIP_IPX": \ + (type == WPLIP_FR_ARP) ? "WPLIP_FR_ARP": "Unknown Packet type") +//convert integer definition of a protocol to string +static char * get_protocol_string(int protocol) +{ +#define MAX_PROT_NAME_LENGTH 256 +#define snprintf _snprintf + static char protocol_name[MAX_PROT_NAME_LENGTH]; + + switch(protocol) + { + case WANCONFIG_X25: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "X25"); + break; + + case WANCONFIG_FR: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Frame Relay"); + break; + + case WANCONFIG_PPP: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "PPP"); + break; + + case WANCONFIG_CHDLC: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "CHDLC"); + break; + + case WANCONFIG_BSC: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "BiSync Streaming"); + break; + + case WANCONFIG_HDLC: + //used with CHDLC firmware + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "HDLC Streaming"); + break; + + case WANCONFIG_MPPP://and WANCONFIG_MPROT too + //snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Multi Port PPP"); + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "PPP"); + break; + + case WANCONFIG_LAPB: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "LAPB"); + break; + + case WANCONFIG_BITSTRM: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Bit Stream"); + break; + + case WANCONFIG_EDUKIT: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "WAN EduKit"); + break; + + case WANCONFIG_SS7: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "SS7"); + break; + + case WANCONFIG_BSCSTRM: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Bisync Streaming Nasdaq"); + break; + + case WANCONFIG_MFR: + //snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Multi-Port Frame Relay"); + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Frame Relay"); + break; + + case WANCONFIG_ADSL: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "LLC Ethernet (ADSL)"); + break; + + case WANCONFIG_SDLC: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "SDLC"); + break; + + case WANCONFIG_ATM: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "ATM"); + break; + + case WANCONFIG_POS: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Point-of-Sale"); + break; + + case WANCONFIG_AFT: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "AFT"); + break; + + case WANCONFIG_AFT_TE3: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "AFT"); + break; + + case WANCONFIG_DEBUG: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Real Time Debugging"); + break; + + case WANCONFIG_ADCCP: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Special HDLC LAPB"); + break; + + case WANCONFIG_MLINK_PPP: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Multi-Link PPP"); + break; + + case WANCONFIG_GENERIC: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "WANPIPE Generic driver"); + break; + + case WANCONFIG_MPCHDLC: + //snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Multi-Port CHDLC"); + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "CHDLC"); + break; + + case WANCONFIG_TTY: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "TTY"); + break; +/* + case PROTOCOL_TDM_VOICE: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "TDM Voice"); + break; +*/ + default: + snprintf((char*)protocol_name, MAX_PROT_NAME_LENGTH, "Invalid Protocol"); + break; + } + + return (char*)protocol_name; +} + +#endif /*__KERNEL__*/ #endif -/*_WANPIPE_X25_HEADER_*/ +/*_WANPIPE_LIP_HEADER_*/ #endif diff --git a/patches/kdrivers/include/wanpipe_lip_kernel.h b/patches/kdrivers/include/wanpipe_lip_kernel.h index f30c082..cee5b7b 100644 --- a/patches/kdrivers/include/wanpipe_lip_kernel.h +++ b/patches/kdrivers/include/wanpipe_lip_kernel.h @@ -31,8 +31,14 @@ typedef struct wplip_reg int (*wplip_bind_link) (void*, netdevice_t *); int (*wplip_unbind_link) (void*, netdevice_t *); +#if defined(__WINDOWS__) + int (*wplip_if_reg) (void* lip_link_ptr, char *dev_name, + wanif_conf_t *conf, void** new_lip_dev); + int (*wplip_if_unreg) (void *); +#else int (*wplip_if_reg) (void*, char*, wanif_conf_t *); int (*wplip_if_unreg) (netdevice_t *); +#endif void (*wplip_disconnect) (void*, int); void (*wplip_connect) (void*, int); diff --git a/patches/kdrivers/include/wanpipe_sppp_iface.h b/patches/kdrivers/include/wanpipe_sppp_iface.h index 428cec0..5351daf 100644 --- a/patches/kdrivers/include/wanpipe_sppp_iface.h +++ b/patches/kdrivers/include/wanpipe_sppp_iface.h @@ -38,10 +38,18 @@ extern int wp_sppp_close(void *sppp_ptr); extern int wp_sppp_rx(void *sppp_ptr, void *skb); extern int wp_sppp_bh(void *sppp_ptr); extern int wp_sppp_tx(void *sppp_ptr, void *skb, int type); + +#if defined(__WINDOWS__) +extern void *wp_register_sppp_prot(void *, char *, void *, wplip_prot_reg_t *); +extern int wp_sppp_timer(void *sppp_ptr, unsigned int *period); +#else extern int wp_sppp_timer(void *sppp_ptr, unsigned int *period, unsigned int carrier_reliable); +#endif extern int wp_sppp_pipemon(void *sppp, int cmd, int addr, unsigned char* data, unsigned int *len); extern int wp_sppp_task(void *sppp_ptr); + + #endif @@ -253,7 +261,11 @@ typedef struct ppp_conn_info unsigned char ipx_remote[6] ; /* 16: */ unsigned char ipx_router[48] ; /* 1C: */ unsigned char auth_status ; /* 4C: */ +#if defined(__WINDOWS__)/* zero-sized array does not comply to ANSI 'C' standard! */ + unsigned char peer_id[1] ; /* 4D: */ +#else unsigned char peer_id[0] ; /* 4D: */ +#endif } ppp_conn_info_t; diff --git a/patches/kdrivers/include/wanpipe_tdm_api.h b/patches/kdrivers/include/wanpipe_tdm_api.h index 2d016b9..996e1cc 100644 --- a/patches/kdrivers/include/wanpipe_tdm_api.h +++ b/patches/kdrivers/include/wanpipe_tdm_api.h @@ -25,283 +25,43 @@ # include # include # include +# include #elif defined(__WINDOWS__) # if defined(__KERNEL__) # include # include +# include # include + +enum{ + TDMAPI_BUFFER_NO_CODEC=1, + TDMAPI_BUFFER_HDLC_DATA, + TDMAPI_BUFFER_ERROR, + TDMAPI_BUFFER_READY, + TDMAPI_BUFFER_ACCEPTED +}; + +#define inline __inline # endif # include + #else # include # include # include # include # include +# include #endif -#if defined(__WINDOWS__) -typedef HANDLE sng_fd_t; -#else -typedef int sng_fd_t; -#endif - -enum wanpipe_tdm_api_cmds { - - SIOC_WP_TDM_GET_USR_MTU_MRU, /* 0x00 */ - - SIOC_WP_TDM_SET_USR_PERIOD, /* 0x01 */ - SIOC_WP_TDM_GET_USR_PERIOD, /* 0x02 */ - - SIOC_WP_TDM_SET_HW_MTU_MRU, /* 0x03 */ - SIOC_WP_TDM_GET_HW_MTU_MRU, /* 0x04 */ - - SIOC_WP_TDM_SET_CODEC, /* 0x05 */ - SIOC_WP_TDM_GET_CODEC, /* 0x06 */ - - SIOC_WP_TDM_SET_POWER_LEVEL, /* 0x07 */ - SIOC_WP_TDM_GET_POWER_LEVEL, /* 0x08 */ - - SIOC_WP_TDM_TOGGLE_RX, /* 0x09 */ - SIOC_WP_TDM_TOGGLE_TX, /* 0x0A */ - - SIOC_WP_TDM_GET_HW_CODING, /* 0x0B */ - SIOC_WP_TDM_SET_HW_CODING, /* 0x0C */ - - SIOC_WP_TDM_GET_FULL_CFG, /* 0x0D */ - - SIOC_WP_TDM_SET_EC_TAP, /* 0x0E */ - SIOC_WP_TDM_GET_EC_TAP, /* 0x0F */ - - SIOC_WP_TDM_ENABLE_RBS_EVENTS, /* 0x10 */ - SIOC_WP_TDM_DISABLE_RBS_EVENTS, /* 0x11 */ - SIOC_WP_TDM_WRITE_RBS_BITS, /* 0x12 */ - - SIOC_WP_TDM_GET_STATS, /* 0x13 */ - SIOC_WP_TDM_FLUSH_BUFFERS, /* 0x14 */ - - SIOC_WP_TDM_READ_EVENT, /* 0x15 */ - - SIOC_WP_TDM_ENABLE_DTMF_EVENTS, /* 0x16 */ - SIOC_WP_TDM_DISABLE_DTMF_EVENTS, /* 0x17 */ - - SIOC_WP_TDM_ENABLE_RM_DTMF_EVENTS, /* 0x18 */ - SIOC_WP_TDM_DISABLE_RM_DTMF_EVENTS, /* 0x19 */ - - SIOC_WP_TDM_ENABLE_RXHOOK_EVENTS, /* 0x1A */ - SIOC_WP_TDM_DISABLE_RXHOOK_EVENTS, /* 0x1B */ - - SIOC_WP_TDM_ENABLE_RING_DETECT_EVENTS, - SIOC_WP_TDM_DISABLE_RING_DETECT_EVENTS, - - SIOC_WP_TDM_ENABLE_RING_TRIP_DETECT_EVENTS, - SIOC_WP_TDM_DISABLE_RING_TRIP_DETECT_EVENTS, - - SIOC_WP_TDM_TXSIG_KEWL, - SIOC_WP_TDM_EVENT_TXSIG_START, - SIOC_WP_TDM_EVENT_TXSIG_OFFHOOK, - SIOC_WP_TDM_EVENT_TXSIG_ONHOOK, - SIOC_WP_TDM_EVENT_ONHOOKTRANSFER, - SIOC_WP_TDM_EVENT_SETPOLARITY, - - SIOC_WP_TDM_SET_RX_GAINS, - SIOC_WP_TDM_SET_TX_GAINS, - SIOC_WP_TDM_CLEAR_RX_GAINS, - SIOC_WP_TDM_CLEAR_TX_GAINS, - - SIOC_WP_TDM_GET_FE_ALARMS, - SIOC_WP_TDM_ENABLE_HWEC, - SIOC_WP_TDM_DISABLE_HWEC, - - SIOC_WP_TDM_NOTSUPP /* */ - - -}; - -enum wanpipe_tdm_api_events { - WP_TDM_EVENT_RBS, - WP_TDM_EVENT_DTMF, - WP_TDM_EVENT_NONE, - WP_TDM_EVENT_RXHOOK, - WP_TDM_EVENT_RING, - WP_TDM_EVENT_TONE, - WP_TDM_EVENT_RING_DETECT, - WP_TDM_EVENT_RING_TRIP, - WP_TDM_EVENT_TXSIG_KEWL, - WP_TDM_EVENT_TXSIG_START, - WP_TDM_EVENT_TXSIG_OFFHOOK, - WP_TDM_EVENT_TXSIG_ONHOOK, - WP_TDM_EVENT_ONHOOKTRANSFER, - WP_TDM_EVENT_SETPOLARITY, - WP_TDM_EVENT_FE_ALARM -}; - -#define WPTDM_A_BIT WAN_RBS_SIG_A -#define WPTDM_B_BIT WAN_RBS_SIG_B -#define WPTDM_C_BIT WAN_RBS_SIG_C -#define WPTDM_D_BIT WAN_RBS_SIG_D - -#define WP_TDMAPI_EVENT_RXHOOK_OFF 0x01 -#define WP_TDMAPI_EVENT_RXHOOK_ON 0x02 - -#define WP_TDMAPI_EVENT_RING_PRESENT 0x01 -#define WP_TDMAPI_EVENT_RING_STOP 0x02 - - -typedef struct { - union { - struct { - unsigned char _event_type; - unsigned char _rbs_rx_bits; - unsigned int _time_stamp; - u_int16_t channel; - union { - struct { - u_int8_t alarm; - }fe; - struct { - u_int8_t rbs_bits; - }rbs; - struct { - u_int8_t state; - }rxhook; - struct { - u_int8_t state; - }ring; - struct { - u_int8_t digit; /* DTMF: digit */ - u_int8_t port; /* DTMF: SOUT/ROUT */ - u_int8_t type; /* DTMF: PRESET/STOP */ - }dtmf; - u_int16_t polarity; - u_int16_t ohttimer; - } u_event; - }wp_event; - struct { - unsigned char _rbs_rx_bits; - unsigned int _time_stamp; - } wp_rx; - unsigned char reserved[16]; - }wp_rx_hdr_u; -#define wp_tdm_api_event_type wp_rx_hdr_u.wp_event._event_type -#define wp_tdm_api_event_rbs_rx_bits wp_rx_hdr_u.wp_event._rbs_rx_bits -#define wp_tdm_api_event_time_stamp wp_rx_hdr_u.wp_event._time_stamp -#define wp_tdm_api_event_channel wp_rx_hdr_u.wp_event.channel -#define wp_tdm_api_event_rxhook_state wp_rx_hdr_u.wp_event.u_event.rxhook.state -#define wp_tdm_api_event_ring_state wp_rx_hdr_u.wp_event.u_event.ring.state -#define wp_tdm_api_event_dtmf_digit wp_rx_hdr_u.wp_event.u_event.dtmf.digit -#define wp_tdm_api_event_dtmf_type wp_rx_hdr_u.wp_event.u_event.dtmf.type -#define wp_tdm_api_event_dtmf_port wp_rx_hdr_u.wp_event.u_event.dtmf.port -#define wp_tdm_api_event_ohttimer wp_rx_hdr_u.wp_event.u_event.ohttimer -#define wp_tdm_api_event_polarity wp_rx_hdr_u.wp_event.u_event.polarity -#define wp_tdm_api_event_fe_alarm wp_rx_hdr_u.wp_event.u_event.fe.alarm -} wp_tdm_api_rx_hdr_t; - -typedef struct { - wp_tdm_api_rx_hdr_t hdr; - unsigned char data[1]; -} wp_tdm_api_rx_element_t; - -typedef struct { - union { - struct { - unsigned char _rbs_rx_bits; - unsigned int _time_stamp; - }wp_tx; - unsigned char reserved[16]; - }wp_tx_hdr_u; -#define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp -} wp_tdm_api_tx_hdr_t; - -typedef struct { - wp_tdm_api_tx_hdr_t hdr; - unsigned char data[1]; -} wp_tdm_api_tx_element_t; - - - -typedef struct wp_tdm_chan_stats -{ - unsigned int rx_packets; /* total packets received */ - unsigned int tx_packets; /* total packets transmitted */ - unsigned int rx_bytes; /* total bytes received */ - unsigned int tx_bytes; /* total bytes transmitted */ - unsigned int rx_errors; /* bad packets received */ - unsigned int tx_errors; /* packet transmit problems */ - unsigned int rx_dropped; /* no space in linux buffers */ - unsigned int tx_dropped; /* no space available in linux */ - unsigned int multicast; /* multicast packets received */ -#if !defined(__WINDOWS__) - unsigned int collisions; -#endif - /* detailed rx_errors: */ - unsigned int rx_length_errors; - unsigned int rx_over_errors; /* receiver ring buff overflow */ - unsigned int rx_crc_errors; /* recved pkt with crc error */ - unsigned int rx_frame_errors; /* recv'd frame alignment error */ -#if !defined(__WINDOWS__) - unsigned int rx_fifo_errors; /* recv'r fifo overrun */ -#endif - unsigned int rx_missed_errors; /* receiver missed packet */ - - /* detailed tx_errors */ -#if !defined(__WINDOWS__) - unsigned int tx_aborted_errors; - unsigned int tx_carrier_errors; -#endif - unsigned int tx_fifo_errors; - unsigned int tx_heartbeat_errors; - unsigned int tx_window_errors; - -}wp_tdm_chan_stats_t; - - - -typedef struct wanpipe_tdm_api_cmd{ - unsigned int cmd; - unsigned int hw_tdm_coding; /* Set/Get HW TDM coding: uLaw muLaw */ - unsigned int hw_mtu_mru; /* Set/Get HW TDM MTU/MRU */ - unsigned int usr_period; /* Set/Get User Period in ms */ - unsigned int tdm_codec; /* Set/Get TDM Codec: SLinear */ - unsigned int power_level; /* Set/Get Power level treshold */ - unsigned int rx_disable; /* Enable/Disable Rx */ - unsigned int tx_disable; /* Enable/Disable Tx */ - unsigned int usr_mtu_mru; /* Set/Get User TDM MTU/MRU */ - unsigned int ec_tap; /* Echo Cancellation Tap */ - unsigned int rbs_poll; /* Enable/Disable RBS Polling */ - unsigned int rbs_rx_bits; /* Rx RBS Bits */ - unsigned int rbs_tx_bits; /* Tx RBS Bits */ - unsigned int hdlc; /* HDLC based device */ - unsigned int idle_flag; /* IDLE flag to Tx */ - unsigned int fe_alarms; /* FE Alarms detected */ - wp_tdm_chan_stats_t stats; /* TDM Statistics */ - wp_tdm_api_rx_hdr_t event; /* TDM Event */ - unsigned int data_len; - void *data; -}wanpipe_tdm_api_cmd_t; - -typedef struct wanpipe_tdm_api_event{ - int (*wp_rbs_event)(sng_fd_t fd, unsigned char rbs_bits); - int (*wp_dtmf_event)(sng_fd_t fd, unsigned char dtmf, unsigned char type, unsigned char port); - int (*wp_rxhook_event)(sng_fd_t fd, unsigned char hook_state); - int (*wp_rxring_event)(sng_fd_t fd, unsigned char ring_state); - int (*wp_ringtrip_event)(sng_fd_t fd, unsigned char ring_state); - int (*wp_fe_alarm_event)(sng_fd_t fd, unsigned char fe_alarm_event); -}wanpipe_tdm_api_event_t; - -typedef struct wanpipe_tdm_api{ - wanpipe_tdm_api_cmd_t wp_tdm_cmd; - wanpipe_tdm_api_event_t wp_tdm_event; -}wanpipe_tdm_api_t; - - - #ifdef WAN_KERNEL -/* Maximum API Len = 200ms = 1600 */ -#define WP_TDM_API_MAX_LEN 8*200 +#if !defined(__WINDOWS__) +#define WP_TDM_API_MAX_LEN 1024 +#endif + #define WP_TDM_API_CHUNK_SZ 8 enum { @@ -384,7 +144,7 @@ typedef struct wanpipe_tdm_api_dev { wait_queue_head_t poll_wait; #endif - u32 rbs_poll_cnt; + wan_ticks_t rbs_poll_cnt; u32 busy; u32 tx_q_len; u32 critical; @@ -419,6 +179,9 @@ typedef struct wanpipe_tdm_api_dev { #if defined(__WINDOWS__) u32 original_active_ch; #endif + + uint8_t dtmfsupport; + }wanpipe_tdm_api_dev_t; static __inline int is_tdm_api(void *chan, wanpipe_tdm_api_dev_t *tdm_api) @@ -536,7 +299,6 @@ static inline int wp_tdmapi_check_mtu(void* pcard, unsigned long timeslot_map, i *mtu = chunksz * num_of_channels; return 0; } - #endif diff --git a/patches/kdrivers/include/wanpipe_tdm_api_iface.h b/patches/kdrivers/include/wanpipe_tdm_api_iface.h new file mode 100644 index 0000000..d453046 --- /dev/null +++ b/patches/kdrivers/include/wanpipe_tdm_api_iface.h @@ -0,0 +1,326 @@ +/***************************************************************************** +* wanpipe_tdm_api.h +* +* WANPIPE(tm) AFT TE1 Hardware Support +* +* Authors: Nenad Corbic +* +* Copyright (c) 2007, Sangoma Technologies +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +* ============================================================================ +* Oct 04, 2005 Nenad Corbic Initial version. +* +* Jul 25, 2006 David Rokhvarg Ported to Windows. +*****************************************************************************/ + +#ifndef __WANPIPE_TDM_API_IFACE_H_ +#define __WANPIPE_TDM_API_IFACE_H_ + + +#if defined(__WINDOWS__) +typedef HANDLE sng_fd_t; +#else +typedef int sng_fd_t; +#endif + +/* Indicate to library that new features exist */ +#define WP_TDM_FEATURE_DTMF_EVENTS 1 +#define WP_TDM_FEATURE_FE_ALARM 1 +#define WP_TDM_FEATURE_EVENTS 1 + +enum wanpipe_tdm_api_cmds { + + SIOC_WP_TDM_GET_USR_MTU_MRU, /* 0x00 */ + + SIOC_WP_TDM_SET_USR_PERIOD, /* 0x01 */ + SIOC_WP_TDM_GET_USR_PERIOD, /* 0x02 */ + + SIOC_WP_TDM_SET_HW_MTU_MRU, /* 0x03 */ + SIOC_WP_TDM_GET_HW_MTU_MRU, /* 0x04 */ + + SIOC_WP_TDM_SET_CODEC, /* 0x05 */ + SIOC_WP_TDM_GET_CODEC, /* 0x06 */ + + SIOC_WP_TDM_SET_POWER_LEVEL, /* 0x07 */ + SIOC_WP_TDM_GET_POWER_LEVEL, /* 0x08 */ + + SIOC_WP_TDM_TOGGLE_RX, /* 0x09 */ + SIOC_WP_TDM_TOGGLE_TX, /* 0x0A */ + + SIOC_WP_TDM_GET_HW_CODING, /* 0x0B */ + SIOC_WP_TDM_SET_HW_CODING, /* 0x0C */ + + SIOC_WP_TDM_GET_FULL_CFG, /* 0x0D */ + + SIOC_WP_TDM_SET_EC_TAP, /* 0x0E */ + SIOC_WP_TDM_GET_EC_TAP, /* 0x0F */ + + SIOC_WP_TDM_ENABLE_RBS_EVENTS, /* 0x10 */ + SIOC_WP_TDM_DISABLE_RBS_EVENTS, /* 0x11 */ + SIOC_WP_TDM_WRITE_RBS_BITS, /* 0x12 */ + + SIOC_WP_TDM_GET_STATS, /* 0x13 */ + SIOC_WP_TDM_FLUSH_BUFFERS, /* 0x14 */ + + SIOC_WP_TDM_READ_EVENT, /* 0x15 */ + + SIOC_WP_TDM_SET_EVENT, /* 0x16 */ + + SIOC_WP_TDM_SET_RX_GAINS, /* 0x17 */ + SIOC_WP_TDM_SET_TX_GAINS, /* 0x18 */ + SIOC_WP_TDM_CLEAR_RX_GAINS, /* 0x19 */ + SIOC_WP_TDM_CLEAR_TX_GAINS, /* 0x1A */ + + SIOC_WP_TDM_GET_FE_ALARMS, /* 0x1B */ + + SIOC_WP_TDM_ENABLE_HWEC, /* 0x1C */ + SIOC_WP_TDM_DISABLE_HWEC, /* 0x1D */ + + SIOC_WP_TDM_SET_FE_STATUS, /* 0x1E */ + SIOC_WP_TDM_GET_FE_STATUS, /* 0x1F */ + + SIOC_WP_TDM_NOTSUPP /* */ + +}; + +enum wanpipe_tdm_api_events { + WP_TDMAPI_EVENT_NONE, + WP_TDMAPI_EVENT_RBS, + WP_TDMAPI_EVENT_ALARM, + WP_TDMAPI_EVENT_DTMF, + WP_TDMAPI_EVENT_RM_DTMF, + WP_TDMAPI_EVENT_RXHOOK, + WP_TDMAPI_EVENT_RING, + WP_TDMAPI_EVENT_RING_DETECT, + WP_TDMAPI_EVENT_RING_TRIP_DETECT, + WP_TDMAPI_EVENT_TONE, + WP_TDMAPI_EVENT_TXSIG_KEWL, + WP_TDMAPI_EVENT_TXSIG_START, + WP_TDMAPI_EVENT_TXSIG_OFFHOOK, + WP_TDMAPI_EVENT_TXSIG_ONHOOK, + WP_TDMAPI_EVENT_ONHOOKTRANSFER, + WP_TDMAPI_EVENT_SETPOLARITY +}; + +#define WP_TDMAPI_EVENT_FE_ALARM WP_TDMAPI_EVENT_ALARM + + +#define WP_TDMAPI_EVENT_ENABLE 0x01 +#define WP_TDMAPI_EVENT_DISABLE 0x02 +#define WP_TDMAPI_EVENT_MODE_DECODE(mode) \ + ((mode) == WP_TDMAPI_EVENT_ENABLE) ? "Enable" : \ + ((mode) == WP_TDMAPI_EVENT_DISABLE) ? "Disable" : \ + "(Unknown mode)" + +#define WPTDM_A_BIT WAN_RBS_SIG_A +#define WPTDM_B_BIT WAN_RBS_SIG_B +#define WPTDM_C_BIT WAN_RBS_SIG_C +#define WPTDM_D_BIT WAN_RBS_SIG_D + +#define WP_TDMAPI_EVENT_RXHOOK_OFF 0x01 +#define WP_TDMAPI_EVENT_RXHOOK_ON 0x02 +#define WP_TDMAPI_EVENT_RXHOOK_DECODE(state) \ + ((state) == WP_TDMAPI_EVENT_RXHOOK_OFF) ? "Off-hook" : \ + ((state) == WP_TDMAPI_EVENT_RXHOOK_ON) ? "On-hook" : \ + "(Unknown state)" + +#define WP_TDMAPI_EVENT_RING_PRESENT 0x01 +#define WP_TDMAPI_EVENT_RING_STOP 0x02 +#define WP_TDMAPI_EVENT_RING_DECODE(state) \ + ((state) == WP_TDMAPI_EVENT_RING_PRESENT) ? "Ring Present" : \ + ((state) == WP_TDMAPI_EVENT_RING_STOP) ? "Ring Stop" : \ + "(Unknown state)" + +#define WP_TDMAPI_EVENT_RING_TRIP_PRESENT 0x01 +#define WP_TDMAPI_EVENT_RING_TRIP_STOP 0x02 +#define WP_TDMAPI_EVENT_RING_TRIP_DECODE(state) \ + ((state) == WP_TDMAPI_EVENT_RING_TRIP_PRESENT) ? "Ring Present" : \ + ((state) == WP_TDMAPI_EVENT_RING_TRIP_STOP) ? "Ring Stop" : \ + "(Unknown state)" + +#define WP_TDMAPI_EVENT_TONE_DIAL 0x01 +#define WP_TDMAPI_EVENT_TONE_BUSY 0x02 +#define WP_TDMAPI_EVENT_TONE_RING 0x03 +#define WP_TDMAPI_EVENT_TONE_CONGESTION 0x04 + + +typedef struct { + + u_int8_t type; + u_int8_t mode; + u_int32_t time_stamp; + u_int16_t channel; + u_int32_t chan_map; + union { + struct { + u_int8_t alarm; + } te1_alarm; + struct { + u_int8_t rbs_bits; + } te1_rbs; + struct { + u_int8_t state; + u_int8_t sig; + } rm_hook; + struct { + u_int8_t state; + } rm_ring; + struct { + u_int8_t type; + } rm_tone; + struct { + u_int8_t digit; /* DTMF: digit */ + u_int8_t port; /* DTMF: SOUT/ROUT */ + u_int8_t type; /* DTMF: PRESET/STOP */ + } dtmf; + struct { + u_int16_t polarity; + u_int16_t ohttimer; + } rm_common; + } wp_tdm_api_event_u; +#define wp_tdm_api_event_type type +#define wp_tdm_api_event_mode mode +#define wp_tdm_api_event_alarm wp_tdm_api_event_u.te1_alarm.alarm +#define wp_tdm_api_event_alarm wp_tdm_api_event_u.te1_alarm.alarm +#define wp_tdm_api_event_rbs_bits wp_tdm_api_event_u.te1_rbs.rbs_bits +#define wp_tdm_api_event_hook_state wp_tdm_api_event_u.rm_hook.state +#define wp_tdm_api_event_hook_sig wp_tdm_api_event_u.rm_hook.sig +#define wp_tdm_api_event_ring_state wp_tdm_api_event_u.rm_ring.state +#define wp_tdm_api_event_tone_type wp_tdm_api_event_u.rm_tone.type +#define wp_tdm_api_event_dtmf_digit wp_tdm_api_event_u.dtmf.digit +#define wp_tdm_api_event_dtmf_type wp_tdm_api_event_u.dtmf.type +#define wp_tdm_api_event_dtmf_port wp_tdm_api_event_u.dtmf.port +#define wp_tdm_api_event_ohttimer wp_tdm_api_event_u.rm_common.ohttimer +#define wp_tdm_api_event_polarity wp_tdm_api_event_u.rm_common.polarity +} wp_tdm_api_event_t; + +typedef struct { + union { + unsigned char reserved[16]; + }wp_rx_hdr_u; +} wp_tdm_api_rx_hdr_t; + +typedef struct { + wp_tdm_api_rx_hdr_t hdr; + unsigned char data[1]; +} wp_tdm_api_rx_element_t; + +typedef struct { + union { + struct { + unsigned char _rbs_rx_bits; + unsigned int _time_stamp; + }wp_tx; + unsigned char reserved[16]; + }wp_tx_hdr_u; +#define wp_api_time_stamp wp_tx_hdr_u.wp_tx._time_stamp +} wp_tdm_api_tx_hdr_t; + +typedef struct { + wp_tdm_api_tx_hdr_t hdr; + unsigned char data[1]; +} wp_tdm_api_tx_element_t; + + + +typedef struct wp_tdm_chan_stats +{ + unsigned int rx_packets; /* total packets received */ + unsigned int tx_packets; /* total packets transmitted */ + unsigned int rx_bytes; /* total bytes received */ + unsigned int tx_bytes; /* total bytes transmitted */ + unsigned int rx_errors; /* bad packets received */ + unsigned int tx_errors; /* packet transmit problems */ + unsigned int rx_dropped; /* no space in linux buffers */ + unsigned int tx_dropped; /* no space available in linux */ + unsigned int multicast; /* multicast packets received */ +#if !defined(__WINDOWS__) + unsigned int collisions; +#endif + /* detailed rx_errors: */ + unsigned int rx_length_errors; + unsigned int rx_over_errors; /* receiver ring buff overflow */ + unsigned int rx_crc_errors; /* recved pkt with crc error */ + unsigned int rx_frame_errors; /* recv'd frame alignment error */ +#if !defined(__WINDOWS__) + unsigned int rx_fifo_errors; /* recv'r fifo overrun */ +#endif + unsigned int rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ +#if !defined(__WINDOWS__) + unsigned int tx_aborted_errors; + unsigned int tx_carrier_errors; +#endif + unsigned int tx_fifo_errors; + unsigned int tx_heartbeat_errors; + unsigned int tx_window_errors; + +}wp_tdm_chan_stats_t; + + + +typedef struct wanpipe_tdm_api_cmd{ + unsigned int cmd; + unsigned int hw_tdm_coding; /* Set/Get HW TDM coding: uLaw muLaw */ + unsigned int hw_mtu_mru; /* Set/Get HW TDM MTU/MRU */ + unsigned int usr_period; /* Set/Get User Period in ms */ + unsigned int tdm_codec; /* Set/Get TDM Codec: SLinear */ + unsigned int power_level; /* Set/Get Power level treshold */ + unsigned int rx_disable; /* Enable/Disable Rx */ + unsigned int tx_disable; /* Enable/Disable Tx */ + unsigned int usr_mtu_mru; /* Set/Get User TDM MTU/MRU */ + unsigned int ec_tap; /* Echo Cancellation Tap */ + unsigned int rbs_poll; /* Enable/Disable RBS Polling */ + unsigned int rbs_rx_bits; /* Rx RBS Bits */ + unsigned int rbs_tx_bits; /* Tx RBS Bits */ + unsigned int hdlc; /* HDLC based device */ + unsigned int idle_flag; /* IDLE flag to Tx */ + unsigned int fe_alarms; /* FE Alarms detected */ + wp_tdm_chan_stats_t stats; /* TDM Statistics */ + /* Do NOT add anything above this! Important for binary backward compatibility. */ + wp_tdm_api_event_t event; /* TDM Event */ + unsigned int data_len; + void *data; + unsigned char fe_status; /* FE status - Connected or Disconnected */ +}wanpipe_tdm_api_cmd_t; + +typedef struct wanpipe_tdm_api_event{ + int (*wp_rbs_event)(sng_fd_t fd, unsigned char rbs_bits); + int (*wp_dtmf_event)(sng_fd_t fd, unsigned char dtmf, unsigned char type, unsigned char port); + int (*wp_rxhook_event)(sng_fd_t fd, unsigned char hook_state); + int (*wp_ring_detect_event)(sng_fd_t fd, unsigned char ring_state); + int (*wp_ring_trip_detect_event)(sng_fd_t fd, unsigned char ring_state); + int (*wp_fe_alarm_event)(sng_fd_t fd, unsigned char fe_alarm_event); +}wanpipe_tdm_api_event_t; + +typedef struct wanpipe_tdm_api{ + wanpipe_tdm_api_cmd_t wp_tdm_cmd; + wanpipe_tdm_api_event_t wp_tdm_event; +}wanpipe_tdm_api_t; + + +#endif diff --git a/patches/kdrivers/include/wanpipe_version.h b/patches/kdrivers/include/wanpipe_version.h index 62fba45..f1bd810 100644 --- a/patches/kdrivers/include/wanpipe_version.h +++ b/patches/kdrivers/include/wanpipe_version.h @@ -6,14 +6,14 @@ #define WANPIPE_COMPANY "Sangoma Technologies Inc" /********** LINUX **********/ -#define WANPIPE_VERSION "3.2.7.1" +#define WANPIPE_VERSION "3.3.2" #define WANPIPE_SUB_VERSION "0" -#define WANPIPE_VERSION_BETA 0 +#define WANPIPE_VERSION_BETA 1 #define WANPIPE_LITE_VERSION "1.1.1" /********** FreeBSD **********/ -#define WANPIPE_VERSION_FreeBSD "2.8.5" -#define WANPIPE_SUB_VERSION_FreeBSD "2" +#define WANPIPE_VERSION_FreeBSD "3.2" +#define WANPIPE_SUB_VERSION_FreeBSD "0" #define WANPIPE_VERSION_BETA_FreeBSD 1 #define WANPIPE_LITE_VERSION_FreeBSD "1.1.1" @@ -28,10 +28,58 @@ #define WANPIPE_SUB_VERSION_NetBSD "5" #define WANPIPE_VERSION_BETA_NetBSD 1 +#if defined(__WINDOWS__) /********** Windows **********/ -#define WANPIPE_VERSION_Windows "1.1.1" -#define WANPIPE_SUB_VERSION_Windows "4" -#define WANPIPE_VERSION_BETA_Windows 1 +typedef struct _DRIVER_VERSION { + unsigned int major; + unsigned int minor; + unsigned int minor1; + unsigned int minor2; +}DRIVER_VERSION, *PDRIVER_VERSION; + +# define WANPIPE_VERSION_MAJOR 6 +# define WANPIPE_VERSION_MINOR 0 + +#if 1 +# define WANPIPE_VERSION_MINOR1 4 +# define WANPIPE_VERSION_MINOR2 6 +#else +# define WANPIPE_VERSION_MINOR1 4 +# define WANPIPE_VERSION_MINOR2 4 +#endif + +static DRIVER_VERSION drv_version = { WANPIPE_VERSION_MAJOR, + WANPIPE_VERSION_MINOR, + WANPIPE_VERSION_MINOR1, + WANPIPE_VERSION_MINOR2 + }; + +#undef VER_PRODUCTVERSION +#undef VER_PRODUCTVERSION_STR +#undef VER_PRODUCTNAME_STR +#undef VER_COMPANYNAME_STR + +#define VER_PRODUCTVERSION 6,0,4,6 +#define VER_PRODUCTVERSION_STR "6.0.4.6" +#define __BUILDDATE__ January 15, 2008 + +#define VER_COMPANYNAME_STR "Sangoma Technologies Corporation" +#define VER_LEGALCOPYRIGHT_YEARS "1984-2008" +#define VER_LEGALCOPYRIGHT_STR "Copyright (c) Sangoma Technologies Corporation" +#define VER_PRODUCTNAME_STR "Sangoma WANPIPE (TM)" + +# undef WANPIPE_VERSION +# undef WANPIPE_VERSION_BETA +# undef WANPIPE_SUB_VERSION + +# define WANPIPE_VERSION_Windows "1.1.1" +# define WANPIPE_SUB_VERSION_Windows "4" +# define WANPIPE_VERSION_BETA_Windows 1 + +# define WANPIPE_VERSION WANPIPE_VERSION_Windows +# define WANPIPE_VERSION_BETA WANPIPE_VERSION_BETA_Windows +# define WANPIPE_SUB_VERSION WANPIPE_SUB_VERSION_Windows +#endif/* __WINDOWS__ */ #endif diff --git a/patches/kdrivers/include/wanproc.h b/patches/kdrivers/include/wanproc.h index f081940..83e2615 100644 --- a/patches/kdrivers/include/wanproc.h +++ b/patches/kdrivers/include/wanproc.h @@ -20,6 +20,7 @@ enum { WANPIPE_PROCFS_CONFIG = 0x1, WANPIPE_PROCFS_HWPROBE, + WANPIPE_PROCFS_HWPROBE_VERBOSE, WANPIPE_PROCFS_STATUS, WANPIPE_PROCFS_INTERFACES, WANPIPE_PROCFS_DEV @@ -83,6 +84,7 @@ enum { int config_get_info(char* buf, char** start, off_t offs, int len); int status_get_info(char* buf, char** start, off_t offs, int len); int probe_get_info(char* buf, char** start, off_t offs, int len); +int probe_get_info_verbose(char* buf, char** start, off_t offs, int len); int wandev_get_info(char* buf, char** start, off_t offs, int len); int interfaces_get_info(char* buf, char** start, off_t offs, int len); int wanproc_active_dev(char* buf, char** start, off_t offs, int len); diff --git a/patches/kdrivers/include/wanrouter.h b/patches/kdrivers/include/wanrouter.h index 49be101..629fc8e 100644 --- a/patches/kdrivers/include/wanrouter.h +++ b/patches/kdrivers/include/wanrouter.h @@ -5,6 +5,7 @@ * * Author: Nenad Corbic * Alex Feldman +* David Rokhvarg * Gideon Hack * Additions: Arnaldo Melo * @@ -15,6 +16,9 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* Nov 27, 2007 David Rokhvarg Implemented functions/definitions for +* Sangoma MS Windows Driver and API. +* * May 25, 2001 Alex Feldman Added T1/E1 support (TE1). * Jul 21, 2000 Nenad Corbic Added WAN_FT1_READY State * Feb 24, 2000 Nenad Corbic Added support for socket based x25api @@ -120,6 +124,10 @@ enum router_ioctls #endif +#if defined(__WINDOWS__) +#undef __LINUX__ +#endif + /* identifiers for displaying proc file data for dual port adapters */ #define PROC_DATA_PORT_0 0x8000 /* the data is for port 0 */ #define PROC_DATA_PORT_1 0x8001 /* the data is for port 1 */ @@ -133,10 +141,11 @@ enum router_ioctls #define NLPID_ISIS 0x83 /* ISO/IEC ISIS */ #define NLPID_Q933 0x08 /* CCITT Q.933 */ - +#if !defined(__WINDOWS__) #ifndef WAN_DRVNAME_SZ #define WAN_DRVNAME_SZ 15 #endif +#endif /****** Data Types **********************************************************/ /*---------------------------------------------------------------------------- @@ -179,6 +188,9 @@ enum fe_status { FE_DISCONNECTED, FE_CONNECTED }; +#define WAN_FE_UNITIALIZED FE_UNITIALIZED +#define WAN_FE_DISCONNECTED FE_DISCONNECTED +#define WAN_FE_CONNECTED FE_CONNECTED /* 'modem_status' masks */ #define WAN_MODEM_CTS 0x0001 /* CTS line active */ @@ -211,6 +223,11 @@ typedef struct wan_conf # include # endif +#elif defined(__WINDOWS__) +# include +# include +# include +# include #else //# include # include @@ -244,11 +261,6 @@ typedef struct wan_conf /****** Kernel Interface ****************************************************/ - -/*---------------------------------------------------------------------------- - * WAN device data space. - */ - typedef struct wan_rtp_chan { netskb_t *rx_skb; @@ -258,7 +270,9 @@ typedef struct wan_rtp_chan }wan_rtp_chan_t; - +/*---------------------------------------------------------------------------- + * WAN device data space. + */ struct wan_dev_le { WAN_LIST_ENTRY(wan_dev_le) dev_link; netdevice_t *dev; @@ -266,12 +280,11 @@ struct wan_dev_le { #define WAN_DEVLE2DEV(devle) (devle && devle->dev) ? devle->dev : NULL WAN_LIST_HEAD(wan_dev_lhead, wan_dev_le); - typedef struct wan_device { unsigned magic; /* magic number */ char* name; /* -> WAN device name (ASCIIZ) */ - void* private; /* -> driver private data */ + void* priv; /* -> driver private data */ unsigned config_id; /* Configuration ID */ /****** hardware configuration ******/ unsigned ioport; /* adapter I/O port base #1 */ @@ -289,7 +302,7 @@ typedef struct wan_device unsigned int udp_port; /* UDP port for management */ unsigned char ttl; /* Time To Live for UDP security */ unsigned int enable_tx_int; /* Transmit Interrupt enabled or not */ - char interface; /* RS-232/V.35, etc. */ + char electrical_interface; /* RS-232/V.35, etc. */ char clocking; /* external/internal */ char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */ char station; /* DTE/DCE, primary/secondary, etc. */ @@ -364,9 +377,15 @@ typedef struct wan_device void (*ringtrip) (void* card_id, wan_event_t*); void (*ringdetect) (void* card_id, wan_event_t*); } event_callback; + unsigned char ignore_front_end_status; unsigned char line_idle; +#if defined(__WINDOWS__) + u32 card_type; + sdla_fe_cfg_t fe_cfg; +#else unsigned char card_type; +#endif atomic_t if_cnt; atomic_t if_up_cnt; wan_sdlc_conf_t sdlc_cfg; @@ -403,9 +422,10 @@ typedef struct wan_device sdla_fe_notify_iface_t fe_notify_iface; void *ec_dev; + unsigned long ec_enable_map; - unsigned long ec_map; - unsigned long ec_intmask; + unsigned long fe_ec_map; + wan_ticks_t ec_intmask; int (*ec_enable)(void *pcard, int, int); @@ -413,9 +433,7 @@ typedef struct wan_device unsigned char (*read_ec)(void*, unsigned short); int (*hwec_reset)(void* card_id, int); int (*hwec_enable)(void* card_id, int, int); - - void (*critical_event) (void *, int); - + unsigned long rtp_tap_call_map; unsigned long rtp_tap_call_status; wan_rtp_chan_t rtp_chan[32]; @@ -474,10 +492,11 @@ extern void wan_skb_destructor (struct sk_buff *skb); extern unsigned long wan_get_ip_address (netdevice_t *dev, int option); -void *wanpipe_ec_register(void*, int); +void *wanpipe_ec_register(void*, u_int32_t, int,int, void*); int wanpipe_ec_unregister(void*,void*); -int wanpipe_ec_isr(void*,void*); +int wanpipe_ec_isr(void*); int wanpipe_ec_poll(void*,void*); +int wanpipe_ec_ready(void*); int wanpipe_ec_event_ctrl(void*,void*,wan_event_ctrl_t*); #endif /* __KERNEL__ */ diff --git a/patches/kdrivers/include/xhfc24succ.h b/patches/kdrivers/include/xhfc24succ.h new file mode 100755 index 0000000..2615393 --- /dev/null +++ b/patches/kdrivers/include/xhfc24succ.h @@ -0,0 +1,2113 @@ +/*___________________________________________________________________________________*/ +/* */ +/* (C) Copyright Cologne Chip AG, 2006 */ +/*___________________________________________________________________________________*/ +/* */ + +/* */ +/* File name: xhfc24succ.h */ +/* File content: This file contains the XHFC-2S4U / XHFC-4SU register definitions. */ +/* Creation date: 10.01.2006 16:34 */ +/* Creator: Genero 3.2 */ +/* Data base: HFC XML 1.5 for XHFC-1SU, XHFC-2SU, XHFC-2S4U and XHFC-4SU */ +/* Address range: 0x00 - 0xFF */ +/* */ +/* The information presented can not be considered as assured characteristics. */ +/* Data can change without notice. Please check version numbers in case of doubt. */ +/* */ +/* For further information or questions please contact support@CologneChip.com */ +/* */ +/* */ +/*___________________________________________________________________________________*/ +/* */ +/* WARNING: This file has been generated automatically and should not be */ +/* changed to maintain compatibility with later versions. */ +/*___________________________________________________________________________________*/ +/* */ + + +#ifndef _XHFC24SUCC_H_ +#define _XHFC24SUCC_H_ + +/* Sangoma: 'BYTE' type defined in octtype.h */ +//#ifndef __OCTTYPE_H__ +//typedef unsigned char BYTE; +//#endif + +typedef unsigned char REGWORD; // maximum register length (standard) +typedef unsigned char REGADDR; // address width + + + +typedef enum {no=0, yes} REGBOOL; + + +typedef enum +{ + // register and bitmap access modes: + writeonly=0, // write only + readonly, // read only + readwrite, // read/write + // following modes only for mixed mode registers: + readwrite_write, // read/write and write only + readwrite_read, // read/write and read only + write_read, // write only and read only + readwrite_write_read // read/write, write only and read only +} ACCESSMODE; + + + +/*___________________________________________________________________________________*/ +/* */ +/* common chip information: */ +/*___________________________________________________________________________________*/ + + #define CHIP_NAME_2S4U "XHFC-2S4U" + #define CHIP_NAME_4SU "XHFC-4SU" + #define CHIP_TITLE_2S4U "ISDN HDLC FIFO controller 2 S/T interfaces combined with 4 Up interfaces (Universal ISDN Ports)" + #define CHIP_TITLE_4SU "ISDN HDLC FIFO controller with 4 S/T interfaces combined with 4 Up interfaces (Universal ISDN Ports)" + #define CHIP_MANUFACTURER "Cologne Chip" + #define CHIP_ID_2S4U 0x62 + #define CHIP_ID_4SU 0x63 + #define CHIP_REGISTER_COUNT 122 + #define CHIP_DATABASE "Version HFC-XMLHFC XML 1.5 for XHFC-1SU, XHFC-2SU, XHFC-2S4U and XHFC-4SU - GeneroGenero 3.2 " + +// This register file can also be used for XHFC-2SU and XHFC-1SU programming. +// For this reason these chip names, IDs and titles are defined here as well: + + #define CHIP_NAME_2SU "XHFC-2SU" + #define CHIP_TITLE_2SU "ISDN HDLC FIFO controller with 2 combined S/T and Up Interfaces" + #define CHIP_ID_2SU 0x61 + + #define CHIP_NAME_1SU "XHFC-1SU" + #define CHIP_TITLE_1SU "ISDN HDLC FIFO controller with a combined S/T and Up Interface" + #define CHIP_ID_1SU 0x60 + + + + +/*___________________________________________________________________________________*/ +/* */ +/* Begin of XHFC-2S4U / XHFC-4SU register definitions. */ +/*___________________________________________________________________________________*/ +/* */ + +#define R_CIRM 0x00 // register access + #define M_CLK_OFF 0x01 // bitmap mask (1bit) + #define M_WAIT_PROC 0x02 // bitmap mask (1bit) + #define M_WAIT_REG 0x04 // bitmap mask (1bit) + #define M_SRES 0x08 // bitmap mask (1bit) + #define M_HFC_RES 0x10 // bitmap mask (1bit) + #define M_PCM_RES 0x20 // bitmap mask (1bit) + #define M_SU_RES 0x40 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_clk_off:1; + REGWORD v_wait_proc:1; + REGWORD v_wait_reg:1; + REGWORD v_sres:1; + REGWORD v_hfc_res:1; + REGWORD v_pcm_res:1; + REGWORD v_su_res:1; + REGWORD reserved_0:1; + } bit_r_cirm; // register and bitmap data + typedef union {REGWORD reg; bit_r_cirm bit;} reg_r_cirm; // register and bitmap access + + +#define R_CTRL 0x01 // register access + #define M_FIFO_LPRIO 0x02 // bitmap mask (1bit) + #define M_NT_SYNC 0x08 // bitmap mask (1bit) + #define M_OSC_OFF 0x20 // bitmap mask (1bit) + #define M_SU_CLK 0xC0 // bitmap mask (2bit) + #define M1_SU_CLK 0x40 + + typedef struct // bitmap construction + { + REGWORD reserved_1:1; + REGWORD v_fifo_lprio:1; + REGWORD reserved_2:1; + REGWORD v_nt_sync:1; + REGWORD reserved_3:1; + REGWORD v_osc_off:1; + REGWORD v_su_clk:2; + } bit_r_ctrl; // register and bitmap data + typedef union {REGWORD reg; bit_r_ctrl bit;} reg_r_ctrl; // register and bitmap access + + +#define R_CLK_CFG 0x02 // register access + #define M_CLK_PLL 0x01 // bitmap mask (1bit) + #define M_CLKO_HI 0x02 // bitmap mask (1bit) + #define M_CLKO_PLL 0x04 // bitmap mask (1bit) + #define M_PCM_CLK 0x20 // bitmap mask (1bit) + #define M_CLKO_OFF 0x40 // bitmap mask (1bit) + #define M_CLK_F1 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_clk_pll:1; + REGWORD v_clko_hi:1; + REGWORD v_clko_pll:1; + REGWORD reserved_4:2; + REGWORD v_pcm_clk:1; + REGWORD v_clko_off:1; + REGWORD v_clk_f1:1; + } bit_r_clk_cfg; // register and bitmap data + typedef union {REGWORD reg; bit_r_clk_cfg bit;} reg_r_clk_cfg; // register and bitmap access + + +#define A_Z1 0x04 // register access + #define M_Z1 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_z1:8; + } bit_a_z1; // register and bitmap data + typedef union {REGWORD reg; bit_a_z1 bit;} reg_a_z1; // register and bitmap access + + +#define A_Z2 0x06 // register access + #define M_Z2 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_z2:8; + } bit_a_z2; // register and bitmap data + typedef union {REGWORD reg; bit_a_z2 bit;} reg_a_z2; // register and bitmap access + + +#define R_RAM_ADDR 0x08 // register access + #define M_RAM_ADDR0 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_ram_addr0:8; + } bit_r_ram_addr; // register and bitmap data + typedef union {REGWORD reg; bit_r_ram_addr bit;} reg_r_ram_addr; // register and bitmap access + + +#define R_RAM_CTRL 0x09 // register access + #define M_RAM_ADDR1 0x0F // bitmap mask (4bit) + #define M1_RAM_ADDR1 0x01 + #define M_ADDR_RES 0x40 // bitmap mask (1bit) + #define M_ADDR_INC 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_ram_addr1:4; + REGWORD reserved_5:2; + REGWORD v_addr_res:1; + REGWORD v_addr_inc:1; + } bit_r_ram_ctrl; // register and bitmap data + typedef union {REGWORD reg; bit_r_ram_ctrl bit;} reg_r_ram_ctrl; // register and bitmap access + + +#define R_FIRST_FIFO 0x0B // register access + #define M_FIRST_FIFO_DIR 0x01 // bitmap mask (1bit) + #define M_FIRST_FIFO_NUM 0x1E // bitmap mask (4bit) + #define M1_FIRST_FIFO_NUM 0x02 + + typedef struct // bitmap construction + { + REGWORD v_first_fifo_dir:1; + REGWORD v_first_fifo_num:4; + REGWORD reserved_6:3; + } bit_r_first_fifo; // register and bitmap data + typedef union {REGWORD reg; bit_r_first_fifo bit;} reg_r_first_fifo; // register and bitmap access + + +#define R_FIFO_THRES 0x0C // register access + #define M_THRES_TX 0x0F // bitmap mask (4bit) + #define M1_THRES_TX 0x01 + #define M_THRES_RX 0xF0 // bitmap mask (4bit) + #define M1_THRES_RX 0x10 + + typedef struct // bitmap construction + { + REGWORD v_thres_tx:4; + REGWORD v_thres_rx:4; + } bit_r_fifo_thres; // register and bitmap data + typedef union {REGWORD reg; bit_r_fifo_thres bit;} reg_r_fifo_thres; // register and bitmap access + + +#define A_F1 0x0C // register access + #define M_F1 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_f1:8; + } bit_a_f1; // register and bitmap data + typedef union {REGWORD reg; bit_a_f1 bit;} reg_a_f1; // register and bitmap access + + +#define R_FIFO_MD 0x0D // register access + #define M_FIFO_MD 0x03 // bitmap mask (2bit) + #define M1_FIFO_MD 0x01 + #define M_DF_MD 0x0C // bitmap mask (2bit) + #define M1_DF_MD 0x04 + #define M_UNIDIR_MD 0x10 // bitmap mask (1bit) + #define M_UNIDIR_RX 0x20 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_md:2; + REGWORD v_df_md:2; + REGWORD v_unidir_md:1; + REGWORD v_unidir_rx:1; + REGWORD reserved_7:2; + } bit_r_fifo_md; // register and bitmap data + typedef union {REGWORD reg; bit_r_fifo_md bit;} reg_r_fifo_md; // register and bitmap access + + +#define A_F2 0x0D // register access + #define M_F2 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_f2:8; + } bit_a_f2; // register and bitmap data + typedef union {REGWORD reg; bit_a_f2 bit;} reg_a_f2; // register and bitmap access + + +#define A_INC_RES_FIFO 0x0E // register access + #define M_INC_F 0x01 // bitmap mask (1bit) + #define M_RES_FIFO 0x02 // bitmap mask (1bit) + #define M_RES_LOST 0x04 // bitmap mask (1bit) + #define M_RES_FIFO_ERR 0x08 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_inc_f:1; + REGWORD v_res_fifo:1; + REGWORD v_res_lost:1; + REGWORD v_res_fifo_err:1; + REGWORD reserved_8:4; + } bit_a_inc_res_fifo; // register and bitmap data + typedef union {REGWORD reg; bit_a_inc_res_fifo bit;} reg_a_inc_res_fifo; // register and bitmap access + + +#define A_FIFO_STA 0x0E // register access + #define M_FIFO_ERR 0x01 // bitmap mask (1bit) + #define M_ABO_DONE 0x10 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_err:1; + REGWORD reserved_11:3; + REGWORD v_abo_done:1; + REGWORD reserved_12:3; + } bit_a_fifo_sta; // register and bitmap data + typedef union {REGWORD reg; bit_a_fifo_sta bit;} reg_a_fifo_sta; // register and bitmap access + + +#define R_FSM_IDX 0x0F // register access + #define M_IDX 0x1F // bitmap mask (5bit) + #define M1_IDX 0x01 + + typedef struct // bitmap construction + { + REGWORD v_idx:5; + REGWORD reserved_10:3; + } bit_r_fsm_idx; // register and bitmap data + typedef union {REGWORD reg; bit_r_fsm_idx bit;} reg_r_fsm_idx; // register and bitmap access + + +#define R_FIFO 0x0F // register access + #define M_FIFO_DIR 0x01 // bitmap mask (1bit) + #define M_FIFO_NUM 0x1E // bitmap mask (4bit) + #define M1_FIFO_NUM 0x02 + #define M_REV 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_dir:1; + REGWORD v_fifo_num:4; + REGWORD reserved_9:2; + REGWORD v_rev:1; + } bit_r_fifo; // register and bitmap data + typedef union {REGWORD reg; bit_r_fifo bit;} reg_r_fifo; // register and bitmap access + + +#define R_SLOT 0x10 // register access + #define M_SL_DIR 0x01 // bitmap mask (1bit) + #define M_SL_NUM 0xFE // bitmap mask (7bit) + + typedef struct // bitmap construction + { + REGWORD v_sl_dir:1; + REGWORD v_sl_num:7; + } bit_r_slot; // register and bitmap data + typedef union {REGWORD reg; bit_r_slot bit;} reg_r_slot; // register and bitmap access + + +#define R_IRQ_OVIEW 0x10 // register access + #define M_FIFO_BL0_IRQ 0x01 // bitmap mask (1bit) + #define M_FIFO_BL1_IRQ 0x02 // bitmap mask (1bit) + #define M_FIFO_BL2_IRQ 0x04 // bitmap mask (1bit) + #define M_FIFO_BL3_IRQ 0x08 // bitmap mask (1bit) + #define M_MISC_IRQ 0x10 // bitmap mask (1bit) + #define M_CH_IRQ 0x20 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_bl0_irq:1; + REGWORD v_fifo_bl1_irq:1; + REGWORD v_fifo_bl2_irq:1; + REGWORD v_fifo_bl3_irq:1; + REGWORD v_misc_irq:1; + REGWORD v_ch_irq:1; + REGWORD reserved_19:2; + } bit_r_irq_oview; // register and bitmap data + typedef union {REGWORD reg; bit_r_irq_oview bit;} reg_r_irq_oview; // register and bitmap access + + +#define R_MISC_IRQMSK 0x11 // register access + #define M_SLIP_IRQMSK 0x01 // bitmap mask (1bit) + #define M_TI_IRQMSK 0x02 // bitmap mask (1bit) + #define M_PROC_IRQMSK 0x04 // bitmap mask (1bit) + #define M_CI_IRQMSK 0x10 // bitmap mask (1bit) + #define M_WAK_IRQMSK 0x20 // bitmap mask (1bit) + #define M_MON_TX_IRQMSK 0x40 // bitmap mask (1bit) + #define M_MON_RX_IRQMSK 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_slip_irqmsk:1; + REGWORD v_ti_irqmsk:1; + REGWORD v_proc_irqmsk:1; + REGWORD reserved_13:1; + REGWORD v_ci_irqmsk:1; + REGWORD v_wak_irqmsk:1; + REGWORD v_mon_tx_irqmsk:1; + REGWORD v_mon_rx_irqmsk:1; + } bit_r_misc_irqmsk; // register and bitmap data + typedef union {REGWORD reg; bit_r_misc_irqmsk bit;} reg_r_misc_irqmsk; // register and bitmap access + + +#define R_MISC_IRQ 0x11 // register access + #define M_SLIP_IRQ 0x01 // bitmap mask (1bit) + #define M_TI_IRQ 0x02 // bitmap mask (1bit) + #define M_PROC_IRQ 0x04 // bitmap mask (1bit) + #define M_CI_IRQ 0x10 // bitmap mask (1bit) + #define M_WAK_IRQ 0x20 // bitmap mask (1bit) + #define M_MON_TX_IRQ 0x40 // bitmap mask (1bit) + #define M_MON_RX_IRQ 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_slip_irq:1; + REGWORD v_ti_irq:1; + REGWORD v_proc_irq:1; + REGWORD reserved_20:1; + REGWORD v_ci_irq:1; + REGWORD v_wak_irq:1; + REGWORD v_mon_tx_irq:1; + REGWORD v_mon_rx_irq:1; + } bit_r_misc_irq; // register and bitmap data + typedef union {REGWORD reg; bit_r_misc_irq bit;} reg_r_misc_irq; // register and bitmap access + + +#define R_SU_IRQ 0x12 // register access + #define M_SU0_IRQ 0x01 // bitmap mask (1bit) + #define M_SU1_IRQ 0x02 // bitmap mask (1bit) + #define M_SU2_IRQ 0x04 // bitmap mask (1bit) + #define M_SU3_IRQ 0x08 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_su0_irq:1; + REGWORD v_su1_irq:1; + REGWORD v_su2_irq:1; + REGWORD v_su3_irq:1; + REGWORD reserved_27:4; + } bit_r_su_irq; // register and bitmap data + typedef union {REGWORD reg; bit_r_su_irq bit;} reg_r_su_irq; // register and bitmap access + + +#define R_SU_IRQMSK 0x12 // register access + #define M_SU0_IRQMSK 0x01 // bitmap mask (1bit) + #define M_SU1_IRQMSK 0x02 // bitmap mask (1bit) + #define M_SU2_IRQMSK 0x04 // bitmap mask (1bit) + #define M_SU3_IRQMSK 0x08 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_su0_irqmsk:1; + REGWORD v_su1_irqmsk:1; + REGWORD v_su2_irqmsk:1; + REGWORD v_su3_irqmsk:1; + REGWORD reserved_29:4; + } bit_r_su_irqmsk; // register and bitmap data + typedef union {REGWORD reg; bit_r_su_irqmsk bit;} reg_r_su_irqmsk; // register and bitmap access + + +#define R_AF0_OVIEW 0x13 // register access + #define M_SU0_AF0 0x01 // bitmap mask (1bit) + #define M_SU1_AF0 0x02 // bitmap mask (1bit) + #define M_SU2_AF0 0x04 // bitmap mask (1bit) + #define M_SU3_AF0 0x08 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_su0_af0:1; + REGWORD v_su1_af0:1; + REGWORD v_su2_af0:1; + REGWORD v_su3_af0:1; + REGWORD reserved_28:4; + } bit_r_af0_oview; // register and bitmap data + typedef union {REGWORD reg; bit_r_af0_oview bit;} reg_r_af0_oview; // register and bitmap access + + +#define R_IRQ_CTRL 0x13 // register access + #define M_FIFO_IRQ_EN 0x01 // bitmap mask (1bit) + #define M_GLOB_IRQ_EN 0x08 // bitmap mask (1bit) + #define M_IRQ_POL 0x10 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_irq_en:1; + REGWORD reserved_14:2; + REGWORD v_glob_irq_en:1; + REGWORD v_irq_pol:1; + REGWORD reserved_15:3; + } bit_r_irq_ctrl; // register and bitmap data + typedef union {REGWORD reg; bit_r_irq_ctrl bit;} reg_r_irq_ctrl; // register and bitmap access + + +#define A_USAGE 0x14 // register access + #define M_USAGE 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_usage:8; + } bit_a_usage; // register and bitmap data + typedef union {REGWORD reg; bit_a_usage bit;} reg_a_usage; // register and bitmap access + + +#define R_PCM_MD0 0x14 // register access + #define M_PCM_MD 0x01 // bitmap mask (1bit) + #define M_C4_POL 0x02 // bitmap mask (1bit) + #define M_F0_NEG 0x04 // bitmap mask (1bit) + #define M_F0_LEN 0x08 // bitmap mask (1bit) + #define M_PCM_IDX 0xF0 // bitmap mask (4bit) + #define M1_PCM_IDX 0x10 + + typedef struct // bitmap construction + { + REGWORD v_pcm_md:1; + REGWORD v_c4_pol:1; + REGWORD v_f0_neg:1; + REGWORD v_f0_len:1; + REGWORD v_pcm_idx:4; + } bit_r_pcm_md0; // register and bitmap data + typedef union {REGWORD reg; bit_r_pcm_md0 bit;} reg_r_pcm_md0; // register and bitmap access + + +#define R_SL_SEL0 0x15 // register access + #define M_SL_SEL0 0x7F // bitmap mask (7bit) + #define M_SH_SEL0 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_sl_sel0:7; + REGWORD v_sh_sel0:1; + } bit_r_sl_sel0; // register and bitmap data + typedef union {REGWORD reg; bit_r_sl_sel0 bit;} reg_r_sl_sel0; // register and bitmap access + + +#define R_SL_SEL1 0x15 // register access + #define M_SL_SEL1 0x7F // bitmap mask (7bit) + #define M_SH_SEL1 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_sl_sel1:7; + REGWORD v_sh_sel1:1; + } bit_r_sl_sel1; // register and bitmap data + typedef union {REGWORD reg; bit_r_sl_sel1 bit;} reg_r_sl_sel1; // register and bitmap access + + +#define R_SL_SEL7 0x15 // register access + #define M_SL_SEL7 0x7F // bitmap mask (7bit) + + typedef struct // bitmap construction + { + REGWORD v_sl_sel7:7; + REGWORD reserved_30:1; + } bit_r_sl_sel7; // register and bitmap data + typedef union {REGWORD reg; bit_r_sl_sel7 bit;} reg_r_sl_sel7; // register and bitmap access + + +#define R_MSS0 0x15 // register access + #define M_MSS_MOD 0x01 // bitmap mask (1bit) + #define M_MSS_MOD_REP 0x02 // bitmap mask (1bit) + #define M_MSS_SRC_EN 0x04 // bitmap mask (1bit) + #define M_MSS_SRC_GRD 0x08 // bitmap mask (1bit) + #define M_MSS_OUT_EN 0x10 // bitmap mask (1bit) + #define M_MSS_OUT_REP 0x20 // bitmap mask (1bit) + #define M_MSS_SRC 0xC0 // bitmap mask (2bit) + #define M1_MSS_SRC 0x40 + + typedef struct // bitmap construction + { + REGWORD v_mss_mod:1; + REGWORD v_mss_mod_rep:1; + REGWORD v_mss_src_en:1; + REGWORD v_mss_src_grd:1; + REGWORD v_mss_out_en:1; + REGWORD v_mss_out_rep:1; + REGWORD v_mss_src:2; + } bit_r_mss0; // register and bitmap data + typedef union {REGWORD reg; bit_r_mss0 bit;} reg_r_mss0; // register and bitmap access + + +#define R_PCM_MD1 0x15 // register access + #define M_PCM_OD 0x02 // bitmap mask (1bit) + #define M_PLL_ADJ 0x0C // bitmap mask (2bit) + #define M1_PLL_ADJ 0x04 + #define M_PCM_DR 0x30 // bitmap mask (2bit) + #define M1_PCM_DR 0x10 + #define M_PCM_LOOP 0x40 // bitmap mask (1bit) + #define M_PCM_SMPL 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD reserved_31:1; + REGWORD v_pcm_od:1; + REGWORD v_pll_adj:2; + REGWORD v_pcm_dr:2; + REGWORD v_pcm_loop:1; + REGWORD v_pcm_smpl:1; + } bit_r_pcm_md1; // register and bitmap data + typedef union {REGWORD reg; bit_r_pcm_md1 bit;} reg_r_pcm_md1; // register and bitmap access + + +#define R_PCM_MD2 0x15 // register access + #define M_SYNC_OUT1 0x02 // bitmap mask (1bit) + #define M_SYNC_SRC 0x04 // bitmap mask (1bit) + #define M_SYNC_OUT2 0x08 // bitmap mask (1bit) + #define M_C2O_EN 0x10 // bitmap mask (1bit) + #define M_C2I_EN 0x20 // bitmap mask (1bit) + #define M_PLL_ICR 0x40 // bitmap mask (1bit) + #define M_PLL_MAN 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD reserved_32:1; + REGWORD v_sync_out1:1; + REGWORD v_sync_src:1; + REGWORD v_sync_out2:1; + REGWORD v_c2o_en:1; + REGWORD v_c2i_en:1; + REGWORD v_pll_icr:1; + REGWORD v_pll_man:1; + } bit_r_pcm_md2; // register and bitmap data + typedef union {REGWORD reg; bit_r_pcm_md2 bit;} reg_r_pcm_md2; // register and bitmap access + + +#define R_MSS1 0x15 // register access + #define M_MSS_OFFS 0x07 // bitmap mask (3bit) + #define M1_MSS_OFFS 0x01 + #define M_MS_SSYNC1 0x08 // bitmap mask (1bit) + #define M_MSS_DLY 0xF0 // bitmap mask (4bit) + #define M1_MSS_DLY 0x10 + + typedef struct // bitmap construction + { + REGWORD v_mss_offs:3; + REGWORD v_ms_ssync1:1; + REGWORD v_mss_dly:4; + } bit_r_mss1; // register and bitmap data + typedef union {REGWORD reg; bit_r_mss1 bit;} reg_r_mss1; // register and bitmap access + + +#define R_SH0L 0x15 // register access + #define M_SH0L 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_sh0l:8; + } bit_r_sh0l; // register and bitmap data + typedef union {REGWORD reg; bit_r_sh0l bit;} reg_r_sh0l; // register and bitmap access + + +#define R_SH0H 0x15 // register access + #define M_SH0H 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_sh0h:8; + } bit_r_sh0h; // register and bitmap data + typedef union {REGWORD reg; bit_r_sh0h bit;} reg_r_sh0h; // register and bitmap access + + +#define R_SH1L 0x15 // register access + #define M_SH1L 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_sh1l:8; + } bit_r_sh1l; // register and bitmap data + typedef union {REGWORD reg; bit_r_sh1l bit;} reg_r_sh1l; // register and bitmap access + + +#define R_SH1H 0x15 // register access + #define M_SH1H 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_sh1h:8; + } bit_r_sh1h; // register and bitmap data + typedef union {REGWORD reg; bit_r_sh1h bit;} reg_r_sh1h; // register and bitmap access + + +#define R_RAM_USE 0x15 // register access + #define M_SRAM_USE 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_sram_use:8; + } bit_r_ram_use; // register and bitmap data + typedef union {REGWORD reg; bit_r_ram_use bit;} reg_r_ram_use; // register and bitmap access + + +#define R_SU_SEL 0x16 // register access + #define M_SU_SEL 0x03 // bitmap mask (2bit) + #define M1_SU_SEL 0x01 + #define M_MULT_SU 0x08 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_su_sel:2; + REGWORD reserved_25:1; + REGWORD v_mult_su:1; + REGWORD reserved_26:4; + } bit_r_su_sel; // register and bitmap data + typedef union {REGWORD reg; bit_r_su_sel bit;} reg_r_su_sel; // register and bitmap access + + +#define R_CHIP_ID 0x16 // register access + #define M_CHIP_ID 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_chip_id:8; + } bit_r_chip_id; // register and bitmap data + typedef union {REGWORD reg; bit_r_chip_id bit;} reg_r_chip_id; // register and bitmap access + + +#define R_SU_SYNC 0x17 // register access + #define M_SYNC_SEL 0x07 // bitmap mask (3bit) + #define M1_SYNC_SEL 0x01 + #define M_MAN_SYNC 0x08 // bitmap mask (1bit) + #define M_AUTO_SYNCI 0x10 // bitmap mask (1bit) + #define M_D_MERGE_TX 0x20 // bitmap mask (1bit) + #define M_E_MERGE_RX 0x40 // bitmap mask (1bit) + #define M_D_MERGE_RX 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_sync_sel:3; + REGWORD v_man_sync:1; + REGWORD v_auto_synci:1; + REGWORD v_d_merge_tx:1; + REGWORD v_e_merge_rx:1; + REGWORD v_d_merge_rx:1; + } bit_r_su_sync; // register and bitmap data + typedef union {REGWORD reg; bit_r_su_sync bit;} reg_r_su_sync; // register and bitmap access + + +#define R_BERT_STA 0x17 // register access + #define M_RD_SYNC_SRC 0x07 // bitmap mask (3bit) + #define M1_RD_SYNC_SRC 0x01 + #define M_BERT_SYNC 0x10 // bitmap mask (1bit) + #define M_BERT_INV_DATA 0x20 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_rd_sync_src:3; + REGWORD reserved_21:1; + REGWORD v_bert_sync:1; + REGWORD v_bert_inv_data:1; + REGWORD reserved_22:2; + } bit_r_bert_sta; // register and bitmap data + typedef union {REGWORD reg; bit_r_bert_sta bit;} reg_r_bert_sta; // register and bitmap access + + +#define R_F0_CNTL 0x18 // register access + #define M_F0_CNTL 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_f0_cntl:8; + } bit_r_f0_cntl; // register and bitmap data + typedef union {REGWORD reg; bit_r_f0_cntl bit;} reg_r_f0_cntl; // register and bitmap access + + +#define R_F0_CNTH 0x19 // register access + #define M_F0_CNTH 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_f0_cnth:8; + } bit_r_f0_cnth; // register and bitmap data + typedef union {REGWORD reg; bit_r_f0_cnth bit;} reg_r_f0_cnth; // register and bitmap access + + +#define R_BERT_ECL 0x1A // register access + #define M_BERT_ECL 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_bert_ecl:8; + } bit_r_bert_ecl; // register and bitmap data + typedef union {REGWORD reg; bit_r_bert_ecl bit;} reg_r_bert_ecl; // register and bitmap access + + +#define R_TI_WD 0x1A // register access + #define M_EV_TS 0x0F // bitmap mask (4bit) + #define M1_EV_TS 0x01 + #define M_WD_TS 0xF0 // bitmap mask (4bit) + #define M1_WD_TS 0x10 + + typedef struct // bitmap construction + { + REGWORD v_ev_ts:4; + REGWORD v_wd_ts:4; + } bit_r_ti_wd; // register and bitmap data + typedef union {REGWORD reg; bit_r_ti_wd bit;} reg_r_ti_wd; // register and bitmap access + + +#define R_BERT_ECH 0x1B // register access + #define M_BERT_ECH 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_bert_ech:8; + } bit_r_bert_ech; // register and bitmap data + typedef union {REGWORD reg; bit_r_bert_ech bit;} reg_r_bert_ech; // register and bitmap access + + +#define R_BERT_WD_MD 0x1B // register access + #define M_PAT_SEQ 0x07 // bitmap mask (3bit) + #define M1_PAT_SEQ 0x01 + #define M_BERT_ERR 0x08 // bitmap mask (1bit) + #define M_AUTO_WD_RES 0x20 // bitmap mask (1bit) + #define M_WD_RES 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_pat_seq:3; + REGWORD v_bert_err:1; + REGWORD reserved_16:1; + REGWORD v_auto_wd_res:1; + REGWORD reserved_17:1; + REGWORD v_wd_res:1; + } bit_r_bert_wd_md; // register and bitmap data + typedef union {REGWORD reg; bit_r_bert_wd_md bit;} reg_r_bert_wd_md; // register and bitmap access + + +#define R_STATUS 0x1C // register access + #define M_BUSY 0x01 // bitmap mask (1bit) + #define M_PROC 0x02 // bitmap mask (1bit) + #define M_LOST_STA 0x08 // bitmap mask (1bit) + #define M_PCM_INIT 0x10 // bitmap mask (1bit) + #define M_WAK_STA 0x20 // bitmap mask (1bit) + #define M_MISC_IRQSTA 0x40 // bitmap mask (1bit) + #define M_FR_IRQSTA 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_busy:1; + REGWORD v_proc:1; + REGWORD reserved_23:1; + REGWORD v_lost_sta:1; + REGWORD v_pcm_init:1; + REGWORD v_wak_sta:1; + REGWORD v_misc_irqsta:1; + REGWORD v_fr_irqsta:1; + } bit_r_status; // register and bitmap data + typedef union {REGWORD reg; bit_r_status bit;} reg_r_status; // register and bitmap access + + +#define R_SL_MAX 0x1D // register access + #define M_SL_MAX 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_sl_max:8; + } bit_r_sl_max; // register and bitmap data + typedef union {REGWORD reg; bit_r_sl_max bit;} reg_r_sl_max; // register and bitmap access + + +#define R_PWM_CFG 0x1E // register access + #define M_PWM0_16KHZ 0x10 // bitmap mask (1bit) + #define M_PWM1_16KHZ 0x20 // bitmap mask (1bit) + #define M_PWM_FRQ 0xC0 // bitmap mask (2bit) + #define M1_PWM_FRQ 0x40 + + typedef struct // bitmap construction + { + REGWORD reserved_18:4; + REGWORD v_pwm0_16khz:1; + REGWORD v_pwm1_16khz:1; + REGWORD v_pwm_frq:2; + } bit_r_pwm_cfg; // register and bitmap data + typedef union {REGWORD reg; bit_r_pwm_cfg bit;} reg_r_pwm_cfg; // register and bitmap access + + +#define R_CHIP_RV 0x1F // register access + #define M_CHIP_RV 0x0F // bitmap mask (4bit) + #define M1_CHIP_RV 0x01 + + typedef struct // bitmap construction + { + REGWORD v_chip_rv:4; + REGWORD reserved_24:4; + } bit_r_chip_rv; // register and bitmap data + typedef union {REGWORD reg; bit_r_chip_rv bit;} reg_r_chip_rv; // register and bitmap access + + +#define R_FIFO_BL0_IRQ 0x20 // register access + #define M_FIFO0_TX_IRQ 0x01 // bitmap mask (1bit) + #define M_FIFO0_RX_IRQ 0x02 // bitmap mask (1bit) + #define M_FIFO1_TX_IRQ 0x04 // bitmap mask (1bit) + #define M_FIFO1_RX_IRQ 0x08 // bitmap mask (1bit) + #define M_FIFO2_TX_IRQ 0x10 // bitmap mask (1bit) + #define M_FIFO2_RX_IRQ 0x20 // bitmap mask (1bit) + #define M_FIFO3_TX_IRQ 0x40 // bitmap mask (1bit) + #define M_FIFO3_RX_IRQ 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo0_tx_irq:1; + REGWORD v_fifo0_rx_irq:1; + REGWORD v_fifo1_tx_irq:1; + REGWORD v_fifo1_rx_irq:1; + REGWORD v_fifo2_tx_irq:1; + REGWORD v_fifo2_rx_irq:1; + REGWORD v_fifo3_tx_irq:1; + REGWORD v_fifo3_rx_irq:1; + } bit_r_fifo_bl0_irq; // register and bitmap data + typedef union {REGWORD reg; bit_r_fifo_bl0_irq bit;} reg_r_fifo_bl0_irq; // register and bitmap access + + +#define R_FIFO_BL1_IRQ 0x21 // register access + #define M_FIFO4_TX_IRQ 0x01 // bitmap mask (1bit) + #define M_FIFO4_RX_IRQ 0x02 // bitmap mask (1bit) + #define M_FIFO5_TX_IRQ 0x04 // bitmap mask (1bit) + #define M_FIFO5_RX_IRQ 0x08 // bitmap mask (1bit) + #define M_FIFO6_TX_IRQ 0x10 // bitmap mask (1bit) + #define M_FIFO6_RX_IRQ 0x20 // bitmap mask (1bit) + #define M_FIFO7_TX_IRQ 0x40 // bitmap mask (1bit) + #define M_FIFO7_RX_IRQ 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo4_tx_irq:1; + REGWORD v_fifo4_rx_irq:1; + REGWORD v_fifo5_tx_irq:1; + REGWORD v_fifo5_rx_irq:1; + REGWORD v_fifo6_tx_irq:1; + REGWORD v_fifo6_rx_irq:1; + REGWORD v_fifo7_tx_irq:1; + REGWORD v_fifo7_rx_irq:1; + } bit_r_fifo_bl1_irq; // register and bitmap data + typedef union {REGWORD reg; bit_r_fifo_bl1_irq bit;} reg_r_fifo_bl1_irq; // register and bitmap access + + +#define R_FIFO_BL2_IRQ 0x22 // register access + #define M_FIFO8_TX_IRQ 0x01 // bitmap mask (1bit) + #define M_FIFO8_RX_IRQ 0x02 // bitmap mask (1bit) + #define M_FIFO9_TX_IRQ 0x04 // bitmap mask (1bit) + #define M_FIFO9_RX_IRQ 0x08 // bitmap mask (1bit) + #define M_FIFO10_TX_IRQ 0x10 // bitmap mask (1bit) + #define M_FIFO10_RX_IRQ 0x20 // bitmap mask (1bit) + #define M_FIFO11_TX_IRQ 0x40 // bitmap mask (1bit) + #define M_FIFO11_RX_IRQ 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo8_tx_irq:1; + REGWORD v_fifo8_rx_irq:1; + REGWORD v_fifo9_tx_irq:1; + REGWORD v_fifo9_rx_irq:1; + REGWORD v_fifo10_tx_irq:1; + REGWORD v_fifo10_rx_irq:1; + REGWORD v_fifo11_tx_irq:1; + REGWORD v_fifo11_rx_irq:1; + } bit_r_fifo_bl2_irq; // register and bitmap data + typedef union {REGWORD reg; bit_r_fifo_bl2_irq bit;} reg_r_fifo_bl2_irq; // register and bitmap access + + +#define R_FIFO_BL3_IRQ 0x23 // register access + #define M_FIFO12_TX_IRQ 0x01 // bitmap mask (1bit) + #define M_FIFO12_RX_IRQ 0x02 // bitmap mask (1bit) + #define M_FIFO13_TX_IRQ 0x04 // bitmap mask (1bit) + #define M_FIFO13_RX_IRQ 0x08 // bitmap mask (1bit) + #define M_FIFO14_TX_IRQ 0x10 // bitmap mask (1bit) + #define M_FIFO14_RX_IRQ 0x20 // bitmap mask (1bit) + #define M_FIFO15_TX_IRQ 0x40 // bitmap mask (1bit) + #define M_FIFO15_RX_IRQ 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo12_tx_irq:1; + REGWORD v_fifo12_rx_irq:1; + REGWORD v_fifo13_tx_irq:1; + REGWORD v_fifo13_rx_irq:1; + REGWORD v_fifo14_tx_irq:1; + REGWORD v_fifo14_rx_irq:1; + REGWORD v_fifo15_tx_irq:1; + REGWORD v_fifo15_rx_irq:1; + } bit_r_fifo_bl3_irq; // register and bitmap data + typedef union {REGWORD reg; bit_r_fifo_bl3_irq bit;} reg_r_fifo_bl3_irq; // register and bitmap access + + +#define R_FILL_BL0 0x24 // register access + #define M_FILL_FIFO0_TX 0x01 // bitmap mask (1bit) + #define M_FILL_FIFO0_RX 0x02 // bitmap mask (1bit) + #define M_FILL_FIFO1_TX 0x04 // bitmap mask (1bit) + #define M_FILL_FIFO1_RX 0x08 // bitmap mask (1bit) + #define M_FILL_FIFO2_TX 0x10 // bitmap mask (1bit) + #define M_FILL_FIFO2_RX 0x20 // bitmap mask (1bit) + #define M_FILL_FIFO3_TX 0x40 // bitmap mask (1bit) + #define M_FILL_FIFO3_RX 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fill_fifo0_tx:1; + REGWORD v_fill_fifo0_rx:1; + REGWORD v_fill_fifo1_tx:1; + REGWORD v_fill_fifo1_rx:1; + REGWORD v_fill_fifo2_tx:1; + REGWORD v_fill_fifo2_rx:1; + REGWORD v_fill_fifo3_tx:1; + REGWORD v_fill_fifo3_rx:1; + } bit_r_fill_bl0; // register and bitmap data + typedef union {REGWORD reg; bit_r_fill_bl0 bit;} reg_r_fill_bl0; // register and bitmap access + + +#define R_FILL_BL1 0x25 // register access + #define M_FILL_FIFO4_TX 0x01 // bitmap mask (1bit) + #define M_FILL_FIFO4_RX 0x02 // bitmap mask (1bit) + #define M_FILL_FIFO5_TX 0x04 // bitmap mask (1bit) + #define M_FILL_FIFO5_RX 0x08 // bitmap mask (1bit) + #define M_FILL_FIFO6_TX 0x10 // bitmap mask (1bit) + #define M_FILL_FIFO6_RX 0x20 // bitmap mask (1bit) + #define M_FILL_FIFO7_TX 0x40 // bitmap mask (1bit) + #define M_FILL_FIFO7_RX 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fill_fifo4_tx:1; + REGWORD v_fill_fifo4_rx:1; + REGWORD v_fill_fifo5_tx:1; + REGWORD v_fill_fifo5_rx:1; + REGWORD v_fill_fifo6_tx:1; + REGWORD v_fill_fifo6_rx:1; + REGWORD v_fill_fifo7_tx:1; + REGWORD v_fill_fifo7_rx:1; + } bit_r_fill_bl1; // register and bitmap data + typedef union {REGWORD reg; bit_r_fill_bl1 bit;} reg_r_fill_bl1; // register and bitmap access + + +#define R_FILL_BL2 0x26 // register access + #define M_FILL_FIFO8_TX 0x01 // bitmap mask (1bit) + #define M_FILL_FIFO8_RX 0x02 // bitmap mask (1bit) + #define M_FILL_FIFO9_TX 0x04 // bitmap mask (1bit) + #define M_FILL_FIFO9_RX 0x08 // bitmap mask (1bit) + #define M_FILL_FIFO10_TX 0x10 // bitmap mask (1bit) + #define M_FILL_FIFO10_RX 0x20 // bitmap mask (1bit) + #define M_FILL_FIFO11_TX 0x40 // bitmap mask (1bit) + #define M_FILL_FIFO11_RX 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fill_fifo8_tx:1; + REGWORD v_fill_fifo8_rx:1; + REGWORD v_fill_fifo9_tx:1; + REGWORD v_fill_fifo9_rx:1; + REGWORD v_fill_fifo10_tx:1; + REGWORD v_fill_fifo10_rx:1; + REGWORD v_fill_fifo11_tx:1; + REGWORD v_fill_fifo11_rx:1; + } bit_r_fill_bl2; // register and bitmap data + typedef union {REGWORD reg; bit_r_fill_bl2 bit;} reg_r_fill_bl2; // register and bitmap access + + +#define R_FILL_BL3 0x27 // register access + #define M_FILL_FIFO12_TX 0x01 // bitmap mask (1bit) + #define M_FILL_FIFO12_RX 0x02 // bitmap mask (1bit) + #define M_FILL_FIFO13_TX 0x04 // bitmap mask (1bit) + #define M_FILL_FIFO13_RX 0x08 // bitmap mask (1bit) + #define M_FILL_FIFO14_TX 0x10 // bitmap mask (1bit) + #define M_FILL_FIFO14_RX 0x20 // bitmap mask (1bit) + #define M_FILL_FIFO15_TX 0x40 // bitmap mask (1bit) + #define M_FILL_FIFO15_RX 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fill_fifo12_tx:1; + REGWORD v_fill_fifo12_rx:1; + REGWORD v_fill_fifo13_tx:1; + REGWORD v_fill_fifo13_rx:1; + REGWORD v_fill_fifo14_tx:1; + REGWORD v_fill_fifo14_rx:1; + REGWORD v_fill_fifo15_tx:1; + REGWORD v_fill_fifo15_rx:1; + } bit_r_fill_bl3; // register and bitmap data + typedef union {REGWORD reg; bit_r_fill_bl3 bit;} reg_r_fill_bl3; // register and bitmap access + + +#define R_CI_TX 0x28 // register access + #define M_GCI_C 0x3F // bitmap mask (6bit) + + typedef struct // bitmap construction + { + REGWORD v_gci_c:6; + REGWORD reserved_33:2; + } bit_r_ci_tx; // register and bitmap data + typedef union {REGWORD reg; bit_r_ci_tx bit;} reg_r_ci_tx; // register and bitmap access + + +#define R_CI_RX 0x28 // register access + #define M_GCI_I 0x3F // bitmap mask (6bit) + + typedef struct // bitmap construction + { + REGWORD v_gci_i:6; + REGWORD reserved_35:2; + } bit_r_ci_rx; // register and bitmap data + typedef union {REGWORD reg; bit_r_ci_rx bit;} reg_r_ci_rx; // register and bitmap access + + +#define R_GCI_CFG0 0x29 // register access + #define M_MON_END 0x01 // bitmap mask (1bit) + #define M_MON_SLOW 0x02 // bitmap mask (1bit) + #define M_MON_DLL 0x04 // bitmap mask (1bit) + #define M_MON_CI6 0x08 // bitmap mask (1bit) + #define M_GCI_SWAP_TXHS 0x10 // bitmap mask (1bit) + #define M_GCI_SWAP_RXHS 0x20 // bitmap mask (1bit) + #define M_GCI_SWAP_STIO 0x40 // bitmap mask (1bit) + #define M_GCI_EN 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_mon_end:1; + REGWORD v_mon_slow:1; + REGWORD v_mon_dll:1; + REGWORD v_mon_ci6:1; + REGWORD v_gci_swap_txhs:1; + REGWORD v_gci_swap_rxhs:1; + REGWORD v_gci_swap_stio:1; + REGWORD v_gci_en:1; + } bit_r_gci_cfg0; // register and bitmap data + typedef union {REGWORD reg; bit_r_gci_cfg0 bit;} reg_r_gci_cfg0; // register and bitmap access + + +#define R_GCI_STA 0x29 // register access + #define M_MON_RXR 0x01 // bitmap mask (1bit) + #define M_MON_TXR 0x02 // bitmap mask (1bit) + #define M_GCI_MX 0x04 // bitmap mask (1bit) + #define M_GCI_MR 0x08 // bitmap mask (1bit) + #define M_GCI_RX 0x10 // bitmap mask (1bit) + #define M_GCI_ABO 0x20 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_mon_rxr:1; + REGWORD v_mon_txr:1; + REGWORD v_gci_mx:1; + REGWORD v_gci_mr:1; + REGWORD v_gci_rx:1; + REGWORD v_gci_abo:1; + REGWORD reserved_36:2; + } bit_r_gci_sta; // register and bitmap data + typedef union {REGWORD reg; bit_r_gci_sta bit;} reg_r_gci_sta; // register and bitmap access + + +#define R_GCI_CFG1 0x2A // register access + #define M_GCI_SL 0x1F // bitmap mask (5bit) + #define M1_GCI_SL 0x01 + + typedef struct // bitmap construction + { + REGWORD v_gci_sl:5; + REGWORD reserved_34:3; + } bit_r_gci_cfg1; // register and bitmap data + typedef union {REGWORD reg; bit_r_gci_cfg1 bit;} reg_r_gci_cfg1; // register and bitmap access + + +#define R_MON_RX 0x2A // register access + #define M_MON_RX 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_mon_rx:8; + } bit_r_mon_rx; // register and bitmap data + typedef union {REGWORD reg; bit_r_mon_rx bit;} reg_r_mon_rx; // register and bitmap access + + +#define R_MON_TX 0x2B // register access + #define M_MON_TX 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_mon_tx:8; + } bit_r_mon_tx; // register and bitmap data + typedef union {REGWORD reg; bit_r_mon_tx bit;} reg_r_mon_tx; // register and bitmap access + + +#define A_SU_WR_STA 0x30 // register access + #define M_SU_SET_STA 0x0F // bitmap mask (4bit) + #define M1_SU_SET_STA 0x01 + #define M_SU_LD_STA 0x10 // bitmap mask (1bit) + #define M_SU_ACT 0x60 // bitmap mask (2bit) + #define M1_SU_ACT 0x20 + #define M_SU_SET_G2_G3 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_su_set_sta:4; + REGWORD v_su_ld_sta:1; + REGWORD v_su_act:2; + REGWORD v_su_set_g2_g3:1; + } bit_a_su_wr_sta; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_wr_sta bit;} reg_a_su_wr_sta; // register and bitmap access + + +#define A_SU_RD_STA 0x30 // register access + #define M_SU_STA 0x0F // bitmap mask (4bit) + #define M1_SU_STA 0x01 + #define M_SU_FR_SYNC 0x10 // bitmap mask (1bit) + #define M_SU_T2_EXP 0x20 // bitmap mask (1bit) + #define M_SU_INFO0 0x40 // bitmap mask (1bit) + #define M_G2_G3 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_su_sta:4; + REGWORD v_su_fr_sync:1; + REGWORD v_su_t2_exp:1; + REGWORD v_su_info0:1; + REGWORD v_g2_g3:1; + } bit_a_su_rd_sta; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_rd_sta bit;} reg_a_su_rd_sta; // register and bitmap access + + +#define A_SU_CTRL0 0x31 // register access + #define M_B1_TX_EN 0x01 // bitmap mask (1bit) + #define M_B2_TX_EN 0x02 // bitmap mask (1bit) + #define M_SU_MD 0x04 // bitmap mask (1bit) + #define M_ST_D_LPRIO 0x08 // bitmap mask (1bit) + #define M_ST_SQ_EN 0x10 // bitmap mask (1bit) + #define M_SU_TST_SIG 0x20 // bitmap mask (1bit) + #define M_ST_PU_CTRL 0x40 // bitmap mask (1bit) + #define M_SU_STOP 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_b1_tx_en:1; + REGWORD v_b2_tx_en:1; + REGWORD v_su_md:1; + REGWORD v_st_d_lprio:1; + REGWORD v_st_sq_en:1; + REGWORD v_su_tst_sig:1; + REGWORD v_st_pu_ctrl:1; + REGWORD v_su_stop:1; + } bit_a_su_ctrl0; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_ctrl0 bit;} reg_a_su_ctrl0; // register and bitmap access + + +#define A_SU_DLYL 0x31 // register access + #define M_SU_DLYL 0x1F // bitmap mask (5bit) + #define M1_SU_DLYL 0x01 + + typedef struct // bitmap construction + { + REGWORD v_su_dlyl:5; + REGWORD reserved_46:3; + } bit_a_su_dlyl; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_dlyl bit;} reg_a_su_dlyl; // register and bitmap access + + +#define A_SU_CTRL1 0x32 // register access + #define M_G2_G3_EN 0x01 // bitmap mask (1bit) + #define M_D_RES 0x04 // bitmap mask (1bit) + #define M_ST_E_IGNO 0x08 // bitmap mask (1bit) + #define M_ST_E_LO 0x10 // bitmap mask (1bit) + #define M_BAC_D 0x40 // bitmap mask (1bit) + #define M_B12_SWAP 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_g2_g3_en:1; + REGWORD reserved_37:1; + REGWORD v_d_res:1; + REGWORD v_st_e_igno:1; + REGWORD v_st_e_lo:1; + REGWORD reserved_38:1; + REGWORD v_bac_d:1; + REGWORD v_b12_swap:1; + } bit_a_su_ctrl1; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_ctrl1 bit;} reg_a_su_ctrl1; // register and bitmap access + + +#define A_SU_DLYH 0x32 // register access + #define M_SU_DLYH 0x1F // bitmap mask (5bit) + #define M1_SU_DLYH 0x01 + + typedef struct // bitmap construction + { + REGWORD v_su_dlyh:5; + REGWORD reserved_47:3; + } bit_a_su_dlyh; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_dlyh bit;} reg_a_su_dlyh; // register and bitmap access + + +#define A_SU_CTRL2 0x33 // register access + #define M_B1_RX_EN 0x01 // bitmap mask (1bit) + #define M_B2_RX_EN 0x02 // bitmap mask (1bit) + #define M_MS_SSYNC2 0x04 // bitmap mask (1bit) + #define M_BAC_S_SEL 0x08 // bitmap mask (1bit) + #define M_SU_SYNC_NT 0x10 // bitmap mask (1bit) + #define M_SU_2KHZ 0x20 // bitmap mask (1bit) + #define M_SU_TRI 0x40 // bitmap mask (1bit) + #define M_SU_EXCHG 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_b1_rx_en:1; + REGWORD v_b2_rx_en:1; + REGWORD v_ms_ssync2:1; + REGWORD v_bac_s_sel:1; + REGWORD v_su_sync_nt:1; + REGWORD v_su_2khz:1; + REGWORD v_su_tri:1; + REGWORD v_su_exchg:1; + } bit_a_su_ctrl2; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_ctrl2 bit;} reg_a_su_ctrl2; // register and bitmap access + + +#define A_MS_TX 0x34 // register access + #define M_MS_TX 0x0F // bitmap mask (4bit) + #define M1_MS_TX 0x01 + #define M_UP_S_TX 0x40 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_ms_tx:4; + REGWORD reserved_39:2; + REGWORD v_up_s_tx:1; + REGWORD reserved_40:1; + } bit_a_ms_tx; // register and bitmap data + typedef union {REGWORD reg; bit_a_ms_tx bit;} reg_a_ms_tx; // register and bitmap access + + +#define A_MS_RX 0x34 // register access + #define M_MS_RX 0x0F // bitmap mask (4bit) + #define M1_MS_RX 0x01 + #define M_MS_RX_RDY 0x10 // bitmap mask (1bit) + #define M_UP_S_RX 0x40 // bitmap mask (1bit) + #define M_MS_TX_RDY 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_ms_rx:4; + REGWORD v_ms_rx_rdy:1; + REGWORD reserved_48:1; + REGWORD v_up_s_rx:1; + REGWORD v_ms_tx_rdy:1; + } bit_a_ms_rx; // register and bitmap data + typedef union {REGWORD reg; bit_a_ms_rx bit;} reg_a_ms_rx; // register and bitmap access + + +#define A_ST_CTRL3 0x35 // register access + #define M_ST_SEL 0x01 // bitmap mask (1bit) + #define M_ST_PULSE 0xFE // bitmap mask (7bit) + + typedef struct // bitmap construction + { + REGWORD v_st_sel:1; + REGWORD v_st_pulse:7; + } bit_a_st_ctrl3; // register and bitmap data + typedef union {REGWORD reg; bit_a_st_ctrl3 bit;} reg_a_st_ctrl3; // register and bitmap access + + +#define A_UP_CTRL3 0x35 // register access + #define M_UP_SEL 0x01 // bitmap mask (1bit) + #define M_UP_VIO 0x02 // bitmap mask (1bit) + #define M_UP_DC_STR 0x04 // bitmap mask (1bit) + #define M_UP_DC_OFF 0x08 // bitmap mask (1bit) + #define M_UP_RPT_PAT 0x10 // bitmap mask (1bit) + #define M_UP_SCRM_MD 0x20 // bitmap mask (1bit) + #define M_UP_SCRM_TX_OFF 0x40 // bitmap mask (1bit) + #define M_UP_SCRM_RX_OFF 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_up_sel:1; + REGWORD v_up_vio:1; + REGWORD v_up_dc_str:1; + REGWORD v_up_dc_off:1; + REGWORD v_up_rpt_pat:1; + REGWORD v_up_scrm_md:1; + REGWORD v_up_scrm_tx_off:1; + REGWORD v_up_scrm_rx_off:1; + } bit_a_up_ctrl3; // register and bitmap data + typedef union {REGWORD reg; bit_a_up_ctrl3 bit;} reg_a_up_ctrl3; // register and bitmap access + + +#define A_SU_STA 0x35 // register access + #define M_ST_D_HPRIO9 0x01 // bitmap mask (1bit) + #define M_ST_D_LPRIO11 0x02 // bitmap mask (1bit) + #define M_ST_D_CONT 0x04 // bitmap mask (1bit) + #define M_ST_D_ACT 0x08 // bitmap mask (1bit) + #define M_SU_AF0 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_st_d_hprio9:1; + REGWORD v_st_d_lprio11:1; + REGWORD v_st_d_cont:1; + REGWORD v_st_d_act:1; + REGWORD reserved_49:3; + REGWORD v_su_af0:1; + } bit_a_su_sta; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_sta bit;} reg_a_su_sta; // register and bitmap access + + +#define A_MS_DF 0x36 // register access + #define M_BAC_NINV 0x01 // bitmap mask (1bit) + #define M_SG_AB_INV 0x02 // bitmap mask (1bit) + #define M_SQ_T_SRC 0x04 // bitmap mask (1bit) + #define M_M_S_SRC 0x08 // bitmap mask (1bit) + #define M_SQ_T_DST 0x10 // bitmap mask (1bit) + #define M_SU_RX_VAL 0x20 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_bac_ninv:1; + REGWORD v_sg_ab_inv:1; + REGWORD v_sq_t_src:1; + REGWORD v_m_s_src:1; + REGWORD v_sq_t_dst:1; + REGWORD v_su_rx_val:1; + REGWORD reserved_41:2; + } bit_a_ms_df; // register and bitmap data + typedef union {REGWORD reg; bit_a_ms_df bit;} reg_a_ms_df; // register and bitmap access + + +#define A_SU_CLK_DLY 0x37 // register access + #define M_SU_CLK_DLY 0x0F // bitmap mask (4bit) + #define M1_SU_CLK_DLY 0x01 + #define M_ST_SMPL 0x70 // bitmap mask (3bit) + #define M1_ST_SMPL 0x10 + + typedef struct // bitmap construction + { + REGWORD v_su_clk_dly:4; + REGWORD v_st_smpl:3; + REGWORD reserved_42:1; + } bit_a_su_clk_dly; // register and bitmap data + typedef union {REGWORD reg; bit_a_su_clk_dly bit;} reg_a_su_clk_dly; // register and bitmap access + + +#define R_PWM0 0x38 // register access + #define M_PWM0 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_pwm0:8; + } bit_r_pwm0; // register and bitmap data + typedef union {REGWORD reg; bit_r_pwm0 bit;} reg_r_pwm0; // register and bitmap access + + +#define R_PWM1 0x39 // register access + #define M_PWM1 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_pwm1:8; + } bit_r_pwm1; // register and bitmap data + typedef union {REGWORD reg; bit_r_pwm1 bit;} reg_r_pwm1; // register and bitmap access + + +#define A_B1_TX 0x3C // register access + #define M_B1_TX 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_b1_tx:8; + } bit_a_b1_tx; // register and bitmap data + typedef union {REGWORD reg; bit_a_b1_tx bit;} reg_a_b1_tx; // register and bitmap access + + +#define A_B1_RX 0x3C // register access + #define M_B1_RX 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_b1_rx:8; + } bit_a_b1_rx; // register and bitmap data + typedef union {REGWORD reg; bit_a_b1_rx bit;} reg_a_b1_rx; // register and bitmap access + + +#define A_B2_TX 0x3D // register access + #define M_B2_TX 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_b2_tx:8; + } bit_a_b2_tx; // register and bitmap data + typedef union {REGWORD reg; bit_a_b2_tx bit;} reg_a_b2_tx; // register and bitmap access + + +#define A_B2_RX 0x3D // register access + #define M_B2_RX 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_b2_rx:8; + } bit_a_b2_rx; // register and bitmap data + typedef union {REGWORD reg; bit_a_b2_rx bit;} reg_a_b2_rx; // register and bitmap access + + +#define A_D_TX 0x3E // register access + #define M_D_TX_S 0x01 // bitmap mask (1bit) + #define M_D_TX_BAC 0x20 // bitmap mask (1bit) + #define M_D_TX 0xC0 // bitmap mask (2bit) + #define M1_D_TX 0x40 + + typedef struct // bitmap construction + { + REGWORD v_d_tx_s:1; + REGWORD reserved_43:4; + REGWORD v_d_tx_bac:1; + REGWORD v_d_tx:2; + } bit_a_d_tx; // register and bitmap data + typedef union {REGWORD reg; bit_a_d_tx bit;} reg_a_d_tx; // register and bitmap access + + +#define A_D_RX 0x3E // register access + #define M_D_RX_S 0x01 // bitmap mask (1bit) + #define M_D_RX_AB 0x10 // bitmap mask (1bit) + #define M_D_RX_SG 0x20 // bitmap mask (1bit) + #define M_D_RX 0xC0 // bitmap mask (2bit) + #define M1_D_RX 0x40 + + typedef struct // bitmap construction + { + REGWORD v_d_rx_s:1; + REGWORD reserved_50:3; + REGWORD v_d_rx_ab:1; + REGWORD v_d_rx_sg:1; + REGWORD v_d_rx:2; + } bit_a_d_rx; // register and bitmap data + typedef union {REGWORD reg; bit_a_d_rx bit;} reg_a_d_rx; // register and bitmap access + + +#define A_E_RX 0x3F // register access + #define M_E_RX_S 0x01 // bitmap mask (1bit) + #define M_E_RX_AB 0x10 // bitmap mask (1bit) + #define M_E_RX_SG 0x20 // bitmap mask (1bit) + #define M_E_RX 0xC0 // bitmap mask (2bit) + #define M1_E_RX 0x40 + + typedef struct // bitmap construction + { + REGWORD v_e_rx_s:1; + REGWORD reserved_51:3; + REGWORD v_e_rx_ab:1; + REGWORD v_e_rx_sg:1; + REGWORD v_e_rx:2; + } bit_a_e_rx; // register and bitmap data + typedef union {REGWORD reg; bit_a_e_rx bit;} reg_a_e_rx; // register and bitmap access + + +#define A_BAC_S_TX 0x3F // register access + #define M_S_TX 0x01 // bitmap mask (1bit) + #define M_BAC_TX 0x20 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_s_tx:1; + REGWORD reserved_44:4; + REGWORD v_bac_tx:1; + REGWORD reserved_45:2; + } bit_a_bac_s_tx; // register and bitmap data + typedef union {REGWORD reg; bit_a_bac_s_tx bit;} reg_a_bac_s_tx; // register and bitmap access + + +#define R_GPIO_OUT1 0x40 // register access + #define M_GPIO_OUT8 0x01 // bitmap mask (1bit) + #define M_GPIO_OUT9 0x02 // bitmap mask (1bit) + #define M_GPIO_OUT10 0x04 // bitmap mask (1bit) + #define M_GPIO_OUT11 0x08 // bitmap mask (1bit) + #define M_GPIO_OUT12 0x10 // bitmap mask (1bit) + #define M_GPIO_OUT13 0x20 // bitmap mask (1bit) + #define M_GPIO_OUT14 0x40 // bitmap mask (1bit) + #define M_GPIO_OUT15 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_out8:1; + REGWORD v_gpio_out9:1; + REGWORD v_gpio_out10:1; + REGWORD v_gpio_out11:1; + REGWORD v_gpio_out12:1; + REGWORD v_gpio_out13:1; + REGWORD v_gpio_out14:1; + REGWORD v_gpio_out15:1; + } bit_r_gpio_out1; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_out1 bit;} reg_r_gpio_out1; // register and bitmap access + + +#define R_GPIO_IN1 0x40 // register access + #define M_GPIO_IN8 0x01 // bitmap mask (1bit) + #define M_GPIO_IN9 0x02 // bitmap mask (1bit) + #define M_GPIO_IN10 0x04 // bitmap mask (1bit) + #define M_GPIO_IN11 0x08 // bitmap mask (1bit) + #define M_GPIO_IN12 0x10 // bitmap mask (1bit) + #define M_GPIO_IN13 0x20 // bitmap mask (1bit) + #define M_GPIO_IN14 0x40 // bitmap mask (1bit) + #define M_GPIO_IN15 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_in8:1; + REGWORD v_gpio_in9:1; + REGWORD v_gpio_in10:1; + REGWORD v_gpio_in11:1; + REGWORD v_gpio_in12:1; + REGWORD v_gpio_in13:1; + REGWORD v_gpio_in14:1; + REGWORD v_gpio_in15:1; + } bit_r_gpio_in1; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_in1 bit;} reg_r_gpio_in1; // register and bitmap access + + +#define R_GPIO_OUT3 0x41 // register access + #define M_GPIO_OUT24 0x01 // bitmap mask (1bit) + #define M_GPIO_OUT25 0x02 // bitmap mask (1bit) + #define M_GPIO_OUT26 0x04 // bitmap mask (1bit) + #define M_GPIO_OUT27 0x08 // bitmap mask (1bit) + #define M_GPIO_OUT28 0x10 // bitmap mask (1bit) + #define M_GPIO_OUT29 0x20 // bitmap mask (1bit) + #define M_GPIO_OUT30 0x40 // bitmap mask (1bit) + #define M_GPIO_OUT31 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_out24:1; + REGWORD v_gpio_out25:1; + REGWORD v_gpio_out26:1; + REGWORD v_gpio_out27:1; + REGWORD v_gpio_out28:1; + REGWORD v_gpio_out29:1; + REGWORD v_gpio_out30:1; + REGWORD v_gpio_out31:1; + } bit_r_gpio_out3; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_out3 bit;} reg_r_gpio_out3; // register and bitmap access + + +#define R_GPIO_IN3 0x41 // register access + #define M_GPIO_IN24 0x01 // bitmap mask (1bit) + #define M_GPIO_IN25 0x02 // bitmap mask (1bit) + #define M_GPIO_IN26 0x04 // bitmap mask (1bit) + #define M_GPIO_IN27 0x08 // bitmap mask (1bit) + #define M_GPIO_IN28 0x10 // bitmap mask (1bit) + #define M_GPIO_IN29 0x20 // bitmap mask (1bit) + #define M_GPIO_IN30 0x40 // bitmap mask (1bit) + #define M_GPIO_IN31 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_in24:1; + REGWORD v_gpio_in25:1; + REGWORD v_gpio_in26:1; + REGWORD v_gpio_in27:1; + REGWORD v_gpio_in28:1; + REGWORD v_gpio_in29:1; + REGWORD v_gpio_in30:1; + REGWORD v_gpio_in31:1; + } bit_r_gpio_in3; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_in3 bit;} reg_r_gpio_in3; // register and bitmap access + + +#define R_GPIO_EN1 0x42 // register access + #define M_GPIO_EN8 0x01 // bitmap mask (1bit) + #define M_GPIO_EN9 0x02 // bitmap mask (1bit) + #define M_GPIO_EN10 0x04 // bitmap mask (1bit) + #define M_GPIO_EN11 0x08 // bitmap mask (1bit) + #define M_GPIO_EN12 0x10 // bitmap mask (1bit) + #define M_GPIO_EN13 0x20 // bitmap mask (1bit) + #define M_GPIO_EN14 0x40 // bitmap mask (1bit) + #define M_GPIO_EN15 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_en8:1; + REGWORD v_gpio_en9:1; + REGWORD v_gpio_en10:1; + REGWORD v_gpio_en11:1; + REGWORD v_gpio_en12:1; + REGWORD v_gpio_en13:1; + REGWORD v_gpio_en14:1; + REGWORD v_gpio_en15:1; + } bit_r_gpio_en1; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_en1 bit;} reg_r_gpio_en1; // register and bitmap access + + +#define R_GPIO_EN3 0x43 // register access + #define M_GPIO_EN24 0x01 // bitmap mask (1bit) + #define M_GPIO_EN25 0x02 // bitmap mask (1bit) + #define M_GPIO_EN26 0x04 // bitmap mask (1bit) + #define M_GPIO_EN27 0x08 // bitmap mask (1bit) + #define M_GPIO_EN28 0x10 // bitmap mask (1bit) + #define M_GPIO_EN29 0x20 // bitmap mask (1bit) + #define M_GPIO_EN30 0x40 // bitmap mask (1bit) + #define M_GPIO_EN31 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_en24:1; + REGWORD v_gpio_en25:1; + REGWORD v_gpio_en26:1; + REGWORD v_gpio_en27:1; + REGWORD v_gpio_en28:1; + REGWORD v_gpio_en29:1; + REGWORD v_gpio_en30:1; + REGWORD v_gpio_en31:1; + } bit_r_gpio_en3; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_en3 bit;} reg_r_gpio_en3; // register and bitmap access + + +#define R_GPIO_SEL_BL 0x44 // register access + #define M_GPIO_BL0 0x01 // bitmap mask (1bit) + #define M_GPIO_BL1 0x02 // bitmap mask (1bit) + #define M_GPIO_BL2 0x04 // bitmap mask (1bit) + #define M_GPIO_BL3 0x08 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_bl0:1; + REGWORD v_gpio_bl1:1; + REGWORD v_gpio_bl2:1; + REGWORD v_gpio_bl3:1; + REGWORD reserved_54:4; + } bit_r_gpio_sel_bl; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_sel_bl bit;} reg_r_gpio_sel_bl; // register and bitmap access + + +#define R_GPIO_OUT2 0x45 // register access + #define M_GPIO_OUT16 0x01 // bitmap mask (1bit) + #define M_GPIO_OUT17 0x02 // bitmap mask (1bit) + #define M_GPIO_OUT18 0x04 // bitmap mask (1bit) + #define M_GPIO_OUT19 0x08 // bitmap mask (1bit) + #define M_GPIO_OUT20 0x10 // bitmap mask (1bit) + #define M_GPIO_OUT21 0x20 // bitmap mask (1bit) + #define M_GPIO_OUT22 0x40 // bitmap mask (1bit) + #define M_GPIO_OUT23 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_out16:1; + REGWORD v_gpio_out17:1; + REGWORD v_gpio_out18:1; + REGWORD v_gpio_out19:1; + REGWORD v_gpio_out20:1; + REGWORD v_gpio_out21:1; + REGWORD v_gpio_out22:1; + REGWORD v_gpio_out23:1; + } bit_r_gpio_out2; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_out2 bit;} reg_r_gpio_out2; // register and bitmap access + + +#define R_GPIO_IN2 0x45 // register access + #define M_GPIO_IN16 0x01 // bitmap mask (1bit) + #define M_GPIO_IN17 0x02 // bitmap mask (1bit) + #define M_GPIO_IN18 0x04 // bitmap mask (1bit) + #define M_GPIO_IN19 0x08 // bitmap mask (1bit) + #define M_GPIO_IN20 0x10 // bitmap mask (1bit) + #define M_GPIO_IN21 0x20 // bitmap mask (1bit) + #define M_GPIO_IN22 0x40 // bitmap mask (1bit) + #define M_GPIO_IN23 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_in16:1; + REGWORD v_gpio_in17:1; + REGWORD v_gpio_in18:1; + REGWORD v_gpio_in19:1; + REGWORD v_gpio_in20:1; + REGWORD v_gpio_in21:1; + REGWORD v_gpio_in22:1; + REGWORD v_gpio_in23:1; + } bit_r_gpio_in2; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_in2 bit;} reg_r_gpio_in2; // register and bitmap access + + +#define R_PWM_MD 0x46 // register access + #define M_WAK_EN 0x02 // bitmap mask (1bit) + #define M_PWM0_MD 0x30 // bitmap mask (2bit) + #define M1_PWM0_MD 0x10 + #define M_PWM1_MD 0xC0 // bitmap mask (2bit) + #define M1_PWM1_MD 0x40 + + typedef struct // bitmap construction + { + REGWORD reserved_52:1; + REGWORD v_wak_en:1; + REGWORD reserved_53:2; + REGWORD v_pwm0_md:2; + REGWORD v_pwm1_md:2; + } bit_r_pwm_md; // register and bitmap data + typedef union {REGWORD reg; bit_r_pwm_md bit;} reg_r_pwm_md; // register and bitmap access + + +#define R_GPIO_EN2 0x47 // register access + #define M_GPIO_EN16 0x01 // bitmap mask (1bit) + #define M_GPIO_EN17 0x02 // bitmap mask (1bit) + #define M_GPIO_EN18 0x04 // bitmap mask (1bit) + #define M_GPIO_EN19 0x08 // bitmap mask (1bit) + #define M_GPIO_EN20 0x10 // bitmap mask (1bit) + #define M_GPIO_EN21 0x20 // bitmap mask (1bit) + #define M_GPIO_EN22 0x40 // bitmap mask (1bit) + #define M_GPIO_EN23 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_en16:1; + REGWORD v_gpio_en17:1; + REGWORD v_gpio_en18:1; + REGWORD v_gpio_en19:1; + REGWORD v_gpio_en20:1; + REGWORD v_gpio_en21:1; + REGWORD v_gpio_en22:1; + REGWORD v_gpio_en23:1; + } bit_r_gpio_en2; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_en2 bit;} reg_r_gpio_en2; // register and bitmap access + + +#define R_GPIO_IN0 0x48 // register access + #define M_GPIO_IN0 0x01 // bitmap mask (1bit) + #define M_GPIO_IN1 0x02 // bitmap mask (1bit) + #define M_GPIO_IN2 0x04 // bitmap mask (1bit) + #define M_GPIO_IN3 0x08 // bitmap mask (1bit) + #define M_GPIO_IN4 0x10 // bitmap mask (1bit) + #define M_GPIO_IN5 0x20 // bitmap mask (1bit) + #define M_GPIO_IN6 0x40 // bitmap mask (1bit) + #define M_GPIO_IN7 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_in0:1; + REGWORD v_gpio_in1:1; + REGWORD v_gpio_in2:1; + REGWORD v_gpio_in3:1; + REGWORD v_gpio_in4:1; + REGWORD v_gpio_in5:1; + REGWORD v_gpio_in6:1; + REGWORD v_gpio_in7:1; + } bit_r_gpio_in0; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_in0 bit;} reg_r_gpio_in0; // register and bitmap access + + +#define R_GPIO_OUT0 0x48 // register access + #define M_GPIO_OUT0 0x01 // bitmap mask (1bit) + #define M_GPIO_OUT1 0x02 // bitmap mask (1bit) + #define M_GPIO_OUT2 0x04 // bitmap mask (1bit) + #define M_GPIO_OUT3 0x08 // bitmap mask (1bit) + #define M_GPIO_OUT4 0x10 // bitmap mask (1bit) + #define M_GPIO_OUT5 0x20 // bitmap mask (1bit) + #define M_GPIO_OUT6 0x40 // bitmap mask (1bit) + #define M_GPIO_OUT7 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_out0:1; + REGWORD v_gpio_out1:1; + REGWORD v_gpio_out2:1; + REGWORD v_gpio_out3:1; + REGWORD v_gpio_out4:1; + REGWORD v_gpio_out5:1; + REGWORD v_gpio_out6:1; + REGWORD v_gpio_out7:1; + } bit_r_gpio_out0; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_out0 bit;} reg_r_gpio_out0; // register and bitmap access + + +#define R_GPIO_EN0 0x4A // register access + #define M_GPIO_EN0 0x01 // bitmap mask (1bit) + #define M_GPIO_EN1 0x02 // bitmap mask (1bit) + #define M_GPIO_EN2 0x04 // bitmap mask (1bit) + #define M_GPIO_EN3 0x08 // bitmap mask (1bit) + #define M_GPIO_EN4 0x10 // bitmap mask (1bit) + #define M_GPIO_EN5 0x20 // bitmap mask (1bit) + #define M_GPIO_EN6 0x40 // bitmap mask (1bit) + #define M_GPIO_EN7 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_en0:1; + REGWORD v_gpio_en1:1; + REGWORD v_gpio_en2:1; + REGWORD v_gpio_en3:1; + REGWORD v_gpio_en4:1; + REGWORD v_gpio_en5:1; + REGWORD v_gpio_en6:1; + REGWORD v_gpio_en7:1; + } bit_r_gpio_en0; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_en0 bit;} reg_r_gpio_en0; // register and bitmap access + + +#define R_GPIO_SEL 0x4C // register access + #define M_GPIO_SEL0 0x01 // bitmap mask (1bit) + #define M_GPIO_SEL1 0x02 // bitmap mask (1bit) + #define M_GPIO_SEL2 0x04 // bitmap mask (1bit) + #define M_GPIO_SEL3 0x08 // bitmap mask (1bit) + #define M_GPIO_SEL4 0x10 // bitmap mask (1bit) + #define M_GPIO_SEL5 0x20 // bitmap mask (1bit) + #define M_GPIO_SEL6 0x40 // bitmap mask (1bit) + #define M_GPIO_SEL7 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_gpio_sel0:1; + REGWORD v_gpio_sel1:1; + REGWORD v_gpio_sel2:1; + REGWORD v_gpio_sel3:1; + REGWORD v_gpio_sel4:1; + REGWORD v_gpio_sel5:1; + REGWORD v_gpio_sel6:1; + REGWORD v_gpio_sel7:1; + } bit_r_gpio_sel; // register and bitmap data + typedef union {REGWORD reg; bit_r_gpio_sel bit;} reg_r_gpio_sel; // register and bitmap access + + +#define R_PLL_STA 0x50 // register access + #define M_PLL_LOCK 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD reserved_56:7; + REGWORD v_pll_lock:1; + } bit_r_pll_sta; // register and bitmap data + typedef union {REGWORD reg; bit_r_pll_sta bit;} reg_r_pll_sta; // register and bitmap access + + +#define R_PLL_CTRL 0x50 // register access + #define M_PLL_NRES 0x01 // bitmap mask (1bit) + #define M_PLL_TST 0x02 // bitmap mask (1bit) + #define M_PLL_FREEZE 0x20 // bitmap mask (1bit) + #define M_PLL_M 0xC0 // bitmap mask (2bit) + #define M1_PLL_M 0x40 + + typedef struct // bitmap construction + { + REGWORD v_pll_nres:1; + REGWORD v_pll_tst:1; + REGWORD reserved_55:3; + REGWORD v_pll_freeze:1; + REGWORD v_pll_m:2; + } bit_r_pll_ctrl; // register and bitmap data + typedef union {REGWORD reg; bit_r_pll_ctrl bit;} reg_r_pll_ctrl; // register and bitmap access + + +#define R_PLL_P 0x51 // register access + #define M_PLL_P 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_pll_p:8; + } bit_r_pll_p; // register and bitmap data + typedef union {REGWORD reg; bit_r_pll_p bit;} reg_r_pll_p; // register and bitmap access + + +#define R_PLL_N 0x52 // register access + #define M_PLL_N 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_pll_n:8; + } bit_r_pll_n; // register and bitmap data + typedef union {REGWORD reg; bit_r_pll_n bit;} reg_r_pll_n; // register and bitmap access + + +#define R_PLL_S 0x53 // register access + #define M_PLL_S 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_pll_s:8; + } bit_r_pll_s; // register and bitmap data + typedef union {REGWORD reg; bit_r_pll_s bit;} reg_r_pll_s; // register and bitmap access + + +#define A_FIFO_DATA 0x80 // register access + #define M_FIFO_DATA 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_data:8; + } bit_a_fifo_data; // register and bitmap data + typedef union {REGWORD reg; bit_a_fifo_data bit;} reg_a_fifo_data; // register and bitmap access + + +#define A_FIFO_DATA_NOINC 0x84 // register access + #define M_FIFO_DATA_NOINC 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_data_noinc:8; + } bit_a_fifo_data_noinc; // register and bitmap data + typedef union {REGWORD reg; bit_a_fifo_data_noinc bit;} reg_a_fifo_data_noinc; // register and bitmap access + + +#define R_INT_DATA 0x88 // register access + #define M_INT_DATA 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_int_data:8; + } bit_r_int_data; // register and bitmap data + typedef union {REGWORD reg; bit_r_int_data bit;} reg_r_int_data; // register and bitmap access + + +#define R_RAM_DATA 0xC0 // register access + #define M_RAM_DATA 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_ram_data:8; + } bit_r_ram_data; // register and bitmap data + typedef union {REGWORD reg; bit_r_ram_data bit;} reg_r_ram_data; // register and bitmap access + + +#define A_SL_CFG 0xD0 // register access + #define M_CH_SDIR 0x01 // bitmap mask (1bit) + #define M_CH_SNUM 0x3E // bitmap mask (5bit) + #define M1_CH_SNUM 0x02 + #define M_ROUT 0xC0 // bitmap mask (2bit) + #define M1_ROUT 0x40 + + typedef struct // bitmap construction + { + REGWORD v_ch_sdir:1; + REGWORD v_ch_snum:5; + REGWORD v_rout:2; + } bit_a_sl_cfg; // register and bitmap data + typedef union {REGWORD reg; bit_a_sl_cfg bit;} reg_a_sl_cfg; // register and bitmap access + + +#define A_CH_MSK 0xF4 // register access + #define M_CH_MSK 0xFF // bitmap mask (8bit) + + typedef struct // bitmap construction + { + REGWORD v_ch_msk:8; + } bit_a_ch_msk; // register and bitmap data + typedef union {REGWORD reg; bit_a_ch_msk bit;} reg_a_ch_msk; // register and bitmap access + + +#define A_CON_HDLC 0xFA // register access + #define M_IFF 0x01 // bitmap mask (1bit) + #define M_HDLC_TRP 0x02 // bitmap mask (1bit) + #define M_FIFO_IRQ 0x1C // bitmap mask (3bit) + #define M1_FIFO_IRQ 0x04 + #define M_DATA_FLOW 0xE0 // bitmap mask (3bit) + #define M1_DATA_FLOW 0x20 + + typedef struct // bitmap construction + { + REGWORD v_iff:1; + REGWORD v_hdlc_trp:1; + REGWORD v_fifo_irq:3; + REGWORD v_data_flow:3; + } bit_a_con_hdlc; // register and bitmap data + typedef union {REGWORD reg; bit_a_con_hdlc bit;} reg_a_con_hdlc; // register and bitmap access + + +#define A_SUBCH_CFG 0xFB // register access + #define M_BIT_CNT 0x07 // bitmap mask (3bit) + #define M1_BIT_CNT 0x01 + #define M_START_BIT 0x38 // bitmap mask (3bit) + #define M1_START_BIT 0x08 + #define M_LOOP_FIFO 0x40 // bitmap mask (1bit) + #define M_INV_DATA 0x80 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_bit_cnt:3; + REGWORD v_start_bit:3; + REGWORD v_loop_fifo:1; + REGWORD v_inv_data:1; + } bit_a_subch_cfg; // register and bitmap data + typedef union {REGWORD reg; bit_a_subch_cfg bit;} reg_a_subch_cfg; // register and bitmap access + + +#define A_CHANNEL 0xFC // register access + #define M_CH_FDIR 0x01 // bitmap mask (1bit) + #define M_CH_FNUM 0x1E // bitmap mask (4bit) + #define M1_CH_FNUM 0x02 + + typedef struct // bitmap construction + { + REGWORD v_ch_fdir:1; + REGWORD v_ch_fnum:4; + REGWORD reserved_57:3; + } bit_a_channel; // register and bitmap data + typedef union {REGWORD reg; bit_a_channel bit;} reg_a_channel; // register and bitmap access + + +#define A_FIFO_SEQ 0xFD // register access + #define M_NEXT_FIFO_DIR 0x01 // bitmap mask (1bit) + #define M_NEXT_FIFO_NUM 0x1E // bitmap mask (4bit) + #define M1_NEXT_FIFO_NUM 0x02 + #define M_SEQ_END 0x40 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_next_fifo_dir:1; + REGWORD v_next_fifo_num:4; + REGWORD reserved_58:1; + REGWORD v_seq_end:1; + REGWORD reserved_59:1; + } bit_a_fifo_seq; // register and bitmap data + typedef union {REGWORD reg; bit_a_fifo_seq bit;} reg_a_fifo_seq; // register and bitmap access + + +#define A_FIFO_CTRL 0xFF // register access + #define M_FIFO_IRQMSK 0x01 // bitmap mask (1bit) + #define M_BERT_EN 0x02 // bitmap mask (1bit) + #define M_MIX_IRQ 0x04 // bitmap mask (1bit) + #define M_FR_ABO 0x08 // bitmap mask (1bit) + #define M_NO_CRC 0x10 // bitmap mask (1bit) + #define M_NO_REP 0x20 // bitmap mask (1bit) + + typedef struct // bitmap construction + { + REGWORD v_fifo_irqmsk:1; + REGWORD v_bert_en:1; + REGWORD v_mix_irq:1; + REGWORD v_fr_abo:1; + REGWORD v_no_crc:1; + REGWORD v_no_rep:1; + REGWORD reserved_60:2; + } bit_a_fifo_ctrl; // register and bitmap data + typedef union {REGWORD reg; bit_a_fifo_ctrl bit;} reg_a_fifo_ctrl; // register and bitmap access + + +#endif /* _XHFC24SUCC_H_ */ + +/*___________________________________________________________________________________*/ +/* */ +/* End of XHFC-2S4U / XHFC-4SU register definitions. */ +/* */ +/* Total number of registers processed: 122 of 122 */ +/* Total number of bitmaps processed : 523 */ +/* */ +/*___________________________________________________________________________________*/ +/* */ diff --git a/patches/kdrivers/src/diff b/patches/kdrivers/src/diff new file mode 100644 index 0000000..5e15c04 --- /dev/null +++ b/patches/kdrivers/src/diff @@ -0,0 +1,390 @@ +Only in /root/3.3/wanpipe/patches/kdrivers/src/lip/: bin +Only in /common/lip: CVS +Only in /common/lip: hupdate +Only in /common/lip: include +Only in /common/lip: include_old +Only in /root/3.3/wanpipe/patches/kdrivers/src/lip/: lip_katm +diff -dur /root/3.3/wanpipe/patches/kdrivers/src/lip/Makefile /common/lip/Makefile +--- /root/3.3/wanpipe/patches/kdrivers/src/lip/Makefile 2008-01-24 12:23:03.000000000 -0500 ++++ /common/lip/Makefile 2007-05-17 20:09:10.000000000 -0400 +@@ -5,9 +5,11 @@ + # Rewritten to use lists instead of if-statements. + # + ++PWD=$(shell pwd) + FRDIR=../fr + SPPPDIR=../sppp + ATMDIR=../atm ++LAPDIR=../lapb + LIP_KATMDIR=../lip_katm + LIP_ATMDIR=../lip_atm + COMMON=../wanpipe +@@ -18,16 +20,18 @@ + CONFIG_WANPIPE_ATM=n + CONFIG_WANPIPE_LIP_KATM=y + CONFIG_WANPIPE_LIP_ATM=y ++CONFIG_WANPIPE_LIP_LAPB=n ++CONFIG_WANPIPE_TTY=y + + EXTRA_CFLAGS=$(EXTRA_FLAGS) +-EXTRA_CFLAGS+=-DWANLIP_DRIVER -DWPLIP_TTY_SUPPORT ++EXTRA_CFLAGS+=-DWANLIP_DRIVER + + wanpipe_lip-y := wanpipe_lip_iface.o wanpipe_lip_sub.o + wanpipe_lip-y += wanpipe_lip_netdev.o wanpipe_lip_prot.o + wanpipe_lip-y += wanpipe_lip_bh.o wanpipe_lip_ipx.o + wanpipe_lip-y += $(COMMON)/wanpipe_abstr.o $(ROUTER)/wanpipe_linux_iface.o + +-ifeq "${CONFIG_WANPIPE_FR}" "y" ++ifeq "${CONFIG_WANPIPE_TTY}" "y" + PRODUCT_DEFINES += -DWPLIP_TTY_SUPPORT + wanpipe_lip-y += wanpipe_lip_tty.o + endif +@@ -64,6 +68,18 @@ + EXTRA_CFLAGS += -I$(ATMDIR) -I$(ATMDIR)/include + endif + ++ifeq "${CONFIG_WANPIPE_LIP_LAPB}" "y" ++PRODUCT_DEFINES += -DCONFIG_PRODUCT_WANPIPE_LIP_LAPD ++PRODUCT_DEFINES += -DCONFIG_PRODUCT_WANPIPE_LIP_LAPB ++wanpipe_lip-y += $(LAPDIR)/wanpipe_lapb_iface.o ++wanpipe_lip-y += $(LAPDIR)/wanpipe_lapb_in.o ++wanpipe_lip-y += $(LAPDIR)/wanpipe_lapb_out.o ++wanpipe_lip-y += $(LAPDIR)/wanpipe_lapb_sub.o ++wanpipe_lip-y += $(LAPDIR)/wanpipe_lapb_timer.o ++EXTRA_CFLAGS += -I$(PWD)/$(LAPDIR) -I$(PWD)/$(LAPDIR)/include ++endif ++ ++ + EXTRA_CFLAGS += $(PRODUCT_DEFINES) + + +Only in /common/lip: Makefile5.FreeBSD +Only in /common/lip: Makefile6.FreeBSD +Only in /common/lip: Makefile.Kbuild.Linux +Only in /common/lip: Makefile.Kbuild.Linux~ +Only in /common/lip: Makefile.Linux +Only in /common/lip: .#Makefile.Linux.1.12 +Only in /common/lip: .#Makefile.Linux.1.2 +Only in /common/lip: .#Makefile.Linux.1.20 +Only in /common/lip: mod +Only in /common/lip: modinfo +Only in /common/lip: Module.symvers +Only in /common/lip: test-fr.sh +Only in /common/lip: test.sh +Only in /common/lip/tmp: CVS +Only in /common/lip: .tmp_versions +diff -dur /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip_bh.c /common/lip/wanpipe_lip_bh.c +--- /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip_bh.c 2008-01-24 12:23:03.000000000 -0500 ++++ /common/lip/wanpipe_lip_bh.c 2008-02-05 18:27:27.000000000 -0500 +@@ -121,7 +121,7 @@ + + } + +- if (WAN_NETIF_QUEUE_STOPPED(lip_dev->common.dev)){ ++ if (WAN_NETIF_UP(lip_dev->common.dev) && WAN_NETIF_QUEUE_STOPPED(lip_dev->common.dev)){ + if (lip_dev->common.usedby == API){ + DEBUG_TEST("%s: Api waking stack!\n",lip_dev->name); + WAN_NETIF_START_QUEUE(lip_dev->common.dev); +Only in /common/lip: .#wanpipe_lip_bh.c.1.13 +Only in /common/lip: .#wanpipe_lip_bh.c.1.17 +Only in /common/lip: .#wanpipe_lip_bh.c.1.4 +Only in /common/lip: .#wanpipe_lip_bh.c.1.8 +Only in /common/lip: wanpipe_lip_bh.o +Only in /common/lip: .wanpipe_lip_bh.o.cmd +diff -dur /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip_iface.c /common/lip/wanpipe_lip_iface.c +--- /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip_iface.c 2008-01-24 12:23:03.000000000 -0500 ++++ /common/lip/wanpipe_lip_iface.c 2008-03-12 17:30:19.000000000 -0400 +@@ -452,12 +452,11 @@ + } + } + +- wplip_close_lipdev_prot(lip_dev); +- + wan_set_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical); + wan_clear_bit(WAN_DEV_READY,&lip_dev->interface_down); +- + ++ wplip_close_lipdev_prot(lip_dev); ++ + wan_spin_lock_irq(&lip_link->bh_lock,&flags); + lip_link->cur_tx=NULL; + wan_skb_queue_purge(&lip_dev->tx_queue); +@@ -840,15 +839,11 @@ + return 0; + } + +-int wplip_lipdev_prot_change_state(void *wplip_id,int state, +- unsigned char *data, int len) +-{ +- wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; + +- DEBUG_EVENT("%s: Lip Dev Prot State %s!\n", +- lip_dev->name, STATE_DECODE(state)); + +- lip_dev->common.state = state; ++int wplip_lipdev_prot_update_state_change(wplip_dev_t *lip_dev, unsigned char *data, int len) ++{ ++ int state = lip_dev->common.state; + + if (lip_dev->common.usedby == API) { + +@@ -857,27 +852,24 @@ + } + + if (state == WAN_CONNECTED){ +- lip_dev->common.state = state; + WAN_NETIF_CARRIER_ON(lip_dev->common.dev); + WAN_NETIF_START_QUEUE(lip_dev->common.dev); +- wan_update_api_state(lip_dev); + }else{ +- lip_dev->common.state = state; + WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); + WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); + } ++ ++ wan_update_api_state(lip_dev); + + wplip_trigger_bh(lip_dev->lip_link); + + }else if (lip_dev->common.lip) { /*STACK*/ + + if (state == WAN_CONNECTED){ +- lip_dev->common.state = state; + WAN_NETIF_CARRIER_ON(lip_dev->common.dev); + WAN_NETIF_START_QUEUE(lip_dev->common.dev); + wplip_connect(lip_dev->common.lip,0); + }else{ +- lip_dev->common.state = state; + WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); + #if defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) + WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); +@@ -887,12 +879,10 @@ + + }else{ + if (state == WAN_CONNECTED){ +- lip_dev->common.state = state; + WAN_NETIF_CARRIER_ON(lip_dev->common.dev); + WAN_NETIF_WAKE_QUEUE(lip_dev->common.dev); + wplip_trigger_bh(lip_dev->lip_link); + }else{ +- lip_dev->common.state = state; + WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); + #if defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) + WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); +@@ -911,6 +901,27 @@ + } + + ++ ++ ++int wplip_lipdev_prot_change_state(void *wplip_id,int state, ++ unsigned char *data, int len) ++{ ++ wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; ++ ++ DEBUG_EVENT("%s: Lip Dev Prot State %s!\n", ++ lip_dev->name, STATE_DECODE(state)); ++ ++ lip_dev->common.state = state; ++ ++ if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical) || ++ wan_test_bit(0,&lip_dev->if_down)) { ++ return 0; ++ } ++ ++ return wplip_lipdev_prot_update_state_change(lip_dev,data,len); ++} ++ ++ + /*============================================================== + * wplip_connect + * +Only in /common/lip: wanpipe_lip_iface.c~ +Only in /common/lip: .#wanpipe_lip_iface.c.1.2 +Only in /common/lip: .#wanpipe_lip_iface.c.1.20 +Only in /common/lip: .#wanpipe_lip_iface.c.1.33 +Only in /common/lip: .#wanpipe_lip_iface.c.1.34 +Only in /common/lip: .#wanpipe_lip_iface.c.1.37 +Only in /common/lip: .#wanpipe_lip_iface.c.1.39 +Only in /common/lip: .#wanpipe_lip_iface.c.1.6 +Only in /common/lip: wanpipe_lip_iface.o +Only in /common/lip: .wanpipe_lip_iface.o.cmd +Only in /common/lip: wanpipe_lip_ipx.o +Only in /common/lip: .wanpipe_lip_ipx.o.cmd +Only in /common/lip: wanpipe_lip.ko +Only in /common/lip: .wanpipe_lip.ko.cmd +diff -dur /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip.mod.c /common/lip/wanpipe_lip.mod.c +--- /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip.mod.c 2008-01-24 12:23:03.000000000 -0500 ++++ /common/lip/wanpipe_lip.mod.c 2008-03-10 14:07:39.000000000 -0400 +@@ -4,25 +4,93 @@ + + MODULE_INFO(vermagic, VERMAGIC_STRING); + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) || defined(WANPIPE_MOD_266_FORCE_UPDATE) +-#undef unix + struct module __this_module + __attribute__((section(".gnu.linkonce.this_module"))) = { +- .name = __stringify(KBUILD_MODNAME), ++ .name = KBUILD_MODNAME, + .init = init_module, + #ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, + #endif + }; +-#endif + + static const struct modversion_info ____versions[] ++__attribute_used__ + __attribute__((section("__versions"))) = { +- ++ { 0x89e24b9c, "struct_module" }, ++ { 0x52c0a61d, "_write_unlock_irqrestore" }, ++ { 0xa5a6ef53, "skb_queue_head" }, ++ { 0x12da5bb2, "__kmalloc" }, ++ { 0xec7bc0d, "__mod_timer" }, ++ { 0xc6405fec, "skb_append" }, ++ { 0x4827a016, "del_timer" }, ++ { 0x3d7c39ea, "_read_lock" }, ++ { 0xe1b7029c, "print_tainted" }, ++ { 0x79aa04a2, "get_random_bytes" }, ++ { 0xab978df6, "malloc_sizes" }, ++ { 0x3adc4c7c, "remove_wait_queue" }, ++ { 0x3093180f, "_write_lock_irqsave" }, ++ { 0x772274b1, "netif_carrier_on" }, ++ { 0xc4f02fe7, "skb_clone" }, ++ { 0x14990642, "skb_copy" }, ++ { 0x1bcd461f, "_spin_lock" }, ++ { 0xf6a5a6c8, "schedule_work" }, ++ { 0x669e2d2f, "seq_printf" }, ++ { 0x87b6fae2, "netif_carrier_off" }, ++ { 0xfb1d0a92, "alloc_netdev" }, ++ { 0x3026fe48, "tty_register_driver" }, ++ { 0x87cddf59, "_spin_lock_irqsave" }, ++ { 0x1d26aa98, "sprintf" }, ++ { 0x5ddb19f0, "in_dev_finish_destroy" }, ++ { 0x7d11c268, "jiffies" }, ++ { 0x58502b7a, "tty_set_operations" }, ++ { 0x92cfbd9d, "netif_rx" }, ++ { 0xffd5a395, "default_wake_function" }, ++ { 0x1b7d4074, "printk" }, ++ { 0x5152e605, "memcmp" }, ++ { 0x15e074de, "free_netdev" }, ++ { 0xed5c73bf, "__tasklet_schedule" }, ++ { 0x2da418b5, "copy_to_user" }, ++ { 0x604efc6a, "register_netdev" }, ++ { 0xa20fdde, "_spin_unlock_irqrestore" }, ++ { 0xa5808bbf, "tasklet_init" }, ++ { 0x1902adf, "netpoll_trap" }, ++ { 0xb13e533f, "atm_dev_register" }, ++ { 0x149a799f, "dev_kfree_skb_any" }, ++ { 0x79ad224b, "tasklet_kill" }, ++ { 0x1c53db6e, "skb_over_panic" }, ++ { 0xb356ebea, "skb_queue_tail" }, ++ { 0x19070091, "kmem_cache_alloc" }, ++ { 0x89ac5254, "tty_std_termios" }, ++ { 0x9aebf873, "__alloc_skb" }, ++ { 0x4292364c, "schedule" }, ++ { 0x89d282ea, "kfree_skb" }, ++ { 0x6b2dc060, "dump_stack" }, ++ { 0xb08e0988, "skb_under_panic" }, ++ { 0xb00b9d99, "eth_type_trans" }, ++ { 0xad97dcd, "ether_setup" }, ++ { 0x95ec5a88, "tty_unregister_driver" }, ++ { 0x19cacd0, "init_waitqueue_head" }, ++ { 0xd0b91f9b, "init_timer" }, ++ { 0x6989a769, "vsnprintf" }, ++ { 0x20f26d60, "tty_hangup" }, ++ { 0x59968f3c, "__wake_up" }, ++ { 0xf6ebc03b, "net_ratelimit" }, ++ { 0xf66fb709, "atm_dev_deregister" }, ++ { 0xa3d44f8c, "add_wait_queue" }, ++ { 0x37a0cba, "kfree" }, ++ { 0x2e60bace, "memcpy" }, ++ { 0x2e2ed056, "skb_dequeue" }, ++ { 0x828fe72a, "unregister_netdev" }, ++ { 0x25da070, "snprintf" }, ++ { 0x45e37139, "__netif_schedule" }, ++ { 0xf2a644fb, "copy_from_user" }, ++ { 0x9e7d6bd0, "__udelay" }, + }; + + static const char __module_depends[] + __attribute_used__ + __attribute__((section(".modinfo"))) = +-"depends=wanrouter"; ++"depends=atm"; + ++ ++MODULE_INFO(srcversion, "332567BBD00B67D83582BEF"); +Only in /common/lip: wanpipe_lip.mod.o +Only in /common/lip: .wanpipe_lip.mod.o.cmd +diff -dur /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip_netdev.c /common/lip/wanpipe_lip_netdev.c +--- /root/3.3/wanpipe/patches/kdrivers/src/lip/wanpipe_lip_netdev.c 2008-01-24 12:23:03.000000000 -0500 ++++ /common/lip/wanpipe_lip_netdev.c 2008-03-12 17:29:15.000000000 -0400 +@@ -55,6 +55,10 @@ + if (!lip_dev || !lip_dev->lip_link){ + return -ENODEV; + } ++ ++ if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)) { ++ return -ENODEV; ++ } + + #if defined(__LINUX__) + # if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) +@@ -63,6 +67,7 @@ + # endif + #endif + ++ wan_clear_bit(0,&lip_dev->if_down); + + #if 0 + /* Done in if register now, do it interface up down +@@ -85,6 +90,10 @@ + WAN_NETIF_WAKE_QUEUE(dev); + #endif + ++ /* Its possible for state update to be skipped if interface was down */ ++ wplip_lipdev_prot_update_state_change(lip_dev,NULL,0); ++ ++ + if (!wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)) { + wan_set_bit(WAN_DEV_READY,&lip_dev->interface_down); + wplip_trigger_if_task(lip_dev); +@@ -125,6 +134,8 @@ + } + #endif + ++ wan_set_bit(0,&lip_dev->if_down); ++ + #if 0 + /* Done in if register now, do it interface up down + * feature on 2.4 kernels */ +Only in /common/lip: .#wanpipe_lip_netdev.c.1.12 +Only in /common/lip: .#wanpipe_lip_netdev.c.1.15 +Only in /common/lip: .#wanpipe_lip_netdev.c.1.17 +Only in /common/lip: .#wanpipe_lip_netdev.c.1.24 +Only in /common/lip: .#wanpipe_lip_netdev.c.1.25 +Only in /common/lip: .#wanpipe_lip_netdev.c.1.29 +Only in /common/lip: .#wanpipe_lip_netdev.c.1.4 +Only in /common/lip: wanpipe_lip_netdev.o +Only in /common/lip: .wanpipe_lip_netdev.o.cmd +Only in /common/lip: wanpipe_lip.o +Only in /common/lip: .wanpipe_lip.o.cmd +Only in /common/lip: wanpipe_lip_prot.c~ +Only in /common/lip: .#wanpipe_lip_prot.c.1.21 +Only in /common/lip: .#wanpipe_lip_prot.c.1.25 +Only in /common/lip: .#wanpipe_lip_prot.c.1.35 +Only in /common/lip: .#wanpipe_lip_prot.c.1.37 +Only in /common/lip: .#wanpipe_lip_prot.c.1.46 +Only in /common/lip: .#wanpipe_lip_prot.c.1.5 +Only in /common/lip: wanpipe_lip_prot.o +Only in /common/lip: .wanpipe_lip_prot.o.cmd +Only in /common/lip: .#wanpipe_lip_sub.c.1.15 +Only in /common/lip: .#wanpipe_lip_sub.c.1.2 +Only in /common/lip: wanpipe_lip_sub.o +Only in /common/lip: .wanpipe_lip_sub.o.cmd +Only in /common/lip: wanpipe_lip_tty.o +Only in /common/lip: .wanpipe_lip_tty.o.cmd +Only in /common/lip: xupdate diff --git a/patches/kdrivers/src/lip/bin/wanpipe_lip_atm.gcc3.i386.o b/patches/kdrivers/src/lip/bin/wanpipe_lip_atm.gcc3.i386.o index 78eaec38bee7fd4d0d902f155c3d462d72cb5f10..1ee33de0a3dfdc2eed7cb27110dce6986d84ee39 100644 GIT binary patch literal 27456 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 z zDBO0jq`MlBr!S5G@@Wb1L*pDv03=nzm zON88?6keckyTa=TG0sDXJQM^Z-yY(a=VycqaBe4re+LQSkJky22j3>dJZA{6fuC`| zLfog|M}U-D!#xW5tt13pBOuq$Rt0ye_P21GnD1@2gYJ@lllYeaIp17D#PbhS`=i7`_axy0>^rLcC~?q_5r=%AD181` zB){tcIqnIC|5o9dGi3iIfb73s;bp`ZYufJ#7r}pog{U_P5r5NW%5h%=Z|!EdL6gY1X?e<6!+ z@QEn=(ktZrUj`(7AtB~>5JI1I3g1My1b-f^@E{=bKo240e~9h#HSJl|-cJa*_p=@I zy+R1N-ynqCU&xZO{&8w&rJIOO=!*ChQ{07+k{@Dk#fuYnNpHOTg<@Plgq+?5i)6p(ZU#4+y; z3g1i|^jj3Zoe**He+a>^pZ({-KEyFEFQ7@E3P^re5kjw0wu7#MIOsMgyj%7EO5snc z{$7Q@KnQ*>u^s$QDEw`O+mLI>{|Z3zpG6$}7b<+Y>Tgmoq}m@K4!Xw_zKam^{E_XL z=YLfDafP2EMBIG9_B7-(Lh6}=cErmpK(^mX2szfX9sIq-LHBiq->dq+rSP8+F4MIC zOL!yJ9U=5dhi%E{LO}AlT;cPGuhFzxg|`ucznATxC zQm~KEu4#W(_z^SrrOuD9r}Jl!SAsh z<9!_3Y;#)f28(uu{SQ2XFhNtN;K2 literal 27936 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 literal 27968 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%0D~@Z=Ma+TzZ}z+< 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 diff --git a/patches/kdrivers/src/lip/bin/wanpipe_lip_atm.gcc3.i686.regparm.o b/patches/kdrivers/src/lip/bin/wanpipe_lip_atm.gcc3.i686.regparm.o index f8b0a02250deefa1f55edf6f70afba04e0515264..fc581545cf1a6c209ca1f9980fce4cbded1a5c5b 100644 GIT binary patch literal 29344 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

bXufcNO`zT#!g_sEud-p#_aaLLd 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 QhjG1%>#6@0T$_6TKMzE*&;S4c literal 133956 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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 LT2`6R}gDvysOnrEK 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 L{v61m9LE0-%?0Fv diff --git a/patches/kdrivers/src/wanrouter/waniface.o b/patches/kdrivers/src/wanrouter/waniface.o index 9d2fcac9a9add19512adf150b0e45b65722867d5..df33f9d0df4edd66386044f96e8dcf7a478b3adf 100644 GIT binary patch literal 148275 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 K)>@7Ke)>N!F%gFV literal 143196 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 diff --git a/patches/kdrivers/src/wanrouter/wanmain.c b/patches/kdrivers/src/wanrouter/wanmain.c index 72d5c81..5b8eee6 100644 --- a/patches/kdrivers/src/wanrouter/wanmain.c +++ b/patches/kdrivers/src/wanrouter/wanmain.c @@ -254,7 +254,7 @@ int __init wanrouter_init (void) } WAN_LIST_INIT(&wan_devlist); - wan_spin_lock_init(&wan_devlist_lock); + wan_spin_lock_init(&wan_devlist_lock,"wan_devlist_lock"); err = wanrouter_proc_init(); @@ -360,7 +360,7 @@ int register_wan_device(wan_device_t *wandev) wandev->ndev = 0; WAN_LIST_INIT(&wandev->dev_head); - wan_spin_lock_init(&wandev->dev_head_lock); + wan_spin_lock_init(&wandev->dev_head_lock, "wan_dev_head_lock"); wan_spin_lock(&wan_devlist_lock); WAN_LIST_INSERT_HEAD(&wan_devlist, wandev, next); @@ -885,7 +885,7 @@ static int wan_device_new_if (wan_device_t *wandev, wanif_conf_t *u_conf) } - if ((dev=wan_dev_get_by_name(conf->name))){ + if ((dev=dev_get_by_name(conf->name))){ dev_put(dev); dev=NULL; err = -EEXIST; /* name already exists */ @@ -917,7 +917,7 @@ static int wan_device_new_if (wan_device_t *wandev, wanif_conf_t *u_conf) if (dev->name == NULL){ err = -EINVAL; - }else if ((tmp_dev=wan_dev_get_by_name(dev->name))){ + }else if ((tmp_dev=dev_get_by_name(dev->name))){ dev_put(tmp_dev); err = -EEXIST; /* name already exists */ }else if (dev->priv){ @@ -990,8 +990,8 @@ static int wan_device_del_if (wan_device_t *wandev, char *u_name) } if (devle == NULL || dev == NULL){ - if ((dev = wan_dev_get_by_name(name)) == NULL){ - printk(KERN_INFO "%s: wan_dev_get_by_name failed\n", name); + if ((dev = dev_get_by_name(name)) == NULL){ + printk(KERN_INFO "%s: dev_get_by_name failed\n", name); return err; } @@ -1522,7 +1522,7 @@ static int wan_device_new_if_lapb (wan_device_t *wandev, wanif_conf_t *u_conf) goto wan_device_new_if_lapb_exit; } - if ((tmp_dev=wan_dev_get_by_name(conf->name)) != NULL){ + if ((tmp_dev=dev_get_by_name(conf->name)) != NULL){ printk(KERN_INFO "%s: Device already exists!\n", conf->name); dev_put(tmp_dev); @@ -1662,7 +1662,7 @@ static int wan_device_new_if_x25 (wan_device_t *wandev, wanif_conf_t *u_conf) goto wan_device_new_if_x25_exit; } - if ((tmp_dev=wan_dev_get_by_name(conf->name)) != NULL){ + if ((tmp_dev=dev_get_by_name(conf->name)) != NULL){ printk(KERN_INFO "%s: Device already exists!\n", conf->name); dev_put(tmp_dev); @@ -1686,7 +1686,7 @@ static int wan_device_new_if_x25 (wan_device_t *wandev, wanif_conf_t *u_conf) } //Find a master device for our x25 lcn - if ((dev = wan_dev_get_by_name(conf->master)) == NULL){ + if ((dev = dev_get_by_name(conf->master)) == NULL){ printk(KERN_INFO "%s: Master device %s used by X25 SVC %s no found!\n", wandev->name,conf->master,conf->name); goto wan_device_new_if_x25_exit; @@ -1773,7 +1773,7 @@ static int wan_device_new_if_dsp (wan_device_t *wandev, wanif_conf_t *u_conf) goto wan_device_new_if_dsp_exit; } - if ((tmp_dev=wan_dev_get_by_name(conf->name)) != NULL){ + if ((tmp_dev=dev_get_by_name(conf->name)) != NULL){ printk(KERN_INFO "%s: Device already exists!\n", conf->name); dev_put(tmp_dev); @@ -1792,7 +1792,7 @@ static int wan_device_new_if_dsp (wan_device_t *wandev, wanif_conf_t *u_conf) } //Find a master device for our x25 lcn - if ((dev = wan_dev_get_by_name(conf->master)) == NULL){ + if ((dev = dev_get_by_name(conf->master)) == NULL){ printk(KERN_INFO "%s: Master device %s, no found for %s\n", wandev->name, conf->master,conf->name); goto wan_device_new_if_dsp_exit; @@ -1918,7 +1918,7 @@ static int wan_device_new_if_lip (wan_device_t *wandev, wanif_conf_t *u_conf) goto wan_device_new_if_lip_exit; } - if ((tmp_dev=wan_dev_get_by_name(conf->name)) != NULL){ + if ((tmp_dev=dev_get_by_name(conf->name)) != NULL){ printk(KERN_INFO "%s: Device already exists!\n", conf->name); dev_put(tmp_dev); @@ -1936,7 +1936,7 @@ static int wan_device_new_if_lip (wan_device_t *wandev, wanif_conf_t *u_conf) } //Find a master device lip device - if ((dev = wan_dev_get_by_name(conf->master)) == NULL){ + if ((dev = dev_get_by_name(conf->master)) == NULL){ printk(KERN_INFO "%s: Master device %s used by LIP %s no found!\n", wandev->name,conf->master,conf->name); goto wan_device_new_if_lip_exit; @@ -2033,12 +2033,12 @@ void unregister_wanec_iface (void) return; } -void *wanpipe_ec_register(void *pcard, int max_channels) +void *wanpipe_ec_register(void *pcard, u_int32_t fe_port_mask, int max_line_no, int max_channels, void *conf) { if (!IS_PROTOCOL_FUNC(wanec_iface)) return NULL; if (wanec_iface.reg){ - return wanec_iface.reg(pcard, max_channels); + return wanec_iface.reg(pcard, fe_port_mask, max_line_no, max_channels, conf); } return NULL; } @@ -2060,11 +2060,11 @@ int wanpipe_ec_event_ctrl(void *arg, void *pcard, wan_event_ctrl_t *event_ctrl) return 0; } -int wanpipe_ec_isr(void *arg, void *pcard) +int wanpipe_ec_isr(void *arg) { if (!IS_PROTOCOL_FUNC(wanec_iface)) return 0; if (wanec_iface.isr){ - return wanec_iface.isr(arg, pcard); + return wanec_iface.isr(arg); } return 0; } @@ -2120,14 +2120,12 @@ int wan_run_wanrouter(char * hwdevname, char *devname, char *action) __FUNCTION__); return -EINVAL; } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + if (!current->fs->root) { /* statically linked USB is initted rather early */ DEBUG_EVENT ("%s: Error: no FS yet",__FUNCTION__); return -ENODEV; } -#endif if (!(envp = (char **) kmalloc (20 * sizeof (char *), GFP_KERNEL))) { DEBUG_EVENT ("%s: Error: no memory!",__FUNCTION__); diff --git a/patches/kdrivers/src/wanrouter/wanmain.o b/patches/kdrivers/src/wanrouter/wanmain.o index ac610ad31359c4e41fc4fbf83f1219386ede7ebe..ce3aa32c14275067bc410aa28043b26da02001a0 100644 GIT binary patch literal 242797 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

1_(p z`SN2#n+$f76uWtH|ZFb zw1|1-fcw+}YTyi{P}97R>VuJ`WqUV5&R)2IQ1?Emi>D`mb3jRI5#y=npweSRjHjMM z3R+@H2!x+g!U1BF8}NC>b&1zT0luJMkT}#8@FfL9#6jkLSwXkxfThIyih^Nc31(XF zs|vOdg>3;}Q!qlTq^c7NwiJ#kz}FRw6kaUu-jfPOiKnUg4F#jcPnfj5Zz|YEoSOvr zmVz;&Umw6z3bq$l4Fh~z!8kD;p5Z;MU`KI24e(u6{Z1lmBH(+9+gU^`2Yg>=^WsM@ zVmYQd?*~#CPc1X$OO(7HN@+9puqlSJ;XhVA2T&q4=7?E%kVW{iyFNI z0$=D0K?*+(UR*o4t@mqP+=$@G`;9V76E7mh@P4bz!qdFk1AeEtcmWSQ$oswG28d}D zfIlj(OEljF_>+QxBIrTDpA`%eEB6APR}hyrUdJZV`-?sh#)N;iA`iG7;HDWLtSDHvD?Y1xNf_hT#6fJx0CN`bql+lf)qExZYSU6>6Ugo z;in~>6Jjs3+sUn9q}@)<6l|qMHP41w&5aXmr?N0z+ns^P+Z$ns7Y2dRQWc_!?`i&J z3K}AC4WRE5wIx19K;dnrE(W_q2LzkmC6Rt?@g0 zDf}^*P*6z48oi zydg?&1tXzR%?l3$c575KnQ9UhbcxI9lHC;y5x0f`_E0cPI5`k{Di{$_)m`)UQYbQ_ zs)y$7tx$ACRWHrkN1>RAIpFnGC{C>8l-EzePU4pa!2Sw$6@SpJu2L{j>}m#hwSv9G zQUs^oBnA7S(0-bCfPzWFyB6Gm3MPw4Y}~wq6dWS%iw5-lR%W>P1%2&JQQQnsj6v%i ztl(%7g2>KmU+Cr!dd|{}A*#7^#ARCm(-a&pati>5DL6sAQVTd-c}uR?j#a`tLcvL5 zVF$o;B|JskyA^Pxf>X7q8cv}Z#xZnc%dz3Q<}K5-CvV(r2j1bGN0i3R2q!>YyW*97;KhNsOsn;Vd#8VFTo{x&tDDOhmjxMnp5v_NTf~va*DuqxPqEpl@!oHUFfN}DC<8SS z=K|c-Sh)!afDbC@5|6C|d`Q6%@mwO{!wQCp6D~#a=lL~*iWRg z3i}mI67QA+9#Ak@^q^G-6&xaF(kBinI6Ptw=FGziWypE)h(esF$JfHt9t=Ht>6stFeVxAaRm!R;xfQz6r3e)7J$zxSR!0q0H0H^T#Ta^ zKd)ew7PaJN;1`UZ@YwKg(X%Cp@%njBDz|-8xqv3#Vk^C+@>$|6TlkcME-?$yvG=rs zAtIIBcN7d0chVEzRS;(mg@ErX7%3*R?>PwiGKlqx`C1q&VRO{7u0qac4`w-xZ7&4_ycNhk|XyikkrcR4_(7I|uMD zRl)XJR5%CM1>+C4#51jQ?T!FWR+=ef)pe5-I8T~Ja&|Wqw8Sl3+)VRs$#sdg%>XS0 zgTw}|gboEm#FeaifP!uzJb+FG!^E^vfG!1Fh&x#IKm{YjIa$y1tY}u91cB|sz`f|@1?lWTGX@L2KF`&p_js|qjl{(!klH^BvZzh1C*R5mcqrn z0~NGnxH(86m-x^HX0n1Ia$ZeQC`>Hx2n-SsgaFm=5vIWD~Px94hNj8pe5Qo2w0(DfbiZ1SgD{(Z0Q78rC^ZQ z!8%nd7$Q2bhvq5h7Wv%(=PMW{jy3?+DA+>0$t84wf)V07`rkqYTZ*@L0xnW8QXHUF zixrF#YjXf=6^s_Uxv+Z`Y$IB6^{rDdMy#9<{jB3ic9TdjYRk zu#f0E67U8E`$ZJsVx0Fz>*2x-UPf( z;Scc4VYc*og)dlQ7$@Od6u#SGkF(q4I75Dic$|KGyK*(WclW`bz;`HD#Cvz;K)hS! zf6HNy#ElC7g7@;WJ2oqPOMvET2Se$q@(R6%BRh8zB(|E@!iB?kgPC^|4-K}N;_7K& z>`)ceBC-+d-K&Nhe&>We@O=uoBC;_F?NkUqL}imapfZMu+a>}&s9a!%_&oC+ychijcR6aVL08WW=C_tcNByggY(9FrU?z<%kdSDFr&na zXL0jqi{4L6(ile6vKv2Du&2o9;5(z#%);;AA;$Gi&JR7bsI`N@|IAFM+E?)P78=3j z{lXMi&|S_oT6co${+A|2cx;QO10ogmTRTv{GPfYze?fbl2dtM_-D`UE#&T})w4{4^ zIVQs>i=jgIq6)0z7B{VtKR$wt(H2+L?v<5&v4UIN>qI_5hi_vsVvO8H3))(YnIdmt z%o1bqfUvu#suZiX#RI|ao}wx&*%o)2k@s*^##%gXiu|4vMV!SbTWi^}gRY%KtGi6^ zkEYrDoZYW3Py+suG+KS{zG8Y`=&io*x+s_7_F;R@1VBoU24!0-&Yf)#A#& zfDQ$d1b?6B4N!1^IJ5)Mso+36c5x{<2<0w7AgN%oXk859AZ67M`!qOM!Qo==B5*?# z%n+-&0}WMqM~nL9fNtv*L~lG5;t%J%%@iyUdp&?HRNg9)NuLf^KS!*=oy6V_)<@DY z7mER`Z6_&;1=11&*`HS`j3=e@8ojrR#cTBPN$J_6fa5KWZ~RKrA)dE@6D$r?oXI%E z!YhEgSv*a_n>p|{^#_0xtv4k9yhHpx8n}mSY}|_D5La~r?y2wvygfVvxR)w_Nr3n@ z54g9&%L25hBQYC!@3Gn=OZa?z zy>-8)>E0cf$2o-V_2tu|?%EE#)0zaC{tkEnR{u5*dl2Cb12`SE$7?$W=i|sEj1zBr z2jj)=1$fW5H`c+aSdQH|ha9_doON*UOw}HL9UVM`vB%sM4vsl{*mrU;8nMTER|m(s z*7D)by7n)I+`|3BSHO>P4x!+bi2P#AJ&!9mBO)&!#}En?MC4&reNv%W!d-%#hgJKP zh?Q3X9#ODVoMp)IloBo%C$0xPs$f+_DfAvwPF*8r=7agPGI)W!>C1auYBFPQ$IT?^ zU_Ybq9l9MiJ}YyZv3Kf129D1uj4Q`7a(vZdm;t=pmFYYKm$+p**8mK{6ZZP>e% zlS)5cA|kgbZzz1ou=go%DtuUNRNhkfh+%I{PRY7qC>i$NusI!`_{| zqwvdyJuSVf^x>r=%a)^bjKmH$n{p7hQrjF*ylI4OLl^x>r> zGB!S|@CSxCmJI&q3V&#b9k&9XQ}`o8+_o0@ONBo+#GM?9Un%^FA=>u>{#xNraV)$Z z_#1`K;NnCC@V5%%r6;#@R{BoivxbPh1^9bqFJ6N3SR(Kb3gaaxg&c@KDvXz)$bI-v zDnDL=vL*`rpA{c3K?%GL_`Je+35vY@@r%MsOfk(3{;vuzGesDuuHO`1rFNRXEB!Z` z;#wXF{$+8eWX9fPiVL%W|4|sn&9PjObcfAHn3J&z*i!ggQ}pFlHNe4T2Kg=d8&JKi1a^o;j#SVP`?Vd7>UzKm0_1%CIzs%1M~LKVVpgst`kcK^Eu=7Sn~Q%_9`jlUbouxA^k zFx#sqVS5n#*taV1eh2%0gU~i;hR|-WGtUo=dE|rq<%75xDJe-O#!qPCUzCjM>a*cL zv?G|LCc|1QziCN_k;q_${uMVC0axhXbAjSI&qwmYjYw)?g^l`35z>bchRh}h5B$RM zkYVw)5qK0DNMX!j*Izz|mj-|}AJi6S@pUz#v;sZ!_h#kA1zPAIGtngI$!0|Wf5yvh zweVtFE%cwR5XNnN@(HD(|ME#3j0kUVz$#5YFrF|>3;VONG}+p04wS}%3~NRm)AXzG z@$tHL2JvlJZJ;imfl0MN`l+v}19wQw01Q^p5^pU843R$);$4M{0|7%7#I=wo$#&}@ zP}u5ve7S0ceN!g>e+-x!c~d6fK?!kFCh5VLtwL%ea0AlKl9^}AM)2XFwJmk~2}^u7 z7nR~&(D)Aj2w%^v#{Czyt?aub@xLlVYvoK};kl~tT>U^#zru6%qY_$LOVUT(p=l?q z+Gt%y0JWDl{>F=&nc6n??K!yJZsr!iw(15;my8c;W0Y`+jMZz~D;OrS9)NJHZpYgZ z;=<*Caq6nNkgx%Sj{RjOj-(o-9+V4RG%YZDagBp0^YZc1}k zQI9#GHc@dCWxQS6UAN=yUUHSI?V(_A8E@D2RIrbn<7#^;*jI+%wY?SWC$C@C_EE6E zjK*vGDtMJRf_S^OpMqD5R+)hP6-*K#nC5G*QbrDtCvLULiaSv3yAj+J1qaCo5Y`UX z<%`Dgz()Dpid3Bsu8^<4<6YggL*$+B_??+9L@98Zy!+IQ#p~dD!Ix@>>$mpe%=;N$ zOpcYZc7(#`bn!7gI$hr-`FI^%R5Eae{<6e)9o$2hDQZXS-$;zt!6CHOYRBl#-qeTJ z!SMmq@GQC?f^1#X#{f^%k4e1D5bq&F?IdN-D%??udAD}5>=C^F50MO3#@cB*$1GMV zLttUnYNso_-Vn)4fb;Y#WO*A5kK!HjK12Mo3wV~oyKsG{3-C2c-)=+X-vB&Y@79O*?8BY7S->TFimd+=hNxcyT&m|v z%*bsL@Ej$NNbDpcm)bI&a}9oHh{&u8xLjdGVkl;jp!PapuGF_c_Ea`u`&;KQ^V^_5weu$~y>o?38LB zQ}`)|IOGL>T>n?p{Q; z3WkXZ7@4&T6^zh=ITG+V$IGxp#bd1c?#E=&!5kHer&iZtB$qXjnS`}`rjB7v0|;v% zQ)*%rLI}a)xsYKkq5!9+CIL|IB9#+V6V-loi7In1`JAx)_*^qX0?ef<*E_A~a?t*Mz5;sCIPq-p#@`4wbwEXYMZ zM7D@x-2`edhXvl;z=o39XdtrP$82;_IqvPwVchHMoa5xvWiR0)>t~?4n!%gKqjBWP zV_UrI30Uge2uIcid%jSS~tH0Gor8(B^_HV>16 zZ4`jV;X;XRrHO{|y>OkXgZbPyJ;a~94U{lG|IIJQ8qBZ0+m{b8+c!BIoo85s$mH|e6q7>*bEG7(TA;Kg(wOL+DnSVbVFK*)E2~(gRNQ*R|zX)`w3lk`El5 zIFseFBN)O?oJH4xugS*&PAs;0cq~W@@UF2@hA$t>R*r0s31fQ`talv?rx;oc| z0xcRXB@^XC^Cm8~OYh|@4+L-NT*>R_yk!bdy&|jGvE+x9W)PHCXB{4QSBb(9s9o5f`3CH+I*>ybS?D=<>ugr(OenHHF;&o9IWRk zsSjAeG+A}A%qzz%TNnc4!3#K#uloMD=OVj{d|p^~S5nwhi}v8TP`tbYWI0D+{mM?D zkyx*s=XU~i^Yv6=5m2Iy!kpL40P1d|2-zFiJ!}-|%-jrKuRmo8(J)~?Qm(+OabGhm zQtw@<0sOWvo_Lzw*BMt1`F_WGvs66p27yp^|5$kno+w|*k$n}T96UB%J_S7cYTNeV z@+siiNjA!G-kyMb18g+fxfmUhJ_P78M@>Dp;T>@h2EvS-SbH#g3d zKc(Wy|Eu**5aCQYatvUDo+_bBY{iVTa*bZ~F)a!aD-b5HT&qu$+%WMkj99r&ZzH)8 z;_d-}>y>b%=+P1I7Nsg0?|(rqd)&!)?8uddPhUox(ZDd4Y4iPA31qQAzpN_P2vCEo z$!ZE5psWBC!{RkX!=fg`;^9r$y^T7gdg(RSf(HIg_%A$efUd2`g4gUAW;fCf-(y-d z@n(#s?HH-g#;{-`?MIvK$j}EO2P2&ug8(yq%ZXT?0XRlyc^Ks)ZzSNj#@~eXLig_& zuTPVCBk}xmB>ZaazlzYJFbZDER}0h-umXAy#7RjhF7a>g@8lx5{c8FhUF&j8|Jw&; zgHLCl-ySHr{UhYLoKx=s8eA=TAGaw3eYG&E%Z3B7Li3O{8-W(7TJz) zEBUm`kIz62Ssw#6m`3V$jI`3u@j560%?Ih)<@H#j?|n)3!M!in$|**3HbXFT?<>l0 zw17_`_!(xVeybv-;Hp->&YByhX{%cQ4L&=o6amVr=;&l3mvcETIjp+8uS6lveV8j& zwH+%_m~#mZgI2}ZD8dL>^`$vn3&J;M+s-CtaI*SI|Z6#lQ%1~IoJP!@Vx`xpd zn=c(Z2F>D&mkqGOSgA|+$l9JP*2#~>ZUSonsG;vPz=+;#^?;MWe_&>fUKAx;bWv;7 zqRsf^nMIfX3O-x(hgF)ksEuv6ORkxVV%kw-Y)CWydU8=ayM|$M&0N&pmW*)n$9#)o zTc%J8Ml03HU6eiJ@YmV)euZfkEf9LNKq;7XE`TVgZ^SF32N7;D$y4uf^=i<>kp)Y5gP z&D86lKh)Iu%Gs15nOH?a9TKo6YjLPCI2~ebAf&$$Xzx#L763rrd%z*qVm6E>0o4esf=q#B^{z@Q|+&*Z7S3yZN%{vsR)9;jt2c?PW)!?RN zdNz{<4e=B{zyiK!+{BC2ZtF+Qsy>DPCz36b+#C*nSa8NV@DhO9(X&pAj?&1 z;HB2~1L_~hxH$DS%n?Y_#h-~y98e8srX;$h?D*HZAHr3#G zh~>_})L3omRA{DE&d$?9s!T4(X(feon0_1Dwb5fCYIR56&iL6d{;tHwsItZsX!?~> zvp!l&+76+9?V#sV+p`8#m1*WDENfsP&sIO-3#tdqL4r;^tgy0JGtcaYreTHnHJF`D z8CIBIqnYwr4`#dPq4G6sZ>ebW>8oKtoxEgXgq z|HduFiKOv`lR{mAvr~{@mH20T>CCA?I;WIh`S=58RikAm=7T|uv7{M4ICB;P=al11)5eP7$aEPqwQ|YIGSfnQ3h|ljshFu5kuJ9T z8sKrOGa+c>hk+;df@#@I;A2F&a)O0}sKBXsRm^u3X4_YIZKM|mIP|H)FpU?&yq z18v&tX-r_-~IG$&i`FW~HtU?LZ!To53aGa2a_UGRl`TEHVY1CZ1-&p!}j zO`iv##l|qFUrjxi!z8lb0_$C}NBFa|M}W;`Z53H#oH@&p&RK{rS<+@u0}iN?^0>Y| zLAkNcoQEm5%_nz)a>tdNHuX;^jYAh1uh`ANCU_p7IE;pIIz#%Gos_8pwwvW;*(_^; z?PhpYHp3Udo)1+8)dX;>CC6nwMZEX2S_|6{_P+pSl zm8@GIETCcdj2k)+jH_ML<#qsbB2$kGxF6s68>$WZ z2-K%BqJnlK-0LzGiHBvZn3C}=%|vf>&P3T0dceY`EE$WiC-&p>2Wo74*Ack`9}s}n zpOOs0BNkhz2zXk3C@}7oLJKS-W;kjbw^+t)z@B?Dbd41n2!$DJhG(suHNaDRgp9j@ z3T}iLgI`jI;1jetXC0uFB9`^Sw8co6p%zsIZOu7u*VFSgvU5Gp2Du0y=)J5Wae1i7mdwx75_7U^%HvA?pZRWek^bLgn#K)c)rbvww zpi%Rj2bW=^HTN~DH|5#Gxb*) zY7PO;l8y75#KxLgo^aT~7EPGh)n~vqxT?oo~59#r<046Z}JZYEZ*`SK*3xxxz zw7n{BA`NH&8@blu{iiP zUNkx7><6~{>1C7sbQ*ZNTz6kFx$b@qoW+B3<5g4M-nnLq?NzVIyQkZRz^Ue-K5X6Z zQRY81?M?I2*7dPu>((JtE?d{ALNj@uLw1JU9Wf$%<72#M=8OfN$UUErs2>f?d50_L ztN5DYqfTHHy_V`2Nh27Uz+iei2vi)5HsKsWr6ZMM&Jp(f;G@d<;R$4s^TQ`haDEV& z=Ah$h=wLWshx{w3<8w3TRvO2E#z)LQX{dn4GZFIih#ipS#?x?F(jx{^U3LSw^oS+& zh+wP9BR2SZ#BQHQjFC2Ivfp2YvbU%(RE=0|>c(tLY*&Ib-R^Vt_a7LS1;}Ri`83(* ze-q2GInCrrPof)Bt{j^)WS`q((Ia_f;Mx73C;NW`v5d3wWru$cJS(#pg+6MYKv|w$ zW9@<24}}-vW6Uz`f$1aI19J|3lfABx#Q z+o53>%U|HvK|W$r2W9^adG4#uu?wy>b6!O{=NP{p!$>m^lv4K+2=|Op8eZt3h^P1yp!+Fxg0hz|3T}+x;5JM{H^&Pg}^-i%TFo zm-3tKdF@WNdLBJE5*0J<@te~USySJfHXK0CX%G3jsT3M%_z`G3PK|qfbLdLNc?;Ap z$T{Sj?zkk8@&l<)nrcZJ{30^6!J$#eii`H9%l-DI%jMn_2L(SucKoXDz@d=MYQY2=&+p5h~9d`1=6nVI8Z{UC<9ZFEUN{WuwVzJPXa z7WoGaScG)H&7#~#l8oal&A8H^rA_Kbovm7d@sLAjOT0-F)aH};72@3vKYiMyQfB%C z8%X0Bht3R)0(_Z>KOlbg;!InaX>)rp1~_$QIOms%_zU8J7jJVrPe7*6!@>B)DNhub zDFSOAwgtvxUIiMJ59<_7b;lc&CiiSI6vI3D$WAGnyWG6A31Sfdro(8SJetg&RY z^)=N0Ks$cDXumXe8SVHz6O4cCjT>zkfX|=MYj3wNNIN>Bk!`zdJOo&3z6`?A_!$3Q ztob`?{&EW#PJ7Elt<&+zLrzckAt>-kY);_9Sts5XOSL=tE;A(vo z3FvqOIyi5=hWzhP$0j|8@t8J|bJhh=95Bb&qRW+cB4aTh(KmNZ@e$zUvh}l2_a#o_kT~=K$eXYfD={OIIWNvpA7OPjWZJ^l+&nwmz=QWCc~(c zlVQ~TTsj);T`moJ0-vr>XYa*U%e~lQV0)LlTJDtYAiuaA4k%yA_XOY&?-J-)Yf)!b z-F&3iSvOvX|JG#K!O?n|^Ato!6jf@*E!H^1T-ms@RR+entmy{plAw4zx0JcuZs=p0 z7J1K6WMbsI8m8XH+TCvXMZP|&jC{XDc@r4<{>=nK-)1e@W%ATw8}jaC{)hP^P_tgs zW@}Th_ZX6N)u(;-n>qdr*1=Jd^Ool%R|X2a+0^JJyk9wLms{bCD`ebXCje)+L?X_ zN>)u#!{jARalK^!znUU_D@2BB={xQJ_V7QzC)NK))&DQ3|6f=CzoY*D#Qq=WdEwJ= z8FB*7_72I*M&OY5);{P^ZMH<7ZVcJ90i30B z3}|ED&xc2ADWF8y?!!S>iNzxx&N+@(6pa=Je+`lu1-x{g#Qa^#Y~acHr3IQ1E*~@F zC6)_NxO{!rd0>0E3F%pjT4NdE9pgqzgLjP2i1sZjmq|~(4%qWK3_pz_bsk3i#^KP` z$oUFb^8`)DHxA^6W6L)NAET#H%HuxbEPUKSny2#&$iS(#kcO>~(cj2v1Dw+WUvr*; zhE*8E6FLL^i_#|aL1M(^IIS9t#6)fsjw9!1_!u~+kp~t&g1u2#0TtXRoPe7D*eJZC za{tFh!N-ytg`Fre>onUZ)yUZkoU;R8P|qIPfFk~*hsLPf z|ItG}maNgYC|CB7*4D0(=2-#FywI>7DsHC%bNxd=&wjAEX?p{#FUel!EaK5aFDQ`5 z4?c$9#_cPWX8`sgL+~*+IGc_ud_+I_R(bXn6UydN{to-9Ng=PAkeH57)0LAyw?52b4@hd|s_!2BuNI(@|WbG@+b2*%f^_dM~9m_d*X*uM~WfosK zo-xS7`cR%eWE}D+<;>%&j~qRe-9q_io%T4?JX@iPi_t!ixiK-WF^bLu&q5DR z@ewCn0A&#<6P%dJwn^{tyo8*b!aqc=^UPUhrFph6_159=fcqk57~r!BZKa>l1@wn6G>}#Pp8ip!s_l?lSKhd>%*nbLHy(Lp($ib6zip$=9rdoVN(NX4ZuR_!v!r4gKl z(@r_MCqk(l-6cq1wc|Px!=unxho=HM*qrNN%ucR;Z5=re0OxGt*E)RRo?U#CcZB?y z|KV$cKY@}_WOlaXmPwc0Wn5{oyN1Z{tczTWho-*;(UgpsG|Yj#;*r7q5ksNIn;f*U zcg#dX_2E1`)ZVGFq1qtgtAqLW(P5e_Cb+$C$sH!$;7Z^jsa=uL#vV_R?ZTH~8`KUT zBU8_z3s3P8r27s-HtD{FNT6BoLN0bzKQ_@Ay=Xhq^npm_#E1%3WWWPgDwW?$s@Q^2P6WW7OlssBdQL`(BG>PDI0M$|`a zEZ0ZK<;4NqM1jA-C!x0s22)7MMQ2~L{m#B-%d@YP5#{+>NV&sB)1y_@=BQ=HhntiGL1}Qc`J%O)&o1Au)TyH5`?WrJ2ZlQD)yK> z6}ygDUNm@2o{HTIJnroTWPDtnrhN`PZAA*O{nMomacIHYU=sasAe0udF%IiFPXOoa z!q=23pm^|^@C?u>$OFEhax4J-9_Dz)KgaE$aML1lcw~<33&_DO?-DxE^Lo=hyofh* zR6%I`2Cy=CLq`U0=77_&iFZ@}1wH2sO*sLjZ{U;h?M3JhApW^{=Tb+c<<;9TE&lSc z2z7a_#KnuejhyCM{BU4bsXy^bttuVUs?p#D)nU$nzWAw>TIVm-L#z4$9AnKkDHTJh zdP+U%FBPm+$>G8PQ=zkPtfqgy;B68Hbrn6{%2Bi-fv_UA5W^fmeHi>M*YaJ?rM7AS`ta z%%P6O(BzuuUuv+Hb;^(ut7M+{0OE^~%nF+&$vtJp-;pt^H}o0Hl&Tu4I_j?~RLhFn zA|>9Cs$QY0JygXF0W#XE*rHhr9|C2CQdLD&A+!D3B3#Sryi!WE0oh?bNmYMSRgRs} zR&|c54o`vLN~NltswViW5?a=k6;h&Ds>0h-wD@62X7T0&WVBU%OjW(ZKv|_!l~C2z zOH|z$BPI4pRX0)9TB;Hal5DFwO;yR@8P_RQXi3fWt-q=WEo=Nu?>^(*mftJYf9W8I`gI>-)l3RQJNGOPAVNw!rzPgSMKpxmrf z&7i7!e^qU?tluX~iCd(q0aR50&_^HFU`bOG66YE%`7WY%5?gKVqX zO;wv80A-z0l}%Lz{;FDNS-VT6#5}3$4R~~XHdT$^BgwX^`>4vO1!cWbHJYj(zC_hp z=2`DLDpfs2Rhy`4YoR3Dsy0*A#u`v=QK~Yi>Q8@F&9tm#w@QhSIjkVBL&kqaRmXYc zb&IOt2C5p@7nEC-s^L_XhCF_gT~@{lDKSB++DKKsk<7XhlP)saR>57htfR2R*r8Mn zp{fRdRhMg7FVPowxVB1FOQ>oIRW-LW+NxGj)dtRN_bOG%RP~;}D)e9yqr-b$-%3?8 zsOlxETESZ!?p0PTp{j;-PeC`nb}3bfROKx9t6-RxH4Ozoq7}&Yv>*Q)RjooF zfoxkfgQ_Nng7T13)s?Eo`m2Js|C}o&3ZyEXRt-in>tha+hmvP1^_=V1R+wb|;%V@st~8JxCcIFKk3}-;;|`K+t4anr z%Y$&scuc8+tKb=a{;Dwb1&2t92C3=>s+vPp*P~L%XseO~lB!E{!Ns-sEUM~qtt8v3VyNm4uDu79 zDzu8`y5C+~D9N@ewoKObZ1zJ+m5Zu=xkS}nRZ_xP$qHhZ ztHqzCs$XgBAyq+ECu`IeP!20q7F8u9Pvg{wnPJauQev!B#XRweNM_A(OR{YhZOGa~ z_c)?dfuOl=@K=Qi`6P~wAaS=;MTz)DRF&9Xl5JHo;}MYKk*e0_wZk%)mbecDU7z^9k0JKHn5kJh4ocXhHZs^RlLH4{9$hDn30GEFu_pK8f^b^z# zuo-S}<6HY}u=6T_Qwp5*0KBKb!hB7;X)JHQMxJq~_sx|`!Sqc4)e77)0AQX1jqU$cLTGtkImks#s_2`LFzu5XWj=)}3!Y5Y;FCIDDQwbuLiJ5l7A z2Z3PtkE~TQZQiewaLd-wBALx~GydC^NOd*Y<3RsVuebHxvk{ktu4sp`0)0=!0c77G zD^ODlt6N4GiPF-VRPd-gE3mthU zq+sv9nzpT@UEz5jBO=&#Mfn-Y`D_b)h+E$zYR}d&qr}TlWqEvD&c$3#leUw#qf$~3ct-`$13q-m5TIQ?u73hdU z+PD@#+D(D%zQ5dfz!?7Ei1_H;D$2^Ly5U@;u%xWKv~W&Ux1I?-yUq8^DK9QBj7K`5 zM?!h`Ufs$)Rr#|DE4$4us3@LSSW(%ncusyvbwOdblHxhlHQN8T8vNR=+nmCxZV3r2 zw4$uKs<1-y>Go8XHm2=zd>o0o4Em1A~Zby1Pc zDX%EYpI*e`p&-Ayq5>VIq~=S#m~iHm_Uof)=qXi1NpU3wnXA0I)Kf{_0Mu7lSy@(L zXDIi~qzR~IX{jwxkylkwsLU#_C@!1c1WQX7md#NtpGgJz9+YWkty)lCs2a+bWQk>! z#WmA?1e8=&T&gnos@=$i`2Wyo8+@ZinK!?(&}XSiLZGN}I=ZYnU)8uGzq-7@Q>9Ar zl)$s*c&gyNs;XrL)g?X?7F7DGGP^AAnnIt7*%gJV2j+WV(Gfl+P-wP&Lo<;Ud`d;YV9;8CTR7?dyI`Q3^Pv66z~ zN=^~5i&Dj9N(dKj%Bm|GN4(E`R;4hXtz_pZZyLCB$_mhZzL8thGzc!9W7rd%J&_+# z)g?2_{Njqj65DAZS5#6q-xjO1XB%W-s?axZ3gLs5Rnz^rg_v|2yQM(RDYBH}nX~dx zA6pxnk>kWKBkZs%1iwc+*y*Z#RmtiVtL8NSD!Q&a0T#YIKM z(%~WF$uFmU7%-fE%6*GoX?bNinh;~dW;Ssur2|7Ai*OUwmRGXA#S_IA6v{CI@p+|w z^9)xB2um-3(^OQKD<{GTt0=6hu27Yk<*6vJ2c0yqysSdWRW7KsJpw8)>eVWY0*lMl zn7nv7f>>!K`<3#ul-tx4Rj3r#>GDG9y>NP8PnCGe^Db&*9|JEe_)j_>fPN7j7a0&_ z;6m4fE%Z&BHf^;G^O4#Z%QV+j#321`XfD#LW%@^%URRM|S>^+HpuAx|+pGcU56W|q z-r20dyds8hZW7=&cW!*Uk!OpiS`PDt@+weHg)X&pbB%*)zh9UTBSC_3MT8Y#eo$I8 z6IqXGMPR-jl8f}il}nL+BP7?AIkG;!8>Ck_5{xuTpDisK34BM3jR4;f7-mE0Df4$N zH>Uf{^T>QpMLK97!(hwYEYqKc=Dt)t>VWy4maxiPm^;{Vns=5z51}ucRjqOLJnb4_ zxy_4UhVF8ZSDz%{>&A6WhK?iwr5e7wv>TVD!urO&H& z^)QdtY_x*RH|H-kLyJ)5BXu<3yel28ck6uCsngbw&)wxRpuXy zi+Y<25~@eyo+ zX}L1J5$UhAQ=49#HE93{&opz9@)SBb*nDT9i9Jj zl{?(*ynju6H*?xjG}a9ZNM7lzdJsCl3`Khy<^vTp<+~aQ);Vd)w>3?s{A5(Qx|zc^ znn|t(^O$$zUNpv@h3GA|%tqNVtmxZju3sy$pH6yNlZVXb&1bY-=7GB0SAK^Dzbued zUL8>7YL9Hkg4vnJs@TwngV`9zs@Tv!h7>{FJ*69^>i_P5SIzyWyCy$UOw` zQ!NMK?Zz&oKM!X2-dWXPZe83kv#{H`FSoktUB68lIn6cM3Ne?X=7#yt;-nD(^=7(R zmfr2^0h^HVi0sSPYZ?Z?37=X_v2#HU*8r@q=CJ)Yh~xcQnf@)b!F*KbfWNka?(=VG zZo7<4uGoQ~{4S?}>(mr58IXS zW`&wR)VfX~$E`-vLuSzade^M^GchCGzxb5pHXoFubElPHbQP{i7?-Ekz_tEa$=s_U$hK4s29@30;^terOX>qecHtda~9pAb(QO@iEy;D13q`Ha$ScU z=1@7pZ>_6xwR;!#U+}tE_v_5(f6gqvY2-5V_gdFRuw3oTwLzy~%HtJkH2J%^J%Tt# z-5314>pe8-^_6mp{3|4Pq}j|>gc;Uhem$4YewW*oYX%t|^q)a`XD*rogS$nQy%5wx z;ET|r5!JI?-Qovyb9Fo$zlp=*VL0c1&;6f=a@0LwxpI91hWQJo;Q%aRoG`eE>E?Es zUo96ugf_U=K>It@;M{3F@5^}6s-l~pV#2^8PexB2bD|QA4_D{_>noIScz-o}g=sK^F$Z6$Iy=dh`^Qg8oHYc`! zcT5L+O;^&a!U61q*A}D55X^_Jgn5M{NjU||8Wg$BOHJ?VMKYZDi{&14G*cD<~s}PXl1h(<-N~Ca%EdQ9sWdbe5 z?HcOFui{oB^zq3K106@Ajk05qraWX<80qeidW3gA*@d9v@~C`#2L98o!{lM}+A!bnNba{hx6lbjHd?v6`ycS>`2O-_gz?nXgzRE)p* zs1I#{?s}*VNuvVSNOuSb({UtUjFf+062%F3~Ips z8R`zJx8}PeQdKjCjB*ZJbN52UGTqTAcBnfNdNnOsmCfId z<4~LSqU;owO9O_o)zOv4jqb!@%#KFyI$Ww6<4#OL8a43g;BS%7{I3p_Lmko35i`tZ z&ldo)reXx!xS>4nwP;C1kfV zpKna^cYs&=WYswH@dkj`-p7-An#$yF?{K9{i^hk4{0SY$0?LH%pqP3~4sf3?{tS&{ z3jD^g@8j{;V7PEi9$gNe*JK}mp>^q;;TxO$p;W4!&%giCcWLf^^$u+_`jvnDUB?0J z{A}BlkD`Z0xOeFspQGHn^%VC$J5eZsG6NT2MfI3b0xt zvzAR|P_d5y^M{j$!A&DCA%lvmHI093kh1#-vuv7g^0tRay&;DUr)b}-&}kZ`W6qzH zMMGnOPf)GBf|Cae*hk9_6vw$pFy^5Df>hm05HRM5BzWpZheS5=*;N+!?wf!V7$8W1Ah9VlXlO&F zrX&RlO{G$Vf((^gRY|1P;~mbu_oU7p>Yj6lLZMN+)mC03K9SaTKm`Rl+CfS?C?ZY> zs1Nmtq9UdtG&q2OV@oUV|Np+V_Sv^mdCGhDSG(5Q`|M#2-~4^+TY~*mLxf5G8By?j zj!eTA*JN6FeB&dQU!C<`mNL-pN4ytjm>;n?8`bvZ{yK_F(;E~%OtdQh$DgM!<>)l< zKXUr*9QMx=51I8{mUs%|)0VHz`lXhy&-!JSZ_4`Rmglm5h2^7|8=Gx;S=KMLd~((= zv;0?CzufYwtY2ZdKkK_Ki3asOS6UjxMBUuM4RO%cueOx$`z<~jfA&fEq?;Bvo~fRQ zpZM?196!UsxV)X>Gg&1@C*IQ;t$*Z~&&IFEExdziBz~j8YiyN^@#puqIcUSfEWa`9 zyDYyY>z7!*D(jb8epk6}sXW57aHh%ozJqJD|GO!^H>(f+b=sS}gWg&EOjM^WekHG3 zyfd#_{90bM@SB~!ekZ5-rsMZfeOvr`eDX{S&_4HW4*P2P8(H6F`QEHwV)<#vh2v6hb8@_cvB{<;eq4c}kvqpt17wJh?wAUtVvsa&`U1%8T;k15r6u zf3afNDBpP?D&JCXv+^Bza(`65r`~4eHT4%OKa?jQh|25gFIL`|Cl5r$P+q?CvBt{V z^W+0j`Q<#hzp?VJJb550@6VHuHC8^HCm)E4dDmieto%iuJP?&n<;lkyE9ed0_7_ok zSe|^cvGRmG`Rk~BVV-=TvGUYBxj!mb=E(z%m8EPPQ1+Pv}eXgXp28; z%V%eOm*sP^eu<^I#<=HF%b(3UtR??^$L$<^-{PC1db@>p();d>H^!xDi?>GgRQ>ff zPJbpYwXJ(8r}?_JXEirjXF~kwe~$-STID70nMIat8b*ZC#ye6@#d_)h2p2PT3>FTe~!ZuwS0TlcUk^Q)-SRAOx7>8{HLs6W_j_$ z;@QhBAD8tjEKMKg40OL^CNo-WaUDN*h_$WAU#BhJ7dM`;_&`*rEv}7cPFVQ%4(R%L z-gvuN&GOfF9)Fo%e>+}t=Lae7kLq!Y>*F=VwB+AkbIDbww9(fb%xeABw?2!*k+OVt z)^}MxC+nA3J}>K+S{}*zWtOka`W2RM%KC20H)s7y%UI*wjIXeKdtTpd`RiG~((*UT zb<5w&`W2QREY~eRob@X$Kb7^XEWh{R(f%teUzhdWmT%1Zm6ku5^{Xu3lJ%=C@5}mL z%U{jKEBW;s;>J6Ffa1+reJjQL;>H##UdE+w ziCsMR8BI|oC ze<14zEq}0Fw^aZ4owX;n@ozZjoW&RLb7$23^-(+p@?OF(KHS0MFXERc#HE(Zu5oD; z58PqvzCWvJ8*^|*!K;Bi0WH>k#E z@}<7}@jKsd>br~M#ug&{#dXH=tM$g3v98lFbIzGCvvbL*c@l@PW_fwm zcUe9;>z7zwk@ZV0pO*E@EPo>FS6H6Q`fkg&X8lUbU(EVdmY+h>=37@-{&m(bx70So z^_Gm-uIF&jREzuhnF+HngBVvW{x+}H9{bFf$1~Fw-yPKxX0^*_PMCPij{&Lmn;ozm zaQ{onYxnRh$2FS*=4o;M7ENo#y{2r#{3bQ@=TGonM{b zf8Y?#EdMdz7!5HtUyK9(iQKgyjpee!1l>S--+^I_tYF@67s@mS3Iqt1K6? zezoO#)-SW%%=+b)U!V0WEMK1W-Im{;^(!s4FLq(nK0TUibkpJ;QEkOUe|>mdnzs1m zsI~;}Qck}(F5PMIjHphpQk==^D=2;`t98)7jMKdF_94~0@pf;tWu0l%u=%GP4z}f| zvcAjm;zz~xODrFm^-C=;$@*oMk1p3OHGJ}(R>Ak(W=^Bi7TykGK9=I~S*@-0#?OyS z)BfsvI>$@z!IqR2LYDDIqOY2nl+_!P?0gHD2Keg_#--`kQuuHObo})@;?nIF=c3v|(GPI?mblbTmT&**xYT~(Rh<4zTxz@M zT|P{c{HVFmI>Tfe-pb(sSiUXmyDWbp>z7!*BkPx1zB}ueS^ho;_Lh65th_%@?wzvo z$9ZyY%F2iGF%)Sy{@H`=+dH=gHfqto%ft+%sk6r}E_9DJy2L zindw#OrG2`WuW^d2;WRm0gc1EwJ*) zJh^wu%4726o+&GjufJG%TArMnvhv0C7b|8~j-FaMP=B#()r zd2(*b%ER*Hz9}n@%#*iGS-Ct<-Z5q6sd>Wg$W(Uc$-Prnz9di1OBC1kAQ@uo-(|J?>(9ld)?woV z?~6;fTYLzVKzROp3UPp{snh-g2USz0eKm7J)s#@CdZKFa)~Me88x*H#5?A{aXR>Nx zLpvRFZ=5%cB{Vq!XO%;UuX6CokjVn>peI zZ>RFkdh$sspROm5pa*s?Zre@8F2%`FDh_v?{3aC#JWgIzx*8{k=*1C^IC&wJo9oF5 zDhU!ar*={pcse}*B<$Y5$*P_E=B(BmS7_nab8zEFDL$UnK5e+0gR8Hl_>ruBg5s~T z`WV{w_?VI7uV)tC#KFCvr1*4JFQZjYUD&)W%Vv z`Wjy7Oz(uR`lgT5olj?%p2nNLG++803eyGh^&v%eaQcU-nkta1AEC&;PQS4I)Nw!c z{n`Hd{s(yXpT_%dua{(K4k`^2b3_}ef=71gPUrSt)cF6zjXAcrTfCX0gD?InF!1tc zGknheg~wo)iCD?WScay20|z3@^>pNh=*;aG=+_)K{S*h7v1EB)JapW`e05&7Gz}fY zWl^wh>Fa1m!KtM>BroRHoTF16?5n?;v2ZckcYD1gMR{jjy7NO6<_x57HSgSoyZI~a zGsk`OQ~#1@q*JD=z7(SKI@lR8t%gN%PkF^p?-zs7iWF9<<(ig(sEzcud=)@>sMQTMb`IP>aOQK z2Q62!eu?EM>z7*U&gY)XEQ{y=Qp;E7^-C;Ym3376{OeOJaxncC-x<{t{2zZpz?g%# zKFo3}>$@!fUDhwL{9_K7)%{WVV4ghCSoxDY`B+pQ$dkWlteD}AXFeH~a&mw9Zo=Mw z;11el@$sm(?fO;3`el}{ zdVD;4x#jm{{R+$flJ(t|KbrL`EuVz(k8fRWX^4n(Q9EQ?p3FV;$Ks3l0j^ko{dz7v zE-u~iM2e?mwf<@vyPMz7+T;tBDdD=f_k$2+0f`R8}8=3w+KcJXt^ z*zd0|j$fzE`}Ufwn$YcSS^WgXXR})0-Wf3;H!~cg?&Ck0RUiL@tWF-kee!qBp4X10UnH~c_ncKwzg>RhtPe-xLdYwur-zYte7f6qM2=626#=Y`*E$uz7;GE%eAy7)ed3k+f z#kZG5-tGbB)y4j}$7;2i`FYkxjv9BvXm5&zaI8I^Ss69%e=+%?zdc~9%RA0*UM%Bd z;aMy}WZk!0MC|N9+_A9LV+r(lb#8UoxFN&^ZgB-&dyo4+@al+8FXs^H=17Da+bf!p-tz;AyY|G&XPC%=a@MF5~RE?zs86ofn(m(ue!M8p%OH^>AqAu4 zu>8^ zH!H-Ka6k?kprZZjUcb3>y?d{5Z1t~u{p&i{Yedcske(Zp{KO+)%P=i-ta6;03|aFk z>fg)p%N)9>jV;h)UH_heH}lIm_HkU#QU5;I>+isS_)8q`;?SR1|3262hj2#Sz;P?b zG>6`=n>p&Aey`u<_&tvIcdolH)8BFYFOJW2uD=?Y>@^%ez@Zze{(Y|3b*H?N<24-a z%v1lgLH{d`FXhmUf3MFyhj(Z+KFV>d^S+0=ei!$A4M(3t)38=#?ZNf$ zbN#(Or$P9o9N)y@rWEz>p|1Zh(t&!P+Piw(2Pi*W)VtrO{B;gBSoMC@eRb#!4)xHx zDeIr+ga4c3eH_2fQU6RI{|1g<;ZVU-@B4X<`gi$bQ=2-4WT-k-|Gcg)Rj=RlxV%p- z??w(azGrjXdnqyvyP3akL6H1yo#g#y^xA>p&H58){B(t37Z_>%%M=OuJ8>U_3xki-Dh6O z@lK9E>O8j}De`&_C0cVN*S~+sb>-vwr-1ZJ9KXt8Cf)k?P}gg=U4=P?v-+1zyEii? zam*~a7#g#E^cL8AYsgynAwpHNv^t#cx!j&y4Gr07PB(L--kjM}*2uvy9L&K}=X>kp zStOW+@o=#0d4ID<(u-!i&7JG(1B5hI#jmc9;un68=aV(UK6yF$AGS%uU>=xed1kvu z8kCtHJ7O=wpw>>0Z#j92bQ8cpVT-r>*J=^BbSYm-rV{i?%#Lt+We_EyM7uOU}nByE&j?3EixI-YNu1Iv+t3D zV40Vko?D+A&&4EW{~*tKueY)>9QLRUXOJnkmsVF#H#6hq-s;RUonBot zp9ybg@AuORF&imtk*=pPQ%!FT*@Sc_k@jLhA_Mah^wyTnk~U?&M`9GR9Gux8K}K)h zlq}8qw(={DXA&0|5kVGu{k0riCWbT`GoyYpOV*?{&k%Q3Mt*8;dFJlk!f?#n%rVnb zS|KG&w$4ErkDAfx-e_e$W}gHXlju5gi$449_*ezVHx`dNk^z!|K}Z#TCdJvn{!rXI(!6DN;OAHC5j z8iwfIEU(Q~2w7GZZ#EZ3%c~n~8^;7O?Ck^<@qPS~-ZH75#{JP2lD?xRa45n9bE^vr zF-r-UO9{grIHKvj@oLW=IAe25gTRXUW^2^jUK?!p!I$M3MZxg~LrW{|Mu@}}6xSAg z!`fm)zMhqhWg9R{#-(Wb=rj|Id|w8cPsH$Uk;0_k8*MN!F`w*$6tl#Lfln)|7aacp zN{|<*7smSQp%^U;H%3dedj=$&+ZX`m8?!+AxWC-YYz})%eG;RL$=SdPYCv)_C5?JpOM|(k-o{9BAlVuXUea&Q_&*&GAxYHI%&x6dSz8-I zE!O+`3qUZFe4>?%jEK`c}YEdRb|Xle5VK zX9lEM>Gykpdb6-MHZnv|pJgszmK!MsL>nk<0(G7AOaKBE6idbsVDrr(k6a*7kT|w&}_vd?jLRxR@ne!D=O=T;Y zruDO6%bB_O*m6S704$i99rgoB&n}CkUCpaiLcat7+&Pog?vCuQ&^~j570w=_Se{RzV=!ByJr)eB-Eh^tK!7xRjQXR13h|ggGGwn6@Wj zb2LII;Wf~K6`*XrKi8Mn%17XFK7-uElt9^~M*+dn*4jA0(@8Z|&?uX;|Mb#JKtI?& z+2tU;(lioWF*_r=(qEgA3ONouxK1h|2wrd2fk@eGVJ1FO=&ES8j$q(`g9GsG4Xhk+ zjzn7WT`kF3d$arY_eMZEJqURM(L?f9aRBzUGy~L}xcTVO~>E`B-zyU}a#34$sf5!Jl3bR6ooe4~2V6Of@)`+&PovRj8un5+ca1v;hq6$%eyn zb%5-E*%6+F;43DskJf>J<@Eq4pd?5z5@v4;q+i`?R>XB~p58vv9}bTM=`!0O?PrE& zNK)tg#_*dtOqvo5%@cYob}B;!vbCwjVs4mbJ{{yKD35P#%-7d&8M121wB~M-k&zZo zI`h!X9YWmU?3=x1IGdBY-!78&3R(l#qUjK%BHV$T5I=t5#ag$5mnw{rCMz1&5t?=y z_8w$@q_xZA4ad*-2)v?yaF~r4Jzh0Bu)n#ZzdpN)9jhpQ5>RCJnDWs+|Jy$io?2Rlxs+Q%FED)? z)Fbgy=?9r$elSxZW+NbmJwdh$B-GEWY$$}tAh9qfg;G+}5*t_}nG&dT1O%rGh{op| zm}dm&L|xvh@CsT&+~n}urAJ#aNuh@*8#T0($8gb&ymt_JKlWONgp zl6uf6?Y`qV1v#;d3~WeF%pKC?N(z&X3N&1~JXt;uR@1b7ww<%v6p%iKc&-nn-FNU1 zNO%JoMf>Xo4cGb9>c$Ag3OY2i)r+jCid(bDJG9|6H3%!8iA0V)GBDDhK(;0T3B(-_ zi~J!^MIvMHksj=bSXB+eHfV0UIeNp98PU}NAZnN=O%qW{u{VoC1W#+SF}LQ)kB&>Y~1fOHxElz}P$@v8CC08Jv~b-ubB zl7;iy(&Ozh(%P_DBjasvZp~pD^6LmihQU!84tZg1L-1=*Pm<*a6(6hw^&<^rxmr}N zVpovNtnnHp;oe4w#L`~+3@*dMd&?-8KyDfcm>4)je>=qL)chS}$Q0sul63?hc2rwT z6j+-Z^q_ajx~MskgE;TfGl96mi&ICBo=Mq!)Ha2>FE4{HOBlh)0V)jrMH6x!phKEV z5T5|6PBEvYx6w-~zgIOt27#<3tL;UO&^a#|LW9$&yLcvPPY`Vw6!T?dm0mE8?$!FG# z&`q$P-puA=2+PdG##$0$gq#`FhX<)&abNJy@h0*gsER$M$Iy}-SCd720_HkA9irH1 zFbnXBZBY3B93URN4{SV7&R$XFhJ2Tscgpqx>m&8nRwN2XD z6>S&@ZqXt>h|mbQ1+X{k%TA;WqDv}T%&T%7vjR9m7e~FNQ1#PvqZJSS98wKUM{sa- zPD4rpER)*6(nI!HUft|7t*fYe@-p~KYD3-O*@(=zA*iNexG>TRkrph;P4C$8W8gC~ zkn--rU|}`jFWHM0CjbMwx3Rp^EU)(#&*+?8aiEb}1y6<65UvWC3*}1CW`$D zFe`|wP?jWZATP6|p&?cIRzQKYk81PLA68SYQ;kSEHoqe3BG?DjAm6YS(jGQhAW*@- zhs^?7S=gyuM;WV##K_yNlG9VXg6glBW*mD4a}-@>a-lhin~@TU%IF~GJ%xTaDw5Om^by8ju}5lJ zhCp!>bcU5fp2IB0rxhO%H)IgrK;L{qRKv9*#-e7sHKd+%95p$9$IsjHRPNY;) zgEG#7mgp0Z*~-vu%-Y2GFt;|GPstc~T-|CREoF`2jIx;Mv27!pGmO2o9~{!oTqeJ| zbE`ReV)kQVQ(9SAmuG2!+$2^4LmJH?zj-R+HaL_h%p(GPg(t{eh@)xWpMX1)w2m=( zn|I8wHsdXTh_@kKn3c8{`M}cz*24J=IePKFpN%0>7pwwOGuSFZs{%{vrlB{*TVMsN zbISmzU>4GUSI6aAN0ZZ9yVBoc+~egDZ?RJ{YmH0xM5tA#ghipGq_Ka}!<`R?tO{_| zAPqZ!I5!islY|*A(@sa+ZU^hIBA5n%k4d0Dq>6@_`Za_JTyF*k4qZ=H^cnQ_qL)L| zCcLFy9IS0hEc}6yEF#e6a*XL*2u%Ta<7VT!Fe@Jd6P8ys1FvDv0a-DpAW{!j4$t4c zfm|aSVY)*U0Z+XHL4F-^i*eED66U0E!k}YrKygq$t}m47yx0S6i6pC+!>Sni*rXMK z{+$i)&N#h0L6DFoXNqj2?KPY=0JW+DpJ@i8c_<7fxp|E{J-BX2ph|e$RoE+1`DT&n z*t5OBsB?2Q_CY8Ruz)TAl@kY=rGUJ!c~3s1h8nsUx8RQ) zf(PjM=sxS{K8b7EIuJ0iu}5!J0xG3dhCL|J()ki7o@@?fd$u{9SlAlqQxMT2tTh}q zw*i%Q25Iz~@xk~Bd~=7s|r%q2Y$P;-xf?iO#Q{ZLI*((nyndkhOk>#Mu@ z=;0H%Mlf4PG@PntP`?u=dPi=%_12?DP9D4UCRhiu*y?x;R?0pE;y~K@^=*~-V1FTg zq8}D9m~P0N!%8YfE-rwPk_j6uMq}(0kka>eJ`>YlFj!e)r+tAM zuK;8S{g^M&)84XRhM@$%2oz?xzM*uO8sWUIo{pzD*e|<0M4K>o&Omd=qvQQ`NH4y@ zISjc&pbRpm&0!OXh3}+4RXV}-d5Anh1{xk;4PzOp>$S$SO@n&c;{M*^0bOp~;6%wf zce=)l5~;*P@A^tPpe|<&{MvA1kpQ_I?}$4KmK1g#cncGUD7px&weGh%mQalP!b);d zwPnu;&AUKoB9M;42_XQPLOmY{o6x^v2MKAv;_1$ryMS3Ce0(J7*Lh@UT(r3r7bQ8E z;uuSR3+gDtM&KE3LM&plh{8$epYj->L$^vJ9dtB9T`Y6@B`4dtM1QJK*T8+|pv$oO zYP~_vAkd(>s}ro(BJbwD-T)?wPGh5jD(XWStX+qVW&6-|sqfGV2cZy6EO@Q|qiP+& zb3!Uo-dRcHMDEmu1NR6_Q<29LnHC3kufd#XyrYyrd&Zo4LCS#9r8y)3TwCR##gv`9b^*C4&Y6;lM3!5P4a^+(g7`Vv`w6 z^LP%?@EIV)k|3Isds?Pd1;?Ms1ICb{MU* z4zoU}I)Xh7nCa}IXAE+`kI=TTh>o{L=mmbM@LI%eDZXuY<+m+u4fANrx7>E)shf}X zPMkb^@@Vg-+oXJ{gKFjjIwj;VF9kLD1-89)oDfWk;<%=ZI?e*~M70B(6=i0zgKjy( z!KWTV8Hn#_F$FB6AppRq<&U-tYBJ(kp z>Ins@(FKGO!ALL9%pKMblhGhMc_}(K6L=cM7X1x9fVXG}*6P+EvZVk5U+s>ufS?_8 z2}0bA>1^oSYAk8cX`QaXAu%CmB#X>eikgKz;ft9?$JEjwHA)5$7CxP=JuFP3DyGer zzoDuiuQiwu=KvcJ9!+Kh$pT0a?Eu7pka$rLW@I3=Np_zjbU^tAYZR{p{g6@gz7gj{ zv{{Tsj+}b3u>^r>VSYz4Dk6$1AO~n!Y)fbmf{2#CFhZugFC1-Mg4Oi|h2A@A=$auM z&RdE-@C9~zN}Ct&TZu1#h)i2>6o#tA$%TQVb)hQk|X4FaWP0 zsPbmSwMB3TlC_NXJ{swqM)wFZ3m;NXUIhy)U{cj##_J+-iu!Q|xIa&ntNWQ`(E!_JFtO8H7tfs}g$O@@1C%um?d67gd4w7eR>l*}NA>xZ$!_5f6<2hu9Baf}f#XM_nlYQVPSK;l*6Cp4X8 zfSU|S1quiA78E9cWV4-aNB1 z4-6s$@g1m;8wR?m9u(OK#l=L?F!gBvL8c1jN;wG|Pi%9?t;#JEKDm=zR4UGt2cW0* zK0u&qhVrmJ3Nv{ ztZjq-kTFk5v#7_xgN*vq2$mi3n^@X|C&c)4`p`1b)iIiHlQ`ZxOK5i*FKZhiWk7HE z9ds{-@0UO#-9TygfXB}di`#LqzKkMV+%4m43%;anMhGpTQA%id>l4G$ILbJ{laO|3 zODh*nnk$DIEgASLU2ZbaCtI5EuaaB>)rrO<+7u7@fOgWln3T2Cp#sKSRb;9HJ9w1< zft|lFXLvfc1`vesO3)goA+DX!n!>#?0YRpX-T?b^5XWV8hcc4wetJPDv9BiVgF`h& zy`tmsJB}d3rBPTAxLs+!#W;OAe1te7Ln;?g>;rouKsRY@sA1Uwp|!PfJS5{-cHl#h zGTyZjRJ%yx0upKEVDl-8AxCJgn`uLz zO9+)Ai!pzzvn;ZR1q`yplt7aR)2AT7)svgdgx*wR0-}nh4Exu{NB6=Up+DE_6?UAA zS>?azWBPAm5b%c&Qp$umupuzZH1vQmuJFOwM-_K5lrQXw%Iqui8t?pM@T|!y*?Fcu z0yzjql;+1o65AP;wq!?mp(D<@@;AJ)xLGlGXvl0K63)wz>v?fdwSENlhRd-oPSEd& zwek7WM~@akgw~`Yg3oBZ?|!*h`UPetDQChxM(H6_*7|XRdx5bJ7l*3|@u|HqZq7)T3Kp%=pyj}W_-)**E@5~yb~RlnGaK8Rcqx#+ zYA{cR^kTn+yM)fN({^*l*bs!1?OyR`D5y-d;MNlsc+hW79J}c*P-(HZ|6p(5_4?!t zu$KTB!xgIn&W{clZ7_O<>&$|MgtSNnWM-kT=IYxWbSflotuv*7R|Tes1Lh) za1-c}dzeadP{Hk&jux7q>X_;=#(>tfNiE{;F}o=JVp-og_z1Serk@dy!IT#UEN%&A zh%BvU=yWS)p>#ocL(&}%HWIYafCS9cfe>~jAH?M9{SSwC@&OetdP}6gM7suL2N;D| zg|%(w^yv+RIlde+v7=m6hFI4Sabei9Qw*E*Fjc;mhxr(8gwrtdCLs9eHZnO<%Tc}3 z8anuSzPa(1!@U!yjvP69;)MR%)Y&j^K}=OSpx!tx6Z(sRoi9UHFbKeSnR%E8nurm{ z8JSufGla*|eHUs=#KlJ572^=&U!pc3@s;Q5eSt$&t1qC*b6Q^Esz};K@2LX8VwEY= z3&4o`VTeu;!3-}#*K(ap$iv1&ha=G4Re=(~zQiEKU=u=u(OA1&)jSlhmXz2`3sNRf~YY?@nh1A8U`kvn6y!s&O@PvizyRP>v&`8N9){SL+W1nDS za4QfNZ>ED!BU0ypM}zk1t4wvFh~$F_FNGQ6x@VM8u~Hu=}(M%xfNef92N9VRHUD&FGGqAt5t6K#4vfexA1qV;<(DM=+vY(w7oy zNH;cjj1aE@7r3m>Dq0*OgT7V4e5pTV?hGWL6)}c&m-R9oKCGdB;3h%=d5C%rQ3dzk1iBEkgXnLAJM=T@hECEWZUbt>tJuCUc zcFce>QjFo5YOG>O6BY`r!ZWi3Ml#+&dQACF+uLooqUQn`uBc^QUu6;8EW*bFL_xwB zay`xxCaHu-h-57K+$jbatl_A2SE@1W5wN9WW8WJ}X)pMPk2OgbD zdPLB(7?UT$;HKHB>20HnC!2Q7a0W(MNuku>TpaR22I08dt9X|ebr=MCoELh|Mhd z>nEo%-fPSy<{RwlI#3{3L8CU-10yF=O2nY0OnlmvNSfn76)aqXWvuEr24bABIfJ(I zxFUi&ghr~3yN2nupnD!`hBg6LaIBTp5XFLkW!&=Vq`Dc`reK3m0ChdaEkM)@-(!=U|%tnB|I~J zW1aN!0)WYTLx!x{ugkRvFETzrBfj)G2y!avfsxp#4EwG8I_+xx@zQveWi1h0f=I6_ zH0n82AR`yIXZ(2Q7ZngiA0~R(X3R&u^p1p1trmH&ktwFE zjAH8Wcpv^GLvf*qz{6nM-0Fg57XC=`f>gN1-SK(RC= zH5T=Q@U@^IM4$nE!}W$l0&iCOJsk`zHDobT`Ejs<-OP2!a0FcP<=Zvhr$ihFGzRrb zCtr~#da9~me>gEJt_GABX9-c*2Brg;v=veu#8aHaWNWm3iE}Rw8Cz-~nM8gWhtK?Q zhIs$-DkzHD83F)&&PYEbT1?`ByY{o#b!cQULj^mN8X)Eo%}3aT6Hb`z`r=-hA+k_( zD}5vmg>JH>B=hhB1rj|50dX}ZxGW-3*1@&Ha=GRCy&?J3vwe`XB2i06!#Cx5#0WLO zsL_w8UGsxQ#$PjN$?;GKHA^spVJo|bp~g>zu&3##;7<}gCbSc%SB)FWIZXvuA ztq}`!G1+Vfjq5tWl(&MkafiifM*j1iHdE1 zb@3ywD~+}Tz0*>#^Q)}^L9J$CL$ADMa2yjXbCHW?s2J29N{&-be&d)UiEm@D0_4Z5 zr&(TxsX{%=h)ob+8*3JlPRbfuN^<;q2d+oJj&PD-b|9%C!-n#Ol&^X=nahxjWE+EA zjpiz!`PBi~?RuqH@T{F$C4mS}eBrYULnbl_imNazx|km##mZz}nHoXH8=&{N_Is(_gRu?i60a2uBc&^@e1BWLJBBY2! zILzWuGAJyxz7sGAu#@T}KuC2iQ76pr5FP?2(8w6fB#TDa7;`$y*v6v$!pb{hWDumzfU8A%{)}cTWhacCr*195m4seG z=eAbYG1riHW=8H+AiN>*9o#B8T0K%K zuepRZmv#zsDwZ3hf$}4=RaZ7uH9lUnKVVN;Vk5lnNXkHIXkGd@P_kXAnesx><+mA~qHJk13#YbhUjW1b zfj?jU#+VlbJO`atlB=bfq1QE@#dR{t}F63t%0RM z%+n?$K&bcz5Q6xqL)8lCXG$bWp>G)jP@EO=FEd?DOn{n!WolSo(I`p-Tl3j8!4=a4 zSJ1Me&B#a`2Q+#BRmn5V>c^`0=u>hLJ4EG4)Rfnj45$+Q| z24B!rr*4$}c3Av$UEg4D3c%E-AELeRifUS)BV`$qtT8cASpXjdr395zQky{_1;4@! z0(gM4EOWx}WGI!Sy~x;!`IDe_=x!(j;18r3umF1}+K@DLvZO^3b$vCK;T8K_ctzF> zsWBCRAx3g1S-SiswTC5Svk<^-LM#{wa+tgism*s5=whI{@@gR$?ex{Dhx|?8Fd2f$ z+CoY-??A{jA>w3!NZM6nyp+fbmy5N9L_G8tkVBhx`G^v%lQr?vnq*)wbDr_B756~% zm0qs-#hQg&0Enx=Xof>r;nkvLNAL^Up+?k0X(M`xIFcJW`2q-k%TaeERg^;POzvis zNC<~Q)WkbV1}qcfBs?oGL(JCnRBQ4VN3=nL>w}Sr>W&{dW?WRPpJ3_>k5^zZ=bU6W zq1KN{{fm)2?6#1E2hE0v(1LMMBQ@Ts-wzgrP$>Z{Khp9lNQQ22D!a%?0D`iFg_uU| zbxFM^+&6~;0T}9UbZFI%kOiO>Olf#OvbUsGK-qK^81Z*yDR+P%J(p3nGP%M{>zs)O zY3(hhIAl@hdvRr1N%BnZO!Cb_YS5BYc1j#jhb&D1vPI=?tm?`(J_%wflglVWnCA}* zx+)Oa)r#PnGbXy4-3a?3SQ1nq_Ijg4!E)5{m2neTHm_S_* z%GfU<$>=MJ5TlUz)bUwhtX182w?w>jk%^elr+=nflN;-cz|EwtG21nuJVjl;mht5U z!U^S%^&(Ztj@9?1K!f7s`ZRe(+USo|bJG7Tbz5iPRQh~b+UM8cHT2`bR{B#B_<%Pc^MbXI&DkcyJl2XcN8I|BaK zK>l#hTZmk&+mFA^QMdlKOnV&Gh zOgv1k=SvqAJWWJ|j#fn(9E3A7g>YlQMRM5s4=}5#KCYgQbTthe2O&`>@3C8ZnALBZ z*3paVW^x`EV9k?(uJTz)1t?W`YLt+dIpM{6hdN_=2*A!2%O&q5c#`g_{|9G%|tC3kKGKG$KqT$Y{i~ z5TCqkVoHM(AF&>m}D|(*`Rf?dP}y>8mf{_Wo167>ru1P-y-g) zW)z#FG&&IlosMB>&cwo1ts(>!fW?B(&e(*=+LMk3cpUZ?7X#=6z>H?_Y<;z6s<|b& zU^rIIc!v*D=?A+=k`dG)5*(0=79W-lbJIsvlbZ6&{(S&bn|q;^C4zhIWO}aQ=biM8 znD=}kBynOXynu*1vC29+5uG-PQc&{p1#R%;`6#qGH`oM(rH^tBVmvS}V5?BZM4dAw z3h<@n&^2bl9t1}LaeS~)n$}HMG@W8-*6KxUds^FKaFg2oxg?|4?Dzmed!p6%hRiC_g{bE1gJrMu`BaM*-dD81I}yox-*N zk|E^!^w2!F2C$Jm?~*2r|EQmG4ZVW3D_rc|JdC1IE=Z!`Q6Ewc=a&d64-B!Ln#j}b6f zhKcLI_e$t<5_YvOM7)t-6X`PBTjZuwSW*Y27e)Es$L=aTxToDtliNYC(f;yI2 ztWuNi^)^V17%<9whV#k*v%`9^tlUs5M}qv+`8TN;bAX(HniI*rz+ED44!1PWo10P`InfCsb-{-9Xe|s`U7xB1isJfsH#mc&2^U``bCH&&AP5oBj%&dv z(7@tIWF7J=9LqJh%(O-Xh>FgUIiaYSyo0Jjs!c%_K(G=ywK4J~VMglF8AGVaa4?&Z z2M`**9ymZi8Qe;`NBidoQA=|`NSdj}mAo>QIMeGk3Jb9!lj=*Wm&j3R{K3NBy~JD? zOT!RwWZZzVDeE)LryJ}^QxTFGJu?EL63sv}1Ps!^B7p%r(Z9r3tfxf40nJF=;ki?K zaZze9+k!L3HdhTY(lckwOUr-C3X+{Zked}m)%RG!t05sYgeq03iJ*%zw2(^1@#J>z z#8=(Q;F>o*qj?!BCr00yGdc)`m@65w+`_C83GH@4ii=?Y!~&YU((V7`g z$R|QBb6yN>vb2)~)ScXaotg*yH=LOfRkO0CU8rRBP*iqOz)qu!p#UzJ2=LCRMr3PK z{?L$kLoyFQ19N;gF;+S+LO~-ZTx3;lHil#qY|Mhq3kIqChvBw_)@5*pdLatoZKtM> z9Hny0ZFgW06(k~fLCF?$RW2O?*Nm*e9_wukeh8%9^f3<#Ja?5XHdPHa$d6&L!BMAO zkKrOjrjTZMKYWxmjU9--Yf%Mx!gpkdydhQ0Fj#3=Oi#o-p%H{t#4FTdrTW02g)=B4 zzy{Dsy__j;bKpG+oz+?8#be_HpTLPkWnh+o{+9e1{Dwg6%UdMnXLW6o3Q9;mHTgT1em^?37 zPc)DGYb_It^&}G>iQlfQ^A#>;Aa${@Dgx~s9!W}M;4mmNJ8bJEHg;T$QA3aPH4|Dr zL6=~&MJSpG@p4jriOiSC;YE92DK5u!i#Ru}7jgy>Jvg5En$o06*OSb4q%Sxmh=^0T zdY;eYpc8>2Ad^o>tZANJ0T@7u8^tz%0R{oQR33!QSCWfT?1F}vSJu^*n9zxZhWO(# z@yA73K$Yqw+U&3^u#S*kw7fE)PFgIQD0&OPX)qzOHQI?b;K{1pBtM`(OLUZ=K$N&# zVl^@gf=zJEEE7M=E)E-!zbKZYL*X>^8}vc=u#`-Vyp?|nJMU6nzFTBOKG(V$!rQWg zVjaHmM(CAs5dy` zApDBO!t^BOIS9ro9FI+C6g4I-33SZyWG;;Ql19pKF&jXo%yp556QXeXEcO7{!VAc) z7*<_T7AavO*^SCF>pZa5CK#55oe>${swlCd3B;-H@KB&KVTRIa*lIJ-f{ul=vVcOH z^j_xV2QaOI0GYAT85)hQ59%Z#PgiYe$I8%b?U3zQpj?qWTz9FJ%-ju+(tZsQR|^X> zv2x175W#LVL!5#UGAxfAy`)PhN*=-%Ms$N!pQSd~Sma^AT||$_#|ea+!_qnk6KIUP zu^z^FAlhxL=k5{#ziDoaVJn|ewr8gddtSJtOG%I!&3x02PU&+n?SSOm5~i#@h(JWx z35*LSZ3eOsKVAL}V~R9lMkr@HGQFSsonY#AWj^MCGW)KK%oQjnGXF=fP5l`0_^EuT zQdR2#uI#k9z&KH<<}kAu^pG|-M6pWhiIwM`-4WKzyHl57X5J8|m7@uRmw?21LZVR6 z4~1DT!dqzu>(yGmVIHHFc_o2~C=>vS1?wuu5debhI3UW!Kv={_;LweW#u?IO9{1|k zm(3LUVWN<>9I9hU5v0oJCLMPkq(~iUfJEcz85YR56CcCYK*n3mv#~%*kcQp>_i1@3 zl^g1nBeim)9#(I4Vq>iQRT;=N5LQy;2D@I$bhD439CHH zIU23FjK(Ftz!y-K>@SV*(39ZPtk(@DB(EyrL}l^Vq8?MGStdGv1BT9 z*TsS|G@h8AJ|wh8y5o?bia6CMA*+EIkCnQpGpH(?eh5s`T$uPFbeZVZss@1?t^<^% z|4KR=jM0oK;${)JT3qRj4+MbJNk#L<&oFUMt25d32p;V`NL9H$~3un2i8U8=u}EMWBROu3>!^aVAF7UL;8`V1hOgBrGc`V*KELZyj&$h5Ud zBa9+Z8*GHVA+fFuI9V1XzZcNhc2ZpBOoRQ*)RwN;3>Jun$1jfkc&XTT0&%8ei>iFV$<BwuFvcl z$@&>KLorJ}UztEjjnghpQ}54h8{m>AMhMFa9Y^UwCj|@#3*j{j@dhXkZ=3|x7#Aoj zA`Y_2I+;%h0uQONGKe;2qSzTE9pTSOlDrX15kv5crOh+5bMr(^9bK8f0a7VC2qpNQ zgQBZcpH_5jGW>nwj)VL%1={B_86pVg^i|EfIKz7E3P5bk3IPo*x7W84JT+DtO8UfU zNmj6r+?^qUYj*Iu3pfYUO(l!&={1P-c`*sCY$t(_4LFKDN0lcvmjbmj;f;sMkiK4O zkw}Y`p)ahOdqKWz)m9?K#fFx2E7Dh7_c5o9moW;MT>$1M4G6Wgd*JW zgs26N3*9C{fdbl>B6gpBj}*AwfpXYqX94jKdET}4DL^FfmKg7aEp{}67tuS!DrJB+ z^~%1Tr~AP#iFAX$8j%6UP{lw=2t#=-X;VseyCB}8Ey+FjK;}|ut%|lul_l6F>fgbR zo%;NE#O25m2TvmT>xc~13hXJYw^7`6w;3HxF<3{A96NdPf^?m+2$M__*T}RVc~}tJ z9Dlng47Lsp1^G50FO=s1Wyq~`1_e1ZPf}JZSfkXV^0)#mU0LB(DanNaGTa7;0su=I zfT&?R!iYzdFO<3yc2pp+Yez0dQ0N?_5}UIhClx|By2JLit~F@xK)iS1@b z&tmxvZBKPSxdD#))l{s5eTBA0s^0Umt`lTBee-Q6LM$qwGOPIgzi3d++l6fL9NfFV#FS14rKkU2Jhg@Ga}gqWQS zHU??DUpn60eE9ec;bhHprtF@I-2>@_^c^put?AIAwV~wj9>T0N!jXuQxGTPD`e;lX6GTJkwdP)L=bXaS#>PPM0~uX z>ZW4^F|reH5JeEqcEz$?46l$Ci54?9oXr@4$ofUBUFZk~T-9*xXd-q~$jn)z0G$0` zFzFCskEl?@o#7J8+eY^dm(Y;O@Dfoo1`)*QCFZ2Jl4u&%0_*G6tD_zkf?iPvg`74E z&w;(Y{nvt&L2YxUf_<1GEHy#QQZmVCuxn2Hi~3j@2^8Alvd|c=vw2MaF!m6k5mF*P zn<OiL~)I(ZuqC3?hm z;{pYBE%hO#$^|FsDl{OAv+~4}m^v+<9U3E`bTn#Bo{S?l3q`iFAS5h9B4Y-g6xDt_ zgJKK8N}EQ&Dzg!eAPh<2c}U$A*5O{Q4WcZ(4~*RDvjc9BE2iNYvZSO+I{DhH{UyA9 z9#hcb2x$;+YJxfxd*S%$@d;)3*h{2Ewn-FSyE@)P<{@PXeiDSR2tL@BU-eq80z0(m zT*XsNt*h*XVQWR15S+8$=T*}c3!k?bz68`3=(q=i$4yM!l*_^3#7_Ns@ zl?E~nKIiKGp>>8@`~k`j2x4P{WnStm@UM4eit(s>#Y448pt7pcc+H#V86 zZl7l5z_a%G-+uo)z+FKPB81T)RFcIYOmqsPO8hG#pX4-5N=c6L2~cypNESkLQcao^ zLQ)u=Fgrp2hEf|q6TD6t-pu>j zAjH5nisd*AX04u>RGf8xd1x%r^2L8q3_kDh0epVG}g>Cy1 zASZh?pxNZsX+?N9m_h;<$SWhFjcIyFg)jjy0#-8^V#pVvdhUD9$j0hhwt|geC{MHv z0v|B;RR>jOM99TRDRCEiRW?{l-MC#|W~zzQikNp^A2xo3DbcqyyuNk7?nd7l%_!yTno;f%8OW}j2fw$e&LiVN(~kTiE8PsmOH{cOm_>1 zm(-XL`03_nMtm1COg(4C-gYf>25RFyA^3&!Z35Ui}>MkF&r73 z5^o4=I3qb(X*8J%+qN^fyp?PZVW>QxO3R}d(AZsFDevTMQmWpq)3@|y`>2oo-U;i$ ziz0z@S|dWlk6i_V83!){$G)*6;YsgWQeZz4SeYUwAcanKxY!vvctkgHIYgv1J}4-mi|aXW7sWy@lxRj!I7}jZ zZz7jgb~Bk?m?g=*jY~p&!*}5x!lC9wNM2u^J{%}`dm(#Bl(TeD{}98;QvKCsDU;e6 zGJh&JM&YRtrP!7_myu2(Q`z*8^Mk)>%bJA+DfkC{B59C%L`1r5j7sR!WW*S#3-rK^ z3~5ntA~2bTrc_YSqZJL558Vr?t^_kX>DmS>5$V138qx!kchLdPQKCk+z?}JY@-D=( zjiqgXPNqwZMv1cMa_n@m6XP|#e+V~$BK8m(NTP^ehf6ly(V8u2}VB+&rg zToZ~S$X9c;Kh677oA2lUS~Ju#sV%Y^G11&|j89Mj=5ce<~TKBZlc| zjdL|_tZN602$?E7O;xB37^4FMSfQNtCvYL>sSC6MPZ}^5AbH42#n~f=N*j6PnFVlp zX$bbBMe%9@(k3rLaf3g)pd_8HG1!p+Bna+=cP9olsBg4f-a#l9o1xf>1-K0)51xk-iDYCleJBe(;50=aJkZUX4S3ZX-N2a4jQN zXJR=d5^315?A%TXlRgs9cWCeaefxS_&{xP!TI^CTR_>@K-Y{!mRCoA`{WF#2QEwAx zT$)G~V*PzMC_9DUpieTT2Wo&cgIjCgJ2=TgjUy4VXXA4>7J#~o~f+TmbN-i9; zDR0KoI5ily*DYdXQ7~%ykaz(c9LW-qwiT9t}fdu{F$jwW1^q4>R7##Za>TvivdL$JafFY742L^8KFax_L^@sp*41z!CWq~b#hOQY$1p*X=e~GA zGv3RDJTiE)7~FX5L}z!thjujXk0pA@VyF$s%A=ZBdmTLlFL`{lAe`c*{c19gF(3y{ zVdFy$D|@**ur)f1K}E|$G{hI_Lv0Rq$yi}79kXK@8}L>4SfpP|Dvn(xWS!}whi@bW z_-(hI>=ErkNb*g+lRMdJapQ_mVO9u5H5ug${u&}zNi+DQ$35#jaU;>;@mBPp{3#Dhf=c$v1yZbLc&;Kz8aDU zwANwLHizFDovf_hRj�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 literal 225492 zcmdqKd3aPs_BUSl_D#}BFV)#dR}w-<2S}3y5(tDPKp-q(Patfv1_A`x0_h+KDv$(e z1Bil(g36|%qN3vhE<+Fyb=+6RWn^4|pyG~>W8TlHst$49?|gsH`|pqEu~VNqr%s(Z zb?Ve|>t3%LGHR${7%cS9U^aFcG4|04Q1ziS>;rRMVl7%AEZjtd-Z<8LP|ztlSXF%WbSZ;c1F#*t!vF<~G*96$o!w z|2U|+E?&10ptfH!ep%o;RIs`^o2p_VF#=(JO7 zscQPylIK3P_OQxgO=j-T!HZL8z!-1;y#54ojX>PE$~{QP_8q>6MqV+c$se*)N=Wbc z;2UQz`~hP%);M9Tcxnx#HBLP~A^7g3;Hin@pZOYPYcCY9?I$bab$!r@!808gWd2eZ z$C{gYAhvQah<`a>`D&=fCjZlKAbt2!C_`E$N%B4OBbof?5M}Ze=e|Pv)Zp|2{Gq>v z997^i31z2P8$yLvTl}dk#Lwnw=~?4tyXu>RGwf3*A4adTK%YsKrHY!YsD~|N2WL2I zPdMwp4kS&eoT%!}s1Ma5O+GaBlUE6G{Y170ThI*Q!8-~U;IU9z0n<5&9CQ~<0 zk(x}Ze{14V>gMsm7lLmG=Knk>%ba)gVsp)Oc*koPAn3ePH6;yOs5ddJ+`$im7n|RN zzE<#5Q?K#OE3C@LLv2?6Nj7f`aH-cR>BVGVt!U`aCDeX=!lc~hiNP0O2753reeKHr zjMq(qu-vcf-+~WVNU}in)2aA#_)w(o5-4;$&^fp92!)5>CqF#c5SM=BcZ`+b>EOrO zP*fOH7UfpW5p)(Z~#9?Dhr3FTA!282MvU8EBAY)Qj- zd+=hzsC4V>({cy}Px1O)D7krqJycCYtPC7QR&bEjFy3mg1tPl?5F2U!w<_n*(E-hBRzBi>zFVX!hWFGJWt=Z9zHcO{RcV+Zr)U3llq9*hJb*HlVfhcXAqcm(`c$k&f z?FSv^pN&5aYtk)r0J4v4#E=SpAT`kX@Om0_L|oTv(!kNM_A;BgtbYLDB4A81B6 zexSXM(BtPF{kEBmULDdO<~~PZ09BHHR~ow9Oz3lx*HJ7vwU%Nf{Zo3MK~MMD+P%IzV8WAJ#$5(swZnlTYK6#kC!9MMo!fY{?y%tyi86tk{B^=lwS z<-OBNfSm-)oPO>o%GX}&TpUO{9FI!0Eo9@h1hc8b&Th<_ZZ@)~G2)D}Yb z+OxI-+luho)z*rd)Kf((NoR_*r-}lUY`&FRfpK!K5q}$s0`-l&PWI&Ll^C%%BeNg- z(O@gmLse7LFR=(YuK<1cyMN?Yvk`&h@N~B#7hySDjIwpAf+zrV7Q_m)79e7<10!d{* z*yLP$=t`sD>^r|g^H}8nmm>d$w8}wL z#pWAnsXVE2T8J#m-}w_738y~S5j_9zvz(sWc>P0=ttPelmw4UXK)G+7i^Csfj)_Rs z{#DOJ!vX$dCX$no{gjnXGZL?xN#$GSBD}oCwO^e{AfynD)V0eT}DojHmG%5WH zw$p3lngnv$wV`&?7~TiYrtS@k((P*6I*D0WTN&f0{e;SUL)_YKRETDX>66dxf#im= zbUS8AJAZQh9kB4aQ=Oqj$)pKX(aBIz^d*^J%B?+t4GXp??Iuhjp6^3Ekn163C@L32 zu%3+?u-e|V>_1ZehdoKuZ(;0wyll)_}3`nPVl zo~#py()OPdr-yWcevE5bvhPy735k3sG3!bB4+59%T zv1uAy8m`gYG#&}iS_Ww8o(PhVD9&9Ve(1!u5`E9k;ZzWfb`WCs9 zWC#8aXE4oSq^mHx&6FipwJ$+W$@rz9zRI>A7!hrVRus z4rdOY3cm5fgTeEZr#j-pKv-_$$Qn;DknWW&n}=8!XJQ|gE<18k?px!J&|s{+P!>EM z{7RPpbls!j9@s9y)G>_tYS{v_bx!~CC+br1qtap z4Xaff8+ssz+;6BA{7v%*q8gr*PW5xmS?xOYKg-PruO~llS)5`XN@%XO)ByVFvVP8{ zMY57pwQ^gDBByHQmRhE0n@ay=ZF?w%&?-GO5G~C(Zi(w*h-I3-=1ShYUN6`I22 zP6WFRxWvSH>wXQlkLOQ)hh6$;fc$lVq4>k>y#5eMHaG0XuNsfdMJ0V}cL7#MA2H)F z)ssrPS&HKY_R3+(JhufuwGZybZ-k=M7L`P_6dpi@vDp95!n&Rp3XQc5G7ik!LoulK zd2?RS+?|Q!#zAI-)F}9U@Zzyg?emVEwMV`&FE}vlFv)8Y<0dM*W&lc4Ne{#%jByKw z|MIVEP4)7w)w35Y>3UW9lI2Tl0&|!D7ta5GX8(V+deXo#CBsXGWCRxbQ-?2sb>@}N znVUMkrmAY`@<8h7r4==c=KgP%F`^Am_&B43JJw-yC%G9jIdeFM$1-M%XPumsz(i=X zI~@HTjD=AiW8pZFjwMn=dp10_D+qS*xD`)iJcz^<6$T<>jy53marBi!odEU_aK(a? zictn*ZdVJf7miCfpe{$y(@{!`cHs}<7%Chp8he@7;cz*e4&sQrEbnq=d_t>YZAchn z39+cD02+I>LSafFp{0hY8WXiV4U<|Fz+{x%A{L-+D=~m68d5U>+Yu{TO_czqUao|( z_S#mcg0VDBk%sdrt5SaY|(65>^v}J zYK?S1WVIBAz---UsYDmq68M6$PuEt0Atndq>}1B=9#V;JL=N$G*G08y^DslO9xV(g z-BVX2o1RaTYcFY2ZKmE-K4h~#trSMlzFlMkNh$K!RH$7L*5XUp&;zu1VE-28un_YA z%`B@f)XWkLq}gOpO9_Z4;YE3^1M2Ue(u4t|J za4Dw{^r@|y2RQArEvWA4RHf7pmYC53pzO>p+UB87o243aS-*0UJUlkfNhX=ys;Lk) zr&Ut`E2vkLnsdnrRQ0?lRY6!Zl%Fq^rygr@lFAUBu?19|Y<6W73KRdrKift(7kVse zD>*_oT-=IJ`l_@dBrVZ)z%V0ambT)91|hC0k{0T|W!jQd1T`(c3EVZiFV8$gTAvO?7Omb{ zuR)HJavb*-A?eyq#M2;JVU8|nSd5#BI)1qt$(Tops48)c0cT9CB&K8Y786e;9UC_w znIMy6?ncrp8C;1-3QC&RPbA}xVki~vcw-jwQ%I`g7OK6SOdde;5aGy6a8#ZQ>S z4_kP`rItO=1dodz=-GYPokPf>xyW&kqMXApm0@>u#4{I@q?e^bp4F5LfGaxoGfH;D(Lr=Pb&q2X6pn6l zEhT?gf@DIFl7E?mq<1GJ_v2_SI{ELE`~Vh?Zu>bUzeaaQw;u}ku`jGe%S}fadMw&U z%Wp^5{Ya)qP)*INknBxy!qLt`auBS_9Ou^{IqWbcf0~M9DJ={goi`&n@ij^op>@%V z2U4*t^kwwYxs?1D%pJWd(F$4axfMXbE_AyF=G{Sf(BHgkOxw#*qBm<;@oq~QEr?Y$Q07;`U?)f0iQKS-n9@Y+_am;lR9dKv>7Exp7@f#DS3W#5;{ap3$6U$J*}%Hck6*CzDe&Ymi-_0smGNr?&|-xq^Umn^ zF-sJh#xKMIEu~&JeY5z(-0Y`(Py3m=9WXdvp)=jsSu>xVK{nAgz_=g8}%tjFB& zjl2v6EH_*u&#!>p4bRBytbo%E$H>c6z~hErw%tLAl)fy|do*3avz zKq?tEFGqoNzP*&Oyl$#ch8s?h*Ij`ua)P`(#g`+kk=H|!^4#e4yq*g5qF&F-S9}Es zo77&{%m~Jw^J55%w)2a3V!aZnxEcQi6Yc0Ig)IIlET6|I0Dxfe(%RLGa2)uR&?8q5!8 z03|6@%!hOaN>*qTe}Yh3g-TfXQkaZ9O8SWnhI|N4eFZWNyj&&qWuuVefT zgrQtXH+>eztiW>JYCPCwZ{>Ovih`&{Nb%5o7XB_$l+ga~D0MT|JCkHOCM6@;MJAuF zM6#=_$@(27TqEsR&0_qd_U<% zFIry1@<({$Dc8$lW<#9SYnZ!geg*3_>T`_f%qnO_h!M%!`LL3Pz z2red$L-?_e^192}C@)1|im$U<(iV%^5J?Pz5A1*enD`W|NyGZ)Q9wxwnXx+vB~x+B z?nMJ)=VrEKSaHaRs}9kPSb`N*i$WP@G-XtUpy8qNH&SJ7r9jI`^zs!bpfU^xWn6|) z1S?vokp$cdh`F|6snI6DSk|^EzIHOWr;y)~xn`6BU2%lU z!poLo7;KwL(F~o;t9k=XQz(+3+XXb8B%$MZKX~W1847v$@FJj@yCf}+AI|`qrI435 z%m6A^D4C~V1+ZNs$tG47s*WLJC^}fyed%!+Cnav@bc}np0I9(Y%eiVk+spC z`|>OHV+;GQg}taOMng4&pA7%BNuSuy)cK+6!4w^*cNyk&+NE=V$c0pY&} zFx zrpq7?vH3O`VjMEi@rEHDM6YIc(fA!h*xkAxy4{)JDo?`P|G{i|Pb~6VW)205G z46!cbHW0mCJl_nA~G&83g^%Cz+ z6Q7blmFxEIPZO>?f#>S-2huQX_R=u4C-)Pv-7R>ux#3Fs$7L3K{&nY@mJ$nY=6osJ}us{vN`C zyYMGSp`hY{boW4o!uX8MK!X$tcQ2n;!`wv*MexISfi_qnJ3o3a&=7?p`77`P_fUnR z_&cdU!xVDxJHmlVp%ChG@{Jhg?s3!*T30L?3pD;IiE{X@bwFjOBr4={cK}VGax}F0 zdm{iRDOhLlx9$dYhrLwE4Cgd;-FNdpb=!Hs5xGzY_~M zL%~}OUcL@+rh+>R{yKclU9R9A246;^W-GYM;Imc(&Qb6#gP()LxGNOgjrArqg*GR8 zh7YI4kRc@IEd2e}cmVV6j>ahg2H95A{kgb}`mmpIGER1BVs%vxx=lJG=50Xc9-vXO z*qILAff}YJV(sW2s!@6(7Mbp08f7G6vFCoU0nl!m>8 zNuD!W!vb;t5Wq1S778a($7(n@anAB?=x7a#1*6^!!BJub87>4%#IWlD#~U}xw$2i@ z2n6nl#=C$v-x*8Lir+m+%Ch-Bw?q~KrF*i*XDt!4xfQ-(iAF^H7Wzd?G>}_Q(ShPe zOB}3hg)doRE?mVu&7djL=KI|e6|;b+Yx!%##N8FZGj;j8F!3q+)LpLW8^eUP6u3g; zO<~NH9fLJm8^)^Km)vu%s$lM4pGOglOm{V*-xRXk0Yd*$$nKs;{r0;;PWL=4`rZFl z$m5>3bSZQHp->zUXw3?F#VMTlxS2tfn!aSw_I5zSP}D^%ydUxjNUw`!Nppcc?kL1d zs?TB2Mj5IlF0TM|YG`Lk4@y3_ktp@zS|Cf5ig`4&5~XI*8rlJ&T8xHHmV8u7i8R`f z8f~a<)^;X_+(krTX1XmSQ5q=BpkYI5NDGB)XeLS%MQBL1K}oxY;nAcc)<5E53~qP4 zuGK3#Vy1Jq(J)yVD8Zm=O<$_mejlh_V=17`hk1G(IioPHQ`m;}KT<6gYsbQg(t-!D z@Ecp>1eUT1jyl87*cx}TZcbZWw{A{~hL&nhI}Kqi>Vi}aoyxTBHS{RcrfC?bOzYE7 zcYAtEw_lA1rS1*}ZBMR_BA&$5+rqpwarxrQs7icA!zUzZnV`+1 zyQ4vkq&3(yj1qSzt;I@AUs(w0?I=vWi@1+2?QEnTssT@?LGdj0;(nyF4Dy52V*`=S zHpqV1|DXshiltwg5JU$8;Z4YW6l9&7WW{4%bjO;B)pO@Fcbqw%>cGs{{()-9iZ_Yh z)f-H8-LUMAkC#i+_%@USHh$)2#zM$K9kiH8nTDU9ogg>LId0@$``TiUNx94x#8O`6teTa82H;06>{>mXzKPPHJUxp zit^)&q|oR#+o4_B`LW>nda<)2fOLPJ0(uTeUM#`npn-G3=ZoldGLVPWPOu8sC3nrHuYeDL zFS@$iBRLD1mz4SkM4buGs~5Bj@qcFXSCAMcE?~a$e{NG!E%8q*F#KQGrlk_qF6hX~ z|D}yQ5epTu6cd#HD-AuO8g1~OvuSO`l|=ncL$8?7vlUDh>*1{})Kn1()A_%*eLa&T zr^Bt8{|DQQazYu2%LB~+qwSM96q(*J#or3Sd&xEccCh)*nqsL9*k;i_4=ZL)z-nP7nCKVXTQNZvr})q$kX zAxpdq#r%V;gR=-fZi%nR?TR!$Y>C_U0T0nleAW_Ms0W8yZw?~0NrK5dDYCIb(b`+3;Y5}U177)!By z^qqf%^c2C@r--QwVPgORS;(Ewe_;{@ouYo}m#C!Uw{{uKHH^V3?RPyA?hZ zmN=ivPp~G-@{fm!5!7EHd^k*$?QVsi4HI{CX@wiZL=mvYzZs z`n?z?wvs(U_>C}eD6ADe9VR}+#M?qY6PEsT5%A>8E_^mj^t>BcQ>v}@6YoX>PuD@=Qkd8YU-8ehX!Bw7{Te2o-UVEtN71HmK>@x6 zZw(hGXjIO(Dxe8AMByTqM%hB$g*(CpUBdG((s)<6=!d@dFSTg%g5^^XOm-tzSIFEMvS6UxS+~^PmSls)swhl^l zPB_F5{-CqS#(tuG0`E8 z>;qnF{UGc6(IGx523}{WQ;$myF@{FSdh1t7|J@1&_29=XveGO&8`2lWWv

A}05@2N5NNRdbc(ju18tWy-+AhA#4MyCkSe00?6D)9-Y;8@@Jk6C>se$gpD=?;9{8Yb~8PBA_P_@uV) z8&0t$9ry)nw4}e|6nD-7e#xSB2u_Kdq8uTk1)qUEFnzb+vrYl`xr{G5g=-@4->gzJ z%jUb}6p06bU)A!qy2RU9gZW?6c!x_+NBLjZ5oNba{IL@FpVkzq&wiIUa~JRzp@{4f z9Vp^{Y0Z`NLoV?_58$&FP5g++uEgbYYB0B3c^KF>-(i>VkiUFmEtC9>E)hwS&PD4g ziBGshOg->VR+;RN7hPB((c-9s75;cT#^{)(BZfTIhkpaKQtkZUZCD6Ls)Yp(bgqQB z)F|SO`C4+g`4bSG%3C;|?*Qm|55!J0FqYW(G9!k(!)h1DkHSjr;z=}?G|ce~Y|$>& z05PVI9Z0m~*pBRWIX>c`7F%I4{72{)7NgcOBm@2#7Bd7yM`8qH-8U0o%x(Cw zr={|Q_E<-@*Sbkf)6z&8IuLgpLNHD9EeCWxho7o2RFGD!$^=^4^NAZ=HG7HcJN(?g z8U361JfmP@{ZGh2C0fYZkjqWifHD*3e!y!LB?R32WW*ERtC-?N=h>Sb_USU zIg*yjuS3sf40{o(Vui*RAe>|rE0n_@zYb`)LcMqe77H08#xvr?ZKb~q2UxA+%m26nm!^KviPqX%C^3o#4_Girl2dP9x-JgAxY`Dc6hXZw? zlBO@5&%+9Ae^-Sf`2CxKa!$grsP0bFfpSSMZ2@W!3HEnW-IdJiZUvH;C9r4b8xRHd z=cyXfc&~myJrpM%oQ?yMcPY?8EIb?HTGVzh*Dl}^2W}hgAIW=l2kR*HoP_afRsfAw z$lx!=0*z6~VRcMSjFy4{W5+(=IQmzTf)eMfq>N;iR)MV>>3PLUjGy~ zMkD($m4n~J#$5|^gsg@2J3>h8HaO$@XH-TCok-{3iHv7M?j0Tpom-3xms|;a-5$97 zo^CulnXx_HF|tTBccC};W#G) z%Ej@rVxWRIWjQa4q#{NXDS$9fb^A!9yk-^3y@7I%w&c=QD~ezgjWBhk%Ct@*Ba);V zG8@8n1GwHq>x(czHtlUApZ)Dk_*S=OF8p_|7eiCF<_KE4H&G!wAA|t1H|c$pr6ctZ zGk}s+H+cB+E&FEb^+8$(R%UwNY9Mkl2*VEVeIYokCmv9 zpWX-5S)swa5?;GEQ=wu`Hx%|}&6S*^_)bjkd%J9ssDzsffx4<1%D5X#ue~{{++_a4 zJfK`fo5n|F0(HAjmYc;_76bKsNumnwCC*-FB&y_pA=E$IPi8Uu#`)xz^LkE>CJ`JO& z;$ad<(aHl2DjrcZJ3q7+NXKa>kH<_@@u-U0F5U)SUGdl+S^t$MPL#lh`BDZip5CTQl`gJSo?S)Ez!Rk5^C zv92A#n7#@kN#%@EpbpnbWM@8l=B_%0Qc=~&5BbC~WVk3JaSK*1S#eTq_JEMslaaX6 zUU(X-tWfyR9;m}Vr^A};K_rou3nO5O?4s{sD~i-B3xEc9MZCj$&Rt!>vWN7QAUU=G zZjwEeqPCo6Qe%%JqGS(K8JJ~KW7{H7Wf!ZAwv_P+VpaBVm641LcnKNQw8$Q&Me3VY z1AbjsLepy@uPm!SPl2Q4&!^)snt?X22dX5`qn5;Au;(vO$j)CF2(-AK#2{vWp9Zv) z?%7bgYVQTAQk-%8WFgSr8`4`Y#Kj4QP z!0M8~Yq0w0;+>XCN@Cc&jLsaG{0DIrq01{#d)&Zec_2QpWj}IYFPMC)DHeYnJJo^d z#7%2WdoQ34%2-b3DBcCwb_@}%GW`0g@uOUpQgS+%E*qMmNjKMCkjknt90qoi%jki6 z9nO?^y$;7#=%F%*@3{)>F7im8~P7m-zQZYmJ6hsfCQWiO~cQ2B+PQklk_UvVR1J$scvdEpc!iBQQG;%_7&#sxr zvICESC?~Y@!$GZ4)VgREP6XyFKxJfLq-oo8E5uNe*G#GUd3fw znTiKjcb3TFBjKIdYf2eOJvqi3rLucO32GUQLRbw$n}l*ze`0?9-2J`MNKOQ zz_dt7S3Q!~pewSf`|wHEchZ8&>~h{>|V*L zhZ82(4Sx;^YP&iJaG6+z-wV^mRWFh|yXwVcHmcxTjECwa3Rye?omjn8A-nXP>Z*|Y zx_U!M#O=6WRbB0_np4H915^tMxer0IdKEnqps@JLJwR6zx9N*#;lq(2lGNG7y#LC@ z3n2lBiLHK*kDL$Q)2e-pmruToEPe@##SqQTL3P=1CG#--nVxUTkit4YrLa_c-{{jsqwB3^0`iRl*YR|h`RQmyNo2M z-u@2a9*lzOWa(iz|L!2lcLKKy>DN)rC;5GhOv%5tqbS0PtGch2SJzQIkN&DI(0F4< zv1|zNKqIm{wQo~Lar4c;)`;d`k(z6=NxA9Ix z)S_M0*}BN4JMj{Xm5a8d^o1TLx1gET|1`vO@~BUZfx300>i|D9hDm6#gb&xqC`d)Z zC*gJ6z1uAy$s%js;i>kX7X= zO~)egW19Wxl&0fgHG1tV^E8V62y5EMbxCs!!;4;BUxlCJm5tkw?n^>lv+@{wbsOH< zD~ghv;37w8*7z9qC~}UM_1O7OcLTW>ft!ZnaEz`Zu4o?qA%x90o4za-N#cyqqM0;FcpuJ#$ph~&F~`CbEG46ZB-XkSzmYrf zV?@y}a`xbl>ok5o#tiEjgd3;OX;32hB-w>F^n+4VThtUisNJ>ThW5;5^kD3tF?g&z zs1tvp5{wxnjfxc&1NlFLWw1nIt}-xwz7R1qB8~UK5RULs4l&Zz=!kT3RkHg7$c^Zr z+J)!OFib?pM`bIWyxV4=P72ZUaLNA-Pn-yp zqZ(!B?+*gX)xnuRjF=G7U7g7z9-tAiHfn#KTtr2TRJ2~aEyhB`s7Ij> zJu6SR0cfK|5NLzt92_xLt;vh!+!Ilv8Z=6-QzFKxbxIlkwk^s{e@e<+ z$s!*_!ib{Z(7K5%YFcE3@KgAq|K!MOhg|CKm`{;ob&JC7@oo<7CCuS>G1krbDo9!X z#%h=4gt_R7@O=Dd&rIX}?!)P*Px-l8F=VDIZ7mkw1x!DojI5?FbKMB+%f(q%W>>x= z3I%iIS{}|qE85K5M?j~+Lo3?M?(azC;m^Q4nR!hT#qnJQEA|%$~6l zB{Lu0M^TwxJvNT3%-(-*+=$MW?$7$%)NMN1uoaBU0ym5$F!E&Pwk{Kn2WAvFTuE5 zoB6Q}W10V;PQh?u88?7bh?r?*e(HZ1LxA}|Ekdn+XDS$&>lnzf9`I$J=M5O0nN70A zu&un(1{*Wz;Ipwx8 z^GD*QVILmRn=w*It)voOz&-{+iE>R#;MemLscofGlIn8NUFX|wBA*$;n-EaC(p5iM z&lQE25rzKARK|}V)2e~t!|4_6Q)Ru^fyH$%ex8GK*@upE&nd5B zL&sANnJ%0j3e&z{iZGbteoO*G%NnTECH!2(H0$g+m-j-P>^U!_*NfwT77(4{SHuRO zD;2_92NvxET>=y3u+`|2o=Z6i=~<;1Kq>*L7A@Gl4UpT%qmU(c z(tV;8!Y-c@zrv&9`fyb&{!hi){Ha)iF2>)3Df@Vp;!Zww6Od4d!YQfZI)k5sm^$oz zk~vk-r)@~^7f`%U%2l#AEcbG}XV#~kLO6Yn#44yT4jnRJI)7*#((XqkBjb(N0&!X+ zz&v;#5=+l~FGY>`?kHpBXQUl1LzbWRjcF9&^0TQZi0i2RmcV<|Ea`W-0>sWw z=wIzQHhb7WSCy57W>*CkvHXElKJ81Wm0v`GJ#8FF`GaYSW%2ie z-O3-Dw$P2dVPw`cnve5~X*OjsbW-8TUoB^l{57g(CcQ8J8nqI^tW3Rhtv(B3@&A%V zu1@<9X34*f2f_9Mnjvf;}j%8W?LkeZ_56I~rRzWR?4~6gKKN9RtoO!%#0?;AdM?99i_c7f? zyd8{~|1^yT(^tZ+IY7@SRK}M~0(wsAGMRtA4d|~5P2*oA0yQc$i~mx88CCENZ7!oq zz8GE};#|b-y6hv065-$)Li zsrwB+nEFn`0|vhiYx?{boIT?FlP8oD zq`+wN{Rrp;{G?AR!8#isN_~80JJyqUMTuTLq~VZ2M|+s)F2eU+(+ja_K_7baxA67* za1nO@YjU{bnfVn!_b6oXoEbp(ek*BqelzN8e}F>{`M(>rw11$pL>|tz06jcJqBvCf zJ5@ucgKsRswOV_p#CbDoSW>L5`8g`h#0?7(IO1$K4kKt6uVUyYCD?v`hM-4;!84M) z`XXhVXn?7bguXfH6^|tYCfd~ba37BM?V^Y~v;lUK0lx)k96=jHDZwG9v%NB~_ zs8(>WxZ4AmV%s5^i$!=Bz*L*M7f>Ne5uTFL^!3g~V!(BP9W<;GTYP|in;K^UvEKmf zY*T}9jo3{}X4xn*l0U;Fb6|8IMGqNjqsTaNd-NYa;9LPxBt;e@ib9oSK=y9rnAU7N zmIdSqAqh6)U%8AdAAoPQrDHESlGi4la2lq}qsv4Ne2POg?QzFy34R%d@UfCjp*I7Wv z70Ti1FmmDxGlF`{D-93xf>-)f}{?dgSo~)$P&yoaV4AF z)#a>Y^S4R{%UlLZ>`iECc|=;9TE@!lWYx5Pz`4pJP8oBNs)%xK;6~l8ocm(5lo))eEu3bu)J3X&D6LVsCUQ(>M+X6`w%A`&+mknm-i)A z2(5|%Do~ubQ_+m?%Y~!9euY#3dp_|R(V~66aFXh>3vi)5MrQLNK`197Fm1#wo56b(Ik+WywHhB49 zYJ1w8amXD_?M}NGj^qStPujzs0tZXl9{U#cwH>EbR|(diNyPr0yxUD z0d>~u@OEfmd8R^kPP?%3Y19nz8OO&6qUF;`v}+ck{d+a|Ue53skab}VhGaE0nI<^W-ZR`Q7qG*Hii(WW9oFHAYG@%;90ucWS?Kz<5$?rH z0<5k5ugIZc@xW-j?iBfIF(Dj2&VaEoj}yO(GKpN**5aQDoMM)R!qUifKoeBVwfOFl zKoeDvvh!o;yp&05Q{v=3?*p2yTI}K9AONS#P?dRkM+AzLnSb9yRVVZBl7Px}jCWUH zLQkpm>?K+bAC2givOv*#@tFujDOV~~$e)Kxr7TndrkF3qjFz%!!aY=O6yGoiXz`oS zfmWvn6M&Yep-{%3Tmn?}v7}Ar*Q3EH%axN&<44nhsy~yoSupkqP+fH2^4pv7M0jkt zoH)itgv>!vdaS)qDph0g&o=-?w)iXhX>62Qi8$R=c%3eU;`li*g%AeBbX3r8H##Y~ zyPPSL^C*WpiJlWC_gE?s9R-jokpzt>VnNOv{BaFMAm6tXUoJZ^ihqjpyaW1sF^uP7 zLOd{5>16S}Wk4k%4e2S)0sT!FC!dYZJW!@8_VDjrKodwVJ*qi82WX-S8eTr;8lXvv zGnub01e&ZkQ~AHJ06Q>6(b9Q(SD-5tErUM+X$SOYVDRA(ykm1ZKk|H)LWfpE$JCPy5G!mw`cCCl;cG$oR` zmsGQ1Jr2qiSbR$q4kmgkceJyFZwsWiQ`s(IXgIx_ku~6u?A~F0L)}a7oDAznbXwlf z?b~7fm5LtzPmHr+`ViF1-;D+;jF+6rESwVbW{iw@xG~oOm>MH7`fCjElj|{43>zxX zfrkxKnlU#iGOU>Bm}_8%$56_3JK+5Y=bkxb{0(^aoXN`T8Q-%DXohMr-r<6u&zY%c zxNr*RoHI*}PQ1fKx4f;HQSuhWO!@d24#pfW-ihy{MNti|&+&755~`V1!l!01Hmfug zRJJ2p&l;x?f{F|KtsZc1`}EHI=DYFbHT{wk<4ve@dY00_Vi`0kM)yFyMZ5jqZlVq> zgrN-FJq6)f^nq2{!`~l&5m~oU&lb_h^FNpP1WP#U;>G$F72zC&q^QYe}4=?vNm(h5PE_w5FBm1 zmta{^@A?4Hv4OI%#r<%;QoRgc#HV1amYz`61o(^lflewHT*Gts0=+=?*4vZ2QLD|6 z%vLHX9*g=aWOpy0Tg?^~Y>+hk z{|8WFQ9p&e%=I&bTu}i>FNo$}qEiZD^m>Yaj&>Hr-b-p@_Kc55KUj%#(&z=5#0p}{ z4pc8>iF4@*A?_3*3O_UtR!^M7UqaMPoE#cie^3GWJpfu;Zma^*%Q4)&DFvGPsH_A3 zH;z3()78zGI6l2E&n`u{{ZtR&U!$iRNfChpIH8^MCrV27SKFu z7aaxVPXnq{rpV%ZHUKT4%OrI86Tn$W;+1OqTP)8e6Bnu0mvCBzB`$#*fwPR$GB9x| zU6wI@lR168HL>bjNt?#o;&0+IMVrOfZvD;|-)RsJ98%nf#{2KmcNOZQ#87mR|89dewK%-Nv-qdL zNP9Oad;m-7G7j&NqsNo|dkwLmJ-GKtlOk}5L01Cqm+#w>?Au88J^EnRE@tKe-fPhA z8o^kk-`)y(#6)EK@6*h2V(>MspqC|=pjylS4qq+iwJXLfQe{C5~do z^Bl&vbCdssX3i2n7XhBs)Eu$mHozA(%u_Gv zzNAmidx`sDZvQL#n7u&!IvenHLrxpM!Qz{VfNvNy>&vhI%p#+`DTAi``j31w@f~Sm z`YwoiGcknmwV!tN;D1-saXTRalXnZ=ZA4S&;-y(b9N7)RXS$*TMl_k9P8`Lmn?Y!j z+T&eNBQX$I#r$6zzri4Q^T<%|dj6zq!1sORyPhHZEUrHw!umrP-}f0u4Gdv?-$%ad z`LiyM@B3KjFaIwZQkH`%P258@kpM#!g_D$)?C2HPySK+*I$1ZnUZWVVv9_;zdQ9*gXLJ@fzdpWp9k$poM z(9``Tt&(qUxQrIbN2+Dds88ZlaT?8K&nkaDWN;d~WzQ-2xFOG^%j5$Ayv1h7HFw!j zQUIsj2JebgS);21uAciEjo6=80v@C5!iEunwi>ZB7GBN?mpLO2T+RuTIX#zL&aq^U zf!V6;c_qgtbIzlWLpdhp@ZWQgbDVf=zLyNX@Fu_$%Eqr4yc;wudqE9}H}Jh3tUk(4 z(e@ng!{gxqE*+M=7={nq(+8+{0vxvNCDo{dCLc+nURL4vkjbY})qhhE2mI$Z0KP(7 ze5hgax**`IG}l6u$+uDmy`~_}`<;l|Wv|ov!R9+-@}_9O_mz@o&DdQCzh$Re%yq$x zjiescIWX4+Gmf5UhH_vo@I2D#G7rp!oMC+~=fGUZ+3!Kl-<4#T3r`Qm5YGp+3b6UU zF?ky=;Dn7lm+lG;Xdlek53{TxueK1h1F`NPBg_)1Z?7pZBH`{3wFI ziQrjwLG>CwPH0**5rxwbr;U`HSn(mHRAA~XiA~mpPKXxHUBxEbJ97H4!-$o73g;OZ z!y{I0{2L86T)9~VbhX;>*!kQ{pw*sNh!*Frp1YWhSfifOc{!~)M_iLEX&Ic}2_A8+ zTBv35N4f%Cr`}x5k*^t!SgVem^5koVBi5ju2P1at(S1tpprLM)pT0S4q zc0`>*gXHiXaidzO4d&O}4%#m2NV>57$UdNZ?vheQ@j;l!Mm+M4L}f4#*&<;btc!!D z_OL?&g)OABDIJ9Ek*4>XQXaz3>{}7R{PXZ-2z0l?G<|4O2yYcfgy>=Mh-wsru0MfZH_8 zVqK>|ivaYt{QFJ+yJ0Y;f6OKr!#~A~0{$?BaT`n72d*5H^!Q&_AAj+`VNxEg(AEw| znKw;(Vn{YQOszhxRkw@B;O+j8b$#>%f+|d5GqA6LgP-=FG1a#wJ~b(ik ziQ46WpX=J}B0&0op=)!B6}JF>sr$zxoLf`%EQw-4}Z4YR~QpsfEJ4Rgf9G$nqkpeCZG@V9 zP=C-`6^N*TfIn*HLeX(P;7=M37MrOFznUM$QQ2Z~ktW~YG%OSMksANfaF+Nc5%6~n z7YRFj-v4h6SBirUz&|9U%jn`>6S!I9t%i7+FtbrrHXoL5J4q9pe6EOz-w=dv)SO;v^7z?#Q2x$IDjj>RBi991pV=UCV!+-rQjj>RRS`6&g7z?$B zFu-WVJ%^!rB0rWO3=XSHyyBtWR`1TdR5uq)3yv`S_`vqN>R{~0To}sS_@47 zsRuB)Dgs&xeZq#mW;4w{!zRC!YuHlT@0cqFvpfD zsZMbQjqq34hDzuWzw88@XPYizoY;iG?ys~}OXw9{5zhPzG&NbAzZ!6c1DZKQJcBUguhI2piHSD>uF%vRF>w#zDoxE3CIW;1YOQlG@oNp>YRz0A z<|CB**VulQ6%~rbV*sz!We1BcvjMNuuvpwj_Fk_=jS{Kk&2<`KIF+)LM7E5()~7@yOSMv2njvJ1W?~@QsnRHz3Xnn{ zSn}V4VC>&)6U!O^w%AB#3dH+dt)Ru)zB&izrrmLg((v!Ji5wbyyKLPcfS5bbBy^`u zuNlO7@`}6U(4@_61DfRDtuG;X#pBxm_h^_Z3eh?Ky&7hSZ#dvS4RZvq0=!4VUg8pY z)V&%O3ab$CehrJotWv-SG%OM4DWW~7;bc)vY8=#XmRME`_^^hR;t1O2e?-G7@gNPT zLpHjBjtBYT(ptdBB$ZBn#2i@7{}+un;w!GSD|=jH1lMnDz)xtr1G}~>fS=NMw;`79 z0zRxUf^8WY@QB6;u7k;fPiu@|y0s1PGa4g!W_y62)fmC@rOm+4X^i05DF^td#-|PO zz|Fvo8lS;y1$P4<)A+0*#;yi_UgL{sPcHCrjV~Eu0EMa(8e^9^oI35K#v4r$mj(QS z##>F%n4v{NHTkMA&tjVj;zxS8acnct5`B)gSnEjStXw@5nb3hz;ZSZLp>I z;c_R@!Eye#ZG!G&_}|f2RhX#g0r;+VIJ-Db(%#dq>=gNxfbZ*Bz{7I4!^KnXgt)ih z5vlkVmwQnqj`~9fqjzD_7(7^A3dZ3symj!9e7TZz^4Foz;Gv@>^6>mLpkd1;isOq1 z0Tqvz{>gS9TGFZ?g~p(iqWNp4!<2o7jpG1~fYrflm`uq4pufza;1 zA&u7y#?ddG$@zXjh6)w5%tr2Kl7pVPCeSB%P^Ov6KYhDQJLVz;&R(#T@)M9Y~IXD+ePFga%o=0*e zoWRrmX1PpnzwJ@kbUZOxii=d+m02wQ6;AZp-=a1NcKKdH``gre2~HMCx3r8Xx}6AB zNuuu@<&Y6&ZWKX~uE8JEdWRV3@|HmY6a!Tg3b8*Covw4K*i2$W7mwnR>!Z6}tz?rB zNXPDZ0iF(<>wq8$fw(Khru!*FbPC| z5_;6;zpEB>=C}bX&xCxE<4Q$Hx&jNrjD&!EK$K8JG9XMEEn$T=lY41ZHA}dv96m&6 zyQ^10z)ITi(?ch^fR?aI9mjjzIO|WiIv>%Bo;Dpt*yQe2mv~^2ZL)U$1%i$tv zgHy4DNw|t{M7&D4UU?_u^s;lpM&BfDYUQ zyU}YLTQ>qd_>4rw^0sWkLmx^sioc6dmheazT$Y~Rm!sPg9_=9!?IP#Hf*$HZ7xhKZ z4wSG`&=FVC<1LHK=jH%Dp`j&Cx&fcGsm`;DPdWoWWmCOJJ0gT0+**VQj}zhUxS3 zPji9Zxr&_I*O`yM1L)msiL&@>RP?=QSyc|7Rsi$~|2uIG=1a4H&d{54bgkisGN6Cn zzmZT0kAV%mpXN!Ez^f4T&^bah-}0UDfaev&*Q%Fn0&Jp^^sQRH5Z>jzpdhZeUPCSZ zn%?%IjSP=Pu=0MRsJP-f8g1}?s~}DYEtuYWQ9+y#o`c@r?`Rmx6T*iP)4ks-h!eu& zeE@$@YBU=BT!5w!4ULsTA zFwNi<=zZ_6)Jyn+puvw&C;z74mj>@L3GiR^+63;>;usSOd4IQp1TO&I2>9>qvg{>% z1{`eOKNS2O=YeGN=D|`)%-k`f0h#{(dYviyBYJxclCPOeCAqsOpaJcc)2I7Ck6pvDU5r)$J4O84j{B{|4 zVI@;c@Bv3^d8bX$tvzs*=KshPU#s3g*C^#;~3dEDJo{yNynCNs4K1M;kJ3@oV_)#LNY6>`g6g@9jby-|U<^f`&pxTN_ zEA=XoD8l{+DOB_<(JAJ(qDyrT&bq9#9dzF?VtN!URo8Y&eiY?F$DxwIGB~- z<=YW6rluYHhinrVvO)80#80bQq$nCEpf4f%zCY8m6=@5RC`h*|N+j6;^)VC8c|UPd z0RQit)F@Q!uWe@f%;I@ zbOO4*2&nJ#@O+wmJ0iS^f_o*+$@ddyKUL1d7t8_buV``nud9FtkSQ?zLbHF9W;D_K zSIuO*!Fd~)d^8CuPMRK~WE=Ei=oryyT2haZB}uM&NM+f^kfeVSXV*V-5{#m6^(jtL z5OvB2?3M#GtoiWUeMJ>6!_Ez`bTc7IJ{y^mph7j{6Na<@L)d$OMRl}s-{+h?B4w9Z zag`kwabZ!>prWFpqN1Xru|~xbV;3|wuqzf2jT!~S*b{q6(`b6{z4u<9^e4Snlf3`` z%%D8^-uL>vE|>G0duGm*d+M2DjZf0#s&#+ko9X^CR{J0&$ER>Mnk%etbV1?1J4sauJ~XzsI{g%al9ue zQ`^iJX=ozGw+)7AbBK5{3DjP9hen9?7l1l$uc2(T=w1Qpr1N;3;CGtwo%bl&#P}ui zms{hz%vLl*#B7JGYZ?kK4?Bt{b^8oq;Rnh1<%_NHxvyS9+QBl-6$UBoOEKT<<@pGQ z9NB3oJ_`#y#K+*c0>x*c-{sCl&iZgk$ihZyV=ZT$Iv)Tg7|UMClV%n+cJ)>OznTtR z7;tC9dyb@e*2}^s27_`c(q&;&_n49<%UffCiSBg@!*WOhFlb(sE)OFA7h<(&b9$9w zrOxJ??(_73?FjwXn#U(SQK2-8wqvOm`lK#%EXgVuq^g%c=qaOnhM=B%lx)Yy-isRmcEGmPJ^44@%i*!o-sRQiE! z)Y-(`xbfm);05P102;h7)8$)r5nqX?>?X(Y>tB_cb{B@}tI|kmCD5K#kz4tAC)(mw z>5t;kilPC}zf>bYe59f256~dR4XvnG!GF~;));;VzBxkQn~Nug!JigoFhLUG4zop; z_2zLb4n3Kmb{(EY`_fXC)|67fUz381=~dpuLzLV-4yO zkksV2Vs3*cb}WD4?LGM8qv#QgNy6&`ViW3`^{EY&Q%h_}0i_vl#q9Q=h&~9(D-L!5 zrE{kUwZd^3IGn{!4>RCAb~)Ow4X$|O3fyQHr4^s)22n=@Jy6+3?R>7hp#IM1%FIDa zRG`()=gPLT6+!0~!6NZM!xct zt=Gsem)>c>8|;e_NA(efL+;AcHWwRlHA{LTs*lPus-vY2W52~tZ*>`rZZt+IY*KLC z{XDDkW_w>>y1K(onzm$-Re8HjJwqQFvxm*#wr`ma{Ioew z25U^BQSnqhYfn^ij2SLI3Vy-%sqkUU(3INxl3DY$)sb)F#g#7`_m~ajffJRl8OChj zbx6$0*X=jU7(O(ZN1HkFw{0pp)(o-H{T@k? z!opHBmHYbh99`~KnsSFV5lF!@CLsHBoZqNiT{olmSQcoFw&~Snt6Y}@zb;!9ngY6P ztpE}m}+5Z+9=gCuYvo4s>-5VPgTu1OZ#COp&#c( zaKH_0F?_2XOSOZ^bF{}dpSKr#6p0Mc2QW=scNIj~7Kvxa_3_OvH?1T-U8&3)!z99z zq|37^8{fh;tTm^I#j2jDeo^lZk#GJ=?8-n$9;s}h)A@Fj&N^l9sGB+ZGKf^Ti-&Tt z-^^PBD(}`ccdi)jg3Otv`C=_v$I5%PY=~Gr0(75tH(ISRsJvenhE28@#?t!0aRh-S zOcWjgKKP+R4Ej7PHz4bp8*V})bx-8lYY%sI!`!(HSr{AfMkQ{9nW9=y-T zh-c5kiuuZxy3qN|!aqw_T*6db(YgrwRT0GDHo62hQY8?b@g$xfU727iy=*z0C8n{e zU-(6vorcPQ&9|d>u1jkZRa&{fUL|s(%~ZxTl2k2O&}PW^MSD^j+)7npqQ4FW{2ac- z(6Sv%4`FgQAcl2=9m`*sOn?$%aV#LhWYwxlSzRmq2}MlfdZPMTY(W%ZqH4KHH&Xz@ z6fuSCiRwG;0a4T({QQids9suQE9GVIBvdZJ%CWXOjjD2-xp2|a$uZs}hpXd1!PZTA zv`(FiRaM3{t4hfx+PYHlOQmF&*t%8;SP{0JI$WxOqng)6nL&uKG5xo^e&BzEr4%+s zx2(rkzDk@H^$e@hBdYabQ+T8g@Ti&~M@5N5W=tJ*j=bXr;V|((-SG;?EyS~LHGbmJ z0J`3p@k}HK=mm%-!D^Owjuy=|BGI}xcAL!8!#wO%LN(x>uPIs`qU>F8 zBQqIAg(D+x2^VUys03;0uc44N@J>;Q9C*ss+afIaz<3m%XKb^{OCG}zH1Lv%Mo>O7 z6Zo>hWO?H_;421k5ga}W2VONvkS-rjhx8p=PnTvS&6qdU3cPEuwYncC@V;@IDO+xW z<^PyMl_e`L27Y7^Yi-f`2R^gA?_&(|WLypKE8{j_?m|=ojT{~K0(m{U9f5#ZCNe}G zsRA}JI6}TY9T;>9l~<$HD$Ia%rXz*09#T$2gBD0}ra`I}$x8Go0%2#7Vtg)K*aMvA ztW}J)7u^!TEu700xI;|M(oqZc(7CagPqmET~K%$M9=dq}v(X zT_p|HyV-IeQ?9qe%db@jrhg7N&-jlH$+jYJALIUSTkb)P6zJzP-c9@Ej{F7@4dkoD z#M&1}zCHom-!M8XpHe=+*hhzD8RY|w937VKO#K4GI~;l6H1Ht9=)i1@0S|LHq(GzO z$br+$p_{b-sH-kFpLSzRfnWtDGV;$84jLj!m|Sx+@N9#lsJ0Q zcaJMObptQ0^S^=IJ_@|jq#rJ@8H2JAC^PZJU4f<4pViJoDtucT$iuV2YmNWg8px-a zzZG@)(LlaMUgzjZ>pcx5cd!RGsSUHp|0ubvF?fp!@A@cd(Z4FS3l`yzl21{;YK*?& zc9$N#z`Gqsy&t!`9HD>voL3a%c9)^(Wd^P?d?-rth>5^KhXozojwtyC)Ax|!Yog>J zrtdN5OC>)UC085=pD^yvM9E~jzsB$_QF1l)?Rtj?P$7S#HXs;11*eGf{FzIrwg8gOa}xC8s2V?{%(H z{7RJkp*#3~!*4{%FWZ41bi4=#%3qZHW&-$OC#d*?D4B_VRp2q>|Ho0XTO;sOPLBn& z|9O=BoZ)}gNmus2ijt$V!OuHcioc6e{fod$4o7M@?;}cHeGu|joGwa!EJl_xe_wZk z2Pi)iBmE4|Tc$p_B}Ud#U*C2jN`6NSS}e9dzJX}vP9DZ&iFdKu&FWoBjYRvTZoKm@ z)8wj6rQQ|%B*A_vS6_Np2E!yA2|!Dqp*w%F={)Vp+5hq6FXIV6yn6r9GmX)53lzp{ z>CI*luZo}7wsln>NSd)|vE}vH`sZ+H3}%%mp?wIH6JYMjB6)3s75lrTT>8M5d%ah|0v9WOLRD z3)!*#DZLY_3vbAn;G^P<^ihLhlB`V}d{vy0KD84}ni)GDWr9l1o1#r{2n*~Cf?9f; z8oziA|ICJz)|tCh&QtCXsVJxB?wGNzb{|OyYYXk=j0{1t( z)t0H4Tl5Yvyv>%}Y~?L5yu(i7%$#?S;XStGF;CvXb`)|>%^#>P(1nH%+4ABkkPlJ$ z&+(1qAt>IVYEu!vZ9?&>^KpmsVEhn$!9q3UbBLa{f zuNa4ZOvwd$(SctSqTrTfYD!RZk0ou}!gtO+aw}~~N3;x}pjg)$WbQIa7BdjflFrBs z$WlbVJW$sg6@^7p0m{+t(glwgDCw@lk|7+_C?&Z|pQpRb_*t{8lAb(9f*%+r)5~5R zpCx6Bj>xEzyjzqkM?4Y@>Z2)FExst}*Yj1{%o8u5?Jw!yPf@-IqNXe<&{fBBQCJQd zJ~2$2tHk9yL28dX8X;TkLZw$SlHug~+eX7*);fbMVyY+BtWq88(@5s1r}6VMEUNKE zdn<;DZpX5wfo%$LN)9SGtbD<5+(zWE3^Q?}_zn1+L!agA0k+}HEBB}k-EyxEs-;%o z%YB+KJ&UP9d8MfVEngv=&Bbfn-8rHP8L_(?=b%-`{z`~4JE2b9eXF>Uum-FU>4>!dGB#Sz~e0d>jTCFz*t7 z#)Fz@!ZpCSGq3 zm2eT9M3sfLlhn_2{IruaO^$v`M85@lYgehaB&3!4;8T#1NE?=d#}tM??F(pnSvo_4 z^I!1mmSu}3NTIUMI!!E*(iqgmq>z=s!`Ga$ZfadlS$F*wOMJ?hnM=xTE8$D!Q!njP z@48?rpYlvFtpsNavbn6k_Gy6e$!fxT7u~W>X&0e|Yv$6N+4ZEpe|`!En~ z7nRJm%K9;B+RmG`*eV;yw_3jY;r=2dcy5_5egUe@viP>tK%CaXO0-O9as_L}GQZIt z(QYKD1(TP9xSBGLd)YL(Ij&4L*0Rzt>I2q-*Y`FF%2f95mjD-9RLT^P2 z@dCMFsIVGf{QXMGN}JluDCZ-fvq2f!-V{;P}GVGwChY=VHnqKH5u3K zjBD|GXE<)JWjNao7t%{!dt%3L%(`Q;0 zy)-qo;<~Jb)!u9QRxgy$t>_~z-3_C@+BK?(4d_r+^!u4Ma$zG-(O=sbU~CAExGDzf z;WU=0d71zV5@9uAE`Fjb28+WC&xLjNxumjUh$h&-8O5Mt=s;NYy@8*UQlxu%nc%>? zeAOteG=ih@^3|GL!BKem8Xbq|cn-qL*XlucY&-|u<>i{<#22Us$}2Q^ttM@&5ykS& zX*Wf|cnc}*wvl+;+6j+sixyhtRo!T~yeAB+d-L%EguT3`KOZ+Ehsw8KNUMuycCgB? z7>P${8?zUyuMl|0W!5<^lhSdSTv#zq9d)TrzG~QiGz6_Izf6_4@{M(A!W+@bH<>gM z&yNM|U}{h+n;d~NfBBKLd&^;blnHG$>0U##6KRXlq?BLHwIgW_;B)yk>ajT*sPb#o z{zOgx@sW12SiB0O@!)JluK29N3(#k6en=gUtoLlDyJPIx@S z*QWi`1&=qX$Gez6H*wgS_AK(H{N}Mt4BvEwE2AO4zLg&o%hOYf$I!JbWNo7R3sJjmxWLkTukk$I*hC zxlFBoKoG^?<)Aq24xbVc^<`d7I8@e8bF`k2cb>12!+?VzX26Eu0nf+L{Dn*4%Y(B%P50nrlavAl^UoFCE~)KpWl zxF18f<%ycY;zCkTQ@Z#OTDM$k$`E;ppd?M1=&NkUZD&xYDa)Iw^jMzKk+FlaGTW9n ze;(Pz{vNY!d011n%8ccyIx}*__CAnBbP|si*TL`Q>6*rg{Ena&nkHI4dT{sv?p9ge zT)YT#>Ai-uuEr6ybvgqDBBdQCWk&;o7H)tWNJ;7*_#O}Ho#X}e;Z zrfjkCD5zEw&Mri0U$I?NuGo&Ev|@**Jn<_MX~j-W`GS4X6}vPQh_eNtJ(}?S2HCM< zuci^=?8TrfHH{WUeER`S7q31$h~$)|4R@jt7}-!kMB9wL)NTXaUT32<@} z(aRC{_XJ&`DOVgD0@|f1PfUZIz-~?XqHllD9!&+JTVv2(O+&J-CN~eu`5%!VT72R-B+w|M7BUm>FD=$O z6;uPR(ph@Il`MXME|$*L)J*kWOE1-wqE65)oujF__y~mz`I%}gkZsnaNb_)0TUP=(P3l+P5Gk~ z1E%V0o0|ud#QlRIbKF^Y_D`h2Yp4ZbFptmt+J@&16t2LJ<8I?4wK_5OawXeIdk*^V zuy+{G5q|3Umny>DDVWCatAkw^h9_vk?+DsN^>bnIEto|3x!`;>>aG^~o+5rJs3&3v zzs{)_qDY_rl@sABM-GmgNeldxP|pL_C=d;WY0L_Wbm8G6jMw5%Vr)McBZ+8*9~O)i zmM>V@0+R@pyPl^+i0;K7A3rrT!K})Zz|HYogIwC09}`gG)%0R%8(k7yU4kw!r9^y* z0$!TA>UrA4sb$rmw$+OKx^%VEr7Iw+S3s7fThE}@{f@et#4WEAA?u{IIIN~ROSAP< zXS#U94_Oy&GgHi-0_v(MOKgU2m*!~77P2eIoa37#nxgG0H4Dmf#jnVdQgd=|p4c!8 zWNx_07e7~l%ndgMqI@OD9PT(oe7+o%r{6F_EO$YDG>sNA9n@FTIN{^_`f1`>tw)fk zi7#(gS(1RXP3%5HJ*V)QpJR|!ZSWj506$zYr0QPBO5rybetyZt_ZPL$`?7X=q-BX` z=33TeS#|xUVjrlZK3~nNE{3_R6IGYPqIqcJFYByB6A*7q26g%9Im&`!I2x?Wa)iny zoZ*Q+&Skmn6@|qS)Iyi_)|4(@M0vR^Py3l68eR(O+h5tt6a^ko{uD)7;t>5Dpk>)& zWm8armT_V!1yS-do>86fRDkY{iY&T5S0ds!s=-U#Ie_aos3ns_OjoiC~z1W{HK2={5Sqj%;-p>gj8>yBzV+0?1BkS#JD{*$b`H zr*-EvPj#D5->9=6 z&!-n?$`BVaIZG;4STe;v8&s-qyv`CkQ9++xctFXrMW^1NMVfNNVKhmnSL+z%S`kJ@ zeT7k1U_uud`xts_RD?+extG%i z#3Y!X>Df(bg5D8&rkBn`S0%@p-a2QZRf3<%)4}r!E{8bNr%s=)ECuy7`lKe>&X|fJ zsB-j7zRpqZO1=$2h)cWz4!Y;_weDd2MkeFOW?4~fhHhAVyI?ph74u;8;^U{zm|@NH zpMnV$|8mq)^BTRZ$Q4OQ$9V}Sr%)Dc#as*&f9{ zG{#_1PKXB6JDeqn}O-q{5>(H!QJBUg3XP%7B0#0`B4byUg>^~Ja)f^KvL@q&d9GYfu zv|O+QINjhxxo9qMh6&XS+5ZyYOy?bRn4HKgIlmBCq?Xt4gX;Z!QL&S*LbXud(GxgJ zE$-lo=y_{^vmKsf#qXhOpt^@TL68F-Gvk+CO&FP?2tkVA8wU+yMfh4b*3 znDZPSn9aSM@-wFOd?)^1GQN0zf@UtXKwZegFP^e#D{zT3t_S5OZP_3LywC|K`&jzZ z2Fe&(Y?gj(avDvzgBG!-=hqMfb!$+tre_yQY-p9k?+*x=BReyob!$$rrbo60mpg5g z$5_+Teld8x@fd4*JkZ3@1{H5EN|tsac#~2CEEsiUEXq%4v*8CEd2I{u7M0{!bA?6H zsJ=s3lY;D18z=JzfNRW}m}ju)c@?dvbLHx5nDUlB z_k8^UMXrc%3E77G6h(^)G@dD!y`sn~Za|zfp45Ud*MM;O`$hEdNSWH zuf7WSmcd3cVHxmk4-YToO8ozz=!V|$G=GqoER!|>-}Ov>h=_YonDg&>E>)N=Z`lZZ z-&3M6Lv9)i{J^tHVWxbuJMcdy7+JE+1N_h+7PK<2Kk__VK%aBu$pyfVJ^EO)T-lI0 z^@&Go^bq+9QaSXg+0Z>v7EzBrGdM-IS_}N#;0*cAQQ&_)%vF}8H!%ks`tsa`D>tz+ z_}WvY0$Cy--3k2Gq~v1RA4whh&fqF}GrB*a?-g=@E&DM3KN!YZgWp&?{OIAVt~#4@ z$7JwNMvjs;b`JO#Pp&EeC|O(t8~W9A5HD9HYg7a9Z^k}K))1z`@18|BQ+~#lof(`z zRm_w^f5wbH>p6n@TI~d$Tn_%*^KvQ~3VZEDu%$Mb@sK|Ga|SrdWis+uJ~?haIM#g# znT_cLkGvBdgOK0-)*|EJpVmXcO$~42H9r?a*As6lQH|y6P{F7l@k3Qo{kMn};kOUn zelROziEtK=KR%Xx<=Ilk&nUMw;3&I zt5_Xz^Q8ngkfPddWxkZS>WGO}>b4`*k}}TTR-rU5dux>(0a;PJ^Nnv(S%H(;Zw3E~ zy4~BOr+5o#)1#M8H%q*Zim*p-efcIX9~}nDyBoIYb>erk5MpfS0jCsRXIW2e!wUA$ z#kSm!`YSY1^|?^F$@>}tFR^tSu+F#8mVoif5ZMzD4RZ(50IE;=5jaO1gNJ@OmLytu0z&R~~4Mrf6{; zYQ*BT+8Gw+Ad8C2HQ_qe)hDsLBZBoRvpR|ssOV>PYL95LRk^SNl&uMOi|qn+*6Yt4 zk}*iiy4P9Bpd3wp@dVUsRyR#S@gq`mmN^wYELNgknq^K!&k&oIf^xOZ zEYW^9sHgrykRyIW-puN)DOVic4$9ME$rJ6Sfcj|aD=wY@>Z@($i|(i*XZ6#57Kp)o zd%mU-;skPUR)0<7L>3Zh)&T8pia5$p57d6n5Z@x*XBCW6=~5*AAPssHYKeN@^4)?2 z%tY1)W^EQr8I;SlmzJ2)2DC*}wD>vz+G=vaip$smtYYf>icX&HypHG%Up3{Gw2Gw9mPrXI0D+CDOrp}!#-=Lepi+#iw2nwIN7492ei8` zVY%~vmie5ME8Jqx-nxXH$T#dW32S9Gs73N!+QfGp!QGsX@;)aZM&a)qQ-|WV0i@`h zrn>aI;uSf^)Y?HC=G- z(G<`H=Uz=gU2yKx$BriJf^)y7u+^jwUhXY^HZ4B|%Ksb_Jni^UJU%}kkCyKc#PfPG zY>$g2Xk3e*_%BRY2>L%j2L7zWgL z>uJk+un~3y7ym5&LC2~17ju(`*v#<#szVzs?rIDAO_N`Ib`12prl4qpCb;+y-O&k) z%nhJFb=M_J6n6rhWoysHIzMHC{$f9nYvM9vK!594=8FM^pnr62TOgay2kA4H@QF#5 zGa+qTF994ar?m$xABm)x}drrhBr1rPW zKzAS@r3Iq=J-Rtr#Z7H_7WGzfqRr(z4DE7MPQ^icghE$7cPUWXB?_bE&FR1-dzV75 ztYzYc>>CyOW$Hm-vXSDfdeo%F&Fq(yG$=bK0aHxiljR)LK*h}shGls>VAx=~JhKm& zYA{3o%3xrzEke&r%p(k~jyU@bbrEO0A`JO?5u%(&Q%2ytX)H@*ovT91x15vnDVC)I zPHXY(=XeEo|IrpB`Y&G~x{4wemU<#xcH9TArQ6#fOWAUhW%arY)oXD}Tgs-0Pb>R6 zm@&~`fO&DoITcxm%BHyWITh){RBmIxpe%dk{wshN81&26h5<9}Kb15fcXj}_H5il+ z9R;?tlW*pWlI8d!V0$}PVOU}zlC1ivs#G6-!(aX*{>apL3N)<7(?R+yW_)6k0h+i|z3kpfO)rGWaY zI-g)lSh?462+YdVu;Zq}z|Y$?QaasgSyhcJD?fyNQFo&r3*Bpvh8eXfe;n{Wdx1h% zUa|mqzr93Zw7hjc@F9DfLa!W*8Yc9peL|sM-oWAh6ZX>z12SVi@HzWCg+Y16R^amn zljX97z?bdx+xXtF9M539W{*>tE+2(9h2FFmDa?@LdIR6GFISi;6ELU=y=@;?m?b-H z2EJ=QuP|E%%Yg6O-zv2v-SaIlM}Os0B1Dp%?} z59%Z=ounluUOh`Hh)QRTr59<5X;{ya@`+86ns(Jc`6Gd&J1dWWp&KUj|BoB>GR~+X zFl}Hx!rZW5q{r$Ne1d2aOkTd;IFo*P8lxG|O!NoR;m|J?^rYd9V$Rg@& ztP1%kScJ{%X_FbL&o?~x+PdoZRmz#O`Xx%P-ozic{~2<}4Z(uHCHzj|L_q2s^zlP+ zj%?Bdn&34vjh2kx0`xg7Q|y2|(+n8zFmUL8$FO)^SU+b%xh^OjFCW`T_slZY zSI@BtW+GUv=o#CXYL6sEXc?dsPN^=(d&XgURV|YU-Q@0hRJ}+Ym=n6$y+ffZktH~y z(0xN;v>d<+=2rJdgk5%N)stTcI7U&OJ+Z zrLOLDCp=7NuKbiqyvtpy5Qm9-fxF#f3cYgsEZ`pZNriqn>=NK!g8`XDJ>Td4S4o4C zhh>JYblpejbF$=VnW3xPBqa^Y-wT2J-R=t0B~Q-`9Wa<7dHH+jpxa!z%~Tr|LxQIn54+u!G+S*(4;?Ym9Leuup`-2uCC!yzuueGUE>V~#dFx2%xVuwfzPhs@ zbi%z=VS(hqnW3xQj};D)yjebUjk^!c1qT5aF@o2+!!wAZWeRiaI`%y_6tXOZ-wd{nx2zfXejq25 zz+RDuW^CHKvI;9!lby`1&(;8E8T8621A((WsrS)xKu%)lFZJm17L>0d7NI#F-Xg>N z*vMp>tL8yfxGBaJazm`9DpSWH6=C z>K571cjhCOSKiIUtV6#Xi}>kwRQLg3XQm}o5fW({zX@i{1)rvWE>Rw=KNaS0+GbccaK zt_vW;7UApuC93Od^r3v|IXR!|M5=_jQ(@w}6F);y0R1z4>U86o@to{O{M4e?nc{xP zQTkLHbPW$Z>Y?pTeelE zAY1CVhR|yBH743hW?}J%mV3f4Oogizo^@~>4j#wzO3$Ns?lQG#kri6w`3ld-zP89G zOs_Dv_z|iVn)@(5NU75&Lc1E61rG8`*50=VNFd+gx+^ER7fqkHv$(QnD!Va7bEte z4-H1kLy5qTTs__4l?_>8d~BqC8D?wviNS!p9Ips{YA`4p?gM`2>Lfvrk?ry42E&qz zUPJ$N^&ADRtR4;g!bme@-@U*u4Q9$I9MOE`PE}#flCM$vwOgSuTUM~Ve`DU8BOhx8 z{MOy0q`C5HR;b^*{ZvNf$#>@ge=wLY<1PUHLyA z%GRxJyb^{eGJ$gSQZ>p`Pit&C!liXo(%3dX`jd>RZ}C zOY8<|OXo*E45=Fa;C0v05_>~BPU>|kagHM%kUvj3yGMFSj*^?hYrmz4y`OqcHy~r- zDi)>@c75uJ*l0l1f+F^N>WS1B#k%-Y&W@0lt56%!6pGj>(juDb^fmG_%Gpb*=e4qA zT8t|xXSbT27&X`LOXdfu5#{(>U*nzT>qyjPVp%%A@``LzKoMcARL z_fBQ$|8qucd)j1QtKRF-HsMTAU15%=oP!Q6SBiNq;p)D}uAn6jMQkNHZ^?YGJwQ3f zCfbw#wS?TckMbYS$$eSC*5d? zBbQ>H7DE)n#>S3SX={>cBc0uR&KaMS94_v}vybi3 z{kw2{XzMCI5Co9l0zE`ZGd z+YT-wW#7K2iTTQdSqH1AY2W84%2Jmr7bP;gFdRX64lt-}0d;1bpS@;?bRA-nb`UH@ z*f{>%rcwX~tFAU*M4Rj!=~QFSM>lZiRfVaAx9^9g6z|jc0vEyUaQ(aLyDjsRX@um6 zUpjB9m7l`uocmGY=gqV7BVVAm#pN+LbTL1jH6d4>2_Dd!--79n^L}i#o*};_D?=;= zvqfeFq^-0R+Ye5n39rLFw%CU8Lw?3>=v=7-2hTJ(k2qoQra{2gJrF;2q#!Rn%x}X4 znh(v(-*Xj4_`)0uAEOp`MT@+jULdG1|UCb1n;5Q9T^BZcD9 z(3KmU@)#bQJOW$MgAb=chpoX!*xzlt+!}oJs(yGVu?8Qb+=}9jjZ924UTyL>*d2U* zT2CbN;FEl7+Mu0yJVi@shg;$C2KN~lC*FA&L3La@NWASr^&AU9;)jjYb5lIyQyy$a zcol$-6nE;@owAVu(-__|V8_xJmiqxv{_*P*&stVrA2vxZm?;_@!71tO#!v{AoVRF^ zHNQRgM6rbaI0v#Uy)`RJ9fC2xgQkWe|2Slw^nfT@Tnf#YpRLI&K7hW@@2ttM4n~>Z zg^}fg@S0l4x+c6s3i8yU`8j%rak4r=VSYF5EG&MX4~yM3rCTv!gjvU>E{co=ws+t+ z@re~GRdV?J3N+gGt;OSqGmuAXL+VJ1waNOEzZH)gjn_8Q`-GhMON*?vDH=TSbF8(^ z%?EqS_XzzOf?n|2Hfl%3+6yLz8D_mocWov$8EF*1aQYH!ZCky+B3dj(7Orhax2U(Q zsF(533;$cfBc%ITJWfYSxtl7)btn&;)|o(wg^0kWN=?|c!1}B&I_&Uzd&Dd$_X+SPY@5T-tEjrbHA?rwZhZPMEKl2$04bQ@pR#3i8r zg-!om_=$L)uk(&ivHXEN27hoP0%G8}-_RQOQs}pG2aU2;XSWGNk^Ypc+M0W;;HooC zxpzXl;x;|C{R*NBDdOfeE#ebQxycQCBLFendSk~L^L2nAx8KyFP~_O9?eyNAEA);W zOI<-!x}z=qK*`y;AKOlLYKj)onE5H)rOB(-e3$MPFVm)9>|6xd9=+!$AVR}Ids`@3 zP|QFjP`aGT%YlbAqVecWJfabehgAbSI!d`k<8c;GrN_9>O*I~cP_WYD8c}PPEe4+8o;V!K zXN&jBfLF7app|m;uDffxE8OOYe?~%jt@e3`Bi_seUUz*LTHfOb{{rCkJzrKYa>N~! zp6sXakRyIy13bkdhozp5_;Dlf1{PJGrz{2x1)kPYToJu;Ebz=A<@SsdUovB+ReBTm z2=MGd(ol-4SP?0@wc>WE94AVThs%kt29OHy^5>#UPZ6yi#EP=jV8a^*jl<)6LyZ}LRPMc z3!<42QDyLy6}zsdV(6<@{JOf97JQ%Zry3=;biG#o4K!husJ6IWrnk7cdW+jey~Rzh zNG;u@n+De4dWoPT|UMMIrYruVR#l1xhxmJD57`D(at0)rTq z5IfeGTmZnAOhgNdHIUVgOF@(MFm_8WO5=8tl2O;96s2(^S;^==ui&v7(JC1;l#lCB zzDo+ne}}Ce$1EV@mmjqli^8X;^vPRiywlZpZ&oDV8`NKsH+p8+b?6Lert<^JKRih=B>H?6V z>X#C;sW($qASLryfw1S_9Jy37Uuz(H{*w{Ms8R5g9SGI^@>&rFTx$}{2SYZ4FOcHoY zSs*w-3lI&5eHgkJQqI}fR^h;cF|&4F=&N3fLJVm3ItcO zCg*_bX{brCOshb$@OeP1V&0@IEPAyAt=8$DZgt?Re3aEJvaAP!Q{*P7d+@BiP+7NR z=2YN6_I8D?9D5DWa!x74ZE~n4gO2m8La+K#7;NBtt`5cou!ALVCuh$DUHPTGU`}KlBXO*&? zCAUEkU-e?OkK>+^;CyG!+pKps+46lTSg^lyyJGC?sK^8lbRJfWGbH%| zAvnn42L!dxqnv7eq4RPo8T&kVyFzfNTIs;sBT!!Mf;J~)BV(h3?+6|-8GM)hIJSu| zqE8fjPm^m!<-=0TXU~ndu$3DSL!B@~2ZRj{-N7)4p-vj(9ol#*Od`xlT}i0%6t|Yu z%~md_oXT2HZhYKB5f#@~uG9}jvCI*?@n*`Y$^UX%H)Z`YSrqZ<~B zdO`Tt)UOHbZL~?PuV<4L7+(AVOjD>!?DixFf3Q{KG(Uwdnc>vN`OP)Cf~q<{tTh$O z#dm=sAHgvfGN)VuYVn66zqpgb)m9utau7Nc)zJJ5FPcg&WyVbtd@D8fKn%J!!5?k$ z#{%3BouGZT#Hkq|vtR|MK{f$3ao(rvXfX?gcuiAX!a3+Fg*SHBhP`!w9 zs9o2jJPCOWgQ!o(jHL`-{FlZIon2>QF{o}3zkY_*$5wtv85WVQZY*9!zO8OT6DClL z^7G`1iKr!3H)R)rLA?l7_v%DF%JhoLRiL1zcyV<)Na_!Fev!BrlvKA0ohJ&cPS(vq za{NLJJyti<6c$K7YjujYnJ)4hf|`#~nZ?UOnjus^_L^S33R_e6G#BfK;pmXCwqObN ze)gpDG&pu?*}d75rYRtvLRRdFXi8VTs6FXa63pz0KN2Bpp%-Cy5nJhJOYLWl*gFqQixtW?GgkYM`DmDLSw?LUt?2q@z+idm_th3L#oDAUwZxM-$hR`HZVC(?>V7okp^5|5x`J_FCGCy@eU9#%_7 zQaen?b5{>f;Yl5~6VKf|O!(9rQHzY}?wN}&KT;vhF zu($9ilZfS?OZ5tmaYY>yfsJk9as9DAPk0uAPH>)@>d%I^@M=v3;vhOqh1Y0bhKSkF z{K9KBjSx>Z2VJLWwD7}y;q{uv#m`?d&ni5rX`-6$DLkc%+Y}Mi1~zZdG)?Tu1fAZ7 zJ#RQONA1@uJVSSC4tq&22yfJgX^0UMfM(E+X^1Q7(aqPkv|$;S=1e;PyyLV&T$*#) zXyBcTj8_$3SY6s@xH+4w9gm@zEuN!UL%HqobxMuK_iBN=nh$hFKWav@EwNv zC5;#czPlOt^2N&MuMmuBz*n^NJ6rT<3Vc=LPuKv5epKOW+VXFfyo z6~4J#VY#D@Wh;Dpjl%VgIE`ko@SS26{Y_XJS_pjasFGs#=PT%R;RkF_xLw^!>H3jn zJ&Ux@AJfZC8a=hx8k6Ua(mE?kFNbdTaXlX>rInb4vc~i^S35?_&!d6;40>e-)O}38 z`zs0&>P&gZ5#V4W&9hQx;2mQwbXi0k_e)sv&Hvc4u7v_^-MU>ZD8_yd+w(iyB7gr-Mw{o`!LJ$xoD7IVoYYK{+vp@$lC5snY zgUsre9&@Du_9^+$W)_o;y8U-rDZt5xZ!Hxn#~AZLKlQ1ddpVvDAZ=l z)(1fh!~JMwwrqV|k&Dw=@vyxLpWL>r(}Au0pTMrK3+%8iaJHc?u(S7pF4Hf?X_sjr zbBLc;>=+B$q}}<&Qe^Lz&Dvc+OzQ)>TvJfZiEY{1NCkzbkuboH%Miu2ZUKwcG)UJEG{;>@!lYoL>yQ(nzr}4mD-XRYn?+3mKFB zMjDjw90VRP(qx%~mZ9dLk%r|roq>mpG+iF$dk-6Fh8)8e9WhcY)IwulbJR$)Y>q*RmHY--6EIRQZpTJ@Rnx@r;#HvoUs%>PHHo+ikvSDKmMpmrz3CchUhm4< z<-pLn_uYbOu_oC_z4CHePBBuy3?2i94K|YHi+~vh6XaPJ*xF!YS&ZUY)5ajy-=P+$ zxxio(c`a&_nzrUeLHX`lU^|1!vMckky}__-G!xjtxJ{QKVn>55WGZz)U;X4nTFO0_ z0y~>Ex*75wl!%(H#;Z(u;5aZx-Alyf=P#kPtm$TOgj`Yt>|rdI$Th@VgNx-6)LJz? z4K9}(DeYx&l|=Jm)#NEulPt-obZYt-#$g#P$bAiCl4W@}=b1snomJ45gfF2j{%!q)1y8r->)Ox~?GUAH{p)I2da!MPrf87}#o4Cj zwJ}n+;&?6nwu0;6O~R-zQEP1*EM{QHx$Q#w%u4?KD$o$^8mCl4&$bQK6o@aHzR21( zOjA&-8V=cTP08Zx0?-Iu9>O@#_AqedFMQ7_ya&gqiV_-))-|6cu0oT%ZH%c0#kZ(i zwiRlM7P+WPw~f_=GdO&pahm*A+{dT|w~e0!PZPexPxQ8V;v+A{5*D}F$;U%QGI zwQ^wpI2ys)HFdF0N6S*XR#R9!fUK`A*OV^qM=WY9G-Zg2@t{ggnIeA!XuYN^@ys&N z1|7z1kp|=1%QSTs-=dMO-K1^ih+fE#TGJ-xT5)j_c=<1gO~yxv%~a@tTl-Jz=UbqA z(fVKxhCr>eQQ94xz5=ngHr|$p`of8@$;fUi%KLS_gHhtF)RDQ6`)zs`dJVFy+5}rZ z-XDgIO+#eKZ9RbjgRVRP)vs-8Fj|%{O%e@yrAm~bLBI54&Y)Hr3`jW{m}D?0x9tLk z3?|Db7}#WkVaYx~Z8L-E^43d$DF!p7bsQKr_wQv|saxnc)ea&Oq5HnUD7H3YVv=s$ zShDm|*lA(Vm3vSYYg^insKkkuvnXw4Gl{q!`+9T^YBS6Wf^sK8VpMxwV|ECbjhwxZQV^n88W;Bm}R7y@{br`2ZLEM_9|dUgW0%_ zeGWL={t%%|{z}DjfZe5N`2wqUpv@e_^CGLZz-Ag)q2Ax(Aj8@&`ewb_uErZnE=+?j zIR;(%0u!&Bjhd8NpR{Opu~nOIq~4?@R_!4BDfowOiIv*F7wleW^WCA-@IF{O)Rye^ z)eb-BJ-dCiBTVYJlKsBgk#*incKm8DI@j+}$uY{f_3LaOZ7^V^UUnsHkFhVrtD5C} zhiivW{9lQx#f6%x7>}!aY0|s}GpyPPHtn$4Uy2S=?L?cOhOkb`CwU7*?IkwXNZ@Ot zPc@shlWl$;^+cZX$toY@GmZUcd~!-LxJU&W-xqyWQ~^9@da9m$qLupM<*-m}-wmTC zYaq+3zCUe(*RrY~U=J~E(_lP4$Z9uj4U(+-A=W@vLWA$oX{o+VEE@r{+jR|UiRWTL zcWAOz?OJ`OCP(bfg6u9$9`VLB(A_txoN`5P)IrtvXj!xvM?de?GOw7{9CV+S`QxV- z6TE%yM7o@S>iEsVld{Vc0;D`7swQ>q^mLlE8S z$F=8}4aF==^%I(0annH1lbWLOLAUxjKU}FM=qB{Gs$bwcqBi4)!BGjAVx@kD0d@5v zdnb$|C-9?kQY~ohYNh_N9>T@;O%y&%Azd0_@<%WTR+rmd7SFV*D{c1Tx-6V$Rj;?H zkya?~2Q(Gcm)Vj-8vLCBX19)G8sMc0T`Ps=FQN*}s9vRuNcC!?w3g&~@6~IJmfG^= z3xI2lvbl11K5&E0kfFq=-5T(i;ljr|3{DsV$EE){*Wu@tsOp_Mw0mv#0mC0Mh4@vl_3Hd_<@C|l_;u6%+;?M#J63HGpb)V7?2N71ioo^ zQ$FK}E7k&U8ELYdzY_Si!LW4DF{*yY9@t)thqWv6j=V*8V6&0P@L{Gt+g!P;$N-qO}xJ0qQw5 zqJ0!G_v?vn)UIx&h?-DOq$0zfOssML0xeNL^oe&SMnBV(dQs1*31%EjBh(R9`NbLs zEn(o%6|I{~8`P6}j#c|)YKQ{LsW|oIYBlG{DJr(JD5tK}ldEtuUUlK#L`&45^TAM} zI{7KesZ#&;#0275%BfTJ}tjYE`J^;Z06hpF)BDK!iRsq z-ee}dNZr^C_M1B^@tpDpej20lcdHiJNlT~CwyGA}%NPjkPF{-Z>#CNRCd{!?Qzqd| zm!z`J}Bw%8^5a#D%+mO zeI7ZA34hqgAMjXFH^3qDRCN-kTdDUTGpml+QGXz>^Uh+2I2v+q)d^b$QKwd2ZGvIR zfl#TcYfLa4xf!if)wM?I$`7DnRo5A5lzi(_;7KEmmMsngPZ^Anz9YaJ493bo4gpUa z#F+VxuHZBFT?lB(tiLSl&9G%9Ro!CCyQp5b8jH|AD$#9qA=1ityFpxiJr0)dG?t@e zbJUwHX(<4TjpwsD5BMsU4U-V4_Z^Ck+O5Iz44jTB+H?5UgkHA;`3pFOg1% z2cpwn^*oMt?g7Dz<|VkQ1?_CrO9pYmz-7RfjW@2`!1D8os-oD1eYQXFRf9N^q!;it zgMPWR6Yvd#7(2cc1ixi3#@kam{*A9KQ>i@f+46;L5WH_JTGB=Lr0N5MuAE#5{ErDj zw3RyZ1o%VyS9nB=o*|L`=kLI7|RpoO{@f?3|@k-2TYxYPA{lJv*#?^`m5No?y#$T zj{F_tiK=)rKW)hq)DL0MmAsv^%5N}Q@_NpyMh3l-_j6Vy81zeC&{@^kU_ib-2N*CI zl)Qkms)@t5b2(**Rc%uhLVQK{=ny9wKIM_GHiulFbcE099+{6mYL!&JVcdoK@;!LO zM5wDT2X29dB&Q*aQ>NOswHwuBZdDsc&dY}20uv5Pjzoi6m1)qGZ?IizYtk`VmahS} zJNHTBt8!p_C(?$MIu7#a1IZm8%V4WI>^QzW}W13QqwudJHPFL_; zJEjCMSHbr74f_CRD0rT|nG?`V1!L@v94coiXxsBSj?7W8gVyDqOM&x^@0goUaY4#tXfW?8_WO@PTD`?r5W4ooHM8ODqE*n6pf>HK!k$?*njJ7v+ z09>eGjD7BTfMp8C+WdW=hH?cxc1N~{3I)5_JGi*0RIsOAumP}2!QS@aWWYrV_O;t` zYO7XopxvPXutve5w!uNtui!{KuN1IW!6dsUQ?*#Zv9``8vP8kO4iy+emnxJYhRHgG zGCTN7E3}4-70dzjX$_Ysm}^I|c9tnP+y1;S;Bp1??H91Q*|0*vB765GfGZU&vDdc+ zT%}-{J&%3kQU$B*oov*r74&OeE?x_~#&`%#wA0cM9bfImhEYSkYNwa0CZO5pl|yff zvUAxFu!OfNXxW+Qmkn1a7-0{gben=vwx3P!N(H0s8FK-5C>Ucu+y?L}1!L_w699KA z=&=i~1>B`zH+$3dfY&J4)BZaj@LC0X+w++9>lEy3TU@U0QE;Hv0d8blZP~ z0Ul5=%6=&k@D2sr+T}d}?^H0_ewhpCyA*71@8=NGq+pEw82i@U3U;t>ZwGjfg0c26 zrs`e=JK5v0fzxnML61FjKHwph!LC}Dzc^XmZ>&XycghUYwLc;_Ivp`=k@W{v)-~JW zV1G1F5_>hkW6CR@SHP;_Aq896%Q-PVtYCz_mIZTMLAU)bXW&N^jIy7zb{c8v+A>U80~=m2>`5F_ zUJT@BbU5Hkf!r+V1o*Oomc5Q+$SVp)*f$LUd{x0HJ8mN2Nd<8l&LqIs6pXRoW=lJz zV65%qZ2h`|9{a)=z&8}^WW#joGNQPJbe=_mpdzr{N>R&e#CK$ALCHh>Mm_6x8j31%RI_XxI&ffS)O7+HJXL z`CLJl{ph)XU#JvWb}4(umkLJM#TMXy6vSd9AMh&$aY7tx{cGhaMvn2{C~2(LWq*5! zzctd3@=jVSUHjo24c+h;Lo7FcReGBJLnG9FQ_v+=pT8@Fmmk=toWr*w#JKvW5=Pnm z;voF5f>^~4z_L#vtYWcl{ac|}IXwKMphuj@)S#)e)bO-#7aZvd_LNhvp7qG{elWa1_FKD1vm5@e7M*Rvm3CVf;f(usp_v_2m56f)&K=# z?H-)i2P)XfzKg^3AO$`4qm_Vz73^wfpd1>8DA>&&z9CVGMycg$t~DHhQRzw5Fmv!o{| z{Flp4<{&&#;p;+VKbs`_8SF#seQd{5R8xB?#NNz>Ql@H(CqraM%vScVg~*ao!vbZ9-~7l1EL89u`vcBVJ_Xy_Cp>`jRbk_{ z;+HwVrRHHIv(suM=SMV=h=w(${aFtP)~QJFZ9JsEVZDbSEr6E?+#KSdvPD6-InG!b&CB6oXl10XJ+3!AXbxW5 ze-Ks)Cif`@S5;x$dC26fJh-?T%L9|Qi=LO+XO5ekzy{aU48g*{;O-h-01Oy?g9O@$px*} z@xSNj+U4f z4yDzLu(fDn{zl`D?od=-faRuwG4>X&xvn>tK1XS+{e3#%US;dCFURn^daC z%6-?n6-=|sY9PHw!3=v_B;dWuHq$=IyOM+E@7-8dIX2&5ZaAc1k$pKwtHa9HZ}VK0 zh6mJ7RV~HKAq~%%ub~MVam(y_c7x}IU(7`=`$M+p7lbL^!I00R8(uQ`JR0v{xa^Uv zl~+u5C4B!N#D3ode$`~3zySmyb{c#6Nt62+*zE|hFP{kfx+q+HAtuCrkQ2un3V$DB zH;xB>Q^ogFh+Q%Z_$`Hh3(>mFVMTvwvbS^^*cPwbLBVJk;j-^ff?%YJgAX6MURDd3 zs36n^&jlXsvS89_4nDeGjwciiWAH^=EC3r)96PPcgS)S;wUHj>LHittD;}s=i=_A>~HtGxS=8Y*kKp@ znC#{cxH!?vzJ0{SzO8j!cb=|Ih{FjeAq^8yPJlN5A`HwhXhyW}@( zEIBq$alMMhj<53B=W*D~bkQMC>z>&LFiY9y+L+$72Css%I~0~;tjSg|zr(yjtszID zq7L&gVNF%2#D1MOdoxw}mDzg-1I|*g+^%f^oUN3r?3!}`=P2m!P!7LyU9t}^wa0R~ zmZuV2XMf4TGGBNy<96vbzkJ_NpzzhYT$0Tb)@Ix_x?GbLDvTF3#iDG1i;FTd?mFxk zkAnR|h2PcXvaH-Cmu1(f8-NPsA3y6S?f@zkK4!>UfGUL_QuhFh6n@x{tNv<{H*_6C zF8gZ~#?JtXWu0H)rwzIAuT}U2R`48#7At=*8FJuRqVn^yAxEC23cq5=F|JP8pETqk zcd^267xn$ zVH{MvnH_PX!uVA=af`c2+5cqNCFeoDS;>Dh?CmRoFH`uxhJ4UauP}av?uFKnHz zp_{{@>T-oQs++hi%0H&^DVrd_!o`~qGp@n3pJYSdt}r%sujLH1Q{m@LyC=)<8il_$ z?Fr`sU#I*vxWrcp8g{Grw&E3W4t0AJzS3o1$GPKr7w>`a!VQjM-VVH1+3$17wb_jd z?|0d|20?z4(!b3mZ>erp@*^&}*1JW?A9UH5=0Ja+i-V>a_ngaK%lhB%;$UdTJ@2wB zxx~Fg*}vej8!iUEOW_w?oF^W1l?v^b@P+d27)aQ2#kO@vt;_AK-eWEfndc|R=vs8c zDVM#k9L(2USY(MoId2W%8wwisj{^YTRM2JL!o}=c3WnN#mjBxdT6P|9dfrj6m0dR( z@LdHX>}`_(-&4?Smvh>BU%@DQcRRq-3bw@<&#Zmm+KVj2%|lw{qw3&C>yyB3y#Ot| zb-x;ran}a4zC~VIbv=QPNGxvT^ZWz(pu|J@){9XLtq0snnjwVv!I!r6hL5EW*q6aCGuRu(IeDXwm zP!nFNAn*7!K5oX6tw?Vjjlmh;gl>JVPAxviF9venICkMzUhq@II(|qMGOGhmA!;3? z%bzNau+N){RNK1vNg=$g8fSEHA{X_OjTjLnV~gw9QiSn?A`4u@#pcSLH zFD4>Ljs2vr=~`CZOuqvg|7Ho>R>LYcrYN(G= z&+as_OsGFcz6XPs(e~kfyS}Y@;m{Imiu!g+Il|_8zW!VVqwJFF0o&_xO&)E((E;#0 z_1y1Vv7WDY-uI3X>-l=;eeYN?U)6V3t~_G8s`n_^O{~f5yC~RGOosJcmFM2}BN#{O zTQ5=^TD|xIWk9_1zU5B-Z5hJro=)#>M&z6dWR!==D7n94ek4)%Q|xm{_sb zU#Q@4drUugzDU6l_751c>w7CW(!LafPJJJh$V9OLRzE;VN7=WphIF8Uqir7JRX<2C z+|D#7i6wgdV4dGG`4P5Pt;Ed`B!+g8l!vtX#E#~ze7`^eTv?`EA4;MZ7jsJ`muUHfq&D*`>$wO zY<@hk%+*dpL*3SSFW88YCPP`UOWLfPhTj?exkleygVs>6E^{?rFx&fNaPQzw~7Mb zV&(6oVMitcSLolPXW}?3L)`e(SBkbHelwRhM)g$+e~;B0Zp7*rDf|Pr;xR1NSL?Gq z%nw#S>oC;T*C>qDPu?D2zs@^<)E|DMcRg^e&bxnX4!l^kkE5oY%ko~LbN0h( z)f6|-^-IMlkNlc;=V-_;(PKn>Pn&i@A@DMNhsfUvY~N%8uh8$7`Ne9e3V5Y{Lg168 z-H$`pD*bbT-!Sc?all*kj}YMXVbk_u3a-CGulSw#W7Gb%8}K&$QGwTn*m2l?tlut% zCA6;)d!P?^hw2|&L+q1G-&G1<8DhW4_P$f$ogw!065y-F8@S@e^n4Cv*XmZBD31`^ z9|e4!9w+ckA$DaS;N3c>6mjEv*$Uu2%KiXuOh*In)rSlHrV#sK*6)ofKHS(&UI2WP z!iPib8JrJp){}(((Ga_K74R)8KS#su!bad*Re2u|wp z{%Zis6^z!x*)w$cvL}i{YsDLB#LuY1*-Mm6&A*Gt-qp+|32lBM8b4YD5O;(^;fYyj zMF{8F!KE;ra<=_5T+72j59EuYT0$ju2&p8J#t+1QEk*1bV$yFVN<@k7 z2REGE1jqETpoE!NOX6%0nz6}>aX?lM*V0bqd_y^#@ELN%=ms~Otu?4l!R`f4XeK_Y zP-bH3-dPK0qf=^kpd?#WhB+UP0>X+0U5;FV2D4vhv+T47jIY{rm2$gUrQGf;Mzl^} zK=?&0S6z4N;%KsZ=iNKaZaW4}?$-Z?3R~>O*8$$6cj_ivY}-)4d-Y)g;#4}S$-?}W zxmKk@|8X=qL*%@o?}8|fKBQb!HcJf|=>~4-6nt>$AhQ3D7Mcgl)~;T_X&sO3=Z2Eg z`aImz<%Zo2<<>`9gS1G7@}LeH34^v;n>O8b?Muu*y>mN9E2aTMz4ycPn zuE?Gpfx1eB@6rzfijycJatOxj+-~&B<8C(H1k`<%K<7k$G##kN0)e_kMwJ0wAW=`P zjTez8psiZ7!yX6!LATT3&Z45G}`NOBX|JYGYxq4*#`98U#l zb_DM8K)~v0@QB-8-89<{XiWYT~Gg_jUNbb<*B>y5};Bgr> zph81>=^AI>9#{!$I1Lx@d@RCqa>hm;!eS>U^$j4Vh`$1mGcLwMlq60C%o#6JJ64-Z%SNK&cMj`thk2aLEB@f0zDKUX@j8n?RM5;uw;Knh+AX6n80dlk1Lpe+1|29XOM7qM_G`)_oT`zAS)oV|EFV3yAKcxXr#)}{Alt1o5Yl_u2eebe+o!WKVg zO(#Lw3!dAUqBts^DOc0x`4F{<=&frnpnVKIG%RvI3jWXtHYv86UMT28qc4J-^Fw53 zprqkfQ)We8vJ+@bhLA->-Vc*QDH26RcI^Q)_N35^j(mY$QYDIsd=;yJL*pchjeG+A z=g|21!iy);(*U-&FA>of!iPJ{^vv;+b;Cafj_x)@yAvZO8eqLe9#X7YY>nqd->V`IiE9bjMQ`5&38gQ0HC(MMd_n2J%Q0 z9XT-(sH?P#iTte;C{9*EY-HPMK;5~3(Ljm&EtlOpA!VT*cHi~BbzXQs}OqpW|Y zh)?2Dfz~YI8>dOTEp0;0w@zVmI5OL^pR(CFl^f}AC~YNe)a?kLl3 ziOF$u=Psh7M7a6I$ju%pixSh}<}MONNAi1no4dXzyr8$zow(&|zOO=}n20#)1f^Hx zSAF;Dafn(sp~N?L8xC?rs{~y;jVg{z)_rIw=E$X5WD+TD#03xy$LcVwPWUntImd)8 z6;t1+EC>%rV3FQIm(tM{)tXD5<&eZTH$YPdNt%uzYBoNS$N2HN7`-{9TsKE9) zH|1Q|%W{(9EwoKMfgvn(3#*5kH$n4~bHUjathrNY^7&-wPEMcHJORyKrlxIb9aJ-$ z#QuNEc+B9NBB-g2_zQXmu-XrML?%tv;BnSq;tXUv>^Of;dhFQo$Dv4r9{qH!2#F25 zL+2T+s>%=0AY~yQnTFjdlAw*KhT^i>U_2S@`H5!FPtbE(G1Ss)w6GKOhInjXT&3siAV2x(J!a_;R+5+w?>_v%h_aI6CW7CWJYUbBWNP1B}MIr6~g_~;& zp>?R)%|W^uS*V!@o1Gk_6XD~&fDb`wBRu_eZTAW^sb#7L&_pj`vq~@2LY8wN)kfj8 z4XrcMrB5+rJW1>p`ebpa&x9)cx|N*i3gytZX%*sZRqA`5y7P*0&Ua@h`woy6Lp?9Wr9V^j6Pwq=Zw=Peg^qz zEP3=S3#OvgX3ADO(HNj>mtmaL6T)>fiTy;64`*p<6FWil2zK1`lz?cA5RKDDO@S} z3m%f(YwC1pj;>iaPm8$6Ym(4ysd< z20<~d7x3p{q7^WOfZ{LnqtOt27DlDs;AC|J!7TC5_#(_Z3$!Lox-kv5IlJs$+NRW;+wFz+7fZN~?o>tjqSV@eTC1}e~%rBa{Socc_W z`surw?picFBXSUlASgV0%8=LW_%asodfL6#s_|D_gxwtvmvl8ky#o|!v#P1 z;!E{>&4>~8zYaKaAyy9x-w3QtA21l^zfJ)+&e9z-#F@*cVRW_FG#-KCj5+wA%L(i> zMt9M?rp-ZdI|8GJ$Bw^Nw)k<{m~?P&!z>g2B$iqHC6@3fsEt{!JtiIeO_??vai5cbL?3sF zM;EM&#i)$aNS|yy4~v;#WGE_N4<4}?54%`MGl6I2Cjmd^;u+IxfK#~)G#+;`j{NiB znVI<&4%@<^@ubW9C-4l1F+LQjo2NmI3r-FH;rDshfy|BpJ(YPe8cSxlU>k-jhuPYJ zSnyZKwWu3RIu1YVy$=w7(^yy+ft85Mc-!S22wcb|2buk;`;@m0az4YsIV^|$(y2Dn z7=f9XZES)|G)|VokG!BDdse!OJ!@8&Q#R?MZ0dkB8_Ysmr^Ebu^93hfl%zn%r8K_bqa@nR`a+TGLjr zelSE@na+i%vyPUN*6$6bwM#hgm=q{}Z}15WzriyrYCQ0d2Hz@}3oOUapA1fvvzAl$ zXQ8_YGMUt0#KP%j;0%$^Uj;_>e?Wo3haI zhl9&?)syi1GE>#j^!^O2Ao!T=KDEW}=>XaIkDhb4^yxN5rCX=9;|A zJrApbR8cwkCM!o)MuCt`gKV~#r{wWU!;m#o3^mqF$=Pe>4rP6onsG#;W(G&7nn?%2zxFIh3G2Q2B1Od%Z&2BF7&5z4p~md)JbQLItkL=`*>yxByR(tYsceXbU*`4z{IW%?f^j3G z-=x|}(MU7~a@wO(W_^em)z~U3uo5ove}@?hX)hG+qS>yXLUNcvg%k;AY}idKr0Z3q zp2i0K7py}Og>hq0gLatB4O+{e#`LhQLb*E)?sj@jm68kwH;s~GPFv?7L{1jD5148Y zntvAzGRLOk$3J!Xo`<|o?;`Kh$BzG7j?1H_VvRC#EljVFgO#2n)+vo*gi0F25vNg% zIH}zCHnxd7r&KW#T`BkzL_^;$MxC@wcpEEfGc6uuT33AhAMf6hgu(y5d&BKIZrDd% z4YjAE5dRq2YgH9ygfMm6pk+mtuF`MYS zxEhU?4VHuVEvSl}=(CyJi!$08e2em~bAVr>Vq2ps8He}-=N6V1X@)#J;xw_i;b|w% zBQ9&}4BF?4w)_O}EWS8pv^U0}>HpRaSoDqa)NVu&l>rT&E^;hatz%U2wrMGzv?*vrOifD(kb1p^iw5p~+}8VlvMGAxF_4 z;F)97Q*iM%6R_Vh;ci}Qp3~vpvcRoI{dm>X)SAsGd-&r9RC)Arpy;Sqe#fc*l`PuK}=P8w+tk+U? z?RvOMgHL0U;eCj)+=GwO9+2dNoAWHtpENuLA{94YQ$Ga3xW|73LL}f%MBWP1yK(Yg z32;Or0b6J;CnYo~Ek6m7aGxjvwj*f&w(0FFCQCmgoOU*XyM>ZZO&{mx8{k3A&yJvZ z>dC(xHk^76K>vQ)ST41udI%CuK`(*(Iwh@L&1))$**pb_dZFHX)NP{{x?0wH^g0fl z`&e3ehIb@rZ(n?r?i;6T$5~owK&Oz#@i`#I=i?)%3?Hq|18XVKT72XJE!YZT2{uDT zdp-}{b{sBaUYJ}0ISkpJOW~gFd8m2T_B>2kpQSxJB2oO8B3{v+uLL36^E>d&ay||h zr`mm~2pjHCQ2#mF><`+b5H^$?qm8pq zk^j1i=L2xRr%ltD@lf&^ZJcID1I7d}s3G-jHFS%Xzp-$D8Vw^kH55@au-vG}ptnh2b z$KviW0-JTS5*ESHC&Et>aMmh#=S*0|+6Xng?}7Hdf)6c!4@BJIO+#F>aYZ~~dOrj9 zzKsuU8nZ`s2`(ed@cuy~ZOVuVNbcWp;BAo4qnOk`aFrsuOtIowFE*^VGdW@!+^F+D z>0aP`H>^4S+zW$abi7BGZFkmPYXtVKfxml15^fPJ>QCM#LS7N440GU06n=?i8p! zd>RcQ_PgZv>rZm4lhv?u0r)?OCEmxt+LYUA{Y)CTf6L`0EoaiYgR{8#OPF^BmhL1@ z0@kMdLG!EFM^@m%bePf7d__VwiS2T9YGe27b!3`l)N&?Qh z9R#=GH?jlV6msS^{64V7Hheae#Ws8~i0r4qK4Tkx4`SHIG~OK2avPp+*i4x+35n{K z4DmxUQB2SaxaydwrR*=qLa1~z6Ey$?6Lp%2diY<7`prqyVJA_~fk2<+fNd~D4{wGoiGLNg zSZ+{m5v%ySDKD+kj4k4)wB7+q+!2N1V0^ zPsrYf+tov`;`j+q$mGMlALUcA@^Mp;Y2PHMe=Axk-EhF~2Zt5nR`|OW)*dlv1MQwvc+Qd4THjMz^4B^az^Rx^jgoPvC4FLTpM#Ch23m5eL z92qNfGLf=$?0FciLUdNcAzX1thpdY55N=If2b_9cUnsQ>VF_m3ITLh5$g}TYBy7BX z<%DVFk+U#jqvj?r2+ukoTXmjkDM-4liqXIb#X zay`!6Wa++Q(APjI`wiy38t6`-xt#mN4rCv-?ndPgg(+9wv4}U0L*;;=mAAuep8c{W zL!W-4xF1*^Jbxa5^}X~^88m-7%w`YTsJr0e*F~7}Z)>r1!TAViq4J6CezA1HoqPz! z9Q=)V4mP*=@RaAK=J!`_^g%XGo5JVNdQUcx!?GM%hWFrh^aL_3*D&{qHOxSd)5`7> zYZxzZrtcyc$`e@|foDB468Hg8&MyJym%%%0>Qgv%!>RF*?%f6KZNSGgK7Ia+nT90d zPIHDs=P=>F!ybS6cPSTLpfr&#o;cIRaBxQ}7Y;34M061@=5oC5$s&JRZ=OVae3si8 z8rew@jpy^+@qCtxzfdj~e+D6*0!3+2+y)BebD{wA94+c+D5dPf(75ZyY#MbBmiN*Y z{elWHwhjh2#LS06)VUx-CkAWv*A{(|2(8B1Ld!#~5!6}~tkqguw0SGEu3Rm&prl0= zQ0uB-t!~<)V|$==e1p*PASa=RgB8NHMSIsl;gNkpL4(4g6BmQ=q!`T1Xfl4!1>-5c zpdVu5{#OhA6Uvx}od;rz2G~$|;XlF!W=}0NHYcc9T5B2edHcB5iU&Kyd>bGt0%XR9 ze8IMdVcax-Ll#1(1{=1~GFo$yvfi3644tPVCj zU&~184UH|E!gjyI+A9o?({LpX-<%`Z z((rm3J{@crsbxHH88oi4-V%mQG(1eh5F{FGX}FVy`t+bYo}*<{EQiKUs~y-O=588( zPs1NPf-McvWwp@Z!G;}?nd#8jXJrV(RW!U1WQGQ1u%+Qf8rB3GqEwf1`(nSfP8jCX zu#ko$Xt-Y)uA&c$w;mFPn9Q`OYiamHj9|+cm(uW)U_*4P&E?QIVErl# z@fc2vdX0u%#|ySJtfFD3+@Qi~uVq}vn!dy83wDUvorZ3Z8GEsM0$UoE&~SRNVU(6( z^@GNpR;e(Irr~%Relc3GrC~k|w+0)c<@Cb-g?hG{e$ z5p0NVwR{yc?zbih!`op zrQsdHh8S~xnhT8wt%rr-Vj5mY!%ZQAEe-q9@Y7&J)MMvm&^T)SCJd1=E$S2vlR1VR zRrT1DhMi{y6%Ja?Z?{0>nAH#L5EJRsq9Q?N97i()TgK?2VQ#P?#?`K4pz)BkKo}09 zVHyoTS}oYpFouTsk*emo7=|yGLE~ZTMq${QhL_T?{jGv64WnrIY_K7E$DQ@iIBvZo z45<-ygoa{k^tei@MMHB|P>dKl7UQPOc*HsvY>aX={E>#QVD$;MjFIf>6{VVXb$hIf zG+nQ5#CUy;m&*l!b{Isi4d)RKx*j?gjyMn3Xw^Ss$R0f{8w_3dZ`-G7gO=-mv=JuT zuEjcPaR_b+AmYfCL(5qa}*;n;B9 zfUx?WYcy?ldzGNaT5H;#99kiD51_{POjDo}rtLk`6BiNzW9 z?NnM+dc4_NON@`EWU0VJ{?Y> zwzdnv#pjC@`v+mo(`CAmi9{44AAysty!>S1s&qEa49n zDNsIK)9w(zvIwC{-gQ-PK1p+Y`jpZeF_cGcr@}fc(RApipNWjt;S}F!>QxQ zaFW|N4yR`$IIoSksF`yfbxy6lu$dFZq4f2KdpC3Xp_v(Pa2v+)GYMHX-sE={9L@wZ zVdEWsAwY2!-xm+gFl#hc%ZlaikC7CsUp`F4JXFyZNV{9Ko}I&l}JmGK{qIO8u2pHIgpySC*F+21KRBd1v!hQ&u}KugF&n8;qC>@gs+lDn+7D z0i}gLiEFA#E6OSh7fRn%)s=;L#f%6>*!Hh2Ru23n)xLtFywZx|%0SFi_SMu>R!iHO zB?a?9VTSeBRryq69TM)UDr-uY<_Si?g{TG?p=+LzuCme^zf1<&LgB)i+VX&!WY@?< z!;+LwDHoJhO0koP>cZNpq5{9lEt*z|lou5iz_D_r%0MRWfACNXrL-$V{MB!CYkKN?LQDj&_TvbF+0mB1#4;>0*nRf+6ZRxlngWYvJEK!M@k z=@Y(1dBvqpdtX#r=`WD_MT_Q@EzDc$G=J1eK~+g*b#t4O3XA&%t1srzi8wGKH?Mv+(5u~BUMNtwHP1^=9P&W2fw(ia*5KdPzoHs zt9&8{tXDLC_Kct`pafB=(p#w-y-O=)da>55Qo~a49I&vtLIZ3x*=j%H!mP!SKor7R z0TQi70yF`q-TDgi0-ae-ZJgorF!5K2Rw{XN5{CC6mBM0{4j45>Wd$g#$_js;uYx_+ z;rV^6=Vmk@2vz&aE34UR9PyyROg&H)77~@{;epBxn$e(vTr^Ll(!$A0S!q>^%wUQZ z`p(=1Q#1&_81GSPhzJ8HR8SlNn!`|Sbv1Gy7$=KVrz>(w3TkRZOsvfL zq6JE$#pN}DiK>uOH`pvH(V-=c^OO4^1DHaamn%48IS*fLZJvt2P?i;FoYl2eYAgr8 z+UKvWRz-@DqIm#dOAl(-0v1+QRAA=AP!c2wR8&FLycRX(2ynFZS@}3Rw*?=&v{-uK zdC{klx*5LPWtdAnF4O$9$^-K1$Xw7L3VOGoKdp*)xy*U-5FU-(3i8vcT+r7?ZZ$9P zcoOdTWYPdvi1}=lAI#U{5}bg z-EG7hsg!N4DxL`ZZRBo%T?B@Cq|GU8Cg*zkHU2c|ify%%A2i?A;y0QX=Z-n?qbtnZ zyvSmb)y7`xU)_YXr&(lWL{@AqCWtlHkTE(9%hRR)0TNh8X z#=mPmymYrK-28IMf%)m9%+@2#+6lg=Cdn`<1UJu>Y3F4#@ap!{jY!LZKQqgvZtZ-ftkA(;PWt+#!XB8=I_gj2bp#8 z{*)V#%#)X#g79*aN&aD3yrAPz+*_A3`8!+(%(~r!z+JnN=Ks}Jr&?nG*N9~OrR55m z6}C}7wddKAS-?9ZEb4w;bHGY)wKCtoxERdKT;yG&`_1ZNv+ab&dmmgoAM6)bSX(DP z56L}{blZ9lQt{Qr77d&v`2{^eB&isRf4iPGpU@7N53bC8{x_7!FLffe%R~KESE&AF zt%lNuB|m`v-D25oSi)TGY*h^3_gC!}?#`au-62Qb=-n3ze=MhyEr!(=5uB>~0pO0% zQ;jHD2(N6-lKI-tL~d)%7{2r88r|9JqFgT&>O3D;V)=W8|G?t0QZyk|pzvuIE}a&G+%` zB)t(CcmP$}TsCJ`*CF$OHN@HhjUv{3H{@S8XVc{c{^zX$i_>f0u-K?4F#chF>-da5 z2??Jherj#BHqmO|N>O?TSNe_a?cPF>-?7~2u0!`t*V8{vDs7m!*8FX`HIhPeok@{t z?!K70{4C^SYt|aLxKiZp>%~W`PUeLN?&y)3*%Fw&-y)v2-nJGtnvqtqwFZ%VwderY*SM`*vlSAD ztcI9xEwb3aw?+A7e_sQQMt5;~ZHbl8Co$okPx|a(rM{&X|BpVu)y*bzO1E-@6on0I04{l_bK80&01JKsXrZT7#K}-^Ba>TH}llH)}_fuQMmkwPv{@%*RYNs^iN> zrUN`;PB1GcB#cO$Z{CaC80MZ!jwG6YugD#}D6apS*UUCnTlTo^7%&a5{Og zw14BCS!Tl}9I$T}YOl58fPJf=-xT!iwSfT}{uY|;s8BByerlCV%bm6HUAuNgOgW77 ziq>1rpA0JPtS0`v4e2Wd{gt41RtG$8c5gLLT}*}dm$F^l7G|OUoU=7E+l=y?&ugn8 z`D6**T!Znsna&+)wjq8414JA1n-#3bN5WT|#S?1RRM)OC&-X7*Tzv3dvvDcL*7$zb zLo-l(A4OtNz*K_?M>kJLvbg@L&0X^vO7kU*-v+)h?>AdNjiDmJii65an6M1Re zfcnVY<_IbsgLx}+>k6YUi~mR6zhQ>?h*lgoHEvixRONT3HL}E)=yIEXE?o`0K8#Kp zmmLB9m1)H<_DwuPwsYB$Mr7sJWgM$EnZ<%0nFz4iTy34OHX0_jgIq3Wo_$$k#Bb=9 z#|WXoa0K7zy4lKO#GPxcM}mLB>}Qw_RlC>r?wf$hIk7_I{&Cv5xaB0ibByg$@g-b- zM~~mN;}@&=m7l#>yYf3Je7%@22J`h-zS7DU_4tQHv3McSc^!@~PVuEBz9UoxSsgCE z*1#7NMh+fzVT(Uca&~sAH^(zBIXxqFtfz(S!dCyUdsQtrpPXe(V6zCR=w36tdy%J) zCk1yarMRQ_U{zIF-HHi>$TO}0_fbV2f2F6$SLP|@qN^A;gTp;z#nz8!YG#*!ZYnK@ zd(xeinFsp@zAm2BrSObfxcGR-sZy+{^pta%UDrjcDXcE7@@r{RCZ#4OXqm}5X^9Cn zxCa_Hf)Wq&J0;NyRN%f9PmJF4h zl!CG{&(s=UwPzC2=ILI8{}!q8oS{)H^WS%A_oa?rZ3R}O*i^zUUB!IQ1>I{dXf6S- zcZ#=nP@y3@Y?JtX9(fa^^6P0Xv*z+GtgNc@)G}#Un--VO_h7TBfCaBi#Z9<048)gR zQtM~gdd5~RsgN?%F>ZEzsG-SIGcr7xIbKf}{snAQ#UbkjW!#FZ^Z1q`H#Gr;^oqr} zyD9RdOd6YreCK++Q>LOM^U|lJ8Zi`zRDw8iZF-wKBEM;XRko)O5e%E zq~!7GDQCp)IYXzow7PsrLA6hocuncWXc(nIb)?i;RiY<|n!*ibxvVZxPyb4=)c*gi z|K{ukQc;XOk0MVO&p0PpB1MTU)5K~<{`2PJ)@ELv*roBvwi+mjsV&-RMtWv*_YLTf zi+d%1WnpERr=rpi6?9fq|HZzd<}9fu)3UuZi@ibJfez8M`i$adPrCLn<<0dosenBP zqX~D8se~q9Db{AfW-p+KQUmD(*ue-Px0qGd)wLrhB^g?VsBx@ZqVfXfAAIvNnwy*&Mf4I9{}f8V}C zakPba3L*zBPqw%fM@r&R;^M!R7R+ZJFOAwlq+Ym<|xzaBpE^_tHQCwumHw&c*W-G-MDcXLF+ z#g^(X@l|sRK@{DL48i0AOTMzC`p1;2%f^KL;f{WYaZ_@Wb2M^ddz>0*pe#Q>UheX`R`MXZhLWQf{mg?r{`hqk(r*EI^2`Ve$hj&C&a3U zOQV)<3Tpk>U{0Kjoi@ylma>KJQk9+OG`=UI^ zEl4c3MDq&$)h(2o7c0TK&IpIiWrt)d$7XA($ii8fEp5{fcotji zJc_M1JpTNbX^;%b%EQ=)$xc2H!Ow;`nHKx0rG*PyF!*dj?(MZ;pN&_IH)_t3FuMKU zxoRP0;{G*40vX~@Iamu@>?mNV-ADOARRyq(4NEHaL?cnnv72hhz1z6v}HtEnwRF3%`Ju1e6STGXk- z6Ioyq@hrf{r#XdrYGBnkCSfG}2k!zbvm#usjTi$k3vF{?&vik>s@K?+4J1_lGv0BQ z=8m20_Kb;l!O`4!%`|o4O8XA>{NwlOGqApp`BZ5}J*B&wbQa2F_dz|`eOOO*AH{WC zM>%IglnZt$*keFXQZzCqwVU+Jcx@KAlrC0MIuKRZq-OoOa)mX44QPKN)Z9ZD&-2?qbAxG&70o-Sy9lwEh<~Z$)iTq~XBx&cACwnA%Ec@foK)FLje0dE1Q^m-c>I}#z)-^^_Jjz*( zyQ%KJN%1{ryDc>DOlOoul3aIdX zVUTpjG=4AY964@4AGN;5#evOO?<7OCo+uv&H7AZIvA_3~j04egE-{`J%_T6COcL`0 z=P}lyq4`}55fy2RA?GpBWQ#xQUVsZ<8J7%M?A-;6lbQHqtKrD4Yttn|9(gzrfRQky zE+Yw+4+Vf@22%x@9W2ceEH48Z>*Bmdp+Go8umXwVJX(y4(J?HQw8gMm(h&?<2hfRP zc&VhL8LpRf48yIGj%E0&q$3!{P(RoozI(tF z<|FV+asz@*lKi)#m-hY^|+997sD-*wisR^=?I3~Bpt=@8c9bpJci5E{O<_jaS2XqB%YJtV?li4sFC23 z05+!u@w1~w;ul9kqB~YW!ZnEtB{(gJK@xndkr?bqNQ{!;9YLfx5)wR61>QauM6Lv% zYb54K@QxtnNpM;t!S96$8xl(-_*@XHC3r_8v0j4Hg1AhAk2MloCHPzrw@UDpM&h^x z?+D@v2~KMyo|WKZLA)Zt=Nbtv3q^rAO^21Y4;R`PgD)Wu8ibmqUP}KXq*EEtQBY%{ z;xocc7Ax&7Nq!hm%yQzp3M?K;iPQP+L-3#=GfyEnElEdl1mGme@**gc&TK0L0nTCf7M01uxO$IED$Je+clkY?r~m?z011oI_Xil9uA6$p6zMo^J3`X#tn zBn&T>w8e0hq$3#KC+R4L4@f$i;X{&+VR%B)u?%?|0iRJ$0WcmeMG!TE?*$piVzbms z=~f}lW^k1ty$rsSTn6+WRA@Apidj6@Qc43Yb0t`p3xnyq5L_e3Oa?zlu9L>Q03VZ5 zy7^X;j+9=1!o`we__L%fhCC(#{0N4BN;-<+-;$1IILjq;Vj21*?O|9Z>23@wB^}GK zPSPHR>m}Wd;ReNL*eK~(hPxD>;ciKHV|YN)JsD=>rVHteWjI699)^XA&#+k1F${T= z2K_)IXBou74{DJCRf48TN?Qx5mw_~HEOH8PKX{BFXsT`l7UM@xVK7Td8SofPa2e1~ zkj<}%WeDsrn&l#3v4Qj>C>4rvKbRWK}g55snn?#A$ZN%v&f zOVY6n`$^iv(2HAO)-1!Rl8#}>TjSswWO}c{g&Jg#3^8hu0S{yZm%((&bt;ZFtAvf0 z!54ze=Bc34CY$FtGBVVX6K7EGdn?8Cqiz!zqFth+!{cI4qJf{aFO9h5d97 z0+u0~!eRtV1)0fUmE>+fAWLfcI5^A|P6O?Xr=dP3oCew%<6s2v=oBK40cG})b%(VF zkl8?~^Qg^enO5c`R+5e)E0L!Jvym~JD`|^ifutiC&XaT$!-bNLX2=tTu{dbbNn9+! zL7l`(2@dNd)=F?xCvl|&$8{11Bxuq}+%3UDoy5Ho9M(x3m!L@}@q`2ibrP>ia9AgC z(vgt(M}j7ugpMUL5_(W4F+_qUoy15-LLylLY(;>`lHe$Q@Bk$sL6c5mz61w#5WVu1ulbrQQIXwpgSmf)aH;(!E)brN?t5)$`F(4>>N-;t1b zLW09Oi6Qk3U4VkLo1O!4?NVlTM<&1P65zV;uZv^}nqI7b2$FNn4h9MnmiE5Tu%1P`x5evXP$tS*$`xK3iR z1lYXLlXbszgcjli;9E zVz2~9Xae-Wi z3`|GrK;|PTmE=wYH%XEKlOHtrb4+IHbaVh82o6L-?Me_k z9B?~`yBvTY7}j2Pz-J&>e8Q##1y?0HAiS+%2Xw%#AXtb(ZGg(40MW=2-vba}2#Apm zNCCmO281L7#AF9d1;IKHlDQyQ69UW!!735JDKP<@BI7Z*&*DPsVPSnNNzOrGxPsc$ zxyV&lTwq;>pizPZ<7mtR2YCs+uz`RKYJZOTc4X&jnWbkCydcR> z5bzLOIBf?nGK1bUko<-+xSJ5jyn4R^DWl3{RI6m79sl+4(kMIy7CFxBj|4gG46AgwfT!uro~Ac@n%?YbIz25H=4VS259y5*X$oYG z{aFoLOf4foe)t=C(oH434iku3i>u_OU zDPhP%T+t91@SIh$8Je>C8K}{zWE&EohNKdwNHU=MCoUw_tyIrm3p`bKib!f8#~fns z6|CtmA~+?D8FrR*G{ZPa$1v5YX_C!y#ahM+={j>nS$ z#Vk9Zm_EVH^Bq-pq+clN8*BS1~UX1h?&w{!SXVoagcAq zdAR7CA)o4j#_%WqD6hf=-_;2GlKi*SODT=d@GWh#nx$EeEtM}52ATB;E|=uLrCv(; za52a;;Z|HsHNzc}wixnRBlv-;qHYr|M1%@a(I*5yrFgzk@ ziyd>jgzPyWOo{r!Ur z31Ki4;^1v%u>KTMFN4lPn%xD#AV~(haS2uygTaCfyaR z!3yM-B5ciz+%m*w25E~SrY6!64ADVJM=?BC($Ne%NIHfgUw(v6EW=)s_Arc>bT@_r zB;AuCiwOF?8S+sm=)Me#ByBM)m2?EdN=ZjCtWtc2>m?oNhO>a@;6jNrSSQFp7iawp z$A#Ej3=<`7F-(B3Oa?BI}@F1?r1V@59B^GkieO7Q-Wwj$oM7PUu82OqFyr!wHg( zVd#}~EJHqEhfh|o_+vbe;zC*(ydcPI1}{r4gU4VLG#y;SG|GVR)CMV;S-+ zQQA5QV>~BuA*&3UAP&kDrD1~Q<$0lFCCPI?izK-N!L5>Xyax@wqFjYEi{?BP6tgJJ zS4gtiJgeC}&;nwi#B)ZGwkr`(8RP*3GMSl9CJe9`LC_S#O`}$d)g52HtGtPeS4~#uo3?@)sY$JM%Tu!$TyyR2GR3dPSB8 zxSvHM_~l$4*M1h27B92%bauq;6pd4|8V_I(;y1g|c({6yBm#F4*oyN&II1Bs=EItqzd9Zf^%#Ya0;1#D58cWKm?MQJOos{ zzWH6=n0xOVf`Xz|tRs%ls$lDYt)g{k9nfm6Gh)>$T0v_aDvnj_zc|wW_qWz>pL^a* z=ZJxD-&*2tD3_lbDte9m5N8}o6S^Rl~8V8zs!m1 z|Mq|0%zS;-Q+Pw4t1++(ZFrI#?a02ZM#;m_^+|?RNsN|?vs8=A4_1FdyDeqrIZ#@79jr zn_)eM&%^jUf=~H7gMSb3xrmQ~g9^tgR#^UCLTKl8eBQ|CDn8{;fuwbOHu5=+Px;e3 z;|BOViO)HW2|1@eDo}@_81Y@+VLH9G@5Sk)uTZljrd%fAYGESmd6NGok$HxSSHj$*`Yu z@;%56@oPTv_5B$i`MO5=?BH__pCkF`jY0Jv*OtFP*OmvR{^Ph@0Ok0@ZRN{PaSWf= z;zPJQ_%iV2e7bz(wU$d`jt?d2s;BTdl+PXb$oT&)pLg<+PvFgb-pWVbkT>ute|mq< zQGAZ!^N7arpK}epB1ZlV-B&)0-}5PdvTPs2XB!{AprriCPI@(;*YlA9BwI;VPx<@5 zo-eN><}5xh=JV%`-~BuP{v{tNdw+!HRQ}5GJ8?|Mb^Z?ya$d)O$EW-a@SSt{Eb@6~ z9j{Xt=R6}jWe8& zT6QU|R0D3V*Xj(msK_%mOIf`os_3Z3Ts1wo)Y7h3dNMPP@R*zIojGt;RsVwfs%Mop zKec9K^Hevx=S~iFCK0uRBdT|#0%QE3Ju}`KhVaC>`u9#E5jO!QOOh zc5s?r&dv=<=pu4E)ueXW%%=)Mg~Lk4v|4k>ceY1I`Kva?hLE=Gqng-HrLd6}wT9^O zzWFxwzeZFfjQVlZPnvFrTF|MwRE-*(ZcpuRu|sJ|+97>rO2)@WJJncgbS}q)=#r=mU? zZ#LqNt=43B|1{e+r7JDdQ@U-cJ&uf4v#LZzQKivp=k|d;+fQxr*|C?M+S|8jaHnzv zr{{*tG)>1H7RI{Ms;U-u=yi05=1!bWucP*mHyN=NTo13BZQ8uV7s?SE$EHgddo!~};oo>aBRo0DY zcW_~6D@yklJ9=g@g zEPE%DgvLfy>n!Lp`lWJ^QT>eP*Jk#ZkWrO)n1%a^e0gOCg-fKkS4Y+U^i_t1d~j?A;n%umDmqhjsUEG6QC5JvY^!^8Y@m_v+sP{lASrs@sP zwR*varsrVR&~21stk`opl!VRLY4SBmD>i6KGSTfp7AKr2Wn3BDtox`nB?ig{ch+vQ zpxy>?Cn^CCX0NHZsFIMq#aTG`ez6>Al3~k2m+C(EkXbkZU#g;zXLUythX0RH&f)QjEHceisTF*(a_6+cgIl zW0cm>=}H%xj?Kcw3imRDM^rOfK73aNC+S++-7>Ws-VKQdEP8Z{7*18k)PmLU)Ri)0 zSVK63LX>yVMJrX)rSK(wB8oA?lFp~LCgosNGe$jBans3aurn8h8C0!Q;s?C|K{Sl! zlo|weMd1*9lV9m6QkpTolyr={>JHPrdCiSZYa#2YMn@-E4P&iw#)fg)xS@K|XlG~^ z9VO~2v_^Tg*gox)Zgr<11NDh3hVtZ+jPQjl;Trr3;)OUg?phJCipzo+VBQfFsxu8O zj3YTlyBioW9aN##s!RFk>Cut)Abo{TGT%}^7vX2Ki{&CS^OBTOW!Qh7%TqF6`^pPP z4$6Tb**A^S6no*N8fd&ma%je?nGQ>BaufyxQ9w#Cno-GBR3P(pu8IhNHA-d;jf#n} zhAIAnwxLozXwq}R646Ha32dXad&{d=tS8!$skkNqs}T8JeS04aKfF+w@FveyQ5CbTY-VM>|_XNt1vc8dphWCT5s{ z>+2=-LR^9CMYUtpbOcLMU={i|gxj04C==gi;90C=<52y`2)*5Y^44vr40yC=LrYfA zQX%ZGg4$D81V-%j7c(126GH^irO=8ItQs(6EEFil$AmHCj8fVn%#rj8{Sf6KMjxGb zM%7T3h-W)O2R^kCQi`*DSPc;;{*f=!U zug6=B&9^8`Iw5l-rcetQ_Cz1rtQhgf_S~k{d`10H$a8jz2SK0ju+}7e&^S^#Xlp5t zLgY|2M;BU)sZdTY4KsOz5JJ}9(RG>n&NN*UnR+Tx!FWO zQ&+??r=gpgVsWCaF+4IbTx;F3z1`eIVDwd6%10IRXgo_qv-JrR9g?l z#m^vi6jr)R z(Q1tl>o~;B7%URL7Df)V2q!G+7X1lskVTMN9cqDLbIAxQf?+^Ux0S-Zl2>9cEosA$ zFZZvd0Lw;ybL-Ll%@ld);0alW0Mf85NSV%}roWic2w$;eYT8TbP!)G8MnV3JjpiTv zM!t#%L$+9LEElTcgcRuT1Ysvs=q5;xpyi9_l z6Yv!=ZZ0so1h+w^YEDCe;@0zXNuev%?>HaQ0iG9H2xQWRPw4Ve2lg@SCRQ|F1e@H( z{bemXGf2PN9%315#h~+y4hIuLIP||6C(|C|KGZ8mtaJvYaPi8;@hXaIrwJ4a!V>k- zXJjv8-bl4VD#^SNb7v5PLKtY#RnV>mNDR3(KQdQ!rbpVCU{Mo0bej<#Xu7p8bo9`a z=%jRZQEr13)QgH)mlbl_o`D@_Vg>ElzIR~Do`E1!X-g79^dv+uEQ2Y<%p9JCX~_Ik zHFznRlqs{9qKm+OwCWv*zG^qnJ#7D>rr4$NNo0C0d=+Vs!Q27r00yZpHLx@M+|f&9>@5E zst1FTqQlDR46cU*NQ5v1-L8}qDUKZ|M=wz}X-Qpy33sKdFGvz2z2O#UCBZs^&y38Z zwu$(1iaVFyILYLXBjaJZZM5K>o>G`8+t|2_kCgJiojSf3;`}LOwOWO$mYTCFjqCA zQ(+1By<+WDQG2r^vq@Xl(Q{GgjUC;zPlNEZklHh;pvecLZiiYRiI-9i@|S}}JX`FM zSC1&pBd!yReb1h)(lJ_;6lYw}i|N{M50!nSV$3?SRVCTc0jha~I{YbglVnldAZIzM zVkl)iwA#~iqa!kI(=w2=Cf|4ftH**26%qCl%70i9=$%@5So<@qJNV`h>mPksoTs)$ zhv%kn(CIBBqd9j>Zm{uG9ic)LxZ>Rl{xLWO3731054Vu`vMQ;RUcuTV#wc#C=+!9C z#{5s=$K1yZN>H$r#J4mKu+_0}LZKzkEl`t4E}Ws@=(1&}+te6G!i39!Wr8Cb@Bk@fH-K$E+FUHtlKO7-cTj0*G!E-d2hDbjW&zqVd%04TM1T8BWa7C|=9(9l3 zB;yd76Bn+X-J#)!9kz6UI6$gGLp&%&r0ncR%=U0M-~d)#KsXExViwI>@6f3xg0Mo7 zgX?7Yf*0Y4%8V(Lf44mYakax)!^FdM>6xqw zNlZkOqH)|J`hdveAS@o55uxxbEk%})^(?Saxx+XGnTdh&o+2oyHPxBtTl7Ze*oeIG zjbK=4VZ3o9_*b_&a}fU7>+T-yz($wpNBEKnvdql~V}S=vL8&2jV>;)?N74#hV64U0 zw1^haFBqU&qomK_<_UfgH=gsr5%NP!plDzK@HF8xn&HhV(#|;|TgkSdlpBafB3}L! zTB+cMoC>`aX`^mJ>oL%zuauuKt|6?F%H*&}RWjGb940RVE9-(8L+pe-+=ez8y%D^F z?XmsA^30=oOB^;OMdqZAqg4fWlQk4wskJzqpOaxE1;>)~Mf2z`zzkS&%vsVpJ=V;c zR1RcU61%QE$l&5wlb0OYkd7$FVNK<&Iizuf0D06H!+DHt5?D z5=Q42>o1y+1wWX7vJVW*(v}NX)fb(+Zj> zzE&^a;I}+v;rJrBLWf9TDUKL$!9XgCVh^0V8=Bv-O)q#O3<>X`w~KPqF#~uccyztN z6D@6K4vTYUL()E`Rd{%%t40up+gV(MkgJ1$;)EOVMdS9j&qPuz6DfH_Ov`lNqLd@s zl<9$q1>aK*+S&cEJV`qkveg#6i8E>WFn7aSh|%r+(m5fQ~)ibn)$<~p*eit`@#I*TkF6vZS$u%-qS zf+HO-q70se`HLZ!PGlvbJ(GMM7o8<|79s9tM-cU*6gjZuE`e9;iNYr!X5Dw|unxn- zCGAAXPU~d1Dhr5^oyJyIQ!SGh&<;wwQ`BHrb%2VUEuIM&5SOF)mo~8D?|@FXU18% z8h^4>Q+qFbcHw9GrBdXTL&&?JOd(c^JJdl)KAnC$`){95d(A<;vB9F@>a+ z8%VxMh0HO)Gz8(DNYNZ*kUH`5MOrw1ai!w}L-C5FMaTmuGEx#Di1g^9jj(K4i$nN+ zJi_qp5vdI2snDuJ7wm`9)8(oFkTP$0f8!Jrmg=aDWcajnIfcXY3$$VpAV21-EcODIa4s@`#4sOgvy z&&C^psxreO3WuXJ9`eIoi$&;B^716cy)ZKE+Z3R*<)nrz4sE&T5x=QpNyy2iqb~gRtQOgI%5#hKNy3UjQH2slEnF9>e-M& z9AtXsV^k_$PH`wRtki~}z#(0pzBb#!qSKO+9*>D3LW5_7@f6w-^o{*1?gELTPmYme z5-e7>b>{C(qmM(9_GpqvH$K^BghhRb6{ITW&munpn` z-{`^cvUJ!$mop>M$u#sb(it5aVbutf6DboZ;dO0@Fcirk2CR=rKM3uW08nz#A|;t8 zVu1KK6!ol$m?&dsRv~BQkzilwQDeOaMPb)v&W0>JIl1vNp0a2A_ROjyBS48TdYd{7 zce3XMrv{gAjL!iJQQ;R2eNL%@Q}}~K4ng>gj}uf=ksY6!Mb~ezgdEx&eUg+H=Yv`GoR1>kS3P&d*MbQwF zAqZzHzXKfzKLIj5EDAJxEqeZ!kD~;r$hux>>2&9LYKPogM3lugl)hM)<}xN$M+GJo z7UAN!@goN$w@8RY21mM?E`}(H7@NY|4aVv5K9IxDIUKa_D4`M*IGPR5eYxVSRWgzcqPEG}Yecv2K5M>}>NOJ?JR@=jWhg>OhLRvBnP=-(~;K&(*> zR5^Rgj)B;L07ncfhoLX3Z_6=*e&jniMP?94Ig+s(ZvTw$k^W5(GSn&=QAow;fW|F5 z!JN1^ayy5-5ho>%B4P@`gSL>iw@5luN{U5=41!gAyG=6pI>~TiR^AjjI^d&H)>=qE zZZCFc-{D4RMTtLhlBe^d6P$?-rzqw=EQikU#&Am0k??FYyRkA9a_>OC(g}kT?ODH$ zToJU<&`Z_%%;H7uk!z)p5WLzNwSqU9#w_xVxr>?OHcVJ*CLw%6yTNG4U?c7XX6`&+wC1YaJ7u`K#W1_(l$}k5R%{@YyKBoYH zs)+zHiCKD{1h&&_7H)&daK3y<6DnnHQ>$21TPjw zEF*aX`Eg(lhtosVXKknxSCZNjdOK`SYAJGTaEP2fcp-BdQ?lHjwQFZGZq0ZqoFOix zucfzcn1{&atL(|?F6r;wZvqm|!?3Q{7Z$_UO#Ws4YiW-5<_47($QFh$J|jPsja*zd zTvalQs@4)5B_$H-heH3E*{Q*vF!u;UGnq1+L4EbGF)<2rvkN2jEzA%_po4B#I3?** zsvhZ45B5@0b90{)T1EO%@_R`*H+(=$gl@){-GB|;l6P;38@)Wqb3KLY>vC@ELcjfWUf`%9H+ zJv>W5okguEW>q56liIPTko1t;y=Y79@4>VQ_8!wAuAv>NVkHm`-wcbsgu#^Bg_C|b zI+hk_s8qaL75a&1K$lYPVv%pTzDOPEk@+2}Y}W3OQCM@XlykjmT!T!`pPZ%gZAe7w zUyyz+M9`)(&7@A{m5`nxn}k>_gRPBH4BY(m^nMmjIC7$6@>0(;CxjbHKK>Xfo<)h| zo1}`y?b>5O4Uu=ALqqzUxMC#7HB&N59)>s(a!5KF6H{_t)on?LV4#Z%`UTgomy4Y| zX})QFNoynVUEW`0YwWtQfC|om608_bFx_@b))P;f9`+IP1XxMQ268k}gBEfzYTtsM zC>1Q04PHhzJC=;;lDNq;sOMs#)6*I{Ii55h$_0oG5?YApF=TcTskaLtHo7sWJieAS zv|R6rNGnr8CCFHUN=b(V{dr1-ZYrh2MB+pQ&qgqv2{!lB$gn@OU5@N(7+DN|rj*MT zQi>ujFuUX=@X$xJz0ML=?%-kNQ|W0%uztnl`c20v3N?f_JiU^cMcJA1@V_?UYGj=?gq$S0q zHJeI>%rJ}$+~sKzN<#<(H!Kro5=xL}(p!o>*IUDbdTMUQLWLw-O1f}JcZm{B3F2=l zH%o+ep*Wq45v2y=GF-yZ!p&u^jG%e&+Yn7GQ>Bh8TPze?*)0934Lw7=UONn=F^4l0 z9a*;{S(kyq8`>M0Cg*&3g0us?BP>&PLbFWC_*KFejx)*)gv)t6GCzo?<;?TQz1i*t z-7a`5i-*zX;)sDv3)4eJsK)UeSTlq!I+0hj&LP5)k*^{R6@lIEs0^%b`*7-z7d@r} zgW*NRq*JcgzA^C6pM0bq(xOLoQXvq6P2#NB)BRf6t0O>{v6 zkjCt6*jx$X8MtYopIaq@|$KLcSHN4{0^QX!j60 z5CaR9nh3#+Wqjq@$Lk5lx<0u) zt7q%3GnLlk*mp8vgk|bD3jawV%xVVmp5oFP#rvU+yMrTP9xK$EnJu#DGY1_aj9Bm( zLCbv;p%0~VRI62FsH`#g>YO$?!T>egq^N0&qp~NaWp`Bz8>F2T@i>nNkHI5)9P+Xr zlBpa5iC%u4i$V54a2_%Sllh#w^Q<*n*KAt5e(m}-yrTSsb?et1x8|5V#7j>b?B(%C z9=GA4N^YNV445tE=xt$p$F6odS}UiXBgN<-XnSqE#{nuFYvWq50PgG2n)39J%7fRk z0hF~u#$jjVSui~|q{+lAuiKSFGd#^wK}1|Q?x#`(hZ7y24ucpJdOu6b5#QHjV5c=C zIDJ*Q6tY3^m6AuP7*ME#>R`z_V}fz22J3*%GXN%$4jV zm}FKjmP`pXrH4GDN0BZX3Oq@@xZEQ#l7NAvKavgACo@^OgO~&kM|pZzZqwXDqQV{$ z75d{U`5R;FxLL+NX={WR>u4-Fw zsmM^#V$W4Nr~D4NpdzmYRZ9X>Ug@Caq?}xf%ngZUGWz85kKv2!X+gyDx5j7sL4@{S z)V*9d6Ur8An(}7F+N5?3k=A4RP!$5gQ}oJvxTcm`X_S za4hV|ZcQRowGDoefiolnq;% zaxY;f>!s>aMF#^*C6iQiq-f>}AC6F4X#)TMnE2Q3tvi%^6M6AWswpLQ3F@?{vR?4e zUi7t@|5(&co)ODlRHgMO{|mAw3PPY`VVJT5QVT65goZ7-e-aBm5dvUj`qsH5z0r-4 zvI+r*%^F>9_xDYqrl4rrdSx4_OvE|7b@Fo~hhn9MM2g)%=}kfzW1%3Lq(4chvWQ?7 z{HCnCgKBhIaS`5G7;Z1jwMz~w#z|Nind%XjJ6K9Z3|KQ$k^R=;7qI4~eG2Iil0AoP z#j4aDBbE!xkW7RF&3n_dA5Bcz{!xNrFVy#50*_6}hpYr%W}mL6;@bw8C0qHbgW$bAOvD zQ)r(ISD%%zhes%s3jM%vgFBOtptQwx@&EPle|9Kg5Dq~seJhs?M2Cbmbp14Glt$f~ zFo@;#$GguPyIVELobcWSRajYVv2jS`?VjqiX>KQwo6**{%4KisGVC3aE95uf7hqIxKjs~u{j3ip-q#L#2 z+ht~mR7)X|<&zud(xF@%E=}sz$SUwqTZyG`SEzwG@;Wa!8B-Fj#yXx5Ru=3@wvW>B z$nKXF7YoF-h9pYhgivveAu#~ubPYz(2m>5>GaO#3urAN1Vrgq+c3L*2p3-3-*Z?Wp z>%Ajwqj8hc@2p~IqaGEv;Mt6AN{Sp=*^WVNN{Xed0vj`ws33(fgDPVX1XT&79bz@H zP}b>x8>rI70HPT&<*IEE`w@~i)deEZtl0dZ9U|JV21QX?hYK}F_khJ7{?s7BhW3bp zt@X>;h%aR(o!p7JPGrEzml&J?b{dZ(1B%(8tHa(fmfjqQkR6}wKa+D{EMlGMGZXLT z+w99m%qy(~UNz2e_jB#oZN+{cGTgO0PgAI@^~f^LCk)foI-nkdCB6{x4{5As7oix3 zkA=0Eg#|+J*mg#Xx5F-F;}r4WP$!wSbgwgi!3?uVi?aoAm}>J)4oB`OsQn$9$=oEG z20Rt7BzZ`mQ{4r5zn8Q-P8#-7#!s`vigYh-4QYkUcg#6SCq}r0-^6{;uYzPSLMNth z?iABW89`E%I*OtxrUUDqmsgC=x^9%^x425lEmp{(@L~oUgF#VR?E|MyR;iAt35YnT zRIyY`Gh|4@18GjfGqrBg zwjyXF>Ji`Bhw+sD9=IjTR2|ZmPteI7;>lV~8JZ_WR(x>?N91(uuuJV*?jYqJmbHvr zfUzgJ+e5*`jSo*CwIbAx8H_(o`lM`ht4TaCQ5J?Gc5KxyxW34ySGCrpd^Ky|^8e=q zlh>RV*}LWR-0QzgZ#Vnp0dV#dLkqS>rYf#%xssI&1cysw!m~VHHLrS%mCl=ycdeQERnY!Kf}atCF6AcgEA! zQLqX&SVwY1P<_dOREf}i8uGpMUOO>lAyh&iNeeyxDLZioN*WopihIb`Uq+e-p?Ik^ zWpkSH^Q8RG^i;vnTU^PaAhH}`jK(6ve$@WN%mhPu_QPtPSm?QflB{{Ok;q^avlCMw z%>tuRf=a}nCHoNQQQ;y9DW-&FFY2p3UqKV9a-fwLQAHMb6fS`WG?-=ZcK8fYnyjB0 z>OmVnYz9b5M3v0P2-^ioq~|$&Qkfuw7|R%3`gE+DIA;sm(8@bmewAE;!El|1S}JAa zKHB15sD+Mvmz%O`WInA7?uj;n0c9#S6fR3)RkB7HM2Zhc;HJFHfSD@aiGAj+6vKj^ zMgMX{X4ZoDu(n0FV_o*Z#p(|=3_lqbA{Xe>#{oLbvb~E3pH~E zeCoy1(iXLCP!_OGL;`I!OyAh3C{;^xiibk43Uy6(1uR&5_uzJNXRxy57nbhmkq9-9 z=Z?ZY;jf7up)qgTWj_-oQo|VRvJ-zO>l#FUg6(+x2~2mNmr&6ZMM6PUiD30rPGp-x z@JNxR?0%F3dZm)QWz~m!7#gS66*>WEZ}SXKs1@%U;(E$LOE4vJMD6#2n51|Xf1%Qg zOGI8t*1<7kR+V%WDk5NWv4YURm+jCzW5<)W$N06P@<3?Rp-Nz=K!y+!W)dS6@s`%W zQfu$IJ0ns_CZ(1)y^LBbdV)qhC)`J{TV$402IgUQp1PA#56n>r84u2N=kc0{Hl9i| zZm#6`v8K~fk%W(u$du?K0Fpi{sRqQE*f5bpK0rdyz=q?a#*<@8k+;BglriP)jVKC1 z>(K@51K5izz12pKxVl0_$v`omxq^1DD)oPSrkbB3OkANvDEJzR2tJ#z3CvSq-!_p$ z`jsr%(2K$j^7o>~UNgnirk-*K%*4=TVe@Q`Vt{$f5DjA2%zRoc;iGVo4+u!{!?>x% zB2FuoOlq9{HQS$o7~=!Am=Tgf2xZ5eWkZR6%l^hQx119W*t}1eYcR&T>Neljz(`ST zQO-w3J`)y6p)nho-i^c(R}y)lLr4v`TP>Vsu_o!H?yHQyu#~u;HtrB3A^Yrn_Q5Jn z(PPeg%(*!z{39H~_&8Np&xsDK1BH!L9?V8_h-79jYUgopjCTnfe(o`5u?{LzIJe#K zJC^nV!xTH6mihL*HBj=Hu6x4D5|)vn9AMmR40{xu!^$CC9l4zjbJ$MBor9(q+@AX? z14+aPBT~LZV`S))%w`RZLN2HsFv4WxxI@ddD!~4>gL_ zHR8QEotI^_M`!T#_2nr?Lcta-GMw^l!+-U?hARyAo0~RtytybiVIB^R7e+u>px)z` zTtYunhGX!^$PckABcz9EE3|BKGNcHwsI4kk1GKRV6_Twh2TzFga3>-U4_I{yM4%E9 zqh9hpK&9;U*Hlvu*1=1~w^Saot6U8Js~V=ye3(8gG3~rj`uzenQ&{dW(F}XAa-$NW z7O>*ca{f+@Qa&~*TBea);#w{UxvbBs5{OzMnJZ4}MnvJfK1n`}Z%c-RLqD>fBJNzr zjy19nZwUR6AdpC#%)PvX#266*<;j%=+?VkO@o1EU2Kmkq0>lWsk&kL2DkH+^z|cn{ zK9xF&c2cPWT8Ux~+Q6zDqu?HFG}m6(2)3r1Lxs4Ydc`5dM^ZIOZ)z~N6g3RIVgO>4 zl9-IN%nfcq+5mkBhX%S_SexiU8d=S4MoP&EiqI)~D47dMf8M+mZopcJ4i_jZHM*zF zJ}GLk{YU#gFq~D%FP*KnIz9b$QDXvN>Bnt&Q-ajHCj>W%QjWnMp)occmZZ|Gg0#&4 zW8PURl88GDo)34B<%1oCwA-+rzScF|q;^uTFO55`7^xs*QM|P9Ved}}qEWA!!6fMv zeh~qr7_pcr(Gug&MR7LCZ-JND8R?^{@ntPp7lJ~9ZDcxMj42gW<5?wG)hIrE)`+0t6h=0%y-|*9)DPKDVG|lz@d|qdpH&q&oDgL zCmbo?QWBIQq=++5gxVm-Ss0YkFOhNz&US@N_|ekI(28f|DXL{DtYR|N^im~dN!S>Y!b-`cE_-Yg!Q`P+|* ztyp;qo1`obXYFmGo|`=@5w%l_UXZ<~J?0h47^G-&IMpN7gY2Ts8i5&ehjv?b06&4^T&=7?00#23%1C5Cp{8D3xii^7j>COnp{Y&O*w z^z}8d`@;l}ihX^-^4~MnH!)^n;4c$h-0 zWmHi%ehSZsFNU)j;a<|iGPAwfyX}lE!Q9*9^H~YkmM+>Ho6y-BB@a>NCH1|*+B+T9 zV8oWfgPmTBF%{pH+=;Sfnhsc(oP)NZ<-1DqWXKD>u*T9?V|`6dv+;C}Yf`#1O8i$D zgH~%E^&^~TdA*c_sos%@8bUiPWrV7|j$LF|4wSaqMlFHdctT|_Zp?rz^G-tna&3;_ znh2e|ULpu20@X6Q%GM++e|z?97KKJ(($K1;U*la49Xj;pkYw7qtm&6YnhtUf$U*Od zK&%zIgW^~0dc~C##D@OTIV#2*UIrCiXm0$>p(p==O0H@1O^w+4hXyo|>MEp<;t}s2 zz)!9{W>Pcl*yPqYJH|73Lm7q{Z53yxcw7dZQurhhr0O9$l-NR!HG~PJ5>2CaHB)R- zT1=`+_$9F(qMk@DZ>=fVm}(Acsi&3{x`|yg^gFb_2sWTQ`SmN}U!6LKI3#aU4*Gxa zqLdfXjdP!5Iy!Pcj^fR115rH?sydLIifxJuSUjJ#z8*%(l=I3Mxm=g2BYF}z$8=OP zk@uPD&a|)0Fx7cXe)N>sDlCedBISZlpJ##QKHUwHp(s3d9h; z&(K>X6JrA5C~z`fze6(%*)_8pl^hQfPD6>**i68}U4j!glcm#Ugoa2-(x$Dr>G`-~ zRGKfltuj;u#_={u4_9Gn#T#^8*DIhp1=(#l(E2sUwP=eb9^0CO?s;5H9BefxkF1<@ z7WUS!!$@Dp*hWl-)e!lV$Vtd}0dXjqu3UR%ZrH--u|lJZ{f&b|!z0wf*gi9IGAt3Y zr02QhRB}+tqtk)=K^&BChEYzlEFUbPgXY0u?aYoivWm9VyB#EdwBE(QxHoUEXgWDL z8^Tb$Na50yOCeBVIklwgMZSFwC}qv+IA#%N%&~2(zHwPLIcH#fFha735K2L7sizPz z>ztm92#RYe%OwtNxmFnQvs7v^J(yP*M#)bp9hXzK@OId=qvd+&ej(f<%@CkSb8{mY zRu;Hc)nw5l%Z@s=p&x`RAl$w1Yw=kJ${WcvvKC#_nO!->oX@h@>D|a=dZ&GIV_pq~ zdWlsgg){gIB(9tQa=7(meSU$<6uO0WCKg#B!Iz_sOH6@;zY791_***Y8+)CV$2?4y zL0euGh$D!&)moIZIFw_(f-7EJ7cno?7FqGJ2U6xKtQKO?Vqq+#(vM)WGZO3<)7CGI zR&fk#vc$Bd!q;gq8MQ9`OqLT|mu0E|jWlCQK=B%Z2t0&uBi4-E3fO0x8b0Ecsa{AE zswsA<3M)M(wc%QODS0D$k5f-VF{Jy}tvdz=4$7Pnk&4P#GUl+OQ&@uuWjaU_+R-*hvzU6W5uqn7huAgi9nZ0)fW)ymVp=G8 zF+_AO4Rp8*b(shQ%%<5JqGrz-yY_|}lF>CMT7;t79ur|}kFEEnM%~{y6)ILpxFYWx z%h!@QWCF`UOVhDtU5k1|nbaXeaDFCiivF699Vzf*$VeolA;awz{tMY z8Ig0UX7F+Dm?6G1w(LGRVs50)sBjQEC@W=t2LIs&+%>rnwv4K%pw>`uFy4!#G&Fo{ z+VrUsL?h=*o*+9}a;(jm*VG*9woe4I8FZvVg~LpBGFZ<%O2)}qAFNcK8D)iV0J|WxPKl^a4TV#1wlk+I zrN+zGo4AX^pWGonI%=O0Tjq6$)j>}wYyifhaBN1D4joPSXD@bgE znVMEE(6LIZK9%XTL>qQE$rTWWa&Hh8j-XB#V~{kYiZOKH ze&-^Cq4<6v3&KFsL%Fhgw@{ou6Wr3h7!Gx*(Zt%j#M}uuCUvv+#&%Ek_DU~~D*M{4 z6JrYJww)=thleH}m~=PAX3QYNDLK2p(kSf9^)NCwfZz?Os>lNm!&M1ZR*g$Y%`#0okQ!u zZZ&wMZC#ZF%%vk{p`p+1SRr=(ZVQ=Ep-V;*0}N6wQ8rwbz(_T-@losbzYY2yr5m*B zobjc#9ST7TE`=!MlM>5IrB-@%N?wcr7nZQEVU*XdVtT4ztqiwxIffqvFB-mznbtX| zqX#pTFlgk*Md`z=WrU!((D)ioZ>=85Rk2(gQ2o8+n2xao#CoLaVsV7JB#v3vq2c}t zC1Wgvx`QPU&aHSofCD+W$}z!WrJB}In~~uuB*oyB5gVcg!kQXVxkNJd#R?c=W#&kD zqqdU*9i_<^NeFh3QtZ%!_SC0Er`|T+*dy1oJo|OJB~OPjAEb@xNA>AK z9pMjx6toRe0RiTRsGuku-A!8a@@ODeLe zV;&dEoe-(L+CSOc(V};Uq-ns^O8Attx-vvk_wj9{ejYjh_FFmsB1Li;3s{eRgYwlB zHNm^7BHSAi7Z*qjyy;A?zmVCXV;5%yr59~dNs)shNPA$1q}@^V#Tjn9GPTz{GVO?( z6~%c@>H&!WniYN`*H4%wbWJ20rdxB5OyOrT_CqzoqUQG4zoAWvR}p_=P{OlI57Cg< zLm%-{XQ~cHYDjT6*F0QIiJ#`{vHS{3@ma04C5@D%P$B0G$*01dbJ}*j3Z)-ve^Vn0 z7#43t5JHiLR;~14%BFuMxRP@uk{{>xLwEo~B4fVWX5`EOtzxAU46j3|SQ?DHk+S;A zdvv2>k|w0cHRMRll-7@YSbcqzY|b9;)+iz!)}SnH4;txxeWP@_=Y>U7>3x^wItc@pV#iNID5~4xtK0IpCZ;JT& zJyNNK;dN1tf;14_)0uu0GK{JA!^ss@S1t{nm`(y&hISj*#j#|s@}Oe6PRnSdphyYg zG0)d-SAG#snd(fe@>o5Ly7M3#M#748+gcOcj8knTvy^ZV?+=}ZF&fwrzdsR>=uK8RVxHV!*Zv`>da zPTNK$B1VVbS?+u38By?eR0gLs?TD}D4`dlD0>OxoM?E{OA|JA1Fh*02XMt)-s|YE| zPOc&4x`c8fD_&faQA0{3SBhl^gPS3PE=zi{ETjsFg=&YBUSO6I6rovOTfzF2=Z)O0 zVUor*T#-evh=WQZQn?CgzNY(CZ@q~~EBum&3c62OmrT5nWOf~$n?9PRG=?}(r6S88 zSWJX?9(yTKGmDq9&dJ)yVm0g8B=;^`T~(6AJ6`#B5diYj$)A$h)p9I{o2%M0uvhVx z6sTUkm?)CVVjIrsfl5i2@jE~Yg~X&wr8qe81m|z=plXCp>x8D=r&6(I2Gmo5ur*o9F&DGjYS*!k}2XL z4ht6s^+ zaw_sDh;=DF3FV>K+7YpkKfUZ5qjQnmGCdK7F-ZY91^Gd}CuDzDMXgAfEpg0LcT9q1 z-&On~JTBxMgsL1b^oxy`v8OcZyigGNm zH8QF-({exAJUj`tqPpAb~s~R z>KBhC%`*xmNS?3-ciWD=jrR-PdLU*)*_c~oVayt@{bQMDfjh+;;T7;t6s@jz8!%aN z=*cLqNmi0ISWLbTA_7OuNQRblm4)NOsU#rfR|7X@DfVQ=`hDJ30J(Tn-MGuQ*hRr=IxDaChkhoAw|88K1x2Dmh-$57k5^!qHz}RI6*=?3llWt_LNoeX#7jl~i zKPpT$EmkS|wqc=6O7xN_OUZdW+;-ZBOmZGE*RW1dYsOU6A-%WeaJ-RqMBL@9on|h` z05->TdTYe=a@$2rJe|UJ3Idfu;it|QE)XH?C_<>Wo<{yW+NC^K(Uner@s|u~hBoM0 z{3YLx9s3vbqGk- zQW{buh^_Ys?>b*ot^hgwEZEak%DxbNNer??^dcEQMq47Th&zBw;0_Ax{slPF7?K5?>D#8 zK5`^N+Jq4uMPUnbMMaUi&q|OZjPWi)i0s5vJK~OL0fenYQzFTU*nk=)mprsQcVBnby_=qQ&5%Mzcr&7} zW!nz3mG6{^WI>lmftQleiQLYJJ_#w~Dz{1)as#t~`dk~qX|{ypQ3Hk?pu(3F?C4LB zT)y;k*Fe7VQ;QC-e0Ttzl2FV~8}V!vCzngcjkX3*vUXNmP3$7hNb}6pbPPvU0a^CY zCAi-vY%Au?+mXpsDZWVZs< zpGuo0DVG&3ms@!3rzdl;=aTWsYs8!Cc~F&hP=CTS_hx}GGo{kgg~-my3=MKMup;yX z?4(iswlrnsc7mg7Q-O9^g;JXKK&-C9TE%H1dFA-@?MVdl^+x7Oxchm+$%suUr$07H zg&=5w9ys)a>%Bi3ZOy4 zeBW1gM=DgS9n+Dsoi4j{;qx5QwhOoM`q@FT2b?vN(e)I$G4p6Yxy0<=4P`a#?$~?+iOKCC zK4~>bj$+c!GX{tcV{~+M^STXayE6K3r+7gIm&W?p3R@|r@5=Dn18Hv;Cl+>=N*x2YPcddu9h{pgs}KbC3vQn%a;8MDh80(w?YQE@R&cFt z$${uGc9jMWhfic)c}|AuTq#>w$B!lWV6&3t`6_{wRc0jQ*s4nklj!|Kh#H%rdd*Rv zlK(phcLK0b}fYy!@Q2JI;Px#&$1Gg zf*O0m!y=DikWwr59UM75hOrpsK`YufHan#YLesKp6Wn@+*UgY^r7`U5a_dpPh+q*D z*8sD=QAIL>fjK1OU%~y{r)FnbqfotfFv!UjloQ`iNygQR64}?dGHVY)q85c7on2}O zO7!@_Zj=Gfz6~txR_tjD!am<&3fr#BMTYxI3Ct0OP)G~bu5?^1*-(R0WmXir9EjKK z&pp}F^?7+MTErw+bZn<&s73BFnFzIMp5&s5!PRj>Gm3z!lxR@Go|1mc*1@UWv?yi zmt%`L#-*cF$Wm4%IdkxI%)dDldVvAbA$o4ESre5W&q>#Z~gn@+E&_)jh zGjM4}`l0qeWpSrS1yIOOCQ7JLRpi^%oforU*kQ@Mat$@y+2_)BNgG0&O3hbsq)T`(aQ}UF4(Y73dti@F|=YC8sG2C)mgkj)mpdTOFNtuITW#;QT3o;=_ql1>r_9b z?lw$IjDy}pEH$#5L%zln@cLb)c1Bhiwwp4mF=~n4hrP4hs${JxO9zeH`m$1qm+5;k zZM^dgJ{meYIzH?}JULXL4%bERjCH5(*xy*cKce2vnAcynK~n+hxRPuMc!5;K$lJ=u zdw&xw99DJiL*bR%r%`~Od$-ApimPX|Fsx`X;^60S-hG{glw+xK!k%Pmi?e)>ZfmrxFbH^hYY?>*Ric=AKN$_B^5@Z0$!pyRWt?9 zVaT?4B}8n~WJU6@>Csh`Ci4bEZO~{Zp~dU4gLeiqhWNGkC2TXFCw!E4Hppm%g=O76 ztn9UclX!-9W1kIr0J%QRT>f}*V-{tq zlmBC5qm*X!Df$uRF^c~@)E8Y5WrT;$L|y4IWBA^co~ezX8c|Uq^sVHOFq2>(>952H z$3tE_#UQb`rUt!^f~~C8R__lh1?+9T208Mc>tZrM3;nOAJRj;{Mr9GavI9!>0GaMw zg`oDQ5-iZrl_?_BW#=RNT?P?|1B&FNl7$HG3yqR41$QN52!9VHL}4kK>`(=l%}~?V z096sz&1Hd@Q1ncRHq3rbZ7wi9qV2r{>Rn17O7Wn#zldMOMl-4O7+pBAAT@bI*|tfP zuuck28&hUM3{jL9h#bXWApQOp@{q?%{7K%z7Rgw6wo+3=h&!29->4Zvuxs6pf)!*< zjPM!?y2jNI0~(felQBj-alY?1s!&=L4M7=lF@l7=@z-dU*{=RlkjG`#IaURwy7Mb3|}#Bbh*xC&MYFGyZ$| z(&zSDB4w8t5^QwkyEBRr_G6fs1do0!nrYM;G_zrCd?1BSrK3f+IjYJjOg*$zT*D)Q zO7FA)xi9#>@{!BK)nz`YCuWNZJvWs`V)c5}V|b>-Vj^H431l(9dwYm+B|V38mO>iZ z-KaGSnISD5ykTlkd|+eY9H}z6LH$xK+o*UECQZ>i((Yz%!xkt!Um^fapvY4ZC^h_~ zHfnmU_okOnA{{jjF_07-0~>S3L!)RQ92WZNGmIO-6wPo}?wULfc@Xcg>JzW%B;1I7 z8H7SAzk=%cpmjSYD0i9EaLkBE?4(v-Do3GdB2L2H$a&NlZW}K$$t{(^Y>LA~x3d`& zY6&ht<{d9~aCV$PW?gb@5xUni=_mH9#w*9t2iRqgrt4**$VhUoTgR?V)PTr}z(y%s zo~IO4O)IcA1siXqT`rG{6QHc=I9m&ja<<_j;ME066GAzol<9%qKfOY;#Fx_4kBN)z z1rZWrLRsPQo-0Jgd~93^eKrPkNn3p|YuWx1`Yx5MmKq*mNSZCNxvM3%E%&R8MI;N2 zt-nh~F)gT>n5dJ(RZu!Dc7~W0R%O&HZ5kE~o`MXdhFMLa!px(NO`2AvH8)X5L2gyo9;vo*z>xj8&{#@dlDSn}_1x$O(#rr8*o}5_z}>x{++~ezRV-)mp}3 zg<``UShc!i-NDGOY963Z%_ch|r8F-44g7(;@MVX}k$h_IQ>|5G7Tcs+i|`p;%fLS} zI8*h1_>)v-S=<<_yhm*zToZphpYQtc1U&1VO4cB$Mk!Bk7o4{w^xJl zch9QYt}pm+jq%~2zF)rg^m|p+n-225b$q9BxYGCTUOL-2cXH$3{Ilxbuc{u}>i@F* z>#>|`KF78z52>ox<#Xt=cF?ld1=Zv!9wEpff49h(2v z|8-8EXB*3XzxL`?)fmUhU%BryInccCBObH5dI86D-#hXt&+%gZ-F%M6zGhW*2ac6L zoztIw+q~X;x!zqkrt96APq`jLAJ;2W`UI|b1jou>x!&a*XkPE*T(6AtT{%~-_cs2m z-<0bOa=qu%E`Q~ES8Qr+K|+ zo&;s{BVCUrP+#xk{JVL*>he|93prN)*7zUSfz9u|f$x34bb@o`d*AW*fcSgCYgbjj zEDz6-(!YP<-^=>m9M;dUyELs!BYf{FUq7 zoqsg@_hqiPhA-)Q;(4Wi4_k4)$8f!KZo?P+SFU%|itGK7>wW9cyxxQOZn@rOU$6A( zRi9f`UGvs*wR~P(bF05s&g_~$q*_}VpuVHOGgf@>LcZ7hE8o)^Xbfwm?>)7gsa(1_2j?|%`hN3ob=;+YWHp@a zi!|5p{fB@DUhkgO*Zpm%X@dN$k^Bh^-iQnp6Ie#>5ofA)A1xJ3o+vWVzX=}_8 z+j0Kcw8gi}`8Uu$u5tdOwAVDwf0MT6Mkb=kLeFoYpwMjrON#KfvdwXzy;E ze+BLD(MBDK-@l*sIgRsQp}mS{lFZTde?j}{jq`V8N;SVpFGp6#(4J_V-$DB!oG;IR zKJB^2`4`ZB4Cl-Ey@mEt+hpmBbH_Om%( zp8uJ&FKwK^oc0x*&-HX<^$`{=MQPWwQ>G& zwEwAb{;9P8x^e#bv{|Ut8bJO3YufK`oc}8AHJmT=dkgK4HqIXnk3Wg?g+6xE{&eH~ z0_~@AzRd6IXn&z`{uCkkHqJkp_DzlR zOSC`0`7*z+q5ZSQ`FGI1j`L#Odj3z+{#E1rjkIszymUC7Z~m=@s(!(F{pI;1s?`XF zHMBSKk*0Pe?Wgnahq(>Zf2pC>O}LjdjsD;2&=i_&%|icgb&Ptm{h)q>f32?mXhr)W zE7}jPj-h{&4WiGx(c_b7>-jZbcZFZ>p#4z(eYnp*owlA$SJwCEXp5g~eW?9h+T~9) z`$F0u1vm52_5PIhi=f9rKKlOK%J*sCl^%bvwE4b%|Ctr-udir-dqw+qE86!|$Ni`4 z-Iw-{na>yUZ{2_Giu1>U`6{gw4cnH zI0L#<|NnW#`F~x}{`VE_n^&}dzoPvIA_o6yylzkXEllob`M2)3X2toVY0vS+7yA53 zJ`bBr`k}3Vm-dra{9d}1{=}c}#xI^lTQ-mGEqZzBitoRf_HQ_;^Xkt(&|bs8_0jh~ zPy29$fgVfee?t2njrJW`s1Km6m8SC#qJ0AGLeD4Aell&*zs{dYd!h0Dr_z2I?Fak( z67BcUmQJtlznb>vX_xi%9@;;qeWuTUlD7Vy&*yG%?XS44V|u0^(0&xc;F)oLRrPDy ze?$AOUN3iSs7(6)8rq+P`TyA8KYqpeQ&zOkUeTUe(SFW~_RCka-?gIs`4#P-tZ3h^ zp%bgWN33Z75$(rwyzqzhw3lcX{_|Mcuc9qBtNA_Mzc1r=w%dh%yZif57ki`PK)&@rv^Y{C=6A`+#mQJDb1l zUr>XkM~f-zcmBWmLSCU<^j3a|D zS?2$3_f~xGR(iMMTes4=72nEhX$`5|TO$bF@6fHBtbZBLtc?KiV&7%IJMh$jziNa5 z4*uH}UpVjz1UuqA%Lo5?^X!4YB_sOaKl6$F#d6ZEpDGeE6nXAn;(znayygL9vurO# z|BCp%N0?@ z<-a`0$@-TE3I6wG!?Mf#kKa7#HTAIniwhq3wS!)5WqQK@)WK!cbkHm6#>>7{^X2CA z9`LP|*NOyz*q+iL+?q5p(XM}b<*%Dt#1HmJE6?Zem#>R{GDH!Hw|+i<-&_R;{`%I= z=5HCY+?Wz!xPG4xJl^*U}f4FMEy@QqhjXk}VO@Tr!Nb0XEZdojM=a zWuH9FDBHpVjZTbCDeIOc&c>yKozcFNYBF9{tsbmc(daIEP9})+a+BDj#OZjmMQ+ljka4_|dLf=rk29xgaUG=(^{>!aWQ?kw zxbbWnmQ;z0b{v@{KCFM|WA!f=)R!EkaTCRaneOvU!ije3lhvw$r#&lQ&A=DpgEp*qc}$u-2rS2O2t1^Kj8^n#WLF zXg2$BFf*!oez`n5_>UQc+}60_^fF-+Bc&t3Xrq<)$wbBa8p>F#8&NW+Ts@X9Oh)gg zG3APhs%d}gr2U@YBRRGTe6(?^aYl$Uq6;1}n{g7gpX1|~`1o7Yp2L@5{HXCCg?#_Z zpnm^Nx4&b&$;W@<_AlK2o!j!A>-V<>_4}P}?{#}fZSFg1yx919VF%x-5dXtRgpwRx!P)$Uc*zpBmmekA03ik<3v|D`t9ITW9pj^ERGKjVXp4+jsKud2tny~FLN zxjo_bC2Dh@7yJ0jb)5UWK}aCu9m2(`dY=$S!rz1X{wIap|5_dA`#1Xh{a4ez0H2HS z8CCT`P~ZEA+ImhQ*ZH;(r_2w81iK!HLrc&9U{KG0itr-*nmW$!$JFNc^KM_@_QgW3 z_Yxm}g^&N4+gG}Mo$y)2n}vM;MEw4TJiDrPfx5op3cCK&gq(k+j?*8-6V#t;h4kl# zI({+NQTsXgX>XgqzXzz_|B>2^#Us>yF0mxFxz292xy}oOT>n)%&UOA&ZLV{T@Qqw?7H$d*2g2zp8#Jyo7a! zBS_b~Kd9qJ2|2#m$4?S+pObZ*-w(Up5%OG%I?i(`4xsUQlh6O9+I;`--2Ml*KP%+< z|IPSQpO;@;#|J>&?_9O{{iN^(`0s>V|Id8>N}qp^+wXV#TH&9tj(q$EAHP}1^U0B^ z=X;ot_C~i~AcP*S^zpa)_?O(i!R>qC|5QIVfUBUT6V!eoF)z2bs}22k)aEyfYV#Z~ zcl$MNzemVCe_hCP-ygrE#`6zBjprUA_qj;N;U|A03KT+Sm7pUvqS8c9$zS`X90v~^o+gBRD;NxEb_5DA@PpI#25OSRp zKpmGqQOBRDw&+}K#_3Phei5-bx35y0@%~#O^Y9TN^YRn7|I_W6JM(+`JrAni-&ULJ zeP8XDFrRm!4G+1EkbWEvsvi&b@rU~OS|5Lw+Akw!qBisNUbQcUFRRUbeAn$C3%SqF zb^PU3b&J}s;Xe4Db^K1kR}xzm&fzx}P7>QOKGt}u@u|i!3q3AxYT z2)WP4jn@mg-?xqTVC{&;`EQ_&VcN#&;V(VEnl8AB|r(e$V)y#@`zcTb0*Wevta}0OLc9>x?HF zPd1)u955=iP`@8D?lV5qc!}{9#?UwT{&(G0zKDMR8{=&ld$sRkysz;n<9g#`jHeoR z8qYP37-x+a7@udn)c9KCTa52Ae#rPKQkG_EyXZhVXJ zy~d9jzhL~e@la?_*IQ>i-6*|7$1gU%&iGE_`;1>Ve%tsn<1NNJK(o5eeT>H#&oEwZ zyv4X4Lf7{nWjxh*mT}m)&-g6kON_5I{-yDK#!ndk$@s6ve>eW#c>6>1{`WR2FG2k| z&bZb1MB@d<=NKnDB|TuAJTT)C#?Uu7zTo!rj2|$5%J>zd^a@?) zD9L|t-gt%aokqpQb^cq%n~eWy`~!H7&fm?r#;EwVjz7lu1miizF=Nm89OGritBikb z{5#|4jM6i7{T~{CZ9EJ;LC23UDo(7n^bg^w#FzJ zw;9hg4jRul?l->P_%`DQjGr=o)A$?XVfV`W-pjbzc$)F~#+MpjXZ$PU`;A{Ve%tsn z<1NNJkRYJvyN~ga#^a6KjRVGEW5;;0@lxZJ#&;M$Z2W=o*T&l&nfJZ7@u9{?8Fv`Z zHMWiWjh7qWYJ9)()5fnEZ!-SMco+#TdftZ{Pc)uxe2Q_>_zdHVjITAm&3KLRTH_7I z9~pmZy#0OhzV|gg+<2n#bmLQulg4KlUu1l(@omOyjMo}(F#gDRdlGQ;y!SOe+<3b2 zDaJ|TGmI}XzSj6Q<2A->jo&o>)Od^WP9&=6z7H_2H9pq3)A%&wjPWAl>y1|%KWx0t z_zmMvjK4SD5yL_Ey}$91#*>U^8qYIM8!t4z#Q1vS)y5ASuQPtb_!Hyrjdy&2?{9ph z@g(D!#`BER#tV%vF}~h-weiEo>x|zp{>1ou;~gL9`x_r=Jjr;baoTvH@g>F&8$W0K z7voQjzcwDeChv1^<0FhG8h0AcGfo(vVf+*0<;JUw?==3M@jByIjNdW-r|~`y%6=SU z++%#YamM&e;|qr{X3X z8lP%B-*}_(yT)G_tE2p!#`_r`X54H%#W-LbGR_$rk_;BNi#?y^YF-{tvVSJJCwZ^v@uQ6V0 zyutV**BifY{FU(@8$G_pM;IStyvX=c<7

zGQQjR3FCFfe>UD^{F(6<;~h5TeeYvD#>jiuLm%8`++*w-pJjZD@g2qw89!_MhVgsG z|1jS6xV-+IjQ2A>%(&Tjim_!JH_jWMYkax!O5?kYA2fd2c)jtv#$On#uTo)_a0#)lX;8n+mC87GX-GQQOKdgI%T*BC!* z{Ac4$#+!||-ID#dr}4qYjmDFWPc%N=_%-9Vj6XHr?&Q4Q5ypoYHyXDXcNxz!P8#W;O zGM;CgH10QEVtlpnjmCEwKVtlv@mt298h>Xzd`I@8XskRoN>ExxA7d~ zn6YPkj`33C6~?z4KWO~4@p|KJ&dh$@(Rg3uLyadGw;T5w2aU7F3ym)_zRCD@;|GnO zHePT1uJISfYG?N6Nyeucr;HaEUt)Z<@gv4B8NY74$@pK!`|Qf=|Dkc6@v+7;j88UB z7#ECxY>W#SLj1M$!Hf}RM**IogG+u1H z)Oe-w9mWqEKWDtb_(S8bjfd^cejH&u%6Ob{yYVdJsBzx-JmVF{_Zh!x{J!yK}zzR&n6<5!K}H{NVK^eo@sc(m~Zbp$y3^LgrBBS;!Qb zhj=oC2z3-?Do5V6&ieSL>;3Ef}mf-WO%@*v&A)Leo+`!#D&R?0LzQ@nJEXB%vjm_Da{rD+Y@;m;>INoN;22tP4 z%+E4>fpyuET{wWFIh|kg8}8u={>CD&NBzsOI_t9w`*Rf6a0id@XI|x9rgs(gvBu?gGoJr3qre#KSX&Lcd> zznHjDw61i_!6*1EUt%M+V^0p_M9$?(ZsTG8%s-i^akP%K%)w%;z*=m|PVC1|IGu~R ziTin)SD30v)IU9Q@kv%>ZGOzLoXMr!%>Dd{zw-`LzZvz-%7T1~)mWdc*^PrZhF@?A zH*p_Nu}rh5Zw0=>7JP@j`7tMRK38)Gf8cpuW0K}kzlWHU#rPawW@Em?4>*ETxriIM zhbMWNcbKL{w2tg7!e{sr8}l80z!99vMclx{Jjct7XR4M_|12!Q>a5RJ?85#W#ZBDJ z@c*=AV1{{F6Kt=09OId~zy2)D@~p{5Y|q{t&M92T_1w)9jAJ}g573{5 zS)Mi7i0#>%!#RZuxt_auf^m#z>Vf*RFw3(h8?ilmb2z7PJ$Lg2}< z;|gx$5uRr}9~lz$%fn|`hmF~eLpY8zxr7_JhsSw|H<@f`)HerEM{_ZM z<^98=c`L9Q8?psEvoA+*Iltv8UT2bzqWRM?KTESR8?rS!b1=v7ORnZVp5!&A`Z((Q z2y?P3+p!0Sa2#iH3HR~@f92myJv{1{h51>URoH;7*^NUvp0l`=oA?|5WttID-yAH; zXIP6(_zrt>5I^N~?&2B7G117VUutG#Bevwb?8gaQz?Iz0-8{;(yv$onGAio-05dZ; zpWt(>%DU{p_c)caxs2Pnm%s8B@B1WLM|$St6MTj>_&VFL8wYYUr*RS2aVJmk9RFl& zbhMrf%*Qf(jxVtx-{Sim%rTt7uepKW^M8!vH75QvT2ER&%EEk_)!2|N*qMDff}e3d zS8*E;@eKdq9i|!+tt&J0u@oz@Hs9ns?8RZ6z}Z~J&HRx+^S-fB{|A_j1zDCauoL@m zI45%+S8^*4@-%;EJX4N~){%*MS&}cYF59vb`*1iXa~@Z6D-ZHCe`h>Xj<+7>Wl28I zT5Q7h?8%`V&ski>joicIyu_PKHX&M1QI=s9zQ*S4%zhljeLTuvc%4ZnMtvUU6wcx% zp5U*%#rq~j=cni6EXHS9lU+H0pYU_8W9rG#ybm!GA7ySfW(W4!#v9?{Fe_;jn?xR3$X_4usJ)i4~KIy=W!*s z@*q$1cg8d2=g~S!@;SC+7xw2UPUQlw;SL_*&%DaJOfxO&o0SDvh0WNNz4;L*at@bs zKTk1^k4%sH<>r&Dz?Zpz>$rsn_!BSlHt(Mi&Hpr8vL}b~6n|mjFQW4@GdD}}8P;S& zzReyS$_bpq72L{0Jj<($&5YLZARlEBmS+vV!ME6*LpXtRxr#e@loxoD$!A6D$iZT) zz*=m|PVC1|IGu~RiTn8*|6-!q9zV0Q5T9aIHsxFF&LJGn*<8*oJjgS=!n=H6PPCrv zEX;Czk*~8Y-{*%M$5~v)Z+U=cc$JCfM*Y($5pKvj>N8 z9A|O~H*yb;^Ah8kbV0P9hnRy!S&`LQpRL%1{W*$Lxqxf9gGcx?uktR_EcE=c0L!on zUt=?NHtfP)9L5R!l1sUXdwGJt@)qy= zDq2^17Gi0>z?a#GZ?ii;clp5LXg%54mYvy;qxd-&aXr81kG#ZNOui)Q^9WD!7hY%5rO|N@^Klku1-`;2 ze22Z+eOWY5e}2Mg{E8d6n}wD~=apn7zRG6o#J(KKsa(i)+{OR#B5(4(6;a;|%*|Jr zXH`@$%4b-U4f!^Ea408m4p(q15AiIoGW;WO;r%BM@=+FHCBDLz?8M$2!SS5MO+3Nt z{FiCgME$d|5T9msHeegR$H5%SnOw@v+|Qr*JMS>{+GrhFS&&b$0h_TC`*I|wav|4o z7yrkLyvh64Mg21{H%st&)@D<7WFL;;6fWRe?&L9E;C<^|2Yi%8Se`Zb2H#?L4&ivt z=5lV~L7w3i-esN*(RxbpSvF!%4&zkL=5lV~L7w3i-v5n#=i_{m<@h3BXIswZSKPqe zJkDSFH&bkk`ex)1j^b1<;9BnDL7w3aCfgLv`zQAWQIh)@D<7WFL;;6fWRe?&L9E;0-4GHd;q|=HipA$Xa}#Lphmq*yy`xzHfM# zXL*JHGWE{r_$(~N-AuD9s%K*%KF#WEz&3o3gE^Knxs;o^pFi<;-r=zCqjiksT%P1b z{>8gYwL3a5Bb%}<2k}!*=T}_MT|CCWm}pNle-S>#O02;_9L|+I#?$NkMk1ane?E2U=9{#dA`U7oWN<^d9Qvbny&>rum^{6 z0oQUTkMRO;FxlZ~-t^4HCs~bk*pltplS4U^OSqAHc$}AblgW-m>v)(s`2;WW1|Rw% zIzA^0unep4H8x{Me!!18iF3J;JNN_7^BR*Jjn?rHbFvtpWj=T*2;ClG|_WjJrJS@SA ze1(nq9{X|xKjVCU!^clV{R*-yUtk?JXD9aIaL(gO?&DFO=U+^8GV1#vv$GJNVpY~< z3wCB-&f$9Q;xYchYfOA9>YtX6vM`@!HP&NGzRP|b$%Xuu*?)@q&eDKe45qS zfNl652XicEaw#`+KY!xyyu;LIqjh9uK|aN5tk2f$#z7pzFSvx8c$jg#&6Gb!{WCK^ z%kpK`V@tlvew@NDxtiN~m}hx~|1$NtXdPLYpQTxuud*roawNxd7MF4p_wodPA%_?ln_Uy%vIEnMPiaU6Mzwsa5 zeQU7c##HU%E4cLb7aWKbnCYN$E_wy(I&VTv9uhBXlWl=uMm)V3J*oPxIjmx;1 z`*@OZyvsDdMg6m~46CpX+prr4ax|y$D{kgKo@5+vGf7<3KOG-q5td_h)@LhrVSkR| zR4(9J?&JX;pAsok< zT*8gq!{fZf`>xto=4M&Gz&h;6k2sf?8PBwTnwR-mhA*%#Kji0J&b>UzINoN;zw}{# zmf;Jm$JTt0A96hBa3#0%2mZnvyzg4n{}GPlOfKbS?&nYZop+e}dNf~F7UWZ`#`^5W zK^(&`xP+UykEeK<@l16i>Ys%LSe8{;kFD611388>xr|$Qh(Gf$cKkc)KZs+vg@<^X zss4$M&%ozdn@!n~eK>+sxPWW9lgD_0H<;{p)HgkI@kv%>ExySP9LcY_k>Bwsf8li| zjgR_1%*R=r61-|Q^Ra(t1m^DXw^0FLH#e$8*VhbI`v zcqaSTzB3m~uo7#sA>U>X4&?-%;$_A&)!nFH7M5jI)?+JnB3D#!|c4Z%q;1n+4T3+A{CQBRj zOV5hzzz;Z_pYcns;Zgp=>r9$1n*U)w&f=`VMr_aC9L_0R$o1UK6O7{>rgQ{n9fRpXBp=i&MFS$umdi zr)4(g=VYE@(JayNrCFJ;vKc$`LyqHoF69~i$|PB%`5$6l7UOe#nT^?=z4#H2@GmCL z7R{fIIrs#h=rY71m`dcH>}<<7}?rHXh-5 zUT3o44=;ybZ!$0sOR);;vK6~=FvoE=S8yAT@I0?G*<<=M4@#`NQaWKbmHdk;P zkMKONGg%J(nTMrVg>~7A-8h)zIGZcDjYoK!DRV}BGc!NS@CCk~D>`lnKjADc;(C71 zAK5f_bbdR&$8ns>1zf`&Ji?!Om3R42o@o9o%+J!S%uRWt7@<48{7mt4*5Jj}Da!hgB7aMX7< zf8=FeXObe(aq0LNi?AH4vp!p~3;S~vr*Z*{6^;5l$Es|>&K$wdc%Ikz;1kh2*;trW z*ql8$np61|w{b7e@lW1m#$r*w(yYsO*q0MHpDVeU2Y8B?n7DW}|AWlJLM+Qle4isY zk>Btn6FnKtn};Pho=bRualFCgC8G1wF&CfVi=jzlu{v@m_TfjI%MIMiznP(A)F*pr z;^6No^J(L?IfB!#n9HV*j=V56&;t3kAw#G0-?ctMOY&= zcpq=Vj(lIe7l-g;&I%3ATP!c<>d;_)-*Hc9aNIHZXZg3#U>$!jap~y1CC z^L1hO&|uzy@=$q=uemxjczo-*+xU<2DPG|{-E(6c!9q$@pDoC^r6B2Wnuvq zVHH;An{2^u?7_*Q!8(@nTkhqL{Dp5+h>mZ|uI$IzT*i(3oirs^%(ncX-fG&t{b`3tV$25t`x=H16L#?SLM?=nN>;P_zu znOTTW@CCleMxntvI>_&G7)Nk?Xt0iHTpSvlx1IZpALAdP!8-n8$|_NQfEh!B`JRwV zusUDj>!HDM&E?kofc-gvpK&1Km3;&sz&R~%z`Y+%B;pFY|ifN%}+U=3%Quv zxr?VmgU5eE{)cI+Me9n>f-K6)ti~p6&aUjvQ5?hRoW;eV!RvcnXz+d9Hu);kRFCSJ zLxblvJ9CBx&r5MuWNp?94d!hocL)t0@37Edo)MhId0ZbFocEo)oBKn9en-?#%je}Q z@}1CN{zNZEKFo~F&%&%28uY6knmHDGiH+He-PxPtLWA?Bh6ep+a1obqS7>nDLHP%s zeQG4Pk>8d3ga+#!zz@~O^Rv)k{yFjz zc|&M$-ezu7Kf)hFgY(YIzslF;Sk0)OIy9IkEpvqi>&>rTLVi|$F*G>-WxlFjU%k29 zF*LZoKIACl6FJrR;?Q8ePbU`KIxe`G&nA| zT!LkdS7sCA?}Y|^dU7RrV`74p>LxXxI zKEV>K5gN?fjPI~7hlB>}{+OdegZZa%R%mekVjd0+_Wd_r3k{CH!xXimdZy4|-fS$( z@_aosn70kPa2Ush2Io)W)X<>M7wU`T4gA*l523;O&KkcUUy=Wo)76gV&%nGa$cmxC zJg>?1*_Q3uFEn@@%Xxq&)z9#JXt4h4O!jJ&Q-%iTXOOeVdE_TUgMBE?nykeJY{XWf zL7#4N502s(e#U8>7aE+mJT!RRyX1Xxs@HwH9l59aD0zzd9C?}g zck&VSpX508M0KP74}=E&Gs$^EgZ@v;Rn=?DP1L){{nS5_C#Wx!*Qjri_p6_m|5T5c z@2?m2e>61MpF*L*`bx>qtJjxXs&|lksed9*Ri7&_SKlfBpnh7ute&`j)c?WIpnqmL zZ)mVT<>YGWugY(#ca{6Ae=JW_UnH+p-zpza|3&^w{f?ZnLDc`T&|rTGhX(5_Emu-+ zAh%NQDEC$$Eq|^)PhO$EOFpW8M*dwr$?H-7w4p)&EONfkV1LTX)zx2i&c-6UGi zqb$t^Y|SpApTuI_<-wt&VzH0p38CYI-^lQrE;dpQzRuBCo7ONYMe-Vo{4RbJWtI(j|+u?XHZ`Uw) zip4$%4b~g}ljt4m557JnTpv?{zi$|h2RUu%XTi@Aa>Dg7Iru(U&Jj8(__;z(xIWqk z??-a6(4cw3x`X)=u8#@!GsqRf`scytfR0bNKE?&#hsm`00H;PXN`c&M>NUwYiZ@!i9`AQtPb-Y;}wEH+3U8agc&8!mqm+Bp^*D+h;9s-kU@5UgJz}wi^5W1SESFb@E($*1kvD~Y6^m_^zYG037TYcF4-FP` zSUwgyCl)&)pAH=veBF>Qh6am?ldpsZi?}A=3SAQXyeMZ1ZSMIDF4p{V;m{ygmaEBi zEGFi$r5 z-gQt+PWXBg)GNuavL0LUEe0>0gg(KSsssmf7(d}y1~09IDOe!@wd$~pX! z%eac0xRrZ&fIspSFYq^B<1L22QwguPWPE@RF)JTqeimjaKE>zx0$<^4Y{aH~i|_C~ z_T)eg;U^r+shq(t`4v}j9d~m-kMcNw}}|{EIhvmq~&jXu{WFDn7`J%*tHM$0t~V<@g+{vIZOSO}6IS?7h(kGwV>p?g zb2jI5HP>?sckl=P$TK|8I9}mhCP@+PS4uv>?99mmEW%QJiWOOfFR?aXXJfYFTkOnk z{DA#Aj3YRXlQ@I3xrj@+h8wtzJ9&Udc#>y$iI;hue>2hjzWy@}(=jLWurQ19IacC} ze3?zyoSoT?z1fdL_%T1_c+Td0F6MHs<3{e~L7w4x#_6nAL zS%PKw94oN~UtxVVWDB-oM|NQ^_T><~=SytFrtHWr?8!bH%we3!DV)W5 zT+HQM&rSS}yLp($c!uZsJOAWu-erp57lz?}rDg_Z=HtxECs=~zS%KC066^5|wqP4} zVpo2^{``m|If0*X7UyvZSMVEt%kR05$9RJ0d5M4W2JbS-1NMz+nVH#{mjzjZWmtig z`4VgM4K`sLwqsXzXMYanNPf!CIF0kTkSn-`-*P+m@eoh&G%xWoZ}1-`c`(|y-GchOguqdBoIX=f~tjW53oz2;r9odDw*^k3Gg5x=vGdY)wxttrg znY*}`M|qs*c#&6mo&Pd%@PS9dzVSh3Vm9Vs0Y1sne2$e^lePFd8?!avW*5HCejLOR z9L>r6oL_Sp*YX?g;Q^lJIsV2!c!U2iycaXvr({gcw9Lq?e4GiN`vvC}k&Ck|%d--z z@@2lt*V&lu*@@lRn*%w7qd10>`8ntCOD^FGZsSfK zVP<3w=4KHV=hJ+aRat{|*nrL0iXHead$BKvayZ9v62IUae$8cE&rRIPJ^X<`@@HP) zEygoR`e?tB^8r4@oXo?*EXFb{$LIM1Ut(=GU?a9*8+PEk?7h(kGwWB3K?scW^Hc@(j;2j#qe-x0yIYw4e7e4bw3bvoRO*u_&KpMOI-QHsG6V!ME9g-PnWu zIEWu}6vuNi=W`L4b2WGHdmiKuJjpY>$T;5SUEUXbK%VgWWjbbHHs)YH7UGjE%_^+U zTCBr{e3PyDHaoK$d$S)$aSXrU94_J#uI74f;ST=5A9;r78OJNU$=ghsG1|We_z1Hw zC-blfi?b}tvofo(0UNOe+pq)QWq%IlSWe_L&g7T;iYvH=-*Gn&@hDI6EHCjg;~5J+ z_zbVJ6im(Z%)}hb&B83kvMkTatj1cb!$xe%wrtO??9P51#Nqse6FG&mIFF0Doa?!X z`+1nh`4fNVpZuG5m^%1OJ>18%%*d>KoOxM<#aV%sS%a^z9^c?we23lGgZ(*}<2Z@a zIg87j2#d1`t{D#}OlgD_1Kl1`_@E;}$ZgdLwBN@{(6LT;(3$qw2urgm`eYWP??7 zn8P@l<2al1xtiM?K8eBW2_zWwuI$vU4 zzRqTB#dp}5J@^3!a~MZ+9H(*y=W`KPa1A$e8~5-4|HqR&&r7_@>rD1&v>*2~Ez>hs zXmEYy;}a~wa(s?eS%Y=hfXOr!MLu`h>mIHz(3=W!v|aU=KgAkXkTFY_w@<{c(` zEPDL+GaWN9J9DxCi?9@*Vs*a6I&8o<*@ADg13zGY4&`uu#%cVDOSy&{xSRWVj3;=G z7kP!(7|&RaXrEFrHPbT_b1*kcvMirtCBDjfY|LhC%l7QT_t}R7IGW=)h0{5g3%Hak zxq+LxpNDyzKk*m-%D;JssdGmAmX?n(7lV(-V~K))-81<0SHkNt`1UB_e#2mz|EK%1 z6V3}>*SW*<1M{;mi?JjturjN$CL6F3o3bT4u`9c?H-~aKKjBzT=Pb_SLayd|ZsJz% z=V2b>30`CzukadUiK2b_@BMwLjc4M2@9)cPycqv`e_wgy)%f50`|23~?|pvv?(b`_ z{@?rj?%m%vNd3R}`Q5v}Z;JYK&f;P&=W4F!ciheWJj`P}!F%`ros%yzj#qe%w;0b@ zaE*r7X;P+Tdj9u5!F%@y7FPf7eS&3;-@9M%zxN5&Qonb<;Jy2UTN?lGeS@8hcV&0> zWfb7ajfx)oWglr z$i-aF)m+c-xSRWVn5TJ;7a7M}jA!^Cj3m51n3n08iP@Ngxmk=QS(fElft6W{b=ZLS z?r&@>w`V7IWq0=GP!8uO9LtHE!g*ZC#azx!+{*8G@BYVQ@(G^iIbLKOZ!w<#y$>?2 k`~A{06SFblzXJ$fD~07^EXjNKLspg({=0zS_?q(n0cIa2e*gdg diff --git a/patches/kdrivers/src/wanrouter/wanproc.c b/patches/kdrivers/src/wanrouter/wanproc.c index f08d97c..2c122b8 100644 --- a/patches/kdrivers/src/wanrouter/wanproc.c +++ b/patches/kdrivers/src/wanrouter/wanproc.c @@ -114,10 +114,6 @@ typedef struct wan_proc_entry #endif /****** Function Prototypes *************************************************/ -#ifdef WAN_DEBUG_MEM -extern atomic_t wan_debug_mem; -#endif - extern wan_spinlock_t wan_devlist_lock; extern struct wan_devlist_ wan_devlist; @@ -531,7 +527,7 @@ static int config_get_info(char* buf, char** start, off_t offs, int len, int dum wan_spin_lock(&wan_devlist_lock); WAN_LIST_FOREACH(wandev, &wan_devlist, next){ /*for (wandev = router_devlist; wandev; wandev = wandev->next){*/ - sdla_t* card = (sdla_t*)wandev->private; + sdla_t* card = (sdla_t*)wandev->priv; u16 arg = 0; if (!wandev->state) continue; @@ -700,9 +696,7 @@ static int interfaces_get_info(char* buf, char** start, off_t offs, int len, int WAN_LIST_FOREACH(devle, &wandev->dev_head, dev_link){ dev = WAN_DEVLE2DEV(devle); - if (!dev || - !(wan_netif_flags(dev)&IFF_UP) || - !wan_netif_priv(dev)){ + if (!dev || !WAN_NETIF_UP(dev) || !wan_netif_priv(dev)){ continue; } @@ -760,7 +754,7 @@ static int probe_get_info(char* buf, char** start, off_t offs, int len, int dumm hw_cnt=(sdla_hw_type_cnt_t*)sdla_get_hw_adptr_cnt(); PROC_ADD_LINE(m, - "\nCard Cnt: S508=%-2d S514X=%-2d S518=%-2d A101-2=%-2d A104=%-2d A300=%-2d A200=%-2d A108=%-2d A056=%-2d\n", + "\nCard Cnt: S508=%d S514X=%d S518=%d A101-2=%d A104=%d A300=%d A200=%d A108=%d A056=%d\n A500=%d A14x=%d\n", hw_cnt->s508_adapters, hw_cnt->s514x_adapters, hw_cnt->s518_adapters, @@ -769,13 +763,10 @@ static int probe_get_info(char* buf, char** start, off_t offs, int len, int dumm hw_cnt->aft300_adapters, hw_cnt->aft200_adapters, hw_cnt->aft108_adapters, - hw_cnt->aft_56k_adapters); - -#ifdef WAN_DEBUG_MEM - PROC_ADD_LINE(m, - - "Total Memory = %d\n", atomic_read(&wan_debug_mem)); -#endif + hw_cnt->aft_56k_adapters, + hw_cnt->aft_isdn_adapters, + hw_cnt->aft_serial_adapters + ); PROC_ADD_RET(m); } @@ -783,13 +774,13 @@ static int probe_get_info(char* buf, char** start, off_t offs, int len, int dumm #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(LINUX_2_4) STATIC int probe_get_info_verbose(char* buf, char** start, off_t offs, int len) #else -#if defined(LINUX_2_6) +# if defined(LINUX_2_6) static int probe_get_info_verbose(struct seq_file *m, void *v) -#elif defined(LINUX_2_4) +# elif defined(LINUX_2_4) static int probe_get_info_verbose(char* buf, char** start, off_t offs, int len) -#else +# else static int probe_get_info_verbose(char* buf, char** start, off_t offs, int len, int dummy) -#endif +# endif #endif { int i=0; @@ -818,7 +809,7 @@ static int probe_get_info_verbose(char* buf, char** start, off_t offs, int len, hw_cnt=(sdla_hw_type_cnt_t*)sdla_get_hw_adptr_cnt(); PROC_ADD_LINE(m, - "\nCard Cnt: S508=%-2d S514X=%-2d S518=%-2d A101-2=%-2d A104=%-2d A300=%-2d A200=%-2d A108=%-2d\n", + "\nCard Cnt: S508=%d S514X=%d S518=%d A101-2=%d A104=%d A300=%d A200=%d A108=%d A056=%d\n A500=%d A14x=%d\n", hw_cnt->s508_adapters, hw_cnt->s514x_adapters, hw_cnt->s518_adapters, @@ -826,12 +817,11 @@ static int probe_get_info_verbose(char* buf, char** start, off_t offs, int len, hw_cnt->aft104_adapters, hw_cnt->aft300_adapters, hw_cnt->aft200_adapters, - hw_cnt->aft108_adapters); -#ifdef WAN_DEBUG_MEM - PROC_ADD_LINE(m, - - "Total Memory = %d\n", atomic_read(&wan_debug_mem)); -#endif + hw_cnt->aft108_adapters, + hw_cnt->aft_56k_adapters, + hw_cnt->aft_isdn_adapters, + hw_cnt->aft_serial_adapters + ); PROC_ADD_RET(m); } @@ -942,7 +932,7 @@ static int wandev_get_info(char* buf, char** start, off_t offs, int len, int dum /* Update Front-End information (alarms, performance monitor counters */ if (wandev->get_info){ m->count = wandev->get_info( - wandev->private, + wandev->priv, m, M_STOP_CNT(m)); } @@ -962,7 +952,7 @@ wandev_get_info_end: int wanrouter_proc_init (void) { struct proc_dir_entry *p; - proc_router = proc_mkdir(ROUTER_NAME, wan_init_net(proc_net)); + proc_router = proc_mkdir(ROUTER_NAME, proc_net); if (!proc_router) goto fail; @@ -1092,7 +1082,7 @@ fail_probe_verbose: fail_stat: remove_proc_entry("config", proc_router); fail_config: - remove_proc_entry(ROUTER_NAME, wan_init_net(proc_net)); + remove_proc_entry(ROUTER_NAME, proc_net); fail: return -ENOMEM; } @@ -1117,7 +1107,7 @@ void wanrouter_proc_cleanup (void) remove_proc_entry("map", proc_router); remove_proc_entry("interfaces", proc_router); remove_proc_entry("dev_map",proc_router); - remove_proc_entry(ROUTER_NAME,wan_init_net(proc_net)); + remove_proc_entry(ROUTER_NAME,proc_net); } /* @@ -1129,7 +1119,7 @@ int wanrouter_proc_add (wan_device_t* wandev) int err=0; struct proc_dir_entry *p; - spin_lock_init(&wandev->get_map_lock); + wan_spin_lock_init(&wandev->get_map_lock, "wan_proc_lock"); if (wandev->magic != ROUTER_MAGIC) return -EINVAL; diff --git a/patches/kdrivers/src/wanrouter/wanproc.o b/patches/kdrivers/src/wanrouter/wanproc.o index adafec960e55a7dee2dbd4fa5dd20246f3ac68c6..2f55ba811f1bf17539731a3a13510fe1db94a134 100644 GIT binary patch literal 219488 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 literal 211384 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

1Y7mp`+8E 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 z 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 Dr)t~8 literal 0 HcmV?d00001 diff --git a/ssmg/sangoma_bri/sangoma_brid.x86_64 b/ssmg/sangoma_bri/sangoma_brid.x86_64 new file mode 100755 index 0000000000000000000000000000000000000000..e48f770e662719f07f284d18a9da085a1c53326d GIT binary patch literal 573952 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�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 literal 0 HcmV?d00001 diff --git a/ssmg/sangoma_bri/smg_ctrl b/ssmg/sangoma_bri/smg_ctrl new file mode 100755 index 0000000..abbca3e --- /dev/null +++ b/ssmg/sangoma_bri/smg_ctrl @@ -0,0 +1,199 @@ +#!/bin/sh +cmd=$1; +cnt=0; +max_retry=5; +function stop_all() +{ + + echo " " + echo "Stopping running processes..." + + stop_sangoma_brid + stop_sangoma_mgd +} + + + +function stop_sangoma_brid() +{ + #stop sangoma_brid + eval "pidof sangoma_brid >/dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + echo -n "Sending TERM signal to sangoma_brid..." + eval "kill -TERM $(pidof sangoma_brid) 2>/dev/null >/dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "FAILED" + break; + fi + fi + for ((i=0;i<$max_retry;i++)) + do + eval "pidof sangoma_brid >/dev/null 2>/dev/null" + if [ $? -ne 0 ]; then + echo "sangoma_brid is stopped" + return; + else + echo "waiting for sangoma_brid to finish($i/$max_retry)...." + sleep 1 + fi + done + eval "pidof sangoma_brid >/dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + echo -n "Sending KILL signal to sangoma_brid..." + eval "kill -KILL $(pidof sangoma_brid) 2>/dev/null >/dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "FAILED" + break; + fi + fi + for ((i=0;i<$max_retry;i++)) + do + eval "pidof sangoma_brid >/dev/null 2>/dev/null" + if [ $? -ne 0 ]; then + echo "sangoma_brid is stopped" + break; + else + echo "waiting for sangoma_brid to finish($i/$max_retry)...." + sleep 1 + fi + done +} + +function stop_sangoma_mgd() +{ + #stop sangoma media gateway + eval "pidof sangoma_mgd >/dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + echo -n "Sending TERM signal to sangoma_mgd..." + eval "sangoma_mgd -term 2>/dev/null >/dev/null" + if [ $? -eq 0 ]; then + echo "OK" + return; + else + echo "FAILED" + echo "Failed to stop sangoma_mgd" + exit 1 + fi + else + echo "sangoma_mgd not running..." + return; + fi + + + #stop sangoma media gateway + eval "pidof sangoma_mgd >/dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + echo -n "Sending TERM signal to sangoma_mgd..." + eval "kill -KILL $(pidof sangoma_mgd) 2>/dev/null >/dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "FAILED" + echo "Failed to stop sangoma_mgd" + exit 1 + fi + else + echo "sangoma_mgd not running..." + fi + + +} + +function start_all() +{ + + echo " " + echo "Starting processes..." + echo -n "Loading SCTP..." + eval "modprobe sctp >>/var/log/sangoma_mgd.log 2>>/var/log/sangoma_mgd.log" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed" + echo "Failed to load SCTP module, check /var/log/sangoma_mgd.log" + exit 1; + fi + sleep 1 + + eval "ls /dev/wptdm* >>/dev/null 2>>/dev/null" + + if [ $? -ne 0 ]; then + echo "No Sangoma TDM API interfaces running" + echo "Did you start wanrouter? " + exit 1; + fi + + echo -n "Starting sangoma_brid..." + eval "sangoma_brid >/dev/null 2>/dev/null &" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed" + echo "Failed to start sangoma_brid, check /var/log/sangoma_mgd.log for errors" + exit 1; + fi + sleep 2 + if [ ! $(pidof sangoma_brid) ]; then + echo "sangoma_brid failed to start" + echo "check /var/log/sangoma_mgd.log for errors" + exit 1; + fi + + echo -n "Starting sangoma_mgd..." + eval "sangoma_mgd -bg >/dev/null 2>/dev/null" + if [ $? -eq 0 ]; then + echo "OK" + else + echo "Failed" + echo "Failed to start sangoma_mgd, check /var/log/sangoma_mgd.log for errors" + exit 1; + fi + + sleep 2 + if [ ! $(pidof sangoma_mgd) ]; then + echo "sangoma_mgd failed to start" + echo "check /var/log/sangoma_mgd.log for errors" + exit 1; + fi + + echo "Sangoma SMG running.." + echo "log file: /var/log/sangoma_mgd.log" + echo " " +} + +if [ "$cmd" = "start" ]; then + if [ $(pidof sangoma_brid) ]; then + echo "sangoma_brid is currently running" + echo "exiting..." + exit 0 + fi + + if [ $(pidof sangoma_mgd) ]; then + echo "sangoma_mgd is currently running" + echo "exiting..." + exit 0 + fi + + start_all +elif [ "$cmd" = "stop" ]; then + + stop_all +elif [ "$cmd" = "restart" ]; then + stop_all + start_all +else + echo " " + echo "Usage: smg_ctrl " + echo " options:" + echo " " + echo "start :start sangoma_brid and sangoma media gateway" + echo "stop :stop sangoma_brid and sangoma media gateway" + echo "restart :restart sangoma_brid and sangoma media gateway" + echo " " +fi + + diff --git a/ssmg/sangoma_mgd.trunk/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/.svn/all-wcprops index 0fba5f0..f7cd42e 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/.svn/all-wcprops @@ -1,7 +1,7 @@ K 25 svn:wc:ra_dav:version-url V 34 -/svn/sangoma_mgd/!svn/ver/65/trunk +/svn/sangoma_mgd/!svn/ver/66/trunk END sigboost.h K 25 diff --git a/ssmg/sangoma_mgd.trunk/.svn/entries b/ssmg/sangoma_mgd.trunk/.svn/entries index f0054bd..98d36fd 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/.svn/entries @@ -1,14 +1,14 @@ 8 dir -65 -https://www.sangomapbx.com:/svn/sangoma_mgd/trunk -https://www.sangomapbx.com:/svn/sangoma_mgd +66 +https://www.sangomapbx.com/svn/sangoma_mgd/trunk +https://www.sangomapbx.com/svn/sangoma_mgd -2008-02-07T18:15:41.313227Z -65 +2008-02-08T17:46:54.335012Z +66 ncorbic @@ -32,7 +32,7 @@ file -2008-01-11T19:07:46.000000Z +2007-11-26T18:06:19.000000Z d2023784f5d89a5623927a366705e22a 2007-11-24T22:45:32.820698Z 36 @@ -47,7 +47,7 @@ file -2008-01-11T19:07:46.000000Z +2007-11-30T16:39:49.000000Z da36acc78b83d5047481df0cca63d969 2007-09-21T20:53:51.260136Z 1 @@ -60,7 +60,7 @@ file -2008-02-07T18:07:12.000000Z +2008-02-13T19:12:32.000000Z 31bd051e4281dc2e6e705cded0c30971 2008-02-07T18:04:31.680485Z 64 @@ -72,7 +72,7 @@ file -2008-01-11T19:07:46.000000Z +2007-11-30T16:39:49.000000Z f4832443a621cbb88e92535898d11b83 2007-09-21T20:53:51.260136Z 1 @@ -84,7 +84,7 @@ file -2008-01-11T19:07:46.000000Z +2007-11-30T16:39:49.000000Z 2403f191bdc1959c4cfd186b5030b9b1 2007-09-21T20:53:51.260136Z 1 @@ -100,7 +100,7 @@ file -2008-01-11T19:07:46.000000Z +2008-01-14T17:24:55.000000Z f20dab977386b2508903e24a307ca2d6 2007-09-21T20:53:51.260136Z 1 @@ -119,11 +119,19 @@ file -2008-01-11T19:07:46.000000Z +2008-01-14T15:56:22.000000Z bcf6ba51a26281d7a0963c364f8610f1 2007-11-28T21:12:42.416435Z 42 ncorbic + + + + + +call_signal.c.r40 +call_signal.c.r53 +call_signal.c.mine re-sync.sh file @@ -131,44 +139,52 @@ file -2008-01-11T19:07:46.000000Z +2007-10-12T19:24:17.000000Z 1cd822495b7d97b8e089c93bac1ad71a 2007-09-25T02:04:57.936973Z 20 ncorbic has-props -sangoma_mgd.c -file -66 - - - -2008-02-08T17:53:31.000000Z -fb2f3311aca106d27d61957211903a0d -2008-02-08T17:46:54.335012Z -66 -ncorbic - woomera.conf file -2008-01-11T19:07:46.000000Z +2007-10-11T20:07:11.000000Z 356d6fc18e0670efac6de6001e58648e 2007-09-21T20:53:51.260136Z 1 root +sangoma_mgd.c +file + + + + +2007-09-25T06:19:28.000000Z +fb2f3311aca106d27d61957211903a0d +2008-02-08T17:46:54.335012Z +66 +ncorbic + + + + + +sangoma_mgd.c.r33 +sangoma_mgd.c.r40 +sangoma_mgd.c.mine + call_signal.h file -2008-01-11T19:07:46.000000Z +2007-10-11T20:07:11.000000Z 1a8b734edbabbe1e04c0086460cf1565 2007-09-21T20:53:51.260136Z 1 @@ -180,19 +196,27 @@ file -2008-02-07T18:07:44.000000Z +2008-01-14T15:37:07.000000Z 0e349003dfb2ecb954424d503cee4c9e 2008-02-07T18:04:31.680485Z 64 ncorbic + + + + + +sangoma_mgd.h.r56 +sangoma_mgd.h.r59 +sangoma_mgd.h.mine Changelog.sangoma_mgd file -66 -2008-02-08T17:54:19.000000Z + +2008-02-13T19:12:32.000000Z 24d92bda7769867980fd44e68f2eb422 2008-02-08T17:46:54.335012Z 66 @@ -204,7 +228,7 @@ file -2008-01-11T19:07:46.000000Z +2007-10-11T20:07:11.000000Z a31121fb876e49155ae5d77812b68cc3 2007-09-21T20:53:51.260136Z 1 @@ -216,7 +240,7 @@ file -2008-01-11T19:07:46.000000Z +2007-10-11T20:07:11.000000Z 0f725f95ced42af15dcaef21f3a1722b 2007-09-21T20:53:51.260136Z 1 @@ -231,7 +255,7 @@ file -2008-01-11T19:07:46.000000Z +2007-09-25T06:34:30.000000Z 0e00003cd276e523b9b6e6df6a2f823f 2007-12-20T00:59:56.095828Z 51 @@ -244,7 +268,7 @@ file -2008-02-06T22:45:23.000000Z +2008-02-13T19:12:32.000000Z c97ea5c4ee482db2409549e9c320d633 2008-02-06T22:23:25.673829Z 62 @@ -256,7 +280,7 @@ file -2008-01-18T21:45:09.000000Z +2008-01-18T22:26:34.000000Z 305c8fe9341c230ec32af102688736fd 2008-01-18T20:47:52.049290Z 56 @@ -269,7 +293,7 @@ file -2008-02-06T22:45:23.000000Z +2008-02-13T19:12:32.000000Z c8cc3aa052980e6c7cb766ae564882d1 2008-02-06T22:22:53.766395Z 61 @@ -281,7 +305,7 @@ file -2008-02-07T18:23:40.000000Z +2008-01-14T15:59:16.000000Z d03c6e24e68df0f99cee78567a623583 2008-02-07T18:15:41.313227Z 65 @@ -293,7 +317,7 @@ file -2008-02-06T22:45:23.000000Z +2008-02-13T19:12:32.000000Z 81957c6e3d9a6caa2e223e954c15c49c 2008-02-06T22:23:25.673829Z 62 diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.10.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.10.tmp new file mode 100644 index 0000000..4a55b8b --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.10.tmp @@ -0,0 +1,306 @@ +#!/bin/sh + +# ---------------------------------------------------------------------------- +# Prompt user for input. +# ---------------------------------------------------------------------------- +prompt() +{ + if test $NONINTERACTIVE; then + return 0 + fi + + echo -ne "$*" >&2 + read CMD rest + return 0 +} + +# ---------------------------------------------------------------------------- +# Get Yes/No +# ---------------------------------------------------------------------------- +getyn() +{ + if test $NONINTERACTIVE; then + return 0 + fi + + while prompt "$* (y/n) " + do case $CMD in + [yY]) return 0 + ;; + [nN]) return 1 + ;; + *) echo -e "\nPlease answer y or n" >&2 + ;; + esac + done +} + + + +home=`pwd`; + +force="false" +noss7="true" +rootdir="" +pbxdir=/usr/src/asterisk +pbxd="asterisk" +cfgdir="/etc/asterisk" + + + +while [ ! -z $1 ] +do + if [ $1 = '-force' ]; then + force="force" + elif [ $1 = '-noss7' ]; then + noss7="true" + elif [ $1 = '-pbxdir' ]; then + shift + pbxdir=$1 + if [ "$pbxdir" = "" ]; then + echo "Error: Invalid $pbxd dir: $pbxdir!"; + exit 1 + elif [ ! -d $pbxdir ]; then + echo "Error: $pbxd dir does not exist: $pbxdir!"; + exit 1 + fi + + elif [ $1 = '-rootdir' ]; then + shift + rootdir=$1 + if [ "$rootdir" = "" ]; then + echo "Error: Invalid root dir: $rootdir!"; + exit 1 + elif [ ! -d $rootdir ]; then + echo "Error: root dir does not exist: $rootdir!"; + exit 1 + fi + + else + echo "Invalid option: $1"; + echo + echo "Usage: ./install " + echo + exit 1 + fi + shift +done + +if [ -f $pbxdir/include/callweaver.h ]; then + echo "PBXD=callweaver" > /etc/wanpipe/pbxd + pbxd="callweaver" + cfgdir="/usr/local/etc/callweaver" +else + echo "PBXD=asterisk" > /etc/wanpipe/pbxd + pbxd="asterisk" + cfgdir="/etc/asterisk" +fi + +if [ $noss7 != 'true' ]; then + if [ ! -e /usr/local/ss7box/$ss7boost ]; then + echo "Error: ss7boost not found in /usr/local/ss7box dir"; + exit 1 + fi + if [ ! -e /usr/local/ss7box/$ss7boxd ]; then + echo "Error: ss7boxd not found in /usr/local/ss7box dir"; + exit 1 + fi +fi + +if [ $force = "force" ]; then + echo "Stopping SMG..." + eval "sangoma_mgd -term" + kill -TERM $(pidof asterisk); + echo "OK." + echo +else + if [ -f /var/run/sangoma_mgd.pid ]; then + echo "Warning: sangoma_mgd is running!" + getyn "Would you like to stop sangoma_mgd?" + if [ $? -ne 0 ]; then + exit 1 + fi + + eval "sangoma_mgd -term" + if [ -f /var/run/sangoma_mgd.pid ];then + echo "Failed to stop sangoma_mgd" + exit 1 + fi + fi + if [ -f /var/run/asterisk.pid ]; then + echo "Warning: asterisk is running" + getyn "Would you like to stop asterisk?" + if [ $? -ne 0 ]; then + exit 1 + fi + eval "asterisk -rx \"stop now\" >/dev/null 2>/dev/null" + sleep 2 + if [ -f /var/run/asterisk.pid ]; then + kill -TERM $(pidof asterisk); + sleep 2 + if [ -f /var/run/asterisk.pid ]; then + echo "Failed to stop asterisk" + exit 1 + fi + fi + fi +fi + +echo +echo "Checking Syslog ...." +if [ -e /etc/syslog.conf ]; then + eval "grep "local2.*sangoma_mgd" /etc/syslog.conf" > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + eval "grep "local2" /etc/syslog.conf " > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + echo + echo "Warning : local2 is already used in syslog.conf" + echo + fi + echo -e "\n# Sangoma Media Gateway log" > tmp.$$ + echo -e "local2.* /var/log/sangoma_mgd.log\n" >> tmp.$$ + eval "cat /etc/syslog.conf tmp.$$ > tmp1.$$" + \cp -f tmp1.$$ /etc/syslog.conf + eval "/etc/init.d/syslog restart" + fi + eval "grep "local3.*sangoma_bri" /etc/syslog.conf" > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + eval "grep "local3" /etc/syslog.conf " > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + echo + echo "Warning : local3 is already used in syslog.conf" + echo + fi + echo -e "\n# Sangoma BRI Daemon (smg_bri) log" > tmp.$$ + echo -e "local3.* /var/log/sangoma_bri.log\n" >> tmp.$$ + eval "cat /etc/syslog.conf tmp.$$ > tmp1.$$" + \cp -f tmp1.$$ /etc/syslog.conf + eval "/etc/init.d/syslog restart" + fi +else + echo "Warning: /etc/syslog.conf not found" +fi + +if [ -f tmp1.$$ ]; then + rm -f tmp1.$$ +fi +if [ -f tmp.$$ ]; then + rm -f tmp.$$ +fi + +echo "Ok" +echo + +echo "Checking logrotate ..." +eval "type logrotate" > /dev/null 2> /dev/null +if [ $? -ne 0 ]; then + echo "Error: Logrotate not found !" +fi + +if [ -e /etc/logrotate.d ] && [ -e /etc/logrotate.d/syslog ]; then + + eval "grep sangoma_mgd /etc/logrotate.d/syslog" > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + eval "sed -e 's/messages/messages \/var\/log\/sangoma_mgd.log/' /etc/logrotate.d/syslog >tmp2.$$ 2>/dev/null" + eval "cp -f tmp2.$$ /etc/logrotate.d/syslog" + eval "logrotate -f /etc/logrotate.d/syslog" + if [ $? -ne 0 ]; then + echo "Error: logrotate restart failed!"; + exit 1; + fi + echo "Logrotate is being changed and restarted!" + else + echo "Logrotate is configured!" + fi + +else + echo "Error: Logrotate dir: /etc/logrotate.d not found !" +fi +echo "OK." +echo + +echo "Checking for SCTP Utilities...." +if [ ! -e /usr/include/netinet/sctp.h ] && [ ! -e /usr/include/sctp.h ]; then + echo "Error: lksctp-tools-devel package missing" + exit 1 +fi +echo "OK." +echo + +echo "Checking for SCTP modules..." +eval "modprobe -l | grep \"\/sctp.ko\" >/dev/null 2>/dev/null" +if [ $? -ne 0 ]; then + if [ ! -e /proc/net/sctp ]; then + echo "Warning: Your Kernel does not support SCTP Protocol!" + echo "SCTP is needed by SMG!" + echo + echo "Please contact sangoma support!" + echo + exit 1 + fi +fi +echo "OK." +echo + + +echo "Compiling Sangoma MGD ..." +eval "make clean 2> /dev/null > /dev/null" +eval "make" +if [ $? -ne 0 ]; then + exit 1; +fi + +if [ $noss7 == 'true' ]; then + make INSTALLPREFIX=$rootdir NO_SS7=YES install +else + make INSTALLPREFIX=$rootdir install +fi +echo "Ok." + +if [ -d chan_woomera.trunk ]; then + + cd chan_woomera.trunk + + echo "Compiling Woomera Channel ..." + + if [ ! -e $pbxdir ]; then + echo + echo "Error: $pbxdir directory does not exist!" + echo " Please create symlink /usr/src/asterisk and" + echo " point to existing asterisk source!" + echo " Then re run ./install.sh " + echo + exit 1 + fi + + eval "make clean 2> /dev/null > /dev/null" + eval "make PBXDIR=$pbxdir" + if [ $? -ne 0 ]; then + exit 1; + fi + + make INSTALLPREFIX=$rootdir install + echo "Ok." + +else + echo "Warning: chan_woomera directory does not exist!" + exit 1 +fi + + +echo "---------------------------------" +echo +echo " SMG Install Done" +echo +echo "--> Config: /etc/sangoma_mgd.conf" +echo "--> Start: sangoma_mgd -bg" +echo +echo " Chan Woomera Install Done" +echo +echo "--> Config: $cfgdir/woomera.conf" +echo "--> Start: start $pbxd (part of $pbxd)" +echo +echo "---------------------------------" + +exit 0 + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.11.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.11.tmp new file mode 100644 index 0000000..9c96639 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.11.tmp @@ -0,0 +1,119 @@ +################################################################################ +# Sangoma MGD +# +# Author: Anthony Minessale II +# Nenad Corbic +# +# Copyright: (c) 2005 Anthony Minessale II +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. +################################################################################ + +SMG_DTMF=YES + +#Default kernel directory to be overwritten by user +#Kernel version and location +ifndef KVER + KVER=$(shell uname -r) +endif +ifndef KMOD + KMOD=/lib/modules/$(KVER) +endif +ifndef KDIR + KDIR=$(KMOD)/build +endif +ifndef KINSTDIR + KINSTDIR=$(KMOD)/kernel +endif + +CC = gcc +INSTALLPREFIX= + +INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src + +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 +CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g +LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm + + +ifeq "${SMG_DTMF}" "YES" +LDFLAGS+= -lteletone +CFLAGS+= -DSMG_DTMF_ENABLE +endif + + +all: sangoma_mgd + +libs: + $(shell cd lib/libteletone; ./configure --prefix=$(INSTALLPREFIX); cd ../../; ) + $(MAKE) -C lib/libteletone all + +switch_buffer.o: switch_buffer.c switch_buffer.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o switch_buffer.o switch_buffer.c + +call_signal.o: call_signal.c call_signal.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o call_signal.o call_signal.c + +sangoma_mgd: sangoma_mgd.o call_signal.o switch_buffer.o sigboost.h + rm -fr core* + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -o sangoma_mgd sangoma_mgd.o switch_buffer.o call_signal.o $(LDFLAGS) + +sangoma_mgd.o: sangoma_mgd.c sangoma_mgd.h sigboost.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o sangoma_mgd.o sangoma_mgd.c + + +clean: old_cleanup + make -C lib/libteletone clean + find . -name '*.o' | xargs rm -f + rm -fr sangoma_mgd pritest *.o *.so *~ *core* *.so* *.a + +distclean: clean + @echo OK + +install: all install_smg old_cleanup + +install_smg: old_cleanup + install -D -m 755 sangoma_mgd $(INSTALLPREFIX)/usr/sbin/sangoma_mgd + +ifeq "${NO_SS7}" "YES" + @echo "BRI control scripts installed" + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample.bri $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi +<<<<<<< .mine + install -D -m 755 ../sangoma_bri/smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl +else + @echo "SS7 control scripts installed" + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample.ss7 $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi +======= +ifeq "${NO_SS7}" "YES" + @echo"SS7 control and service script not installed" +else +>>>>>>> .r53 + install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/usr/sbin/smgss7_init_ctrl +<<<<<<< .mine +endif + +======= +endif +>>>>>>> .r53 + @echo "sangoma_mgd Installed" + +old_cleanup: + ./scripts/old_cleanup.sh + + +install_all: all install_smg + +uninstall: + /bin/rm $(INSTALLPREFIX)/usr/sbin/sangoma_mgd $(INSTALLPREFIX)/etc/sangoma_mgd.conf + + + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.12.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.12.tmp new file mode 100644 index 0000000..974de84 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.12.tmp @@ -0,0 +1,5018 @@ +/********************************************************************************* + * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-08, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * ============================================= + * v1.26 Nenad Corbic + * Jan 18 2007 + * Fixed hangup after invalid Answer or Ack Session + * Can cause double use of setup id - now fixed + * + * v1.25 Nenad Corbic + * Dec 31 2007 + * Removed UDP Resync it can cause skb_over errors. + * Moved RDNIS message to higher debug level + * + * v1.24 Nenad Corbic + * Nov 30 2007 + * Bug fix on return code on ALL ckt busy + * + * v1.23 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + * + * v1.21 Nenad Corbic + * Nov 25 2007 + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + *********************************************************************************/ + +#include "sangoma_mgd.h" +#include "q931_cause.h" + + +#define USE_SYSLOG 1 +#define CODEC_LAW_DEFAULT 1 + +#ifdef CODEC_LAW_DEFAULT +static uint32_t codec_sample=8; +#else +static uint32_t codec_sample=16; +#endif + +static char ps_progname[]="sangoma_mgd"; + +static struct woomera_interface woomera_dead_dev; + +#if 0 +#define DOTRACE +#endif + + +#define SMG_VERSION "v1.26" + +/* enable early media */ +#if 1 +#define WOOMERA_EARLY_MEDIA 1 +#endif + + +#define SMG_DTMF_ON 60 +#define SMG_DTMF_OFF 10 +#define SMG_DTMF_RATE 8000 + +#if 0 +#define MEDIA_SOCK_SHUTDOWN 1 +#endif + +#ifdef DOTRACE +static int tc = 0; +#endif + +#if 0 +#warning "NENAD: HPTDM API" +#define WP_HPTDM_API 1 +#else +#undef WP_HPTDM_API +#endif + +#ifdef WP_HPTDM_API +hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; +#endif + +#define SMG_CALLING_NAME 1 + +const char WELCOME_TEXT[] = +"================================================================================\n" +"Sangoma Media Gateway Daemon v1.26 \n" +"TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" +"Copyright 2005, 2006, 2007 \n" +"Nenad Corbic , Anthony Minessale II \n" +"This program is free software, distributed under the terms of\n" +"the GNU General Public License\n" +"================================================================================\n" +""; + + +static int master_reset=0; + +static int coredump=1; +static int autoacm=1; + +static int launch_media_tdm_thread(struct woomera_interface *woomera); +static int launch_woomera_thread(struct woomera_interface *woomera); +static struct woomera_interface *alloc_woomera(void); + +q931_cause_to_str_array_t q931_cause_to_str_array[255]; + + +#if 0 +static uint32_t string_to_release(char *code) +{ + if (code) { + if (!strcasecmp(code, "CHANUNAVAIL")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "INVALID")) { + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "ERROR")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + if (!strcasecmp(code, "CONGESTION")) { + //return SIGBOOST_RELEASE_CAUSE_BUSY; + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "BUSY")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "NOANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "ANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (!strcasecmp(code, "CANCEL")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "UNKNOWN")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + } + return SIGBOOST_RELEASE_CAUSE_NORMAL; +} + +static char * release_to_string(uint32_t rel_cause) +{ + switch (rel_cause) { + + case SIGBOOST_RELEASE_CAUSE_UNDEFINED: + return "UNKNOWN"; + case SIGBOOST_RELEASE_CAUSE_NORMAL: + return "NORMAL"; + case SIGBOOST_RELEASE_CAUSE_BUSY: + return "BUSY"; + case SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST: + return "CHANUNAVAIL"; + case SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET: + return "CANCEL"; + case SIGBOOST_RELEASE_CAUSE_NOANSWER: + return "NOANSWER"; + case SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT: + return "TIMEOUT"; + case SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY: + return "CONGESTION"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL: + return "ERROR"; + } + + return "NORMAL"; +} +#endif + + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return; + } + + if (level && level > server.debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + } else { + char date[80] = ""; + struct tm now; + time_t epoch; + + if (time(&epoch) && localtime_r(&epoch, &now)) { + strftime(date, sizeof(date), "%Y-%m-%d %T", &now); + } + +#ifdef USE_SYSLOG + syslog(LOG_DEBUG | LOG_LOCAL2, data); +#else + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + + + + +static int isup_exec_command(int span, int chan, int id, int cmd, int cause) +{ + call_signal_event_t oevent; + int retry=5; + + call_signal_event_init(&oevent, cmd, chan, span); + oevent.release_cause = cause; + + if (id >= 0) { + oevent.call_setup_id = id; + } +isup_exec_cmd_retry: + if (call_signal_connection_write(&server.mcon, &oevent) <= 0){ + + --retry; + if (retry <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket: %s\n", + strerror(errno)); + return -1; + } else { + log_printf(0, server.log, + "System Warning: Failed to tx on ISUP socket: %s :retry %i\n", + strerror(errno),retry); + } + + goto isup_exec_cmd_retry; + } + + return 0; +} + +static int socket_printf(int socket, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return -1; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + log_printf(0, server.log, "Crtical ERROR: Memory Error!\n"); + } else { + int err; + int len = strlen(data); + err=send(socket, data, strlen(data), 0); + if (err != strlen(data)) { + log_printf(2, server.log, "ERROR: Failed to send data to woomera socket(%i): err=%i len=%d %s\n", + socket,err,len,strerror(errno)); + ret = err; + } else { + ret = 0; + } + + free(data); + } + + return ret; +} + + + +static int woomera_next_pair(struct woomera_config *cfg, char **var, char **val) +{ + int ret = 0; + char *p, *end; + + *var = *val = NULL; + + for(;;) { + cfg->lineno++; + + if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { + ret = 0; + break; + } + + *var = cfg->buf; + + if (**var == '[' && (end = strchr(*var, ']'))) { + *end = '\0'; + (*var)++; + strncpy(cfg->category, *var, sizeof(cfg->category) - 1); + continue; + } + + if (**var == '#' || **var == '\n' || **var == '\r') { + continue; + } + + if ((end = strchr(*var, '#'))) { + *end = '\0'; + end--; + } else if ((end = strchr(*var, '\n'))) { + if (*end - 1 == '\r') { + end--; + } + *end = '\0'; + } + + p = *var; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *var = p; + + if (!(*val = strchr(*var, '='))) { + ret = -1; + log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); + continue; + } else { + p = *val - 1; + *(*val) = '\0'; + (*val)++; + if (*(*val) == '>') { + *(*val) = '\0'; + (*val)++; + } + + while ((*p == ' ' || *p == '\t') && p != *var) { + *p = '\0'; + p--; + } + + p = *val; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *val = p; + ret = 1; + break; + } + } + + return ret; + +} + + +#if 0 +static void woomera_set_span_chan(struct woomera_interface *woomera, int span, int chan) +{ + pthread_mutex_lock(&woomera->vlock); + woomera->span = span; + woomera->chan = chan; + pthread_mutex_unlock(&woomera->vlock); + +} +#endif + + +static struct woomera_event *new_woomera_event_printf(struct woomera_event *ebuf, char *fmt, ...) +{ + struct woomera_event *event = NULL; + int ret = 0; + va_list ap; + + if (ebuf) { + event = ebuf; + } else if (!(event = new_woomera_event())) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + return NULL; + } else { + return NULL; + } + + va_start(ap, fmt); +#ifdef SOLARIS + event->data = (char *) malloc(2048); + vsnprintf(event->data, 2048, fmt, ap); +#else + ret = vasprintf(&event->data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + destroy_woomera_event(&event, EVENT_FREE_DATA); + return NULL; + } + + return event; + +} + +static struct woomera_event *woomera_clone_event(struct woomera_event *event) +{ + struct woomera_event *clone; + + if (!(clone = new_woomera_event())) { + return NULL; + } + + memcpy(clone, event, sizeof(*event)); + clone->next = NULL; + clone->data = strdup(event->data); + + return clone; +} + +static void enqueue_event(struct woomera_interface *woomera, + struct woomera_event *event, + event_args free_data) +{ + struct woomera_event *ptr, *clone = NULL; + + assert(woomera != NULL); + assert(event != NULL); + + if (!(clone = woomera_clone_event(event))) { + log_printf(0, server.log, "Error Cloning Event\n"); + return; + } + + pthread_mutex_lock(&woomera->queue_lock); + + for (ptr = woomera->event_queue; ptr && ptr->next ; ptr = ptr->next); + + if (ptr) { + ptr->next = clone; + } else { + woomera->event_queue = clone; + } + + pthread_mutex_unlock(&woomera->queue_lock); + + woomera_set_flag(woomera, WFLAG_EVENT); + + if (free_data && event->data) { + /* The event has been duplicated, the original data + * should be freed */ + free(event->data); + event->data=NULL; + } +} + +static char *dequeue_event(struct woomera_interface *woomera) +{ + struct woomera_event *event; + char *data = NULL; + + if (!woomera) { + return NULL; + } + + pthread_mutex_lock(&woomera->queue_lock); + if (woomera->event_queue) { + event = woomera->event_queue; + woomera->event_queue = event->next; + data = event->data; + pthread_mutex_unlock(&woomera->queue_lock); + + destroy_woomera_event(&event, EVENT_KEEP_DATA); + return data; + } + pthread_mutex_unlock(&woomera->queue_lock); + + return data; +} + + +static int enqueue_event_on_listeners(struct woomera_event *event) +{ + struct woomera_listener *ptr; + int x = 0; + + assert(event != NULL); + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + enqueue_event(ptr->woomera, event, EVENT_KEEP_DATA); + x++; + } + pthread_mutex_unlock(&server.listen_lock); + + return x; +} + + +static void del_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *ptr, *last = NULL; + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + if (ptr->woomera == woomera) { + if (last) { + last->next = ptr->next; + } else { + server.listeners = ptr->next; + } + free(ptr); + break; + } + last = ptr; + } + pthread_mutex_unlock(&server.listen_lock); +} + +static void add_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *new; + + pthread_mutex_lock(&server.listen_lock); + + if ((new = malloc(sizeof(*new)))) { + memset(new, 0, sizeof(*new)); + new->woomera = woomera; + new->next = server.listeners; + server.listeners = new; + } else { + log_printf(0, server.log, "Memory Error adding listener!\n"); + } + + pthread_mutex_unlock(&server.listen_lock); +} + + + +static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) +{ + struct media_session *ms = woomera_get_ms(woomera); + char *cur = NULL; + int wrote = 0; + int err; + + if (!ms) { + return -EINVAL; + } + + if (!ms->dtmf_buffer) { + log_printf(3, woomera->log, "Allocate DTMF Buffer...."); + + err=switch_buffer_create_dynamic(&ms->dtmf_buffer, 1024, server.dtmf_size, 0); + + if (err != 0) { + log_printf(0, woomera->log, "Failed to allocate DTMF Buffer!\n"); + return -ENOMEM; + } else { + log_printf(3, woomera->log, "SUCCESS!\n"); + } + + } + + log_printf(3, woomera->log, "Sending DTMF %s\n",digits); + for (cur = digits; *cur; cur++) { + if ((wrote = teletone_mux_tones(&ms->tone_session, + &ms->tone_session.TONES[(int)*cur]))) { + + pthread_mutex_lock(&woomera->dtmf_lock); + + err=switch_buffer_write(ms->dtmf_buffer, ms->tone_session.buffer, wrote * 2); + + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3, woomera->log, "Sending DTMF %s Wrote=%i (err=%i)\n", + digits,wrote*2,err); + } else { + log_printf(0, woomera->log, "Error: Sending DTMF %s (err=%i)\n", + digits,wrote); + } + } + + ms->skip_read_frames = 200; + return 0; +} + +static struct woomera_interface *alloc_woomera(void) +{ + struct woomera_interface *woomera = NULL; + + if ((woomera = malloc(sizeof(struct woomera_interface)))) { + + memset(woomera, 0, sizeof(struct woomera_interface)); + + woomera->chan = -1; + woomera->span = -1; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->q931_rel_cause_topbx=SIGBOOST_RELEASE_CAUSE_NORMAL; + woomera->q931_rel_cause_tosig=SIGBOOST_RELEASE_CAUSE_NORMAL; + + woomera_set_interface(woomera, "w-1g-1"); + + + + } + + return woomera; + +} + + +static struct woomera_interface *new_woomera_interface(int socket, struct sockaddr_in *sock_addr, int len) +{ + struct woomera_interface *woomera = NULL; + + if (socket < 0) { + log_printf(0, server.log, "Critical: Invalid Socket on new interface!\n"); + return NULL; + } + + if ((woomera = alloc_woomera())) { + if (socket >= 0) { + no_nagle(socket); + woomera->socket = socket; + } + + if (sock_addr && len) { + memcpy(&woomera->addr, sock_addr, len); + } + } + + return woomera; + +} + +static char *woomera_message_header(struct woomera_message *wmsg, char *key) +{ + int x = 0; + char *value = NULL; + + for (x = 0 ; x < wmsg->last ; x++) { + if (!strcasecmp(wmsg->names[x], key)) { + value = wmsg->values[x]; + break; + } + } + + return value; +} + + +#if 1 + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +static int waitfor_tx_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if (pfds[0].revents & POLLOUT) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +#else + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags | errflags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & errflags)) { + res = -1; + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X)!\n", + pfds[0].revents); +#endif + res = -1; + } + } + + return res; +} + +#endif + +#if 1 +static int waitfor_2sockets(int fda, int fdb, char *a, char *b, int timeout) +{ + struct pollfd pfds[2]; + int res = 0; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + if (fda < 0 || fdb < 0) { + return -1; + } + + *a=0; + *b=0; + + memset(pfds, 0, sizeof(pfds)); + pfds[0].fd = fda; + pfds[1].fd = fdb; + pfds[0].events = POLLIN | errflags; + pfds[1].events = POLLIN | errflags; + if ((res = poll(pfds, 2, timeout)) > 0) { + res = 1; + if ((pfds[0].revents & errflags) || (pfds[1].revents & errflags)) { + res = -1; + } else { + if ((pfds[0].revents & POLLIN)) { + *a=1; + res++; + } + if ((pfds[1].revents & POLLIN)) { + *b=1; + res++; + } + } + + if (res == 1) { + /* No event found what to do */ + res=-1; + } + } + + return res; +} +#endif + + +static struct media_session *media_session_new(struct woomera_interface *woomera) +{ + struct media_session *ms = NULL; + int x; + char *p; + int span,chan; + + span=woomera->span; + chan=woomera->chan; + + log_printf(2, server.log,"Starting new MEDIA session [%s] [%s]\n", + woomera->interface,woomera->raw?woomera->raw:"N/A"); + + if ((ms = malloc(sizeof(struct media_session)))) { + memset(ms, 0, sizeof(struct media_session)); + + if (woomera->loop_tdm != 1) { + for(x = 0; x < strlen(woomera->raw) ; x++) { + if (woomera->raw[x] == ':') { + break; + } + if (woomera->raw[x] == '/') { + break; + } + } + + ms->ip = strndup(woomera->raw, x); + time(&ms->started); + p = woomera->raw + (x+1); + ms->port = atoi(p); + } + + time(&ms->started); + woomera_set_ms(woomera,ms); + ms->woomera = woomera; + + /* Setup artificial DTMF stuff */ + memset(&ms->tone_session, 0, sizeof(ms->tone_session)); + if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { + log_printf(0, server.log, "ERROR: Failed to initialize TONE [w%ig%i]!\n", + span+1,chan+1); + } + + ms->tone_session.rate = SMG_DTMF_RATE; + ms->tone_session.duration = server.dtmf_on * (ms->tone_session.rate / 1000); + ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); + + teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); + + } else { + log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", + span+1,chan+1); + } + + return ms; +} + +static void media_session_free(struct media_session *ms) +{ + if (ms->ip) { + free(ms->ip); + } + + teletone_destroy_session(&ms->tone_session); + switch_buffer_destroy(&ms->dtmf_buffer); + + ms->woomera = NULL; + + free(ms); +} + + +static int create_udp_socket(struct media_session *ms, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + log_printf(5,server.log,"LocalIP %s:%d IP %s:%d \n",local_ip, local_port, ip, port); + + memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); + memset(&ms->local_hp, 0, sizeof(ms->local_hp)); + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { + gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + ms->remote_addr.sin_family = ms->remote_hp.h_addrtype; + memcpy((char *) &ms->remote_addr.sin_addr.s_addr, ms->remote_hp.h_addr_list[0], ms->remote_hp.h_length); + ms->remote_addr.sin_port = htons(port); + + ms->local_addr.sin_family = ms->local_hp.h_addrtype; + memcpy((char *) &ms->local_addr.sin_addr.s_addr, ms->local_hp.h_addr_list[0], ms->local_hp.h_length); + ms->local_addr.sin_port = htons(local_port); + + rc = bind(ms->socket, (struct sockaddr *) &ms->local_addr, sizeof(ms->local_addr)); + if (rc < 0) { + close(ms->socket); + ms->socket = -1; + + log_printf(5,server.log, + "Failed to bind LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + + /* OK */ + + } else { + log_printf(0,server.log, + "Failed to get hostbyname LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + } else { + log_printf(0,server.log, + "Failed to create/allocate UDP socket\n"); + } + + return ms->socket; +} + +static int next_media_port(void) +{ + int port; + + pthread_mutex_lock(&server.media_udp_port_lock); + port = ++server.next_media_port; + if (port > WOOMERA_MAX_MEDIA_PORT) { + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + port = WOOMERA_MIN_MEDIA_PORT; + } + pthread_mutex_unlock(&server.media_udp_port_lock); + + return port; +} + + + +static int woomera_dtmf_transmit(struct media_session *ms, int mtu) +{ + struct woomera_interface *woomera = ms->woomera; + int bread; + unsigned char dtmf[1024]; + unsigned char dtmf_law[1024]; + sangoma_api_hdr_t hdrframe; + int i; + int slin_len = mtu*2; + short *data; + int used; + int res; + int err; + int txdtmf=0; + memset(&hdrframe,0,sizeof(hdrframe)); + + if (!ms->dtmf_buffer) { + return -1; + } + + for (;;) { + + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + break; + } + + res = waitfor_tx_socket(ms->sangoma_sock, -1, POLLERR | POLLOUT); + if (res <= 0) { + break; + } + +#ifdef CODEC_LAW_DEFAULT + + pthread_mutex_lock(&woomera->dtmf_lock); + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + pthread_mutex_unlock(&woomera->dtmf_lock); + break; + } + + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, slin_len); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread <= 0) { + break; + } + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", + woomera->interface,bread,mtu,ms->hw_coding,used); + + data=(short*)dtmf; + for (i=0;ihw_coding) { + /* ALAW */ + dtmf_law[i] = linear_to_alaw((int)data[i]); + } else { + /* ULAW */ + dtmf_law[i] = linear_to_ulaw((int)data[i]); + } + } + + err=sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf_law, mtu, 0); + + if (err != mtu) { + log_printf(0, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu); + } + + txdtmf++; + ms->skip_write_frames++; +#else +... + pthread_mutex_lock(&woomera->dtmf_lock); + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", + woomera->interface,bread); + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf, mtu, 0); + txdtmf++; + ms->skip_write_frames++; +#endif + + } + + if (txdtmf) { + return 0; + } else { + return -1; + } +} + +static void media_loop_run(struct media_session *ms) +{ + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int errs=0; + int res=0; + wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + char filename[100]; + FILE *filed=NULL; + int loops=0; + + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + + log_printf(1, server.log, "Media Loop Started %s fd=%i\n", + woomera->interface,ms->sangoma_sock); + + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "WANPIPE MEDIA Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + + + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } + + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + sangoma_tdm_disable_hwec(ms->sangoma_sock,&tdm_api); + + } + + if (errs) { + + log_printf(0, server.log, "Media Loop: failed to open tdm device %s\n", + woomera->interface); + return; + } + + if (server.loop_trace) { + sprintf(filename,"/smg/w%ig%i-loop.trace",woomera->span+1,woomera->chan+1); + unlink(filename); + filed = safe_fopen(filename, "w"); + } + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + ((res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2)) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + log_printf(0, server.log, "Media Loop Restart %s\n", + woomera->interface); + continue; + } + + if (res < 0 ){ + log_printf(0, server.log, "Media Loop Socket error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM Loop ReadMsg Error: %s\n", + strerror(errno), woomera->interface); + break; + } + + if (server.loop_trace && filed != NULL) { + int i; + for (i=0;isangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + res, 0); + + res=0; + + loops++; + } + + + if (res < 0) { + log_printf(2, server.log, "Media Loop: socket error %s (fd=%i)!\n", + woomera->interface, ms->sangoma_sock); + } + + + if (server.loop_trace && filed != NULL) { + fclose(filed); + } + + sangoma_tdm_enable_hwec(ms->sangoma_sock,&tdm_api); + + sleep(1); + + close_socket(&ms->sangoma_sock); + + log_printf(1, server.log, "Media Loop Finished %s Master=%i MediaEnd=%i Loops=%i\n", + woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_MEDIA_END),loops); + + return; + +} + +#ifdef WP_HPTDM_API +static int media_rx_ready(void *p, unsigned char *data, int len) +{ + struct media_session *ms = (struct media_session *)p; + + if (ms->udp_sock < 0) { + return -1; + } + + return sendto(ms->udp_sock, + data,len, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + +} +#endif + +static void *media_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int local_port, x = 0, errs = 0, res = 0, packet_len = 0; + //int udp_cnt=0; + struct woomera_event wevent; + wanpipe_tdm_api_t tdm_api; + FILE *tx_fd=NULL; + int sock_timeout=200; + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + !woomera->interface || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(2, server.log, + "MEDIA session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(ms); + pthread_exit(NULL); + return NULL; + } + + + log_printf(2, server.log, "MEDIA session for [%s] started (ptr=%p loop=%i)\n", + woomera->interface,woomera,woomera->loop_tdm); + + if (woomera->loop_tdm) { + media_loop_run(ms); + ms->udp_sock=-1; + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + goto media_thread_exit; + } + + for(x = 0; x < 1000 ; x++) { + local_port = next_media_port(); + if ((ms->udp_sock = create_udp_socket(ms, server.media_ip, local_port, ms->ip, ms->port)) > -1) { + break; + } + } + + if (ms->udp_sock < 0) { + log_printf(0, server.log, "UDP Socket Error (%s) [%s] LocalPort=%d\n", + strerror(errno), woomera->interface, local_port); + + errs++; + } else { + +#ifdef WP_HPTDM_API + hp_tdm_api_span_t *span=hptdmspan[woomera->span+1]; + if (!span || !span->init) { + errs++; + } else { + hp_tdm_api_usr_callback_t usr_callback; + memset(&usr_callback,0,sizeof(usr_callback)); + usr_callback.p = ms; + usr_callback.rx_avail = media_rx_ready; + if (span->open_chan(span, &usr_callback, &ms->tdmchan,woomera->chan+1)) { + errs++; + } + } +#else + if ((ms->sangoma_sock = sangoma_create_socket_by_name(woomera->interface, NULL)) < 0) { + log_printf(0, server.log, "WANPIPE Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + +# ifdef CODEC_LAW_DEFAULT + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } +# else + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_SLINEAR) < 0 ) { + errs++; + } +# endif + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + +# ifdef CODEC_LAW_DEFAULT +# ifdef LIBSANGOMA_GET_HWCODING + ms->hw_coding=sangoma_tdm_get_hw_coding(ms->sangoma_sock, &tdm_api); + if (ms->hw_coding < 0) { + errs++; + } +# else +# error "libsangoma missing hwcoding feature: not up to date!" +# endif +# endif + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + } +#endif + } + + + +#ifdef WP_HPTDM_API + /* No tdm thread */ +#else + if (!errs && + launch_media_tdm_thread(woomera)) { + errs++; + } +#endif + + if (!errs) { + + unsigned char udp_frame[4096]; + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(udp_frame,0,sizeof(udp_frame)); +#ifdef DOTRACE + int fdin, fdout; + char path_in[512], path_out[512]; +#endif + + + +#if 0 + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: %s%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + ms->hw_coding ?"ALAW":"ULAW", + WOOMERA_RECORD_SEPERATOR + ); +#else + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Unique-Call-Id: %s%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: PCM-16%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + WOOMERA_RECORD_SEPERATOR + ); +#endif + + + enqueue_event(woomera, &wevent, EVENT_FREE_DATA); + +#ifdef DOTRACE + sprintf(path_in, "/tmp/debug-in.%d.raw", tc); + sprintf(path_out, "/tmp/debug-out.%d.raw", tc++); + fdin = open(path_in, O_WRONLY | O_CREAT, O_TRUNC, 0600); + fdout = open(path_out, O_WRONLY | O_CREAT, O_TRUNC, 0600); +#endif + + if (server.out_tx_test) { + tx_fd=fopen("/smg/sound.raw","rb"); + if (!tx_fd){ + log_printf(0,server.log, "FAILED TO OPEN Sound file!\n"); + } + } + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { + + unsigned int fromlen = sizeof(struct sockaddr_in); + + + if (res == 0) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", + woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if ((packet_len = recvfrom(ms->udp_sock, udp_frame, sizeof(udp_frame), + MSG_DONTWAIT, (struct sockaddr *) &ms->local_addr, &fromlen)) < 1) { + log_printf(2, server.log, "UDP Recv Error: %s\n",strerror(errno)); + break; + } + +#if 0 + log_printf(6, server.log, "%s: UDP Receive %i !!!\n", + woomera->interface,packet_len); +#endif + + if (packet_len > 0) { + +#if 0 +/* NC: This can cause skb_over panic must be retested */ + if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { + /* Assume that we will always receive SLINEAR here */ + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, packet_len/codec_sample); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + log_printf(3, server.log, + "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", + woomera->interface,sangoma_frame_len, + sangoma_frame_len/codec_sample,packet_len); + + + if (++ms->udp_sync_cnt >= 6) { + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, 20); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + log_printf(0, server.log, + "%s: UDP TDM Period Force ReSync to 20ms \n", + woomera->interface); + } + + } +#endif + if (!server.out_tx_test) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + continue; + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } + + } + + if (server.out_tx_test && tx_fd && + fread((void*)udp_frame, + sizeof(char), + packet_len,tx_fd) <= 0) { + + sangoma_get_full_cfg(ms->sangoma_sock,&tdm_api); + fclose(tx_fd); + tx_fd=NULL; + } + +#ifdef WP_HPTDM_API + if (ms->tdmchan->push) { + ms->tdmchan->push(ms->tdmchan,udp_frame,packet_len); + } +#else + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + udp_frame, + packet_len, 0); +#endif + + } + +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + udp_cnt++; + if (udp_cnt && udp_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA UDP TX RX CNT %i %i\n", + woomera->interface,udp_cnt,packet_len); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media Thread: socket error !\n"); + } + } + + + + new_woomera_event_printf(&wevent, + "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Start-Time: %ld%s" + "End-Time: %ld%s" + "Answer-Time: %ld%s" + "Call-ID: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + woomera->session, + WOOMERA_LINE_SEPERATOR, + + time(&ms->started), + WOOMERA_LINE_SEPERATOR, + + time(NULL), + WOOMERA_LINE_SEPERATOR, + + time(&ms->answered), + WOOMERA_LINE_SEPERATOR, + + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + +media_thread_exit: + + if (woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + usleep(1000); + sched_yield(); + } + } + + + close_socket(&ms->udp_sock); + close_socket(&ms->sangoma_sock); + + if (tx_fd){ + fclose(tx_fd); + tx_fd=NULL; + } + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + + woomera_set_ms(woomera,NULL); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + + media_session_free(ms); + + log_printf(2, server.log, "MEDIA session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + + pthread_exit(NULL); + return NULL; +} + + + + +static void *media_tdm_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int res = 0; + //int tdm_cnt=0; + //wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + sangoma_api_hdr_t hdrframe; + + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || !woomera->interface) { + log_printf(2, server.log, "MEDIA TDM session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + pthread_exit(NULL); + return NULL; + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] started (ptr=%p)\n", + woomera->interface,woomera); + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + (res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } else if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "Media TDM Restart Failed%s\n", + woomera->interface); + break; + } + log_printf(0, server.log, "Media TDM Restart %s\n", + woomera->interface); + continue; + } else if (res < 0) { + log_printf(0, server.log, "Media TDM Sangoma Socket Error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM ReadMsg Error: %s\n", strerror(errno)); + break; + } + + res = sendto(ms->udp_sock, + circuit_frame, + res, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + if (res < 0) { + log_printf(2, server.log, "UDP Sento Error: %s\n", strerror(errno)); + break; + } +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + tdm_cnt++; + if (tdm_cnt && tdm_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA TDM TX RX CNT %i %i\n", + woomera->interface,tdm_cnt,res); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media TDM Thread: socket error !\n"); + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + + pthread_exit(NULL); + return NULL; + +} + + +/* This function must be called with process_lock + * because it modifies shared process_table */ + +static int launch_media_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms; + + if ((ms = media_session_new(woomera))) { + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_RUNNING); + result = pthread_create(&ms->thread, &attr, media_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(woomera->ms); + + } + pthread_attr_destroy(&attr); + + } else { + log_printf(0, server.log, "Failed to start new media session\n"); + } + + return result; + +} + +static int launch_media_tdm_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms = woomera_get_ms(woomera); + + if (!ms) { + return result; + } + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + result = pthread_create(&ms->thread, &attr, media_tdm_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + char callid[20]; + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + + if ((woomera = alloc_woomera())) { + + woomera->chan = event->chan; + woomera->span = event->span; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->loop_tdm=1; + + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + woomera_set_interface(woomera,callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = woomera; + pthread_mutex_unlock(&server.process_lock); + + if (launch_woomera_thread(woomera)) { + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + free(woomera); + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + return woomera; +} + +static int woomera_message_parse(struct woomera_interface *woomera, struct woomera_message *wmsg, int timeout) +{ + char *cur, *cr, *next = NULL, *eor = NULL; + char buf[2048]; + int res = 0, bytes = 0, sanity = 0; + struct timeval started, ended; + int elapsed, loops = 0; + int failto = 0; + int packet = 0; + + memset(wmsg, 0, sizeof(*wmsg)); + + if (woomera->socket < 0 ) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Invalid Socket! %d\n", + woomera->interface,woomera->socket); + return -1; + } + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP !\n", + woomera->interface); + return -1; + } + + gettimeofday(&started, NULL); + memset(buf, 0, sizeof(buf)); + + if (timeout < 0) { + timeout = abs(timeout); + failto = 1; + } else if (timeout == 0) { + timeout = -1; + } + + + while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) { + if (sanity > 1000) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Failed Sanity Check!\n[%s]\n\n", woomera->interface, buf); + return -1; + } + + if ((res = waitfor_socket(woomera->socket, 1000, POLLERR | POLLIN) > 0)) { + res = recv(woomera->socket, buf, sizeof(buf), MSG_PEEK); + + if (res > 1) { + packet++; + } + if (!strncmp(buf, WOOMERA_LINE_SEPERATOR, 2)) { + res = read(woomera->socket, buf, 2); + return 0; + } + if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + + } else if (res < 0) { + log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX + "%s error during packet retry (err=%i) Loops#%d (%s)\n", + woomera->interface, res, loops, + strerror(errno)); + return res; + } else if (loops) { + ysleep(100000); + } + } + + gettimeofday(&ended, NULL); + elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000)); + + if (res < 0) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Bad RECV\n", + woomera->interface); + return res; + } else if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } + + if (packet && loops > 150) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout waiting for packet.\n", + woomera->interface); + return -1; + } + + if (timeout > 0 && (elapsed > timeout)) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout [%d] reached\n", + woomera->interface, timeout); + return failto ? -1 : 0; + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)) { + /* BRB! we have an Event to deliver....*/ + return 0; + } + + /* what're we still doing here? */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + !woomera_test_flag(woomera, WFLAG_RUNNING)) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MASTER RUNNING or RUNNING!\n", woomera->interface); + return -1; + } + loops++; + } + + *eor = '\0'; + bytes = strlen(buf) + 4; + + memset(buf, 0, sizeof(buf)); + res = read(woomera->socket, buf, bytes); + next = buf; + + if (woomera->debug > 1) { + log_printf(3, woomera->log, "%s:WOOMERA RX MSG: %s\n",woomera->interface,buf); + + } + + while ((cur = next)) { + + if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) { + *cr = '\0'; + next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1); + if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) { + break; + } + } + if (!cur || !*cur) { + break; + } + + if (!wmsg->last) { + char *cmd, *id, *args; + woomera_set_flag(wmsg, MFLAG_EXISTS); + cmd = cur; + + if ((id = strchr(cmd, ' '))) { + *id = '\0'; + id++; + if ((args = strchr(id, ' '))) { + *args = '\0'; + args++; + strncpy(wmsg->command_args, args, sizeof(wmsg->command_args)-1); + } + strncpy(wmsg->callid, id, sizeof(wmsg->callid)-1); + } + + strncpy(wmsg->command, cmd, sizeof(wmsg->command)-1); + } else { + char *name, *val; + name = cur; + + if ((val = strchr(name, ':'))) { + *val = '\0'; + val++; + while (*val == ' ') { + *val = '\0'; + val++; + } + strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN); + } + strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN); + if (name && val && !strcasecmp(name, "content-type")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + if (name && val && !strcasecmp(name, "content-length")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + + + } + wmsg->last++; + } + + wmsg->last--; + + if (bytes && woomera_test_flag(wmsg, MFLAG_CONTENT)) { + read(woomera->socket, wmsg->body, + (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes); + } + + return woomera_test_flag(wmsg, MFLAG_EXISTS); + +} + +static struct woomera_interface *pull_from_holding_tank(int index, int span , int chan) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + + /* Block this index until the call is completed */ + server.holding_tank[index] = &woomera_dead_dev; + + woomera->timeout = 0; + woomera->index = 0; + woomera->span=span; + woomera->chan=chan; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static void clear_from_holding_tank(int index, struct woomera_interface *woomera) +{ + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] == &woomera_dead_dev) { + server.holding_tank[index] = NULL; + } else if (woomera && server.holding_tank[index] == woomera) { + server.holding_tank[index] = NULL; + } else if (server.holding_tank[index]) { + log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", + index, server.holding_tank[index]); + } + pthread_mutex_unlock(&server.ht_lock); + + return; +} + +static struct woomera_interface *peek_from_holding_tank(int index) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static int add_to_holding_tank(struct woomera_interface *woomera) +{ + int next, i, found=0; + + pthread_mutex_lock(&server.ht_lock); + + for (i=0;i= CORE_TANK_LEN) { + next = server.holding_tank_index = 1; + } + + if (next == 0) { + log_printf(0, server.log, "\nCritical Error on TANK INDEX == 0\n"); + continue; + } + + if (server.holding_tank[next]) { + continue; + } + + found=1; + break; + } + + if (!found) { + /* This means all tank vales are busy + * should never happend */ + pthread_mutex_unlock(&server.ht_lock); + log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); + return 0; + } + + server.holding_tank[next] = woomera; + woomera->timeout = time(NULL) + 100; + + pthread_mutex_unlock(&server.ht_lock); + return next; +} + +static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, + struct woomera_message *wmsg, + int media, int answer, int accept) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + + log_printf(4, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + + if (woomera_test_flag(woomera, WFLAG_HANGUP) || + !woomera_test_flag(woomera, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END)) { + + log_printf(2, server.log, + "ERROR! call was cancelled MEDIA on HANGUP or MEDIA END!\n"); + + woomera->timeout=0; + return -1; + } + + log_printf(3, server.log,"WOOMERA: GOT %s EVENT: [%s] RAW=%s\n", + wmsg->command,wmsg->callid,raw); + + + if (raw && + woomera->raw == NULL && + !woomera_test_flag(woomera, WFLAG_RAW_MEDIA_STARTED)) { + + woomera_set_flag(woomera, WFLAG_RAW_MEDIA_STARTED); + + woomera_set_raw(woomera, raw); + + if (launch_media_thread(woomera)) { + struct woomera_event wevent; + + log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + woomera->timeout=0; + return -1; + } + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + + } else { + + if (accept) { + if (!autoacm) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + } + + if (answer) { + struct media_session *ms; + + pthread_mutex_lock(&woomera->ms_lock); + if ((ms=woomera->ms)) { + time(&woomera->ms->answered); + } + pthread_mutex_unlock(&woomera->ms_lock); + + if (ms) { + + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_ANSWERED, + 0); + log_printf(2, server.log, + "Sent SIGBOOST_EVENT_CALL_ANSWERED [w%dg%d]\n", + woomera->span+1,woomera->chan+1); + } else { + struct woomera_event wevent; + log_printf(0, server.log, + "WOOMERA ANSWER: FAILED [%s] no Media \n", + wmsg->command,wmsg->callid); + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera->timeout=0; + return -1; + } + } + } + + { + struct woomera_event wevent; + new_woomera_event_printf(&wevent, "200 %s OK%s" + "Unique-Call-Id: %s%s", + answer ? "ANSWER" : + accept ? "ACCEPT" : "MEDIA", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + + return 0; +} + +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); +#ifdef SMG_CALLING_NAME + char *calling_name = woomera_message_header(wmsg, "local-name"); +#endif + char *presentation = woomera_message_header(wmsg, "Presentation"); + char *screening = woomera_message_header(wmsg, "Screening"); + char *rdnis = woomera_message_header(wmsg, "RDNIS"); + char *called = wmsg->callid; + char *grp = wmsg->callid; + char *p; + int cause = 34; + int tg = 0; + + if (smg_check_all_busy()) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, + "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); + log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", + server.call_count, server.all_ckt_busy); + return -1; + } + + log_printf(2, woomera->log, "New Call %d/%d\n", server.call_count, server.max_calls); + + if ((p = strchr(called, '/'))) { + *p = '\0'; + called = p+1; + tg = atoi(grp+1) - 1; + if (tg < 0) { + tg=0; + } + } + + woomera->trunk_group=tg; + + if (raw) { + woomera_set_raw(woomera, raw); + } + + woomera->index = add_to_holding_tank(woomera); + if (woomera->index < 1) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, + "405 SMG Server All Tanks Busy!%s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0, woomera->log, "Error: Call Tank Full (Call Cnt=%i)\n", + server.call_count); + return -1; + } + + + woomera->index_hold = woomera->index; + + call_signal_call_init(&event, calling, called, woomera->index); + + if (presentation) { + event.calling_number_presentation = atoi(presentation); + } else { + event.calling_number_presentation = 0; + } + + if (screening) { + event.calling_number_screening_ind = atoi(screening); + } else { + event.calling_number_screening_ind = 0; + } + + if (rdnis && strlen(rdnis)) { + strncpy((char*)event.redirection_string,rdnis, + sizeof(event.redirection_string)-1); + log_printf(3,server.log,"RDNIS %s\n", rdnis); + + } + +#ifdef SMG_CALLING_NAME + if (calling_name) { + strncpy((char*)event.calling_name,calling_name, + sizeof(event.calling_name)-1); + } +#endif + + event.trunk_group = tg; + + + if (call_signal_connection_write(&server.mcon, &event) <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, + "405 SMG Signalling Contestion!%s", + WOOMERA_RECORD_SEPERATOR); + return -1; + } + + socket_printf(woomera->socket, "100 Trying%s", WOOMERA_RECORD_SEPERATOR); + + log_printf(2, server.log, "Call Called Event [Setup ID: %d] TG=%d\n", + woomera->index,tg); + + return 0; +} + + +static void interpret_command(struct woomera_interface *woomera, struct woomera_message *wmsg) +{ + int answer = 0, media = 0, accept=0; + char *unique_id; + int cause=0; + + + + if (!strcasecmp(wmsg->command, "call")) { + int err; + if (strlen(woomera->session) != 0) { + /* Call has already been placed */ + socket_printf(woomera->socket, "400 Error Call already in progress %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0,server.log,"Woomera RX Call Even while call in progress!\n"); + return; + } + + err=handle_woomera_call_start(woomera,wmsg); + if (err) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + return; + + } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + if (cause) { + log_printf(3, woomera->log, "Bye Cause Received: [%s]\n", cause); + } + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + log_printf(2, woomera->log, "WOOMERA CMD: Bye Received: [%s]\n", woomera->interface); + + woomera_clear_flag(woomera, WFLAG_RUNNING); + socket_printf(woomera->socket, "200 Connection closed%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + + } else if (!strcasecmp(wmsg->command, "listen")) { + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + socket_printf(woomera->socket, "405 Listener already started%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + } else { + char *event_string; + + woomera_set_flag(woomera, WFLAG_LISTENING); + add_listener(woomera); + + if (!strcmp(wmsg->callid,"MASTER")) { + woomera_set_flag(woomera, WFLAG_MASTER_DEV); + log_printf(0,woomera->log, "Starting MASTER Listen Device!\n"); + master_reset=0; + } + + + socket_printf(woomera->socket, "%s", + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "200 Listener enabled%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + if ((event_string = dequeue_event(&server.master_connection))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + event_string = NULL; + } + } + return; + + } else if ((media = !strcasecmp(wmsg->command, "debug"))) { + + int debug_level=atoi(wmsg->callid); + + if (debug_level < 10) { + server.debug=debug_level; + log_printf(0,server.log,"SMG Debugging set to %i (window=%i)\n",server.debug,server.mcon.txwindow); + } + + return; + } + + + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); + if (!unique_id) { + + cause=111; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (strlen(woomera->session) == 0) { + struct woomera_interface *session_woomera=NULL; + char *session=NULL; + int span, chan; + char ifname[100]; + /* If session does not exist this is an incoming call */ + sscanf(unique_id, "w%dg%d", &span, &chan); + span--; + chan--; + + log_printf(3, woomera->log, + "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", + wmsg->command,span,chan,unique_id); + + if (smg_validate_span_chan(span,chan) != 0) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Invalid span/chan in session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2, woomera->log, + "WOOMERA Warning invalid span chan in session %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + pthread_mutex_lock(&server.process_lock); + session = server.process_table[span][chan].session; + session_woomera = server.process_table[span][chan].dev; + + if (session_woomera) { + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Session not found%s" + WOOMERA_RECORD_SEPERATOR); + + + log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (!session || strlen(session) == 0 || + strncmp(session,unique_id,sizeof(woomera->session))){ + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Invalid/Expired Session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(3, woomera->log, + "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", + wmsg->command,unique_id,session?session:"N/A"); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + server.process_table[span][chan].dev=woomera; + strncpy(woomera->session,unique_id,sizeof(woomera->session)); + sprintf(ifname,"w%dg%d",span+1,chan+1); + woomera_set_interface(woomera, ifname); + + woomera->span=span; + woomera->chan=chan; + + pthread_mutex_unlock(&server.process_lock); + + + log_printf(3, woomera->log, "WOOMERA Got New If=%s Session %s\n", + woomera->interface, woomera->session); + + + } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Session Mis-match%s" + WOOMERA_RECORD_SEPERATOR); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + + if (!strcasecmp(wmsg->command, "dtmf")) { + + log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", + woomera->interface, wmsg->command_args, wmsg->body); + + wanpipe_send_dtmf(woomera,wmsg->body); + + socket_printf(woomera->socket, "200 DTMF OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "hangup")) { + + int chan = -1, span = -1; + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + span=woomera->span; + chan=woomera->chan; + + log_printf(3, woomera->log, "WOOMERA CMD: Hangup Received: [%s] MEDIA EXIST Cause=%s\n", + woomera->interface,cause); + + if (smg_validate_span_chan(span,chan) != 0) { + + socket_printf(woomera->socket, "405 No Such Channel%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + } + + + log_printf(2, woomera->log, "Hangup Received: [w%dg%d]\n", + span+1,chan+1); + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + + socket_printf(woomera->socket, "200 HANGUP OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "proceed")) { + + log_printf(3, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + socket_printf(woomera->socket, + "200 %s PROCEED OK%s" + "Unique-Call-Id: %s%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + } else if ((media = !strcasecmp(wmsg->command, "media")) || + (answer = !strcasecmp(wmsg->command, "answer")) || + (accept = !strcasecmp(wmsg->command, "accept"))) { + + handle_woomera_media_accept_answer(woomera, wmsg, media,answer,accept); + + + + } else { + log_printf(0, server.log,"WOOMERA INVALID EVENT: %s [%s] \n", + wmsg->command,wmsg->callid); + socket_printf(woomera->socket, "501 Command '%s' not implemented%s", + wmsg->command, WOOMERA_RECORD_SEPERATOR); + } +} + + +/* + EVENT INCOMING 1 + Remote-Address: 10.3.3.104 + Remote-Number: + Remote-Name: Anthony Minessale!8668630501 + Protocol: H.323 + User-Agent: Post Increment Woomera 1.0alpha1 (OpenH323 v1.17.2) 9/61 + H323-Call-Id: 887b1ff8-bb1f-da11-85c0-0007e98988c4 + Local-Number: 996 + Start-Time: Fri, 09 Sep 2005 12:25:14 -0400 + Local-Name: root +*/ + + +static void handle_call_answer(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int kill = 0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + char callid[80]; + struct woomera_event wevent; + + if (!woomera->raw) { + log_printf(1, server.log, "Refusing to answer call with no media!\n"); + kill++; + goto handle_call_answer_end; + } + + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { + log_printf(1, server.log, "Refusing to double-answer a call!\n"); + kill++; + goto handle_call_answer_end; + } + + woomera_set_flag(woomera, WFLAG_ANSWER); + + if (woomera->span != event->span || woomera->chan != event->chan) { + log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); + kill++; + goto handle_call_answer_end; + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to answer a dead call!\n"); + kill++; + } else { + int err; + err=0; + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + woomera_set_interface(woomera, callid); +#ifndef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + + kill++; + } +#endif + + if (!kill) { + new_woomera_event_printf(&wevent, "EVENT CONNECT w%dg%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + } + } else { + log_printf(1, server.log, "Answer requested on non-existant session. [w%dg%d]\n", + event->span+1, event->chan+1); + kill++; + } + +handle_call_answer_end: + + if (kill) { + if (woomera) { + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to Answer without session [w%dg%d]\n", + event->span+1, event->chan+1); + } + } +} + +static void handle_call_start_ack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + struct woomera_event wevent; + int kill = 0; + + if ((woomera = peek_from_holding_tank(event->call_setup_id))) { + char callid[80]; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to ack a dead call!\n"); + kill++; + } else { + int err, span, chan; + + pull_from_holding_tank(event->call_setup_id,event->span,event->chan); + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + + span = event->span; + chan = event->chan; + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + woomera_set_interface(woomera, callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[span][chan].dev = woomera; + sprintf(woomera->session,"%s-%i-%i",callid,rand(),rand()); + sprintf(server.process_table[span][chan].session,"%s-%s", + callid,woomera->session); + pthread_mutex_unlock(&server.process_lock); + + + +#ifdef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id:%s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + kill++; + } +#endif + if (!kill) { + new_woomera_event_printf(&wevent, "201 Accepted%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Channel-Name: g%d/%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + log_printf(2, server.log, "Call Answered Event ID = %d Device = w%dg%d!\n", + event->call_setup_id,woomera->span+1,woomera->chan+1); + } + } + } else { + log_printf(1, server.log, + "Event (START ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id, event->call_setup_id,event->span+1, event->chan+1); + kill++; + } + + if (kill) { + if (woomera) { + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to CALL START ACK without session [w%dg%d]\n", + event->span+1, event->chan+1); + } + } +} + +static void handle_call_start_nack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int span=-1, chan=-1; + int ack=0; + + /* Always ACK the incoming NACK + * Send out the NACK ACK before pulling the TANK, because + * if we send after the pull, the outgoing call could send + * a message to boost with the pulled TANK value before + * we send a NACK ACK */ + + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + if (event->call_setup_id > 0) { + woomera=peek_from_holding_tank(event->call_setup_id); + } + + if (woomera) { + + struct woomera_event wevent; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", + event->call_setup_id); + ack++; + } else { + + woomera_set_cause_topbx(woomera,event->release_cause); + woomera_set_flag(woomera, (WFLAG_HANGUP|WFLAG_HANGUP_NACK_ACK)); + + new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + /* Do not ack here, let woomera thread ack it */ + ack=0; + } + + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hang up */ + woomera=NULL; + } else { + /* At this point call is already hang up */ + woomera=NULL; + } + } + + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + + log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + if (!woomera_test_flag(woomera,WFLAG_HANGUP)){ + woomera_set_cause_topbx(woomera,event->release_cause); + } + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + + /* Nack Ack will be sent by the woomera thread */ + ack=0; + } else { + /* Valid state when we are not in autoacm mode */ + ack++; + log_printf(3, server.log, "Event: NACK no woomera on span chan [w%dg%d]!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(0, server.log, + "Error: Start Nack Invalid State Should not happen [%d] [w%dg%d]!\n", + event->call_setup_id, event->span+1, event->chan+1); + ack++; + } + + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + log_printf(0, server.log, "WARNING: All ckt busy!\n"); + smg_all_ckt_busy(); + } + + +#warning "Ignoring CALL GAP" +#if 0 + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { + log_printf(0, server.log, "WARNING: Call Gapping Detected!\n"); + smg_all_ckt_gap(); + } +#endif + + if (ack) { + span=0; + chan=0; + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + isup_exec_command(span, + chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + if (!woomera) { + log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } + } +} + +static void handle_call_loop_start(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + + woomera=launch_woomera_loop_thread(event); + if (woomera == NULL) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + } + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + + return; +} + +static void handle_call_start(call_signal_event_t *event) +{ + struct woomera_event wevent; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(0, server.log, + "Sent (From Handle START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + pthread_mutex_unlock(&server.process_lock); + return; + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" + "Unique-Call-Id: %s%s" + "Remote-Number: %s%s" + "Remote-Name: %s%s" + "Protocol: SS7%s" + "User-Agent: sangoma_mgd%s" + "Local-Number: %s%s" + "Channel-Name: g%d/%d%s" + "Trunk-Group: %d%s" + "Presentation: %d%s" + "Screening: %d%s" + "RDNIS: %s%s" + , + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + session, + WOOMERA_LINE_SEPERATOR, + event->calling_number_digits, + WOOMERA_LINE_SEPERATOR, +#ifdef SMG_CALLING_NAME + event->calling_name, +#else + "", +#endif + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + event->called_number_digits, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + WOOMERA_LINE_SEPERATOR, + event->calling_number_presentation, + WOOMERA_LINE_SEPERATOR, + event->calling_number_screening_ind, + WOOMERA_LINE_SEPERATOR, + event->redirection_string, + WOOMERA_RECORD_SEPERATOR + ); + + if (enqueue_event_on_listeners(&wevent)) { + enqueue_event(&server.master_connection, &wevent, EVENT_KEEP_DATA); + } else { + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + } + + } + + destroy_woomera_event_data(&wevent); + +} + +static void handle_gap_abate(call_signal_event_t *event) +{ + log_printf(0, server.log, "NOTICE: GAP Cleared!\n", + event->span+1, event->chan+1); + smg_clear_ckt_gap(); +} + +static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_t *event) +{ + mcon->rxseq_reset =0; +} + +static void handle_call_stop(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + int ack=0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hangup */ + woomera=NULL; + } else { + /* At this point call is already hangup */ + woomera=NULL; + } + } + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); + + /* We have to close the socket because + At this point we are release span chan */ + + log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + } else { + ack++; + } + + + if (ack) { + /* At this point we have already sent our STOP so its safe to ACK */ + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } + + if (!woomera){ + /* This is allowed on incoming call if remote app does not answer it */ + log_printf(3, server.log, "Event CALL STOP referrs to a non-existant session [w%dg%d]!\n", + event->span+1, event->chan+1); + } +} + +static void handle_heartbeat(call_signal_event_t *event) +{ + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + } else { + int err=call_signal_connection_write(&server.mcon, event); + if (err <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + } + } + return; +} + +static void handle_call_stop_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + log_printf(2, server.log, "Stop Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id, + woomera->interface); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + } else { + log_printf(2, server.log, "Event CALL_STOP_ACK(%d) referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->event_id, event->span+1, event->chan+1, event->call_setup_id); + } + + /* No need for us to do any thing here */ + return; +} + + +static void handle_call_start_nack_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + if ((woomera=pull_from_holding_tank(event->call_setup_id,-1,-1))) { + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else if (autoacm==0){ + log_printf(2, server.log, "Nack Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } else { + log_printf(0, server.log, + "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(2, server.log, + "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } + + if (event->call_setup_id > 0) { + clear_from_holding_tank(event->call_setup_id, NULL); + } + + /* No need for us to do any thing here */ + return; +} + +#if 0 +static void validate_number(unsigned char *s) +{ + unsigned char *p; + for (p = s; *p; p++) { + if (*p < 48 || *p > 57) { + log_printf(2, server.log, "Encountered a non-numeric character [%c]!\n", *p); + *p = '\0'; + break; + } + } +} +#endif + +static int parse_ss7_event(call_signal_connection_t *mcon, call_signal_event_t *event) +{ + int ret = 0; + +#if 0 + validate_number((unsigned char*)event->called_number_digits); + validate_number((unsigned char*)event->calling_number_digits); +#endif + +#if 1 + log_printf(2, server.log, + "RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + +#if 0 + log_printf(2, server.log, "RX EVENT\n"); + log_printf(2, server.log, "===================================\n"); + log_printf(2, server.log, " rType: %s (%0x HEX)\n", + call_signal_event_id_name(event->event_id),event->event_id); + log_printf(2, server.log, " rSpan: [%d]\n",event->span+1); + log_printf(2, server.log, " rChan: [%d]\n",event->chan+1); + log_printf(2, server.log, " rCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + log_printf(2, server.log, " rCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + log_printf(2, server.log, " rCause: %d\n",event->release_cause); + log_printf(2, server.log, " rInterface: [w%dg%d]\n",event->span+1,event->chan+1); + log_printf(2, server.log, " rEvent ID: [%d]\n",event->event_id); + log_printf(2, server.log, " rSetup ID: [%d]\n",event->call_setup_id); + log_printf(2, server.log, " rSeq: [%d]\n",event->fseqno); + log_printf(2, server.log, "===================================\n"); + +#endif + +#if 0 + log_printf(2, server.log, + "\nRX EVENT\n" + "===================================\n" + " rType: %s (%0x HEX)\n" + " rSpan: [%d]\n" + " rChan: [%d]\n" + " rCalledNum: %s\n" + " rCallingNum: %s\n" + " rCause: %s\n" + " rInterface : [w%dg%d]\n" + " rEvent ID : [%d]\n" + " rSetup ID: [%d]\n" + " rSeq: [%d]\n" + "===================================\n" + "\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), + release_to_string(event->release_cause), + event->span+1, + event->chan+1, + event->event_id, + event->call_setup_id, + event->fseqno + ); +#endif + + + switch(event->event_id) { + + case SIGBOOST_EVENT_CALL_START: + handle_call_start(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_CALL_START_ACK: + handle_call_start_ack(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK: + handle_call_start_nack(event); + break; + case SIGBOOST_EVENT_CALL_ANSWERED: + handle_call_answer(event); + break; + case SIGBOOST_EVENT_HEARTBEAT: + handle_heartbeat(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK_ACK: + handle_call_start_nack_ack(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED_ACK: + handle_call_stop_ack(event); + break; + case SIGBOOST_EVENT_INSERT_CHECK_LOOP: + handle_call_loop_start(event); + break; + case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: + handle_restart_ack(mcon,event); + break; + case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: + handle_gap_abate(event); + break; + default: + log_printf(0, server.log, "Warning no handler implemented for [%s]\n", + call_signal_event_id_name(event->event_id)); + break; + } + + return ret; +} + + +static void *monitor_thread_run(void *obj) +{ + int ss = 0; + int policy=0,priority=0; + char a=0,b=0; + call_signal_connection_t *mcon=&server.mcon; + call_signal_connection_t *mconp=&server.mconp; + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + + if (call_signal_connection_open(mcon, + mcon->cfg.local_ip, + mcon->cfg.local_port, + mcon->cfg.remote_ip, + mcon->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCON Socket [%d] %s\n", + mcon->socket,strerror(errno)); + exit(-1); + } + + if (call_signal_connection_open(mconp, + mconp->cfg.local_ip, + mconp->cfg.local_port, + mconp->cfg.remote_ip, + mconp->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCONP Socket [%d] %s\n", + mconp->socket,strerror(errno)); + exit(-1); + } + + mcon->log = server.log; + mconp->log = server.log; + + isup_exec_command(0, + 0, + -1, + SIGBOOST_EVENT_SYSTEM_RESTART, + 0); + + mcon->rxseq_reset=1; + + smg_get_current_priority(&policy,&priority); + + log_printf(1, server.log, "Open udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + log_printf(1, server.log, "Monitor Thread Started (%i:%i)\n",policy,priority); + + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { +#if 0 + ss = waitfor_socket(server.mcon.socket, 1000, POLLERR | POLLIN); +#else + ss = waitfor_2sockets(mcon->socket, + mconp->socket, + &a, &b, 1000); +#endif + + if (ss > 0) { + + call_signal_event_t *event=NULL; + int i=0; + + if (b) { +mcon_retry_priority: + if ((event = call_signal_connection_readp(mconp,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event P [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mconp,event); + if (++i < 10) { + goto mcon_retry_priority; + } + + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost P Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + i=0; + + if (a) { +mcon_retry: + if ((event = call_signal_connection_read(mcon,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mcon,event); + + if (++i < 50) { + goto mcon_retry; + } + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + } + + if (ss < 0){ + log_printf(0, server.log, "Thread Run: Select Socket Error!\n"); + break; + } + + } + + log_printf(1, server.log, "Close udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + call_signal_connection_close(&server.mcon); + call_signal_connection_close(&server.mconp); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + log_printf(0, server.log, "Monitor Thread Ended\n"); + + return NULL; +} + +static void woomera_loop_thread_run(struct woomera_interface *woomera) +{ + int err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log, "Failed to start loop media thread\n"); + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + return; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP)) { + + sleep(1); + continue; + + } + + woomera_clear_flag(woomera, WFLAG_RUNNING); + + log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); + + + + return; +} + +static void *woomera_thread_run(void *obj) +{ + struct woomera_interface *woomera = obj; + struct woomera_message wmsg; + struct woomera_event wevent; + char *event_string; + int mwi; + int err; + int policy=0, priority=0; + int span = -1, chan = -1; + + woomera_message_init(&wmsg); + + //smg_get_current_priority(&policy,&priority); + + log_printf(2, server.log, "WOOMERA session started (ptr=%p : loop=%i)(%i:%i) Index=%i\n", + woomera,woomera->loop_tdm,policy,priority, woomera->index); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_mutex_init(&woomera->queue_lock, NULL); + pthread_mutex_init(&woomera->ms_lock, NULL); + pthread_mutex_init(&woomera->dtmf_lock, NULL); + pthread_mutex_init(&woomera->vlock, NULL); + pthread_mutex_init(&woomera->flags_lock, NULL); + + if (woomera->loop_tdm) { + woomera_loop_thread_run(woomera); + goto woomera_session_close; + } + + err=socket_printf(woomera->socket, + "EVENT HELLO Sangoma Media Gateway%s" + "Supported-Protocols: TDM%s" + "Version: %s%s" + "Remote-Address: %s%s" + "Remote-Port: %d%s" + "Raw-Format: %s%s", + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + SMG_VERSION, WOOMERA_LINE_SEPERATOR, + inet_ntoa(woomera->addr.sin_addr), WOOMERA_LINE_SEPERATOR, + ntohs(woomera->addr.sin_port), WOOMERA_LINE_SEPERATOR, + server.hw_coding?"ALAW":"ULAW", WOOMERA_RECORD_SEPERATOR + ); + + if (err) { + log_printf(0, server.log, "Woomera session socket failure! (ptr=%p)\n", + woomera); + woomera_clear_flag(woomera, WFLAG_RUNNING); + goto woomera_session_close; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + woomera_test_flag(woomera, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + !master_reset) { + + + mwi = woomera_message_parse(woomera, &wmsg, WOOMERA_HARD_TIMEOUT); + if (mwi >= 0) { + + if (mwi) { + interpret_command(woomera, &wmsg); + } else if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + if (socket_printf(woomera->socket, "%s", event_string)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + free(event_string); + log_printf(4, server.log, + "WOOMERA session (ptr=%p) print string error\n", + woomera); + break; + } + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + if (woomera->timeout > 0 && time(NULL) >= woomera->timeout) { + + /* Sent the hangup only after we sent a NACK */ + + log_printf(2, server.log, + "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", + woomera,woomera->interface,woomera->timeout); + + /* Let the Index check below send a NACK */ + if (woomera->index) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + break; + } + + } else { + log_printf(3, server.log, "WOOMERA session (ptr=%p) [%s] READ MSG Error %i \n", + woomera,woomera->interface,mwi); + break; + } + + } + +woomera_session_close: + + log_printf(2, server.log, "WOOMERA session (ptr=%p) is dying [%s]: SR=%d WR=%d WF=0x%04X\n", + woomera,woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_RUNNING), + woomera->flags); + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + usleep(100); + sched_yield(); + } + } + + + /*********************************************** + * Identify the SPAN CHAN to be used below + ***********************************************/ + + chan = woomera->chan; + span = woomera->span; + + + if (!woomera_test_flag(woomera, WFLAG_HANGUP)) { + + /* The call was not HUNGUP. This is the last check, + If the call is valid, hungup the call if the call + was never up the keep going */ + + + if (smg_validate_span_chan(span,chan) == 0) { + + if (!woomera->index) { + + if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } + } else { + log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + + } + }else{ + /* This can happend if an outgoing call times out + or gets hungup before it gets acked. Its not a + failure */ + if (!woomera->index) { + + /* In this case we really failed to tx STOP */ + log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + + } + +woo_re_hangup: + + /* We must send a STOP ACK to boost telling it that we are done */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + + /* SMG received a HANGUP from boost. + We must now send back the ACK to the HANGUP. + Boost will not release channel until we + ACK the hangup */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Ack) to SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + }else{ + /* This should never happen! If it does + we broke protocol */ + log_printf(0, woomera->log, + "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + + /* SMG received a NACK from boost during call startup. + We must now send back the ACK to the NACK. + Boost will not release channel until we + ACK the NACK */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + woomera->index=0; + + } else if (woomera->index) { + isup_exec_command(0, + 0, + woomera->index, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + woomera->index=0; + + } else { + log_printf(0, woomera->log, + "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + } + + if (woomera->index) { + + int index = woomera->index; + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Timeout: %ld%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + woomera->timeout, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(18), + WOOMERA_LINE_SEPERATOR, + 18, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + + if (peek_from_holding_tank(index)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(0, + 0, + index, + SIGBOOST_EVENT_CALL_START_NACK, + 0); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(2, woomera->log, + "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", + index); + } else { + log_printf(1, woomera->log, + "Error Failed to Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] - index stale!\n", + index); + } + } + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //30sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] ... \n", + woomera->index); + } + + if (overall_cnt > 10) { //300sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent HANGUP to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + log_printf(2, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i] ... \n", + woomera->interface,woomera->index_hold); + } + + if (overall_cnt > 10) { //100sec + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + server.process_table[span][chan].dev != woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + } + } + + /***************************************************** + * We must wait for WFLAG_WAIT_FOR_STOPPED_ACK here + * so that STOP_ACK can access the woomera + *****************************************************/ + + if (smg_validate_span_chan(span,chan) == 0) { + log_printf(2, woomera->log, + "WOOMERA Clearing Processs Table ... \n", + woomera->interface); + pthread_mutex_lock(&server.process_lock); + if (server.process_table[span][chan].dev == woomera){ + server.process_table[span][chan].dev = NULL; + memset(server.process_table[span][chan].session,0,SMG_SESSION_NAME_SZ); + } + pthread_mutex_unlock(&server.process_lock); + } + +#if 0 +//Used for testing + if (1) { + int chan = woomera->chan; + int span = woomera->span; + if (smg_validate_span_chan(span,chan) == 0) { + pthread_mutex_lock(&server.process_lock); + /* This is possible in case media thread dies on startup */ + + if (server.process_table[span][chan]){ + log_printf(0, server.log, + "Sanity Span Chan Still in use: [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + //server.process_table[span][chan] = NULL; + } + pthread_mutex_unlock(&server.process_lock); + } + } +#endif + + usleep(3000000); + + /* Sanity Check */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP ACK\n"); + goto woo_re_hangup; + } + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP NACK ACK\n"); + goto woo_re_hangup; + } + + /* This is where we actually pull the index + * out of the tank. We had to keep the tank + * value until the end of the call. Tank is only + * used on outgoing calls. */ + if (woomera->index_hold >= 1) { + clear_from_holding_tank(woomera->index_hold, woomera); + woomera->index_hold=0; + } + + log_printf(2, woomera->log, "Woomera Thread Finished %u\n", (unsigned long) woomera->thread); + close_socket(&woomera->socket); + woomera->socket=-1; + + /* delete queue */ + while ((event_string = dequeue_event(woomera))) { + free(event_string); + } + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + del_listener(woomera); + } + + log_printf(2, server.log, "WOOMERA session for [%s] stopped (ptr=%p)\n", + woomera->interface,woomera); + + if (woomera_test_flag(woomera, WFLAG_MASTER_DEV)) { + log_printf(0,server.log,"MASTER Thread Stopped (ptr=%p)\n",woomera); + master_reset=0; + } + + + pthread_mutex_destroy(&woomera->queue_lock); + pthread_mutex_destroy(&woomera->ms_lock); + pthread_mutex_destroy(&woomera->dtmf_lock); + pthread_mutex_destroy(&woomera->vlock); + pthread_mutex_destroy(&woomera->flags_lock); + woomera_set_raw(woomera, NULL); + woomera_set_interface(woomera, NULL); + + woomera_message_clear(&wmsg); + + free(woomera); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count--; + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_exit(NULL); + return NULL; +} + + +static int launch_woomera_thread(struct woomera_interface *woomera) +{ + int result = 0; + pthread_attr_t attr; + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_RUNNING); + result = pthread_create(&woomera->thread, &attr, woomera_thread_run, woomera); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! (%i) %s\n", + __FUNCTION__,result,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + +static int launch_monitor_thread(void) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 10; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + log_printf(0,server.log,"%s: Old Priority =%i res=%i \n",__FUNCTION__, + param.sched_priority,result); + + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + result = pthread_create(&server.monitor_thread, &attr, monitor_thread_run, NULL); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +#ifdef WP_HPTDM_API +static void *hp_tdmapi_span_run(void *obj) +{ + hp_tdm_api_span_t *span = obj; + int err; + + log_printf(0,server.log,"Starting %s span!\n",span->ifname); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + break; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + sleep(3); + log_printf(0,server.log,"Stopping %s span!\n",span->ifname); + + pthread_exit(NULL); +} + + +static int launch_hptdm_api_span_thread(int span) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 5; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + result = pthread_create(&server.monitor_thread, &attr, hp_tdmapi_span_run, &hptdmspan[span]); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} +#endif + +static int configure_server(void) +{ + struct woomera_config cfg; + char *var, *val; + int cnt = 0; + + server.dtmf_intr_ch = -1; + + if (!woomera_open_file(&cfg, server.config_file)) { + log_printf(0, server.log, "open of %s failed\n", server.config_file); + return 0; + } + + while (woomera_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(var, "boost_local_ip")) { + strncpy(server.mcon.cfg.local_ip, val, + sizeof(server.mcon.cfg.local_ip) -1); + strncpy(server.mconp.cfg.local_ip, val, + sizeof(server.mconp.cfg.local_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_local_port")) { + server.mcon.cfg.local_port = atoi(val); + server.mconp.cfg.local_port = + server.mcon.cfg.local_port+1; + cnt++; + } else if (!strcasecmp(var, "boost_remote_ip")) { + strncpy(server.mcon.cfg.remote_ip, val, + sizeof(server.mcon.cfg.remote_ip) -1); + strncpy(server.mconp.cfg.remote_ip, val, + sizeof(server.mconp.cfg.remote_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_remote_port")) { + server.mcon.cfg.remote_port = atoi(val); + server.mconp.cfg.remote_port = + server.mcon.cfg.remote_port+1; + cnt++; + } else if (!strcasecmp(var, "logfile_path")) { + if (!server.logfile_path) { + server.logfile_path = strdup(val); + } + } else if (!strcasecmp(var, "woomera_port")) { + server.port = atoi(val); + } else if (!strcasecmp(var, "debug_level")) { + server.debug = atoi(val); + } else if (!strcasecmp(var, "out_tx_test")) { + server.out_tx_test = atoi(val); + } else if (!strcasecmp(var, "loop_trace")) { + server.loop_trace = atoi(val); + } else if (!strcasecmp(var, "rxgain")) { + server.rxgain = atoi(val); + } else if (!strcasecmp(var, "txgain")) { + server.txgain = atoi(val); + } else if (!strcasecmp(var, "dtmf_on_duration")){ + server.dtmf_on = atoi(val); + } else if (!strcasecmp(var, "dtmf_off_duration")){ + server.dtmf_off = atoi(val); + } else if (!strcasecmp(var, "dtmf_inter_ch_duration")){ + server.dtmf_intr_ch = atoi(val); + } else if (!strcasecmp(var, "max_calls")) { + int max = atoi(val); + if (max > 0) { + server.max_calls = max; + } + } else if (!strcasecmp(var, "autoacm")) { + int max = atoi(val); + if (max >= 0) { + autoacm=max; + } + + } else if (!strcasecmp(var, "media_ip")) { + strncpy(server.media_ip, val, sizeof(server.media_ip) -1); + } else { + log_printf(0, server.log, "Invalid Option %s at line %d!\n", var, cfg.lineno); + } + } + + /* Post initialize */ + if (server.dtmf_on == 0){ + server.dtmf_on=SMG_DTMF_ON; + } + if (server.dtmf_off == 0) { + server.dtmf_off=SMG_DTMF_OFF; + } + if (server.dtmf_intr_ch == -1) { + server.dtmf_intr_ch = 0; + } + server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; + + log_printf(0,server.log, "DTMF On=%i Off=%i IntrCh=%i Size=%i\n", + server.dtmf_on,server.dtmf_off,server.dtmf_intr_ch,server.dtmf_size); + + woomera_close_file(&cfg); + return cnt == 4 ? 1 : 0; +} + + + +static int main_thread(void) +{ + + struct sockaddr_in sock_addr, client_addr; + struct woomera_interface *new_woomera; + int client_sock = -1, pid = 0; + unsigned int len = 0; + FILE *tmp; + + if ((server.master_connection.socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + log_printf(0, server.log, "socket() failed\n"); + return 1; + } + + memset(&sock_addr, 0, sizeof(sock_addr)); /* Zero out structure */ + sock_addr.sin_family = AF_INET; /* Internet address family */ + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + sock_addr.sin_port = htons(server.port); /* Local port */ + + /* Bind to the local address */ + if (bind(server.master_connection.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) { + log_printf(0, server.log, "bind(%d) failed\n", server.port); + return 1; + } + + /* Mark the socket so it will listen for incoming connections */ + if (listen(server.master_connection.socket, MAXPENDING) < 0) { + log_printf(0, server.log, "listen() failed\n"); + return 1; + } + + if ((pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "pid %d already exists.\n", pid); + exit(0); + } + + if (!(tmp = safe_fopen(PIDFILE, "w"))) { + log_printf(0, stderr, "Error creating pidfile %s\n", PIDFILE); + return 1; + } else { + fprintf(tmp, "%d", getpid()); + fclose(tmp); + tmp = NULL; + } + + no_nagle(server.master_connection.socket); + +#if 0 + if (1) { + int span,chan; + call_signal_event_t event; +#if 0 + span=1; + chan=30; + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); +#else + for (span=0;span<8;span++) { + for (chan=0;chan<31;chan++) { + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); + } + } +#endif + } +#endif + +#ifdef WP_HPTDM_API + if (1) { + int span; + for (span=0;span<16;span++) { + hptdmspan[span] = sangoma_hptdm_api_span_init(span); + if (!hptdmspan[span]) { + break; + } else { + log_printf(0, server.log, "HP TDM API Span: %d configured...\n", + span); + launch_hptdm_api_span_thread(span); + } + } + } +#endif + + log_printf(1, server.log, "Main Process Started: Woomera Ready port: %d\n", server.port); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + /* Set the size of the in-out parameter */ + len = sizeof(client_addr); + + /* Wait for a client to connect */ + if ((client_sock = accept(server.master_connection.socket, (struct sockaddr *) &client_addr, &len)) < 0) { + log_printf(0, server.log, "accpet() failed\n"); + return 1; + } + + if ((new_woomera = new_woomera_interface(client_sock, &client_addr, len))) { + log_printf(2, server.log, "Starting Thread for New Connection %s:%d Sock=%d\n", + inet_ntoa(new_woomera->addr.sin_addr), + ntohs(new_woomera->addr.sin_port), + client_sock); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count++; + pthread_mutex_unlock(&server.thread_count_lock); + if (launch_woomera_thread(new_woomera)) { + socket_printf(new_woomera->socket, + "501 call was cancelled!%s", + WOOMERA_RECORD_SEPERATOR); + + close_socket(&new_woomera->socket); + new_woomera->socket=-1; + free(new_woomera); + } + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + } + } + + log_printf(1, server.log, "Main Process End\n"); + + return 0; +} + +static int do_ignore(int sig) +{ + return 0; +} + +static int do_shut(int sig) +{ + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + close_socket(&server.master_connection.socket); + log_printf(1, server.log, "Caught SIG %d, Closing Master Socket!\n", sig); + return 0; +} + +static int sangoma_tdm_init (int span) +{ +#ifdef LIBSANGOMA_GET_HWCODING + wanpipe_tdm_api_t tdm_api; + int fd=sangoma_open_tdmapi_span(span); + if (fd < 0 ){ + return -1; + } else { + server.hw_coding=sangoma_tdm_get_hw_coding(fd,&tdm_api); + close_socket(&fd); + } +#else +#error "libsangoma missing hwcoding feature: not up to date!" +#endif + return 0; +} + + +static int woomera_startup(int argc, char **argv) +{ + int x = 0, pid = 0, bg = 0; + char *cfg=NULL, *debug=NULL, *arg=NULL; + + while((arg = argv[x++])) { + + if (!strcasecmp(arg, "-hup")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGHUP); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-term") || !strcasecmp(arg, "--term")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGTERM); + unlink(PIDFILE); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-version")) { + fprintf(stdout, "\nSangoma Media Gateway: Version %s\n\n", SMG_VERSION); + exit(0); + + } else if (!strcasecmp(arg, "-help")) { + fprintf(stdout, "%s\n%s [-help] | [ -version] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(0); + } else if (!strcasecmp(arg, "-wipe")) { + unlink(PIDFILE); + } else if (!strcasecmp(arg, "-bg")) { + bg = 1; + + } else if (!strcasecmp(arg, "-g")) { + coredump = 1; + + } else if (!strcasecmp(arg, "-debug")) { + if (argv[x] && *(argv[x]) != '-') { + debug = argv[x++]; + } + } else if (!strcasecmp(arg, "-cfg")) { + if (argv[x] && *(argv[x]) != '-') { + cfg = argv[x++]; + } + } else if (!strcasecmp(arg, "-log")) { + if (argv[x] && *(argv[x]) != '-') { + server.logfile_path = strdup(argv[x++]); + } + } else if (*arg == '-') { + log_printf(0, stderr, "Unknown Option %s\n", arg); + fprintf(stdout, "%s\n%s [-help] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(1); + } + } + + if (1){ + int spn; + for (spn=1;spn<=WOOMERA_MAX_SPAN;spn++) { + if (sangoma_tdm_init(spn) == 0) { + break; + } + } + if (spn>WOOMERA_MAX_SPAN) { + printf("\nError: Failed to access a channel on spans 1-16\n"); + printf(" Please start Wanpipe TDM API drivers\n"); + return 0; + } + } + + if (bg && (pid = fork())) { + log_printf(0, stderr, "Backgrounding!\n"); + return 0; + } + + q931_cause_setup(); + + server.port = 42420; + server.debug = 0; + strcpy(server.media_ip, "127.0.0.1"); + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + server.log = stdout; + server.master_connection.socket = -1; + server.master_connection.event_queue = NULL; + server.config_file = cfg ? cfg : "/etc/sangoma_mgd.conf"; + pthread_mutex_init(&server.listen_lock, NULL); + pthread_mutex_init(&server.ht_lock, NULL); + pthread_mutex_init(&server.process_lock, NULL); + pthread_mutex_init(&server.media_udp_port_lock, NULL); + pthread_mutex_init(&server.thread_count_lock, NULL); + pthread_mutex_init(&server.master_connection.queue_lock, NULL); + pthread_mutex_init(&server.master_connection.flags_lock, NULL); + pthread_mutex_init(&server.mcon.lock, NULL); + server.master_connection.chan = -1; + server.master_connection.span = -1; + + if (!configure_server()) { + log_printf(0, server.log, "configuration failed!\n"); + return 0; + } + +#ifndef USE_SYSLOG + if (server.logfile_path) { + if (!(server.log = safe_fopen(server.logfile_path, "a"))) { + log_printf(0, stderr, "Error setting logfile %s!\n", server.logfile_path); + server.log = stderr; + return 0; + } + } +#endif + + + if (debug) { + server.debug = atoi(debug); + } + + if (coredump) { + struct rlimit l; + memset(&l, 0, sizeof(l)); + l.rlim_cur = RLIM_INFINITY; + l.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &l)) { + log_printf(0, stderr, "Warning: Failed to disable core size limit: %s\n", + strerror(errno)); + } + } + +#ifdef __LINUX__ + if (geteuid() && coredump) { + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { + log_printf(0, stderr, "Warning: Failed to disable core size limit for non-root: %s\n", + strerror(errno)); + } + } +#endif + + + + (void) signal(SIGINT,(void *) do_shut); + (void) signal(SIGPIPE,(void *) do_ignore); + (void) signal(SIGHUP,(void *) do_shut); + + + woomera_set_flag(&server.master_connection, WFLAG_RUNNING); + if (launch_monitor_thread()) { + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + return 0; + } + + fprintf(stderr, "%s", WELCOME_TEXT); + log_printf(0, stderr, "Woomera STARTUP Complete. [AutoACM=%i]\n",autoacm); + + return 1; +} + +static int woomera_shutdown(void) +{ + char *event_string; + int told = 0, loops = 0; + + close_socket(&server.master_connection.socket); + pthread_mutex_destroy(&server.listen_lock); + pthread_mutex_destroy(&server.ht_lock); + pthread_mutex_destroy(&server.process_lock); + pthread_mutex_destroy(&server.media_udp_port_lock); + pthread_mutex_destroy(&server.thread_count_lock); + pthread_mutex_destroy(&server.master_connection.queue_lock); + pthread_mutex_destroy(&server.master_connection.flags_lock); + pthread_mutex_destroy(&server.mcon.lock); + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + + + if (server.logfile_path) { + free(server.logfile_path); + server.logfile_path = NULL; + } + + /* delete queue */ + while ((event_string = dequeue_event(&server.master_connection))) { + free(event_string); + } + + while(server.thread_count > 0) { + loops++; + + if (loops % 1000 == 0) { + told = 0; + } + + if (loops > 10000) { + log_printf(0, server.log, "Red Alert! threads did not stop\n"); + assert(server.thread_count == 0); + } + + if (told != server.thread_count) { + log_printf(1, server.log, "Waiting For %d thread%s.\n", + server.thread_count, server.thread_count == 1 ? "" : "s"); + told = server.thread_count; + } + ysleep(10000); + } + unlink(PIDFILE); + log_printf(0, stderr, "Woomera SHUTDOWN Complete.\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + + mlockall(MCL_FUTURE); + + + server.hw_coding=0; + + openlog (ps_progname ,LOG_PID, LOG_LOCAL2); + + if (! (ret = woomera_startup(argc, argv))) { + exit(0); + } + ret = main_thread(); + + woomera_shutdown(); + + return ret; +} + +/** EMACS ** + * Local variables: + * mode: C + * c-basic-offset: 4 + * End: + */ + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.13.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.13.tmp new file mode 100644 index 0000000..ae92204 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.13.tmp @@ -0,0 +1,5020 @@ +/********************************************************************************* + * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-08, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * ============================================= + * v1.27 Nenad Corbic + * Jan 24 2007 + * Fixed a memory leak on incoming calls + * Removed the use of server listener which + * was not used + * + * v1.26 Nenad Corbic + * Jan 18 2007 + * Fixed hangup after invalid Answer or Ack Session + * Can cause double use of setup id - now fixed + * Update on autoacm on accept check for acked. + * + * v1.25 Nenad Corbic + * Dec 31 2007 + * Removed UDP Resync it can cause skb_over errors. + * Moved RDNIS message to higher debug level + * + * v1.24 Nenad Corbic + * Nov 30 2007 + * Bug fix on return code on ALL ckt busy + * + * v1.23 Nenad Corbic + * Bug fix on socket open. Check for retun code >= 0 + * + * v1.22 Nenad Corbic + * Nov 27 2007 + * Updated DTMF Tx function + * Fixed - dtmf tx without voice + * Fxied - dtmf clipping. + * + * v1.21 Nenad Corbic + * Nov 25 2007 + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + *********************************************************************************/ + +#include "sangoma_mgd.h" +#include "q931_cause.h" + + +#define USE_SYSLOG 1 +#define CODEC_LAW_DEFAULT 1 + +#ifdef CODEC_LAW_DEFAULT +static uint32_t codec_sample=8; +#else +static uint32_t codec_sample=16; +#endif + +static char ps_progname[]="sangoma_mgd"; + +static struct woomera_interface woomera_dead_dev; + +#if 0 +#define DOTRACE +#endif + + +#define SMG_VERSION "v1.27" + +/* enable early media */ +#if 1 +#define WOOMERA_EARLY_MEDIA 1 +#endif + + +#define SMG_DTMF_ON 60 +#define SMG_DTMF_OFF 10 +#define SMG_DTMF_RATE 8000 + +#if 0 +#define MEDIA_SOCK_SHUTDOWN 1 +#endif + +#ifdef DOTRACE +static int tc = 0; +#endif + +#if 0 +#warning "NENAD: HPTDM API" +#define WP_HPTDM_API 1 +#else +#undef WP_HPTDM_API +#endif + +#ifdef WP_HPTDM_API +hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; +#endif + +#define SMG_CALLING_NAME 1 + +const char WELCOME_TEXT[] = +"================================================================================\n" +"Sangoma Media Gateway Daemon v1.27 \n" +"TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" +"Copyright 2005, 2006, 2007 \n" +"Nenad Corbic , Anthony Minessale II \n" +"This program is free software, distributed under the terms of\n" +"the GNU General Public License\n" +"================================================================================\n" +""; + + +static int master_reset=0; + +static int coredump=1; +static int autoacm=1; + +static int launch_media_tdm_thread(struct woomera_interface *woomera); +static int launch_woomera_thread(struct woomera_interface *woomera); +static struct woomera_interface *alloc_woomera(void); + +q931_cause_to_str_array_t q931_cause_to_str_array[255]; + + +#if 0 +static uint32_t string_to_release(char *code) +{ + if (code) { + if (!strcasecmp(code, "CHANUNAVAIL")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "INVALID")) { + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "ERROR")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + if (!strcasecmp(code, "CONGESTION")) { + //return SIGBOOST_RELEASE_CAUSE_BUSY; + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "BUSY")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "NOANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "ANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (!strcasecmp(code, "CANCEL")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "UNKNOWN")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + } + return SIGBOOST_RELEASE_CAUSE_NORMAL; +} + +static char * release_to_string(uint32_t rel_cause) +{ + switch (rel_cause) { + + case SIGBOOST_RELEASE_CAUSE_UNDEFINED: + return "UNKNOWN"; + case SIGBOOST_RELEASE_CAUSE_NORMAL: + return "NORMAL"; + case SIGBOOST_RELEASE_CAUSE_BUSY: + return "BUSY"; + case SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST: + return "CHANUNAVAIL"; + case SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET: + return "CANCEL"; + case SIGBOOST_RELEASE_CAUSE_NOANSWER: + return "NOANSWER"; + case SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT: + return "TIMEOUT"; + case SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY: + return "CONGESTION"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL: + return "ERROR"; + } + + return "NORMAL"; +} +#endif + + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return; + } + + if (level && level > server.debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + } else { + char date[80] = ""; + struct tm now; + time_t epoch; + + if (time(&epoch) && localtime_r(&epoch, &now)) { + strftime(date, sizeof(date), "%Y-%m-%d %T", &now); + } + +#ifdef USE_SYSLOG + syslog(LOG_DEBUG | LOG_LOCAL2, data); +#else + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + + + + +static int isup_exec_command(int span, int chan, int id, int cmd, int cause) +{ + call_signal_event_t oevent; + int retry=5; + + call_signal_event_init(&oevent, cmd, chan, span); + oevent.release_cause = cause; + + if (id >= 0) { + oevent.call_setup_id = id; + } +isup_exec_cmd_retry: + if (call_signal_connection_write(&server.mcon, &oevent) <= 0){ + + --retry; + if (retry <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket: %s\n", + strerror(errno)); + return -1; + } else { + log_printf(0, server.log, + "System Warning: Failed to tx on ISUP socket: %s :retry %i\n", + strerror(errno),retry); + } + + goto isup_exec_cmd_retry; + } + + return 0; +} + +static int socket_printf(int socket, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return -1; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + log_printf(0, server.log, "Crtical ERROR: Memory Error!\n"); + } else { + int err; + int len = strlen(data); + err=send(socket, data, strlen(data), 0); + if (err != strlen(data)) { + log_printf(2, server.log, "ERROR: Failed to send data to woomera socket(%i): err=%i len=%d %s\n", + socket,err,len,strerror(errno)); + ret = err; + } else { + ret = 0; + } + + free(data); + } + + return ret; +} + + + +static int woomera_next_pair(struct woomera_config *cfg, char **var, char **val) +{ + int ret = 0; + char *p, *end; + + *var = *val = NULL; + + for(;;) { + cfg->lineno++; + + if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { + ret = 0; + break; + } + + *var = cfg->buf; + + if (**var == '[' && (end = strchr(*var, ']'))) { + *end = '\0'; + (*var)++; + strncpy(cfg->category, *var, sizeof(cfg->category) - 1); + continue; + } + + if (**var == '#' || **var == '\n' || **var == '\r') { + continue; + } + + if ((end = strchr(*var, '#'))) { + *end = '\0'; + end--; + } else if ((end = strchr(*var, '\n'))) { + if (*end - 1 == '\r') { + end--; + } + *end = '\0'; + } + + p = *var; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *var = p; + + if (!(*val = strchr(*var, '='))) { + ret = -1; + log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); + continue; + } else { + p = *val - 1; + *(*val) = '\0'; + (*val)++; + if (*(*val) == '>') { + *(*val) = '\0'; + (*val)++; + } + + while ((*p == ' ' || *p == '\t') && p != *var) { + *p = '\0'; + p--; + } + + p = *val; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *val = p; + ret = 1; + break; + } + } + + return ret; + +} + + +#if 0 +static void woomera_set_span_chan(struct woomera_interface *woomera, int span, int chan) +{ + pthread_mutex_lock(&woomera->vlock); + woomera->span = span; + woomera->chan = chan; + pthread_mutex_unlock(&woomera->vlock); + +} +#endif + + +static struct woomera_event *new_woomera_event_printf(struct woomera_event *ebuf, char *fmt, ...) +{ + struct woomera_event *event = NULL; + int ret = 0; + va_list ap; + + if (ebuf) { + event = ebuf; + } else if (!(event = new_woomera_event())) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + return NULL; + } else { + return NULL; + } + + va_start(ap, fmt); +#ifdef SOLARIS + event->data = (char *) malloc(2048); + vsnprintf(event->data, 2048, fmt, ap); +#else + ret = vasprintf(&event->data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + destroy_woomera_event(&event, EVENT_FREE_DATA); + return NULL; + } + + return event; + +} + +static struct woomera_event *woomera_clone_event(struct woomera_event *event) +{ + struct woomera_event *clone; + + if (!(clone = new_woomera_event())) { + return NULL; + } + + memcpy(clone, event, sizeof(*event)); + clone->next = NULL; + clone->data = strdup(event->data); + + return clone; +} + +static void enqueue_event(struct woomera_interface *woomera, + struct woomera_event *event, + event_args free_data) +{ + struct woomera_event *ptr, *clone = NULL; + + assert(woomera != NULL); + assert(event != NULL); + + if (!(clone = woomera_clone_event(event))) { + log_printf(0, server.log, "Error Cloning Event\n"); + return; + } + + pthread_mutex_lock(&woomera->queue_lock); + + for (ptr = woomera->event_queue; ptr && ptr->next ; ptr = ptr->next); + + if (ptr) { + ptr->next = clone; + } else { + woomera->event_queue = clone; + } + + pthread_mutex_unlock(&woomera->queue_lock); + + woomera_set_flag(woomera, WFLAG_EVENT); + + if (free_data && event->data) { + /* The event has been duplicated, the original data + * should be freed */ + free(event->data); + event->data=NULL; + } +} + +static char *dequeue_event(struct woomera_interface *woomera) +{ + struct woomera_event *event; + char *data = NULL; + + if (!woomera) { + return NULL; + } + + pthread_mutex_lock(&woomera->queue_lock); + if (woomera->event_queue) { + event = woomera->event_queue; + woomera->event_queue = event->next; + data = event->data; + pthread_mutex_unlock(&woomera->queue_lock); + + destroy_woomera_event(&event, EVENT_KEEP_DATA); + return data; + } + pthread_mutex_unlock(&woomera->queue_lock); + + return data; +} + + +static int enqueue_event_on_listeners(struct woomera_event *event) +{ + struct woomera_listener *ptr; + int x = 0; + + assert(event != NULL); + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + enqueue_event(ptr->woomera, event, EVENT_KEEP_DATA); + x++; + } + pthread_mutex_unlock(&server.listen_lock); + + return x; +} + + +static void del_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *ptr, *last = NULL; + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + if (ptr->woomera == woomera) { + if (last) { + last->next = ptr->next; + } else { + server.listeners = ptr->next; + } + free(ptr); + break; + } + last = ptr; + } + pthread_mutex_unlock(&server.listen_lock); +} + +static void add_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *new; + + pthread_mutex_lock(&server.listen_lock); + + if ((new = malloc(sizeof(*new)))) { + memset(new, 0, sizeof(*new)); + new->woomera = woomera; + new->next = server.listeners; + server.listeners = new; + } else { + log_printf(0, server.log, "Memory Error adding listener!\n"); + } + + pthread_mutex_unlock(&server.listen_lock); +} + + + +static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) +{ + struct media_session *ms = woomera_get_ms(woomera); + char *cur = NULL; + int wrote = 0; + int err; + + if (!ms) { + return -EINVAL; + } + + if (!ms->dtmf_buffer) { + log_printf(3, woomera->log, "Allocate DTMF Buffer...."); + + err=switch_buffer_create_dynamic(&ms->dtmf_buffer, 1024, server.dtmf_size, 0); + + if (err != 0) { + log_printf(0, woomera->log, "Failed to allocate DTMF Buffer!\n"); + return -ENOMEM; + } else { + log_printf(3, woomera->log, "SUCCESS!\n"); + } + + } + + log_printf(3, woomera->log, "Sending DTMF %s\n",digits); + for (cur = digits; *cur; cur++) { + if ((wrote = teletone_mux_tones(&ms->tone_session, + &ms->tone_session.TONES[(int)*cur]))) { + + pthread_mutex_lock(&woomera->dtmf_lock); + + err=switch_buffer_write(ms->dtmf_buffer, ms->tone_session.buffer, wrote * 2); + + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3, woomera->log, "Sending DTMF %s Wrote=%i (err=%i)\n", + digits,wrote*2,err); + } else { + log_printf(0, woomera->log, "Error: Sending DTMF %s (err=%i)\n", + digits,wrote); + } + } + + ms->skip_read_frames = 200; + return 0; +} + +static struct woomera_interface *alloc_woomera(void) +{ + struct woomera_interface *woomera = NULL; + + if ((woomera = malloc(sizeof(struct woomera_interface)))) { + + memset(woomera, 0, sizeof(struct woomera_interface)); + + woomera->chan = -1; + woomera->span = -1; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->q931_rel_cause_topbx=SIGBOOST_RELEASE_CAUSE_NORMAL; + woomera->q931_rel_cause_tosig=SIGBOOST_RELEASE_CAUSE_NORMAL; + + woomera_set_interface(woomera, "w-1g-1"); + + + + } + + return woomera; + +} + + +static struct woomera_interface *new_woomera_interface(int socket, struct sockaddr_in *sock_addr, int len) +{ + struct woomera_interface *woomera = NULL; + + if (socket < 0) { + log_printf(0, server.log, "Critical: Invalid Socket on new interface!\n"); + return NULL; + } + + if ((woomera = alloc_woomera())) { + if (socket >= 0) { + no_nagle(socket); + woomera->socket = socket; + } + + if (sock_addr && len) { + memcpy(&woomera->addr, sock_addr, len); + } + } + + return woomera; + +} + +static char *woomera_message_header(struct woomera_message *wmsg, char *key) +{ + int x = 0; + char *value = NULL; + + for (x = 0 ; x < wmsg->last ; x++) { + if (!strcasecmp(wmsg->names[x], key)) { + value = wmsg->values[x]; + break; + } + } + + return value; +} + + +#if 1 + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +static int waitfor_tx_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if (pfds[0].revents & POLLOUT) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + + +#else + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags | errflags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & errflags)) { + res = -1; + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X)!\n", + pfds[0].revents); +#endif + res = -1; + } + } + + return res; +} + +#endif + +#if 1 +static int waitfor_2sockets(int fda, int fdb, char *a, char *b, int timeout) +{ + struct pollfd pfds[2]; + int res = 0; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + if (fda < 0 || fdb < 0) { + return -1; + } + + *a=0; + *b=0; + + memset(pfds, 0, sizeof(pfds)); + pfds[0].fd = fda; + pfds[1].fd = fdb; + pfds[0].events = POLLIN | errflags; + pfds[1].events = POLLIN | errflags; + if ((res = poll(pfds, 2, timeout)) > 0) { + res = 1; + if ((pfds[0].revents & errflags) || (pfds[1].revents & errflags)) { + res = -1; + } else { + if ((pfds[0].revents & POLLIN)) { + *a=1; + res++; + } + if ((pfds[1].revents & POLLIN)) { + *b=1; + res++; + } + } + + if (res == 1) { + /* No event found what to do */ + res=-1; + } + } + + return res; +} +#endif + + +static struct media_session *media_session_new(struct woomera_interface *woomera) +{ + struct media_session *ms = NULL; + int x; + char *p; + int span,chan; + + span=woomera->span; + chan=woomera->chan; + + log_printf(2, server.log,"Starting new MEDIA session [%s] [%s]\n", + woomera->interface,woomera->raw?woomera->raw:"N/A"); + + if ((ms = malloc(sizeof(struct media_session)))) { + memset(ms, 0, sizeof(struct media_session)); + + if (woomera->loop_tdm != 1) { + for(x = 0; x < strlen(woomera->raw) ; x++) { + if (woomera->raw[x] == ':') { + break; + } + if (woomera->raw[x] == '/') { + break; + } + } + + ms->ip = strndup(woomera->raw, x); + time(&ms->started); + p = woomera->raw + (x+1); + ms->port = atoi(p); + } + + time(&ms->started); + woomera_set_ms(woomera,ms); + ms->woomera = woomera; + + /* Setup artificial DTMF stuff */ + memset(&ms->tone_session, 0, sizeof(ms->tone_session)); + if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { + log_printf(0, server.log, "ERROR: Failed to initialize TONE [w%ig%i]!\n", + span+1,chan+1); + } + + ms->tone_session.rate = SMG_DTMF_RATE; + ms->tone_session.duration = server.dtmf_on * (ms->tone_session.rate / 1000); + ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); + + teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); + + } else { + log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", + span+1,chan+1); + } + + return ms; +} + +static void media_session_free(struct media_session *ms) +{ + if (ms->ip) { + free(ms->ip); + } + + teletone_destroy_session(&ms->tone_session); + switch_buffer_destroy(&ms->dtmf_buffer); + + ms->woomera = NULL; + + free(ms); +} + + +static int create_udp_socket(struct media_session *ms, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + log_printf(5,server.log,"LocalIP %s:%d IP %s:%d \n",local_ip, local_port, ip, port); + + memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); + memset(&ms->local_hp, 0, sizeof(ms->local_hp)); + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { + gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + ms->remote_addr.sin_family = ms->remote_hp.h_addrtype; + memcpy((char *) &ms->remote_addr.sin_addr.s_addr, ms->remote_hp.h_addr_list[0], ms->remote_hp.h_length); + ms->remote_addr.sin_port = htons(port); + + ms->local_addr.sin_family = ms->local_hp.h_addrtype; + memcpy((char *) &ms->local_addr.sin_addr.s_addr, ms->local_hp.h_addr_list[0], ms->local_hp.h_length); + ms->local_addr.sin_port = htons(local_port); + + rc = bind(ms->socket, (struct sockaddr *) &ms->local_addr, sizeof(ms->local_addr)); + if (rc < 0) { + close(ms->socket); + ms->socket = -1; + + log_printf(5,server.log, + "Failed to bind LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + + /* OK */ + + } else { + log_printf(0,server.log, + "Failed to get hostbyname LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + } else { + log_printf(0,server.log, + "Failed to create/allocate UDP socket\n"); + } + + return ms->socket; +} + +static int next_media_port(void) +{ + int port; + + pthread_mutex_lock(&server.media_udp_port_lock); + port = ++server.next_media_port; + if (port > WOOMERA_MAX_MEDIA_PORT) { + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + port = WOOMERA_MIN_MEDIA_PORT; + } + pthread_mutex_unlock(&server.media_udp_port_lock); + + return port; +} + + + +static int woomera_dtmf_transmit(struct media_session *ms, int mtu) +{ + struct woomera_interface *woomera = ms->woomera; + int bread; + unsigned char dtmf[1024]; + unsigned char dtmf_law[1024]; + sangoma_api_hdr_t hdrframe; + int i; + int slin_len = mtu*2; + short *data; + int used; + int res; + int err; + int txdtmf=0; + memset(&hdrframe,0,sizeof(hdrframe)); + + if (!ms->dtmf_buffer) { + return -1; + } + + for (;;) { + + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + break; + } + + res = waitfor_tx_socket(ms->sangoma_sock, -1, POLLERR | POLLOUT); + if (res <= 0) { + break; + } + +#ifdef CODEC_LAW_DEFAULT + + pthread_mutex_lock(&woomera->dtmf_lock); + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + pthread_mutex_unlock(&woomera->dtmf_lock); + break; + } + + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, slin_len); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread <= 0) { + break; + } + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", + woomera->interface,bread,mtu,ms->hw_coding,used); + + data=(short*)dtmf; + for (i=0;ihw_coding) { + /* ALAW */ + dtmf_law[i] = linear_to_alaw((int)data[i]); + } else { + /* ULAW */ + dtmf_law[i] = linear_to_ulaw((int)data[i]); + } + } + + err=sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf_law, mtu, 0); + + if (err != mtu) { + log_printf(0, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu); + } + + txdtmf++; + ms->skip_write_frames++; +#else +... + pthread_mutex_lock(&woomera->dtmf_lock); + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", + woomera->interface,bread); + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf, mtu, 0); + txdtmf++; + ms->skip_write_frames++; +#endif + + } + + if (txdtmf) { + return 0; + } else { + return -1; + } +} + +static void media_loop_run(struct media_session *ms) +{ + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int errs=0; + int res=0; + wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + char filename[100]; + FILE *filed=NULL; + int loops=0; + + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + + log_printf(1, server.log, "Media Loop Started %s fd=%i\n", + woomera->interface,ms->sangoma_sock); + + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "WANPIPE MEDIA Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + + + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } + + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + sangoma_tdm_disable_hwec(ms->sangoma_sock,&tdm_api); + + } + + if (errs) { + + log_printf(0, server.log, "Media Loop: failed to open tdm device %s\n", + woomera->interface); + return; + } + + if (server.loop_trace) { + sprintf(filename,"/smg/w%ig%i-loop.trace",woomera->span+1,woomera->chan+1); + unlink(filename); + filed = safe_fopen(filename, "w"); + } + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + ((res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2)) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + log_printf(0, server.log, "Media Loop Restart %s\n", + woomera->interface); + continue; + } + + if (res < 0 ){ + log_printf(0, server.log, "Media Loop Socket error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM Loop ReadMsg Error: %s\n", + strerror(errno), woomera->interface); + break; + } + + if (server.loop_trace && filed != NULL) { + int i; + for (i=0;isangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + res, 0); + + res=0; + + loops++; + } + + + if (res < 0) { + log_printf(2, server.log, "Media Loop: socket error %s (fd=%i)!\n", + woomera->interface, ms->sangoma_sock); + } + + + if (server.loop_trace && filed != NULL) { + fclose(filed); + } + + sangoma_tdm_enable_hwec(ms->sangoma_sock,&tdm_api); + + sleep(1); + + close_socket(&ms->sangoma_sock); + + log_printf(1, server.log, "Media Loop Finished %s Master=%i MediaEnd=%i Loops=%i\n", + woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_MEDIA_END),loops); + + return; + +} + +#ifdef WP_HPTDM_API +static int media_rx_ready(void *p, unsigned char *data, int len) +{ + struct media_session *ms = (struct media_session *)p; + + if (ms->udp_sock < 0) { + return -1; + } + + return sendto(ms->udp_sock, + data,len, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + +} +#endif + +static void *media_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int local_port, x = 0, errs = 0, res = 0, packet_len = 0; + //int udp_cnt=0; + struct woomera_event wevent; + wanpipe_tdm_api_t tdm_api; + FILE *tx_fd=NULL; + int sock_timeout=200; + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + !woomera->interface || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(2, server.log, + "MEDIA session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(ms); + pthread_exit(NULL); + return NULL; + } + + + log_printf(2, server.log, "MEDIA session for [%s] started (ptr=%p loop=%i)\n", + woomera->interface,woomera,woomera->loop_tdm); + + if (woomera->loop_tdm) { + media_loop_run(ms); + ms->udp_sock=-1; + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + goto media_thread_exit; + } + + for(x = 0; x < 1000 ; x++) { + local_port = next_media_port(); + if ((ms->udp_sock = create_udp_socket(ms, server.media_ip, local_port, ms->ip, ms->port)) > -1) { + break; + } + } + + if (ms->udp_sock < 0) { + log_printf(0, server.log, "UDP Socket Error (%s) [%s] LocalPort=%d\n", + strerror(errno), woomera->interface, local_port); + + errs++; + } else { + +#ifdef WP_HPTDM_API + hp_tdm_api_span_t *span=hptdmspan[woomera->span+1]; + if (!span || !span->init) { + errs++; + } else { + hp_tdm_api_usr_callback_t usr_callback; + memset(&usr_callback,0,sizeof(usr_callback)); + usr_callback.p = ms; + usr_callback.rx_avail = media_rx_ready; + if (span->open_chan(span, &usr_callback, &ms->tdmchan,woomera->chan+1)) { + errs++; + } + } +#else + if ((ms->sangoma_sock = sangoma_create_socket_by_name(woomera->interface, NULL)) < 0) { + log_printf(0, server.log, "WANPIPE Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + +# ifdef CODEC_LAW_DEFAULT + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } +# else + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_SLINEAR) < 0 ) { + errs++; + } +# endif + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + +# ifdef CODEC_LAW_DEFAULT +# ifdef LIBSANGOMA_GET_HWCODING + ms->hw_coding=sangoma_tdm_get_hw_coding(ms->sangoma_sock, &tdm_api); + if (ms->hw_coding < 0) { + errs++; + } +# else +# error "libsangoma missing hwcoding feature: not up to date!" +# endif +# endif + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + } +#endif + } + + + +#ifdef WP_HPTDM_API + /* No tdm thread */ +#else + if (!errs && + launch_media_tdm_thread(woomera)) { + errs++; + } +#endif + + if (!errs) { + + unsigned char udp_frame[4096]; + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(udp_frame,0,sizeof(udp_frame)); +#ifdef DOTRACE + int fdin, fdout; + char path_in[512], path_out[512]; +#endif + + + +#if 0 + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: %s%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + ms->hw_coding ?"ALAW":"ULAW", + WOOMERA_RECORD_SEPERATOR + ); +#else + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Unique-Call-Id: %s%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: PCM-16%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + WOOMERA_RECORD_SEPERATOR + ); +#endif + + + enqueue_event(woomera, &wevent, EVENT_FREE_DATA); + +#ifdef DOTRACE + sprintf(path_in, "/tmp/debug-in.%d.raw", tc); + sprintf(path_out, "/tmp/debug-out.%d.raw", tc++); + fdin = open(path_in, O_WRONLY | O_CREAT, O_TRUNC, 0600); + fdout = open(path_out, O_WRONLY | O_CREAT, O_TRUNC, 0600); +#endif + + if (server.out_tx_test) { + tx_fd=fopen("/smg/sound.raw","rb"); + if (!tx_fd){ + log_printf(0,server.log, "FAILED TO OPEN Sound file!\n"); + } + } + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { + + unsigned int fromlen = sizeof(struct sockaddr_in); + + + if (res == 0) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", + woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if ((packet_len = recvfrom(ms->udp_sock, udp_frame, sizeof(udp_frame), + MSG_DONTWAIT, (struct sockaddr *) &ms->local_addr, &fromlen)) < 1) { + log_printf(2, server.log, "UDP Recv Error: %s\n",strerror(errno)); + break; + } + +#if 0 + log_printf(6, server.log, "%s: UDP Receive %i !!!\n", + woomera->interface,packet_len); +#endif + + if (packet_len > 0) { + +#if 0 +/* NC: This can cause skb_over panic must be retested */ + if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { + /* Assume that we will always receive SLINEAR here */ + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, packet_len/codec_sample); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + log_printf(3, server.log, + "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", + woomera->interface,sangoma_frame_len, + sangoma_frame_len/codec_sample,packet_len); + + + if (++ms->udp_sync_cnt >= 6) { + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, 20); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + log_printf(0, server.log, + "%s: UDP TDM Period Force ReSync to 20ms \n", + woomera->interface); + } + + } +#endif + if (!server.out_tx_test) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=(sangoma_frame_len/codec_sample); + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + continue; + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } + + } + + if (server.out_tx_test && tx_fd && + fread((void*)udp_frame, + sizeof(char), + packet_len,tx_fd) <= 0) { + + sangoma_get_full_cfg(ms->sangoma_sock,&tdm_api); + fclose(tx_fd); + tx_fd=NULL; + } + +#ifdef WP_HPTDM_API + if (ms->tdmchan->push) { + ms->tdmchan->push(ms->tdmchan,udp_frame,packet_len); + } +#else + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + udp_frame, + packet_len, 0); +#endif + + } + +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + udp_cnt++; + if (udp_cnt && udp_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA UDP TX RX CNT %i %i\n", + woomera->interface,udp_cnt,packet_len); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media Thread: socket error !\n"); + } + } + + + + new_woomera_event_printf(&wevent, + "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Start-Time: %ld%s" + "End-Time: %ld%s" + "Answer-Time: %ld%s" + "Call-ID: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + woomera->session, + WOOMERA_LINE_SEPERATOR, + + time(&ms->started), + WOOMERA_LINE_SEPERATOR, + + time(NULL), + WOOMERA_LINE_SEPERATOR, + + time(&ms->answered), + WOOMERA_LINE_SEPERATOR, + + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + +media_thread_exit: + + if (woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + usleep(1000); + sched_yield(); + } + } + + + close_socket(&ms->udp_sock); + close_socket(&ms->sangoma_sock); + + if (tx_fd){ + fclose(tx_fd); + tx_fd=NULL; + } + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + + woomera_set_ms(woomera,NULL); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + + media_session_free(ms); + + log_printf(2, server.log, "MEDIA session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + + pthread_exit(NULL); + return NULL; +} + + + + +static void *media_tdm_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int res = 0; + //int tdm_cnt=0; + //wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + sangoma_api_hdr_t hdrframe; + + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || !woomera->interface) { + log_printf(2, server.log, "MEDIA TDM session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + pthread_exit(NULL); + return NULL; + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] started (ptr=%p)\n", + woomera->interface,woomera); + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + (res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } else if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "Media TDM Restart Failed%s\n", + woomera->interface); + break; + } + log_printf(0, server.log, "Media TDM Restart %s\n", + woomera->interface); + continue; + } else if (res < 0) { + log_printf(0, server.log, "Media TDM Sangoma Socket Error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM ReadMsg Error: %s\n", strerror(errno)); + break; + } + + res = sendto(ms->udp_sock, + circuit_frame, + res, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + if (res < 0) { + log_printf(2, server.log, "UDP Sento Error: %s\n", strerror(errno)); + break; + } +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + tdm_cnt++; + if (tdm_cnt && tdm_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA TDM TX RX CNT %i %i\n", + woomera->interface,tdm_cnt,res); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media TDM Thread: socket error !\n"); + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + + pthread_exit(NULL); + return NULL; + +} + + +/* This function must be called with process_lock + * because it modifies shared process_table */ + +static int launch_media_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms; + + if ((ms = media_session_new(woomera))) { + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_RUNNING); + result = pthread_create(&ms->thread, &attr, media_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(woomera->ms); + + } + pthread_attr_destroy(&attr); + + } else { + log_printf(0, server.log, "Failed to start new media session\n"); + } + + return result; + +} + +static int launch_media_tdm_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms = woomera_get_ms(woomera); + + if (!ms) { + return result; + } + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + result = pthread_create(&ms->thread, &attr, media_tdm_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + char callid[20]; + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + + if ((woomera = alloc_woomera())) { + + woomera->chan = event->chan; + woomera->span = event->span; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->loop_tdm=1; + + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + woomera_set_interface(woomera,callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = woomera; + pthread_mutex_unlock(&server.process_lock); + + if (launch_woomera_thread(woomera)) { + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + free(woomera); + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + return woomera; +} + +static int woomera_message_parse(struct woomera_interface *woomera, struct woomera_message *wmsg, int timeout) +{ + char *cur, *cr, *next = NULL, *eor = NULL; + char buf[2048]; + int res = 0, bytes = 0, sanity = 0; + struct timeval started, ended; + int elapsed, loops = 0; + int failto = 0; + int packet = 0; + + memset(wmsg, 0, sizeof(*wmsg)); + + if (woomera->socket < 0 ) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Invalid Socket! %d\n", + woomera->interface,woomera->socket); + return -1; + } + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP !\n", + woomera->interface); + return -1; + } + + gettimeofday(&started, NULL); + memset(buf, 0, sizeof(buf)); + + if (timeout < 0) { + timeout = abs(timeout); + failto = 1; + } else if (timeout == 0) { + timeout = -1; + } + + + while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) { + if (sanity > 1000) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Failed Sanity Check!\n[%s]\n\n", woomera->interface, buf); + return -1; + } + + if ((res = waitfor_socket(woomera->socket, 1000, POLLERR | POLLIN) > 0)) { + res = recv(woomera->socket, buf, sizeof(buf), MSG_PEEK); + + if (res > 1) { + packet++; + } + if (!strncmp(buf, WOOMERA_LINE_SEPERATOR, 2)) { + res = read(woomera->socket, buf, 2); + return 0; + } + if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + + } else if (res < 0) { + log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX + "%s error during packet retry (err=%i) Loops#%d (%s)\n", + woomera->interface, res, loops, + strerror(errno)); + return res; + } else if (loops) { + ysleep(100000); + } + } + + gettimeofday(&ended, NULL); + elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000)); + + if (res < 0) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Bad RECV\n", + woomera->interface); + return res; + } else if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } + + if (packet && loops > 150) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout waiting for packet.\n", + woomera->interface); + return -1; + } + + if (timeout > 0 && (elapsed > timeout)) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout [%d] reached\n", + woomera->interface, timeout); + return failto ? -1 : 0; + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)) { + /* BRB! we have an Event to deliver....*/ + return 0; + } + + /* what're we still doing here? */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + !woomera_test_flag(woomera, WFLAG_RUNNING)) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MASTER RUNNING or RUNNING!\n", woomera->interface); + return -1; + } + loops++; + } + + *eor = '\0'; + bytes = strlen(buf) + 4; + + memset(buf, 0, sizeof(buf)); + res = read(woomera->socket, buf, bytes); + next = buf; + + if (woomera->debug > 1) { + log_printf(3, woomera->log, "%s:WOOMERA RX MSG: %s\n",woomera->interface,buf); + + } + + while ((cur = next)) { + + if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) { + *cr = '\0'; + next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1); + if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) { + break; + } + } + if (!cur || !*cur) { + break; + } + + if (!wmsg->last) { + char *cmd, *id, *args; + woomera_set_flag(wmsg, MFLAG_EXISTS); + cmd = cur; + + if ((id = strchr(cmd, ' '))) { + *id = '\0'; + id++; + if ((args = strchr(id, ' '))) { + *args = '\0'; + args++; + strncpy(wmsg->command_args, args, sizeof(wmsg->command_args)-1); + } + strncpy(wmsg->callid, id, sizeof(wmsg->callid)-1); + } + + strncpy(wmsg->command, cmd, sizeof(wmsg->command)-1); + } else { + char *name, *val; + name = cur; + + if ((val = strchr(name, ':'))) { + *val = '\0'; + val++; + while (*val == ' ') { + *val = '\0'; + val++; + } + strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN); + } + strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN); + if (name && val && !strcasecmp(name, "content-type")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + if (name && val && !strcasecmp(name, "content-length")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + + + } + wmsg->last++; + } + + wmsg->last--; + + if (bytes && woomera_test_flag(wmsg, MFLAG_CONTENT)) { + read(woomera->socket, wmsg->body, + (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes); + } + + return woomera_test_flag(wmsg, MFLAG_EXISTS); + +} + +static struct woomera_interface *pull_from_holding_tank(int index, int span , int chan) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + + /* Block this index until the call is completed */ + server.holding_tank[index] = &woomera_dead_dev; + + woomera->timeout = 0; + woomera->index = 0; + woomera->span=span; + woomera->chan=chan; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static void clear_from_holding_tank(int index, struct woomera_interface *woomera) +{ + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] == &woomera_dead_dev) { + server.holding_tank[index] = NULL; + } else if (woomera && server.holding_tank[index] == woomera) { + server.holding_tank[index] = NULL; + } else if (server.holding_tank[index]) { + log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", + index, server.holding_tank[index]); + } + pthread_mutex_unlock(&server.ht_lock); + + return; +} + +static struct woomera_interface *peek_from_holding_tank(int index) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static int add_to_holding_tank(struct woomera_interface *woomera) +{ + int next, i, found=0; + + pthread_mutex_lock(&server.ht_lock); + + for (i=0;i= CORE_TANK_LEN) { + next = server.holding_tank_index = 1; + } + + if (next == 0) { + log_printf(0, server.log, "\nCritical Error on TANK INDEX == 0\n"); + continue; + } + + if (server.holding_tank[next]) { + continue; + } + + found=1; + break; + } + + if (!found) { + /* This means all tank vales are busy + * should never happend */ + pthread_mutex_unlock(&server.ht_lock); + log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); + return 0; + } + + server.holding_tank[next] = woomera; + woomera->timeout = time(NULL) + 100; + + pthread_mutex_unlock(&server.ht_lock); + return next; +} + +static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, + struct woomera_message *wmsg, + int media, int answer, int accept) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + + log_printf(4, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + + if (woomera_test_flag(woomera, WFLAG_HANGUP) || + !woomera_test_flag(woomera, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END)) { + + log_printf(2, server.log, + "ERROR! call was cancelled MEDIA on HANGUP or MEDIA END!\n"); + + woomera->timeout=0; + return -1; + } + + log_printf(3, server.log,"WOOMERA: GOT %s EVENT: [%s] RAW=%s\n", + wmsg->command,wmsg->callid,raw); + + + if (raw && + woomera->raw == NULL && + !woomera_test_flag(woomera, WFLAG_RAW_MEDIA_STARTED)) { + + woomera_set_flag(woomera, WFLAG_RAW_MEDIA_STARTED); + + woomera_set_raw(woomera, raw); + + if (launch_media_thread(woomera)) { + struct woomera_event wevent; + + log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + woomera->timeout=0; + return -1; + } + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + + } else { + + if (accept) { + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + } + + if (answer) { + struct media_session *ms; + + pthread_mutex_lock(&woomera->ms_lock); + if ((ms=woomera->ms)) { + time(&woomera->ms->answered); + } + pthread_mutex_unlock(&woomera->ms_lock); + + if (ms) { + + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_ANSWERED, + 0); + log_printf(2, server.log, + "Sent SIGBOOST_EVENT_CALL_ANSWERED [w%dg%d]\n", + woomera->span+1,woomera->chan+1); + } else { + struct woomera_event wevent; + log_printf(0, server.log, + "WOOMERA ANSWER: FAILED [%s] no Media \n", + wmsg->command,wmsg->callid); + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera->timeout=0; + return -1; + } + } + } + + { + struct woomera_event wevent; + new_woomera_event_printf(&wevent, "200 %s OK%s" + "Unique-Call-Id: %s%s", + answer ? "ANSWER" : + accept ? "ACCEPT" : "MEDIA", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + + return 0; +} + +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); +#ifdef SMG_CALLING_NAME + char *calling_name = woomera_message_header(wmsg, "local-name"); +#endif + char *presentation = woomera_message_header(wmsg, "Presentation"); + char *screening = woomera_message_header(wmsg, "Screening"); + char *rdnis = woomera_message_header(wmsg, "RDNIS"); + char *called = wmsg->callid; + char *grp = wmsg->callid; + char *p; + int cause = 34; + int tg = 0; + + if (smg_check_all_busy()) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, + "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); + log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", + server.call_count, server.all_ckt_busy); + return -1; + } + + log_printf(2, woomera->log, "New Call %d/%d\n", server.call_count, server.max_calls); + + if ((p = strchr(called, '/'))) { + *p = '\0'; + called = p+1; + tg = atoi(grp+1) - 1; + if (tg < 0) { + tg=0; + } + } + + woomera->trunk_group=tg; + + if (raw) { + woomera_set_raw(woomera, raw); + } + + woomera->index = add_to_holding_tank(woomera); + if (woomera->index < 1) { + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, + "405 SMG Server All Tanks Busy!%s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0, woomera->log, "Error: Call Tank Full (Call Cnt=%i)\n", + server.call_count); + return -1; + } + + + woomera->index_hold = woomera->index; + + call_signal_call_init(&event, calling, called, woomera->index); + + if (presentation) { + event.calling_number_presentation = atoi(presentation); + } else { + event.calling_number_presentation = 0; + } + + if (screening) { + event.calling_number_screening_ind = atoi(screening); + } else { + event.calling_number_screening_ind = 0; + } + + if (rdnis && strlen(rdnis)) { + strncpy((char*)event.redirection_string,rdnis, + sizeof(event.redirection_string)-1); + log_printf(3,server.log,"RDNIS %s\n", rdnis); + + } + +#ifdef SMG_CALLING_NAME + if (calling_name) { + strncpy((char*)event.calling_name,calling_name, + sizeof(event.calling_name)-1); + } +#endif + + event.trunk_group = tg; + + + if (call_signal_connection_write(&server.mcon, &event) <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, + "405 SMG Signalling Contestion!%s", + WOOMERA_RECORD_SEPERATOR); + return -1; + } + + socket_printf(woomera->socket, "100 Trying%s", WOOMERA_RECORD_SEPERATOR); + + log_printf(2, server.log, "Call Called Event [Setup ID: %d] TG=%d\n", + woomera->index,tg); + + return 0; +} + + +static void interpret_command(struct woomera_interface *woomera, struct woomera_message *wmsg) +{ + int answer = 0, media = 0, accept=0; + char *unique_id; + int cause=0; + + + + if (!strcasecmp(wmsg->command, "call")) { + int err; + if (strlen(woomera->session) != 0) { + /* Call has already been placed */ + socket_printf(woomera->socket, "400 Error Call already in progress %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0,server.log,"Woomera RX Call Even while call in progress!\n"); + return; + } + + err=handle_woomera_call_start(woomera,wmsg); + if (err) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + return; + + } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + if (cause) { + log_printf(3, woomera->log, "Bye Cause Received: [%s]\n", cause); + } + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + log_printf(2, woomera->log, "WOOMERA CMD: Bye Received: [%s]\n", woomera->interface); + + woomera_clear_flag(woomera, WFLAG_RUNNING); + socket_printf(woomera->socket, "200 Connection closed%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + + } else if (!strcasecmp(wmsg->command, "listen")) { + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + socket_printf(woomera->socket, "405 Listener already started%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + } else { + + woomera_set_flag(woomera, WFLAG_LISTENING); + add_listener(woomera); + + if (!strcmp(wmsg->callid,"MASTER")) { + woomera_set_flag(woomera, WFLAG_MASTER_DEV); + log_printf(0,woomera->log, "Starting MASTER Listen Device!\n"); + master_reset=0; + } + + + socket_printf(woomera->socket, "%s", + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "200 Listener enabled%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + } + return; + + } else if ((media = !strcasecmp(wmsg->command, "debug"))) { + + int debug_level=atoi(wmsg->callid); + + if (debug_level < 10) { + server.debug=debug_level; + log_printf(0,server.log,"SMG Debugging set to %i (window=%i)\n",server.debug,server.mcon.txwindow); + } + + return; + } + + + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); + if (!unique_id) { + + cause=111; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (strlen(woomera->session) == 0) { + struct woomera_interface *session_woomera=NULL; + char *session=NULL; + int span, chan; + char ifname[100]; + /* If session does not exist this is an incoming call */ + sscanf(unique_id, "w%dg%d", &span, &chan); + span--; + chan--; + + log_printf(3, woomera->log, + "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", + wmsg->command,span,chan,unique_id); + + if (smg_validate_span_chan(span,chan) != 0) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Invalid span/chan in session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2, woomera->log, + "WOOMERA Warning invalid span chan in session %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + pthread_mutex_lock(&server.process_lock); + session = server.process_table[span][chan].session; + session_woomera = server.process_table[span][chan].dev; + + if (session_woomera) { + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Session not found%s" + WOOMERA_RECORD_SEPERATOR); + + + log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (!session || strlen(session) == 0 || + strncmp(session,unique_id,sizeof(woomera->session))){ + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Invalid/Expired Session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(3, woomera->log, + "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", + wmsg->command,unique_id,session?session:"N/A"); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + server.process_table[span][chan].dev=woomera; + strncpy(woomera->session,unique_id,sizeof(woomera->session)); + sprintf(ifname,"w%dg%d",span+1,chan+1); + woomera_set_interface(woomera, ifname); + + woomera->span=span; + woomera->chan=chan; + + pthread_mutex_unlock(&server.process_lock); + + + log_printf(3, woomera->log, "WOOMERA Got New If=%s Session %s\n", + woomera->interface, woomera->session); + + + } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Session Mis-match%s" + WOOMERA_RECORD_SEPERATOR); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + + if (!strcasecmp(wmsg->command, "dtmf")) { + + log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", + woomera->interface, wmsg->command_args, wmsg->body); + + wanpipe_send_dtmf(woomera,wmsg->body); + + socket_printf(woomera->socket, "200 DTMF OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "hangup")) { + + int chan = -1, span = -1; + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + span=woomera->span; + chan=woomera->chan; + + log_printf(3, woomera->log, "WOOMERA CMD: Hangup Received: [%s] MEDIA EXIST Cause=%s\n", + woomera->interface,cause); + + if (smg_validate_span_chan(span,chan) != 0) { + + socket_printf(woomera->socket, "405 No Such Channel%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + } + + + log_printf(2, woomera->log, "Hangup Received: [w%dg%d]\n", + span+1,chan+1); + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + + socket_printf(woomera->socket, "200 HANGUP OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "proceed")) { + + log_printf(3, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + socket_printf(woomera->socket, + "200 %s PROCEED OK%s" + "Unique-Call-Id: %s%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + } else if ((media = !strcasecmp(wmsg->command, "media")) || + (answer = !strcasecmp(wmsg->command, "answer")) || + (accept = !strcasecmp(wmsg->command, "accept"))) { + + handle_woomera_media_accept_answer(woomera, wmsg, media,answer,accept); + + + + } else { + log_printf(0, server.log,"WOOMERA INVALID EVENT: %s [%s] \n", + wmsg->command,wmsg->callid); + socket_printf(woomera->socket, "501 Command '%s' not implemented%s", + wmsg->command, WOOMERA_RECORD_SEPERATOR); + } +} + + +/* + EVENT INCOMING 1 + Remote-Address: 10.3.3.104 + Remote-Number: + Remote-Name: Anthony Minessale!8668630501 + Protocol: H.323 + User-Agent: Post Increment Woomera 1.0alpha1 (OpenH323 v1.17.2) 9/61 + H323-Call-Id: 887b1ff8-bb1f-da11-85c0-0007e98988c4 + Local-Number: 996 + Start-Time: Fri, 09 Sep 2005 12:25:14 -0400 + Local-Name: root +*/ + + +static void handle_call_answer(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int kill = 0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + char callid[80]; + struct woomera_event wevent; + + if (!woomera->raw) { + log_printf(1, server.log, "Refusing to answer call with no media!\n"); + kill++; + goto handle_call_answer_end; + } + + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { + log_printf(1, server.log, "Refusing to double-answer a call!\n"); + kill++; + goto handle_call_answer_end; + } + + woomera_set_flag(woomera, WFLAG_ANSWER); + + if (woomera->span != event->span || woomera->chan != event->chan) { + log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); + kill++; + goto handle_call_answer_end; + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to answer a dead call!\n"); + kill++; + } else { + int err; + err=0; + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + woomera_set_interface(woomera, callid); +#ifndef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + + kill++; + } +#endif + + if (!kill) { + new_woomera_event_printf(&wevent, "EVENT CONNECT w%dg%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + } + } else { + log_printf(1, server.log, "Answer requested on non-existant session. [w%dg%d]\n", + event->span+1, event->chan+1); + kill++; + } + +handle_call_answer_end: + + if (kill) { + if (woomera) { + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to Answer without session [w%dg%d]\n", + event->span+1, event->chan+1); + } + } +} + +static void handle_call_start_ack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + struct woomera_event wevent; + int kill = 0; + + if ((woomera = peek_from_holding_tank(event->call_setup_id))) { + char callid[80]; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to ack a dead call!\n"); + kill++; + } else { + int err, span, chan; + + pull_from_holding_tank(event->call_setup_id,event->span,event->chan); + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + + span = event->span; + chan = event->chan; + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + woomera_set_interface(woomera, callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[span][chan].dev = woomera; + sprintf(woomera->session,"%s-%i-%i",callid,rand(),rand()); + sprintf(server.process_table[span][chan].session,"%s-%s", + callid,woomera->session); + pthread_mutex_unlock(&server.process_lock); + + + +#ifdef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id:%s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + kill++; + } +#endif + if (!kill) { + new_woomera_event_printf(&wevent, "201 Accepted%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Channel-Name: g%d/%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + log_printf(2, server.log, "Call Answered Event ID = %d Device = w%dg%d!\n", + event->call_setup_id,woomera->span+1,woomera->chan+1); + } + } + } else { + log_printf(1, server.log, + "Event (START ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id, event->call_setup_id,event->span+1, event->chan+1); + kill++; + } + + if (kill) { + if (woomera) { + woomera_set_flag(woomera,WFLAG_MEDIA_END); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(1, server.log, "Sent CALL STOP to CALL START ACK without session [w%dg%d]\n", + event->span+1, event->chan+1); + } + } +} + +static void handle_call_start_nack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int span=-1, chan=-1; + int ack=0; + + /* Always ACK the incoming NACK + * Send out the NACK ACK before pulling the TANK, because + * if we send after the pull, the outgoing call could send + * a message to boost with the pulled TANK value before + * we send a NACK ACK */ + + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + if (event->call_setup_id > 0) { + woomera=peek_from_holding_tank(event->call_setup_id); + } + + if (woomera) { + + struct woomera_event wevent; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", + event->call_setup_id); + ack++; + } else { + + woomera_set_cause_topbx(woomera,event->release_cause); + woomera_set_flag(woomera, (WFLAG_HANGUP|WFLAG_HANGUP_NACK_ACK)); + + new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + /* Do not ack here, let woomera thread ack it */ + ack=0; + } + + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hang up */ + woomera=NULL; + } else { + /* At this point call is already hang up */ + woomera=NULL; + } + } + + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + + log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + if (!woomera_test_flag(woomera,WFLAG_HANGUP)){ + woomera_set_cause_topbx(woomera,event->release_cause); + } + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + + /* Nack Ack will be sent by the woomera thread */ + ack=0; + } else { + /* Valid state when we are not in autoacm mode */ + ack++; + log_printf(3, server.log, "Event: NACK no woomera on span chan [w%dg%d]!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(0, server.log, + "Error: Start Nack Invalid State Should not happen [%d] [w%dg%d]!\n", + event->call_setup_id, event->span+1, event->chan+1); + ack++; + } + + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + log_printf(0, server.log, "WARNING: All ckt busy!\n"); + smg_all_ckt_busy(); + } + + +#warning "Ignoring CALL GAP" +#if 0 + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { + log_printf(0, server.log, "WARNING: Call Gapping Detected!\n"); + smg_all_ckt_gap(); + } +#endif + + if (ack) { + span=0; + chan=0; + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + isup_exec_command(span, + chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + if (!woomera) { + log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } + } +} + +static void handle_call_loop_start(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + + woomera=launch_woomera_loop_thread(event); + if (woomera == NULL) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + } + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + + return; +} + +static void handle_call_start(call_signal_event_t *event) +{ + struct woomera_event wevent; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(0, server.log, + "Sent (From Handle START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + pthread_mutex_unlock(&server.process_lock); + return; + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" + "Unique-Call-Id: %s%s" + "Remote-Number: %s%s" + "Remote-Name: %s%s" +#if defined(BRI_PROT) + "Protocol: BRI%s" +#else + "Protocol: SS7%s" +#endif + "User-Agent: sangoma_mgd%s" + "Local-Number: %s%s" + "Channel-Name: g%d/%d%s" + "Trunk-Group: %d%s" + "Presentation: %d%s" + "Screening: %d%s" + "RDNIS: %s%s" + , + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + session, + WOOMERA_LINE_SEPERATOR, + event->calling_number_digits, + WOOMERA_LINE_SEPERATOR, +#ifdef SMG_CALLING_NAME + event->calling_name, +#else + "", +#endif + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + event->called_number_digits, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + WOOMERA_LINE_SEPERATOR, + event->calling_number_presentation, + WOOMERA_LINE_SEPERATOR, + event->calling_number_screening_ind, + WOOMERA_LINE_SEPERATOR, + event->redirection_string, + WOOMERA_RECORD_SEPERATOR + ); + + if (!enqueue_event_on_listeners(&wevent)) { + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + } + + } + + destroy_woomera_event_data(&wevent); + +} + +static void handle_gap_abate(call_signal_event_t *event) +{ + log_printf(0, server.log, "NOTICE: GAP Cleared!\n", + event->span+1, event->chan+1); + smg_clear_ckt_gap(); +} + +static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_t *event) +{ + mcon->rxseq_reset =0; +} + +static void handle_call_stop(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + int ack=0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + if (woomera) { + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } else if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* At this point call is already hangup */ + woomera=NULL; + } else { + /* At this point call is already hangup */ + woomera=NULL; + } + } + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); + + /* We have to close the socket because + At this point we are release span chan */ + + log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + } else { + ack++; + } + + + if (ack) { + /* At this point we have already sent our STOP so its safe to ACK */ + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } + + if (!woomera){ + /* This is allowed on incoming call if remote app does not answer it */ + log_printf(3, server.log, "Event CALL STOP referrs to a non-existant session [w%dg%d]!\n", + event->span+1, event->chan+1); + } +} + +static void handle_heartbeat(call_signal_event_t *event) +{ + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + } else { + int err=call_signal_connection_write(&server.mcon, event); + if (err <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + } + } + return; +} + +static void handle_call_stop_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + log_printf(2, server.log, "Stop Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id, + woomera->interface); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + } else { + log_printf(2, server.log, "Event CALL_STOP_ACK(%d) referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->event_id, event->span+1, event->chan+1, event->call_setup_id); + } + + /* No need for us to do any thing here */ + return; +} + + +static void handle_call_start_nack_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + if ((woomera=pull_from_holding_tank(event->call_setup_id,-1,-1))) { + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else if (autoacm==0){ + log_printf(2, server.log, "Nack Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } else { + log_printf(0, server.log, + "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(2, server.log, + "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } + + if (event->call_setup_id > 0) { + clear_from_holding_tank(event->call_setup_id, NULL); + } + + /* No need for us to do any thing here */ + return; +} + +#if 0 +static void validate_number(unsigned char *s) +{ + unsigned char *p; + for (p = s; *p; p++) { + if (*p < 48 || *p > 57) { + log_printf(2, server.log, "Encountered a non-numeric character [%c]!\n", *p); + *p = '\0'; + break; + } + } +} +#endif + +static int parse_ss7_event(call_signal_connection_t *mcon, call_signal_event_t *event) +{ + int ret = 0; + +#if 0 + validate_number((unsigned char*)event->called_number_digits); + validate_number((unsigned char*)event->calling_number_digits); +#endif + +#if 1 + log_printf(2, server.log, + "RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + +#if 0 + log_printf(2, server.log, "RX EVENT\n"); + log_printf(2, server.log, "===================================\n"); + log_printf(2, server.log, " rType: %s (%0x HEX)\n", + call_signal_event_id_name(event->event_id),event->event_id); + log_printf(2, server.log, " rSpan: [%d]\n",event->span+1); + log_printf(2, server.log, " rChan: [%d]\n",event->chan+1); + log_printf(2, server.log, " rCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + log_printf(2, server.log, " rCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + log_printf(2, server.log, " rCause: %d\n",event->release_cause); + log_printf(2, server.log, " rInterface: [w%dg%d]\n",event->span+1,event->chan+1); + log_printf(2, server.log, " rEvent ID: [%d]\n",event->event_id); + log_printf(2, server.log, " rSetup ID: [%d]\n",event->call_setup_id); + log_printf(2, server.log, " rSeq: [%d]\n",event->fseqno); + log_printf(2, server.log, "===================================\n"); + +#endif + +#if 0 + log_printf(2, server.log, + "\nRX EVENT\n" + "===================================\n" + " rType: %s (%0x HEX)\n" + " rSpan: [%d]\n" + " rChan: [%d]\n" + " rCalledNum: %s\n" + " rCallingNum: %s\n" + " rCause: %s\n" + " rInterface : [w%dg%d]\n" + " rEvent ID : [%d]\n" + " rSetup ID: [%d]\n" + " rSeq: [%d]\n" + "===================================\n" + "\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), + release_to_string(event->release_cause), + event->span+1, + event->chan+1, + event->event_id, + event->call_setup_id, + event->fseqno + ); +#endif + + + switch(event->event_id) { + + case SIGBOOST_EVENT_CALL_START: + handle_call_start(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_CALL_START_ACK: + handle_call_start_ack(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK: + handle_call_start_nack(event); + break; + case SIGBOOST_EVENT_CALL_ANSWERED: + handle_call_answer(event); + break; + case SIGBOOST_EVENT_HEARTBEAT: + handle_heartbeat(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK_ACK: + handle_call_start_nack_ack(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED_ACK: + handle_call_stop_ack(event); + break; + case SIGBOOST_EVENT_INSERT_CHECK_LOOP: + handle_call_loop_start(event); + break; + case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: + handle_restart_ack(mcon,event); + break; + case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: + handle_gap_abate(event); + break; + default: + log_printf(0, server.log, "Warning no handler implemented for [%s]\n", + call_signal_event_id_name(event->event_id)); + break; + } + + return ret; +} + + +static void *monitor_thread_run(void *obj) +{ + int ss = 0; + int policy=0,priority=0; + char a=0,b=0; + call_signal_connection_t *mcon=&server.mcon; + call_signal_connection_t *mconp=&server.mconp; + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + + if (call_signal_connection_open(mcon, + mcon->cfg.local_ip, + mcon->cfg.local_port, + mcon->cfg.remote_ip, + mcon->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCON Socket [%d] %s\n", + mcon->socket,strerror(errno)); + exit(-1); + } + + if (call_signal_connection_open(mconp, + mconp->cfg.local_ip, + mconp->cfg.local_port, + mconp->cfg.remote_ip, + mconp->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCONP Socket [%d] %s\n", + mconp->socket,strerror(errno)); + exit(-1); + } + + mcon->log = server.log; + mconp->log = server.log; + + isup_exec_command(0, + 0, + -1, + SIGBOOST_EVENT_SYSTEM_RESTART, + 0); + + mcon->rxseq_reset=1; + + smg_get_current_priority(&policy,&priority); + + log_printf(1, server.log, "Open udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + log_printf(1, server.log, "Monitor Thread Started (%i:%i)\n",policy,priority); + + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { +#if 0 + ss = waitfor_socket(server.mcon.socket, 1000, POLLERR | POLLIN); +#else + ss = waitfor_2sockets(mcon->socket, + mconp->socket, + &a, &b, 1000); +#endif + + if (ss > 0) { + + call_signal_event_t *event=NULL; + int i=0; + + if (b) { +mcon_retry_priority: + if ((event = call_signal_connection_readp(mconp,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event P [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mconp,event); + if (++i < 10) { + goto mcon_retry_priority; + } + + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost P Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + i=0; + + if (a) { +mcon_retry: + if ((event = call_signal_connection_read(mcon,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mcon,event); + + if (++i < 50) { + goto mcon_retry; + } + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + } + + if (ss < 0){ + log_printf(0, server.log, "Thread Run: Select Socket Error!\n"); + break; + } + + } + + log_printf(1, server.log, "Close udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + call_signal_connection_close(&server.mcon); + call_signal_connection_close(&server.mconp); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + log_printf(0, server.log, "Monitor Thread Ended\n"); + + return NULL; +} + +static void woomera_loop_thread_run(struct woomera_interface *woomera) +{ + int err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log, "Failed to start loop media thread\n"); + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + return; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP)) { + + sleep(1); + continue; + + } + + woomera_clear_flag(woomera, WFLAG_RUNNING); + + log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); + + + + return; +} + +static void *woomera_thread_run(void *obj) +{ + struct woomera_interface *woomera = obj; + struct woomera_message wmsg; + struct woomera_event wevent; + char *event_string; + int mwi; + int err; + int policy=0, priority=0; + int span = -1, chan = -1; + + woomera_message_init(&wmsg); + + smg_get_current_priority(&policy,&priority); + + log_printf(2, server.log, "WOOMERA session started (ptr=%p : loop=%i)(%i:%i) Index=%i\n", + woomera,woomera->loop_tdm,policy,priority, woomera->index); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_mutex_init(&woomera->queue_lock, NULL); + pthread_mutex_init(&woomera->ms_lock, NULL); + pthread_mutex_init(&woomera->dtmf_lock, NULL); + pthread_mutex_init(&woomera->vlock, NULL); + pthread_mutex_init(&woomera->flags_lock, NULL); + + if (woomera->loop_tdm) { + woomera_loop_thread_run(woomera); + goto woomera_session_close; + } + + err=socket_printf(woomera->socket, + "EVENT HELLO Sangoma Media Gateway%s" + "Supported-Protocols: TDM%s" + "Version: %s%s" + "Remote-Address: %s%s" + "Remote-Port: %d%s" + "Raw-Format: %s%s", + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + SMG_VERSION, WOOMERA_LINE_SEPERATOR, + inet_ntoa(woomera->addr.sin_addr), WOOMERA_LINE_SEPERATOR, + ntohs(woomera->addr.sin_port), WOOMERA_LINE_SEPERATOR, + server.hw_coding?"ALAW":"ULAW", WOOMERA_RECORD_SEPERATOR + ); + + if (err) { + log_printf(0, server.log, "Woomera session socket failure! (ptr=%p)\n", + woomera); + woomera_clear_flag(woomera, WFLAG_RUNNING); + goto woomera_session_close; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + woomera_test_flag(woomera, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + !master_reset) { + + + mwi = woomera_message_parse(woomera, &wmsg, WOOMERA_HARD_TIMEOUT); + if (mwi >= 0) { + + if (mwi) { + interpret_command(woomera, &wmsg); + } else if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + if (socket_printf(woomera->socket, "%s", event_string)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + free(event_string); + log_printf(4, server.log, + "WOOMERA session (ptr=%p) print string error\n", + woomera); + break; + } + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + if (woomera->timeout > 0 && time(NULL) >= woomera->timeout) { + + /* Sent the hangup only after we sent a NACK */ + + log_printf(2, server.log, + "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", + woomera,woomera->interface,woomera->timeout); + + /* Let the Index check below send a NACK */ + if (woomera->index) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + break; + } + + } else { + log_printf(3, server.log, "WOOMERA session (ptr=%p) [%s] READ MSG Error %i \n", + woomera,woomera->interface,mwi); + break; + } + + } + +woomera_session_close: + + log_printf(2, server.log, "WOOMERA session (ptr=%p) is dying [%s]: SR=%d WR=%d WF=0x%04X\n", + woomera,woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_RUNNING), + woomera->flags); + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + usleep(100); + sched_yield(); + } + } + + + /*********************************************** + * Identify the SPAN CHAN to be used below + ***********************************************/ + + chan = woomera->chan; + span = woomera->span; + + + if (!woomera_test_flag(woomera, WFLAG_HANGUP)) { + + /* The call was not HUNGUP. This is the last check, + If the call is valid, hungup the call if the call + was never up the keep going */ + + + if (smg_validate_span_chan(span,chan) == 0) { + + if (!woomera->index) { + + if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + woomera->q931_rel_cause_tosig); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } + } else { + log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + + } + }else{ + /* This can happend if an outgoing call times out + or gets hungup before it gets acked. Its not a + failure */ + if (!woomera->index) { + + /* In this case we really failed to tx STOP */ + log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + + } + +woo_re_hangup: + + /* We must send a STOP ACK to boost telling it that we are done */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + + /* SMG received a HANGUP from boost. + We must now send back the ACK to the HANGUP. + Boost will not release channel until we + ACK the hangup */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Ack) to SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + }else{ + /* This should never happen! If it does + we broke protocol */ + log_printf(0, woomera->log, + "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + + /* SMG received a NACK from boost during call startup. + We must now send back the ACK to the NACK. + Boost will not release channel until we + ACK the NACK */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + woomera->index=0; + + } else if (woomera->index) { + isup_exec_command(0, + 0, + woomera->index, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + woomera->index=0; + + } else { + log_printf(0, woomera->log, + "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + } + + if (woomera->index) { + + int index = woomera->index; + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Timeout: %ld%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + woomera->timeout, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(18), + WOOMERA_LINE_SEPERATOR, + 18, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + + if (peek_from_holding_tank(index)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(0, + 0, + index, + SIGBOOST_EVENT_CALL_START_NACK, + 0); + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT); + + log_printf(2, woomera->log, + "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", + index); + } else { + log_printf(1, woomera->log, + "Error Failed to Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] - index stale!\n", + index); + } + } + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //30sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] ... \n", + woomera->index); + } + + if (overall_cnt > 10) { //300sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent HANGUP to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + log_printf(2, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i] ... \n", + woomera->interface,woomera->index_hold); + } + + if (overall_cnt > 10) { //100sec + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + server.process_table[span][chan].dev != woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + usleep(5000); + sched_yield(); + } + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + } + } + + /***************************************************** + * We must wait for WFLAG_WAIT_FOR_STOPPED_ACK here + * so that STOP_ACK can access the woomera + *****************************************************/ + + if (smg_validate_span_chan(span,chan) == 0) { + log_printf(2, woomera->log, + "WOOMERA Clearing Processs Table ... \n", + woomera->interface); + pthread_mutex_lock(&server.process_lock); + if (server.process_table[span][chan].dev == woomera){ + server.process_table[span][chan].dev = NULL; + memset(server.process_table[span][chan].session,0,SMG_SESSION_NAME_SZ); + } + pthread_mutex_unlock(&server.process_lock); + } + +#if 0 +//Used for testing + if (1) { + int chan = woomera->chan; + int span = woomera->span; + if (smg_validate_span_chan(span,chan) == 0) { + pthread_mutex_lock(&server.process_lock); + /* This is possible in case media thread dies on startup */ + + if (server.process_table[span][chan]){ + log_printf(0, server.log, + "Sanity Span Chan Still in use: [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + //server.process_table[span][chan] = NULL; + } + pthread_mutex_unlock(&server.process_lock); + } + } +#endif + + usleep(3000000); + + /* Sanity Check */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP ACK\n"); + goto woo_re_hangup; + } + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP NACK ACK\n"); + goto woo_re_hangup; + } + + /* This is where we actually pull the index + * out of the tank. We had to keep the tank + * value until the end of the call. Tank is only + * used on outgoing calls. */ + if (woomera->index_hold >= 1) { + clear_from_holding_tank(woomera->index_hold, woomera); + woomera->index_hold=0; + } + + log_printf(2, woomera->log, "Woomera Thread Finished %u\n", (unsigned long) woomera->thread); + close_socket(&woomera->socket); + woomera->socket=-1; + + /* delete queue */ + while ((event_string = dequeue_event(woomera))) { + free(event_string); + } + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + del_listener(woomera); + } + + log_printf(2, server.log, "WOOMERA session for [%s] stopped (ptr=%p)\n", + woomera->interface,woomera); + + if (woomera_test_flag(woomera, WFLAG_MASTER_DEV)) { + log_printf(0,server.log,"MASTER Thread Stopped (ptr=%p)\n",woomera); + master_reset=0; + } + + + pthread_mutex_destroy(&woomera->queue_lock); + pthread_mutex_destroy(&woomera->ms_lock); + pthread_mutex_destroy(&woomera->dtmf_lock); + pthread_mutex_destroy(&woomera->vlock); + pthread_mutex_destroy(&woomera->flags_lock); + woomera_set_raw(woomera, NULL); + woomera_set_interface(woomera, NULL); + + woomera_message_clear(&wmsg); + + free(woomera); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count--; + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_exit(NULL); + return NULL; +} + + +static int launch_woomera_thread(struct woomera_interface *woomera) +{ + int result = 0; + pthread_attr_t attr; + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_RUNNING); + result = pthread_create(&woomera->thread, &attr, woomera_thread_run, woomera); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! (%i) %s\n", + __FUNCTION__,result,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + +static int launch_monitor_thread(void) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 10; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + log_printf(0,server.log,"%s: Old Priority =%i res=%i \n",__FUNCTION__, + param.sched_priority,result); + + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + result = pthread_create(&server.monitor_thread, &attr, monitor_thread_run, NULL); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +#ifdef WP_HPTDM_API +static void *hp_tdmapi_span_run(void *obj) +{ + hp_tdm_api_span_t *span = obj; + int err; + + log_printf(0,server.log,"Starting %s span!\n",span->ifname); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + break; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + sleep(3); + log_printf(0,server.log,"Stopping %s span!\n",span->ifname); + + pthread_exit(NULL); +} + + +static int launch_hptdm_api_span_thread(int span) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 5; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + result = pthread_create(&server.monitor_thread, &attr, hp_tdmapi_span_run, &hptdmspan[span]); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} +#endif + +static int configure_server(void) +{ + struct woomera_config cfg; + char *var, *val; + int cnt = 0; + + server.dtmf_intr_ch = -1; + + if (!woomera_open_file(&cfg, server.config_file)) { + log_printf(0, server.log, "open of %s failed\n", server.config_file); + return 0; + } + + while (woomera_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(var, "boost_local_ip")) { + strncpy(server.mcon.cfg.local_ip, val, + sizeof(server.mcon.cfg.local_ip) -1); + strncpy(server.mconp.cfg.local_ip, val, + sizeof(server.mconp.cfg.local_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_local_port")) { + server.mcon.cfg.local_port = atoi(val); + server.mconp.cfg.local_port = + server.mcon.cfg.local_port+1; + cnt++; + } else if (!strcasecmp(var, "boost_remote_ip")) { + strncpy(server.mcon.cfg.remote_ip, val, + sizeof(server.mcon.cfg.remote_ip) -1); + strncpy(server.mconp.cfg.remote_ip, val, + sizeof(server.mconp.cfg.remote_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_remote_port")) { + server.mcon.cfg.remote_port = atoi(val); + server.mconp.cfg.remote_port = + server.mcon.cfg.remote_port+1; + cnt++; + } else if (!strcasecmp(var, "logfile_path")) { + if (!server.logfile_path) { + server.logfile_path = strdup(val); + } + } else if (!strcasecmp(var, "woomera_port")) { + server.port = atoi(val); + } else if (!strcasecmp(var, "debug_level")) { + server.debug = atoi(val); + } else if (!strcasecmp(var, "out_tx_test")) { + server.out_tx_test = atoi(val); + } else if (!strcasecmp(var, "loop_trace")) { + server.loop_trace = atoi(val); + } else if (!strcasecmp(var, "rxgain")) { + server.rxgain = atoi(val); + } else if (!strcasecmp(var, "txgain")) { + server.txgain = atoi(val); + } else if (!strcasecmp(var, "dtmf_on_duration")){ + server.dtmf_on = atoi(val); + } else if (!strcasecmp(var, "dtmf_off_duration")){ + server.dtmf_off = atoi(val); + } else if (!strcasecmp(var, "dtmf_inter_ch_duration")){ + server.dtmf_intr_ch = atoi(val); + } else if (!strcasecmp(var, "max_calls")) { + int max = atoi(val); + if (max > 0) { + server.max_calls = max; + } + } else if (!strcasecmp(var, "autoacm")) { + int max = atoi(val); + if (max >= 0) { + autoacm=max; + } + + } else if (!strcasecmp(var, "media_ip")) { + strncpy(server.media_ip, val, sizeof(server.media_ip) -1); + } else { + log_printf(0, server.log, "Invalid Option %s at line %d!\n", var, cfg.lineno); + } + } + + /* Post initialize */ + if (server.dtmf_on == 0){ + server.dtmf_on=SMG_DTMF_ON; + } + if (server.dtmf_off == 0) { + server.dtmf_off=SMG_DTMF_OFF; + } + if (server.dtmf_intr_ch == -1) { + server.dtmf_intr_ch = 0; + } + server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; + + log_printf(0,server.log, "DTMF On=%i Off=%i IntrCh=%i Size=%i\n", + server.dtmf_on,server.dtmf_off,server.dtmf_intr_ch,server.dtmf_size); + + woomera_close_file(&cfg); + return cnt == 4 ? 1 : 0; +} + + + +static int main_thread(void) +{ + + struct sockaddr_in sock_addr, client_addr; + struct woomera_interface *new_woomera; + int client_sock = -1, pid = 0; + unsigned int len = 0; + FILE *tmp; + + if ((server.master_connection.socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + log_printf(0, server.log, "socket() failed\n"); + return 1; + } + + memset(&sock_addr, 0, sizeof(sock_addr)); /* Zero out structure */ + sock_addr.sin_family = AF_INET; /* Internet address family */ + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + sock_addr.sin_port = htons(server.port); /* Local port */ + + /* Bind to the local address */ + if (bind(server.master_connection.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) { + log_printf(0, server.log, "bind(%d) failed\n", server.port); + return 1; + } + + /* Mark the socket so it will listen for incoming connections */ + if (listen(server.master_connection.socket, MAXPENDING) < 0) { + log_printf(0, server.log, "listen() failed\n"); + return 1; + } + + if ((pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "pid %d already exists.\n", pid); + exit(0); + } + + if (!(tmp = safe_fopen(PIDFILE, "w"))) { + log_printf(0, stderr, "Error creating pidfile %s\n", PIDFILE); + return 1; + } else { + fprintf(tmp, "%d", getpid()); + fclose(tmp); + tmp = NULL; + } + + no_nagle(server.master_connection.socket); + +#if 0 + if (1) { + int span,chan; + call_signal_event_t event; +#if 0 + span=1; + chan=30; + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); +#else + for (span=0;span<8;span++) { + for (chan=0;chan<31;chan++) { + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); + } + } +#endif + } +#endif + +#ifdef WP_HPTDM_API + if (1) { + int span; + for (span=0;span<16;span++) { + hptdmspan[span] = sangoma_hptdm_api_span_init(span); + if (!hptdmspan[span]) { + break; + } else { + log_printf(0, server.log, "HP TDM API Span: %d configured...\n", + span); + launch_hptdm_api_span_thread(span); + } + } + } +#endif + + log_printf(1, server.log, "Main Process Started: Woomera Ready port: %d\n", server.port); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + /* Set the size of the in-out parameter */ + len = sizeof(client_addr); + + /* Wait for a client to connect */ + if ((client_sock = accept(server.master_connection.socket, (struct sockaddr *) &client_addr, &len)) < 0) { + log_printf(0, server.log, "accpet() failed\n"); + return 1; + } + + if ((new_woomera = new_woomera_interface(client_sock, &client_addr, len))) { + log_printf(2, server.log, "Starting Thread for New Connection %s:%d Sock=%d\n", + inet_ntoa(new_woomera->addr.sin_addr), + ntohs(new_woomera->addr.sin_port), + client_sock); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count++; + pthread_mutex_unlock(&server.thread_count_lock); + if (launch_woomera_thread(new_woomera)) { + socket_printf(new_woomera->socket, + "501 call was cancelled!%s", + WOOMERA_RECORD_SEPERATOR); + + close_socket(&new_woomera->socket); + new_woomera->socket=-1; + free(new_woomera); + } + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + } + } + + log_printf(1, server.log, "Main Process End\n"); + + return 0; +} + +static int do_ignore(int sig) +{ + return 0; +} + +static int do_shut(int sig) +{ + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + close_socket(&server.master_connection.socket); + log_printf(1, server.log, "Caught SIG %d, Closing Master Socket!\n", sig); + return 0; +} + +static int sangoma_tdm_init (int span) +{ +#ifdef LIBSANGOMA_GET_HWCODING + wanpipe_tdm_api_t tdm_api; + int fd=sangoma_open_tdmapi_span(span); + if (fd < 0 ){ + return -1; + } else { + server.hw_coding=sangoma_tdm_get_hw_coding(fd,&tdm_api); + close_socket(&fd); + } +#else +#error "libsangoma missing hwcoding feature: not up to date!" +#endif + return 0; +} + + +static int woomera_startup(int argc, char **argv) +{ + int x = 0, pid = 0, bg = 0; + char *cfg=NULL, *debug=NULL, *arg=NULL; + + while((arg = argv[x++])) { + + if (!strcasecmp(arg, "-hup")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGHUP); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-term") || !strcasecmp(arg, "--term")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGTERM); + unlink(PIDFILE); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-version")) { + fprintf(stdout, "\nSangoma Media Gateway: Version %s\n\n", SMG_VERSION); + exit(0); + + } else if (!strcasecmp(arg, "-help")) { + fprintf(stdout, "%s\n%s [-help] | [ -version] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(0); + } else if (!strcasecmp(arg, "-wipe")) { + unlink(PIDFILE); + } else if (!strcasecmp(arg, "-bg")) { + bg = 1; + + } else if (!strcasecmp(arg, "-g")) { + coredump = 1; + + } else if (!strcasecmp(arg, "-debug")) { + if (argv[x] && *(argv[x]) != '-') { + debug = argv[x++]; + } + } else if (!strcasecmp(arg, "-cfg")) { + if (argv[x] && *(argv[x]) != '-') { + cfg = argv[x++]; + } + } else if (!strcasecmp(arg, "-log")) { + if (argv[x] && *(argv[x]) != '-') { + server.logfile_path = strdup(argv[x++]); + } + } else if (*arg == '-') { + log_printf(0, stderr, "Unknown Option %s\n", arg); + fprintf(stdout, "%s\n%s [-help] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(1); + } + } + + if (1){ + int spn; + for (spn=1;spn<=WOOMERA_MAX_SPAN;spn++) { + if (sangoma_tdm_init(spn) == 0) { + break; + } + } + if (spn>WOOMERA_MAX_SPAN) { + printf("\nError: Failed to access a channel on spans 1-16\n"); + printf(" Please start Wanpipe TDM API drivers\n"); + return 0; + } + } + + if (bg && (pid = fork())) { + log_printf(0, stderr, "Backgrounding!\n"); + return 0; + } + + q931_cause_setup(); + + server.port = 42420; + server.debug = 0; + strcpy(server.media_ip, "127.0.0.1"); + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + server.log = stdout; + server.master_connection.socket = -1; + server.master_connection.event_queue = NULL; + server.config_file = cfg ? cfg : "/etc/sangoma_mgd.conf"; + pthread_mutex_init(&server.listen_lock, NULL); + pthread_mutex_init(&server.ht_lock, NULL); + pthread_mutex_init(&server.process_lock, NULL); + pthread_mutex_init(&server.media_udp_port_lock, NULL); + pthread_mutex_init(&server.thread_count_lock, NULL); + pthread_mutex_init(&server.master_connection.queue_lock, NULL); + pthread_mutex_init(&server.master_connection.flags_lock, NULL); + pthread_mutex_init(&server.mcon.lock, NULL); + server.master_connection.chan = -1; + server.master_connection.span = -1; + + if (!configure_server()) { + log_printf(0, server.log, "configuration failed!\n"); + return 0; + } + +#ifndef USE_SYSLOG + if (server.logfile_path) { + if (!(server.log = safe_fopen(server.logfile_path, "a"))) { + log_printf(0, stderr, "Error setting logfile %s!\n", server.logfile_path); + server.log = stderr; + return 0; + } + } +#endif + + + if (debug) { + server.debug = atoi(debug); + } + + if (coredump) { + struct rlimit l; + memset(&l, 0, sizeof(l)); + l.rlim_cur = RLIM_INFINITY; + l.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &l)) { + log_printf(0, stderr, "Warning: Failed to disable core size limit: %s\n", + strerror(errno)); + } + } + +#ifdef __LINUX__ + if (geteuid() && coredump) { + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { + log_printf(0, stderr, "Warning: Failed to disable core size limit for non-root: %s\n", + strerror(errno)); + } + } +#endif + + + + (void) signal(SIGINT,(void *) do_shut); + (void) signal(SIGPIPE,(void *) do_ignore); + (void) signal(SIGHUP,(void *) do_shut); + + + woomera_set_flag(&server.master_connection, WFLAG_RUNNING); + if (launch_monitor_thread()) { + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + return 0; + } + + fprintf(stderr, "%s", WELCOME_TEXT); + log_printf(0, stderr, "Woomera STARTUP Complete. [AutoACM=%i]\n",autoacm); + + return 1; +} + +static int woomera_shutdown(void) +{ + char *event_string; + int told = 0, loops = 0; + + close_socket(&server.master_connection.socket); + pthread_mutex_destroy(&server.listen_lock); + pthread_mutex_destroy(&server.ht_lock); + pthread_mutex_destroy(&server.process_lock); + pthread_mutex_destroy(&server.media_udp_port_lock); + pthread_mutex_destroy(&server.thread_count_lock); + pthread_mutex_destroy(&server.master_connection.queue_lock); + pthread_mutex_destroy(&server.master_connection.flags_lock); + pthread_mutex_destroy(&server.mcon.lock); + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + + + if (server.logfile_path) { + free(server.logfile_path); + server.logfile_path = NULL; + } + + /* delete queue */ + while ((event_string = dequeue_event(&server.master_connection))) { + free(event_string); + } + + while(server.thread_count > 0) { + loops++; + + if (loops % 1000 == 0) { + told = 0; + } + + if (loops > 10000) { + log_printf(0, server.log, "Red Alert! threads did not stop\n"); + assert(server.thread_count == 0); + } + + if (told != server.thread_count) { + log_printf(1, server.log, "Waiting For %d thread%s.\n", + server.thread_count, server.thread_count == 1 ? "" : "s"); + told = server.thread_count; + } + ysleep(10000); + } + unlink(PIDFILE); + log_printf(0, stderr, "Woomera SHUTDOWN Complete.\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + + mlockall(MCL_FUTURE); + + + server.hw_coding=0; + + openlog (ps_progname ,LOG_PID, LOG_LOCAL2); + + if (! (ret = woomera_startup(argc, argv))) { + exit(0); + } + ret = main_thread(); + + woomera_shutdown(); + + return ret; +} + +/** EMACS ** + * Local variables: + * mode: C + * c-basic-offset: 4 + * End: + */ + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.14.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.14.tmp new file mode 100644 index 0000000..b20fd53 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.14.tmp @@ -0,0 +1,602 @@ +/********************************************************************************* + * sangoma_mgd.h -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-07, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * =============================================*/ + +#ifndef __SANGOMA_MGD_H_ +#define __SANGOMA_MGD_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef __LINUX__ +#include +#endif + + +#include +#include + + +#define WOOMERA_MAX_SPAN 16 +#define WOOMERA_MAX_CHAN 31 + +#define SMG_SESSION_NAME_SZ 100 +#define SMG_CHAN_NAME_SZ 20 + +#define PIDFILE "/var/run/sangoma_mgd.pid" +#define CORE_EVENT_LEN 512 +#define WOOMERA_STRLEN 256 +#define WOOMERA_ARRAY_LEN 50 +#define WOOMERA_BODYLEN 2048 +#define WOOMERA_MIN_MEDIA_PORT 9000 +#define WOOMERA_MAX_MEDIA_PORT 9899 +#define WOOMERA_HARD_TIMEOUT 0 +#define WOOMERA_LINE_SEPERATOR "\r\n" +#define WOOMERA_RECORD_SEPERATOR "\r\n\r\n" +#define WOOMERA_DEBUG_PREFIX "[DEBUG] " +#define WOOMERA_DEBUG_LINE "------------------------------------------------------------------------------------------------" + + + + + +#define STDERR fileno(stderr) +#define MAXPENDING 500 +#define MGD_STACK_SIZE 1024 * 240 + + +typedef enum { + WFLAG_RUNNING = (1 << 0), + WFLAG_LISTENING = (1 << 1), + WFLAG_MASTER_DEV = (1 << 2), + WFLAG_EVENT = (1 << 3), + WFLAG_MALLOC = (1 << 4), + WFLAG_MEDIA_RUNNING = (1 << 5), + WFLAG_MEDIA_END = (1 << 6), + WFLAG_MONITOR_RUNNING = (1 << 7), + WFLAG_HANGUP = (1 << 8), + WFLAG_ANSWER = (1 << 9), + WFLAG_MEDIA_TDM_RUNNING = (1 << 10), + WFLAG_HANGUP_ACK = (1 << 11), + WFLAG_HANGUP_NACK_ACK = (1 << 12), + WFLAG_WAIT_FOR_NACK_ACK = (1 << 13), + WFLAG_WAIT_FOR_STOPPED_ACK = (1 << 14), + WFLAG_RAW_MEDIA_STARTED = (1 << 15), + WFLAG_CALL_ACKED = (1 << 16), + WFLAG_WAIT_FOR_NACK_ACK_SENT = (1 << 17), + WFLAG_WAIT_FOR_STOPPED_ACK_SENT = (1 << 18), +} WFLAGS; + +typedef enum { + MFLAG_EXISTS = (1 << 0), + MFLAG_CONTENT = (1 << 1), +} MFLAGS; + +typedef enum { + EVENT_FREE_DATA = 1, + EVENT_KEEP_DATA = 0 +} event_args; + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...); + +#define ysleep(usec) sched_yield() ; usleep(usec); +#define log_printf(level, fp, fmt, ...) __log_printf(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) + + +#define woomera_test_flag(p,flag) ({ \ + ((p)->flags & (flag)); \ + }) + +#define _woomera_set_flag(p,flag) do { \ + ((p)->flags |= (flag)); \ + } while (0) + +#define _woomera_clear_flag(p,flag) do { \ + ((p)->flags &= ~(flag)); \ + } while (0) + +#define woomera_set_flag(p,flag) do { \ + pthread_mutex_lock(&(p)->flags_lock); \ + ((p)->flags |= (flag)); \ + pthread_mutex_unlock(&(p)->flags_lock); \ + } while (0) + +#define woomera_clear_flag(p,flag) do { \ + pthread_mutex_lock(&(p)->flags_lock); \ + ((p)->flags &= ~(flag)); \ + pthread_mutex_unlock(&(p)->flags_lock); \ + } while (0) + +#define woomera_copy_flags(dest,src,flagz) do { \ + pthread_mutex_lock(&(p)->flags_lock); \ + (dest)->flags &= ~(flagz); \ + (dest)->flags |= ((src)->flags & (flagz)); \ + pthread_mutex_unlock(&(p)->flags_lock); \ + } while (0) + + +struct media_session { + int udp_sock; + int sangoma_sock; + char *ip; + int port; + time_t started; + time_t answered; + pthread_t thread; + int socket; + struct woomera_interface *woomera; + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + struct hostent remote_hp; + struct hostent local_hp; + int skip_read_frames; + int skip_write_frames; + int hw_coding; + int udp_sync_cnt; + +#ifdef WP_HPTDM_API + hp_tdm_api_chan_t *tdmchan; +#endif + + teletone_dtmf_detect_state_t dtmf_detect; + teletone_generation_session_t tone_session; + switch_buffer_t *dtmf_buffer; + +}; + +struct woomera_message { + char callid[WOOMERA_STRLEN]; + char command[WOOMERA_STRLEN]; + char command_args[WOOMERA_STRLEN]; + char names[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN]; + char values[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN]; + char body[WOOMERA_BODYLEN]; + uint32_t flags; + pthread_mutex_t flags_lock; + int last; + struct woomera_message *next; +}; + +struct woomera_event { + char *data; + uint32_t flags; + struct woomera_event *next; +}; + +struct woomera_listener { + struct woomera_interface *woomera; + struct woomera_listener *next; +}; + +struct woomera_interface { + int socket; + char *raw; + char *interface; + time_t timeout; + struct sockaddr_in addr; + struct media_session *ms; + pthread_mutex_t queue_lock; + pthread_mutex_t ms_lock; + pthread_mutex_t dtmf_lock; + struct woomera_event *event_queue; + struct woomera_event *incoming_event_queue; + pthread_t thread; + uint32_t flags; + pthread_mutex_t flags_lock; + int debug; + int call_id; + FILE *log; + pthread_mutex_t vlock; + int index; + int index_hold; + int span; + int chan; + int trunk_group; + int call_count; + int q931_rel_cause_tosig; + int q931_rel_cause_topbx; + int loop_tdm; + char session[SMG_SESSION_NAME_SZ]; + struct woomera_interface *next; +}; + +struct woomera_session { + struct woomera_interface *dev; + char session[SMG_SESSION_NAME_SZ]; +}; + +#define CORE_TANK_LEN CORE_MAX_CHAN_PER_SPAN*CORE_MAX_SPANS + +struct woomera_server { + struct woomera_session process_table[CORE_MAX_CHAN_PER_SPAN][CORE_MAX_SPANS]; + struct woomera_interface *holding_tank[CORE_TANK_LEN]; + int holding_tank_index; + struct woomera_interface master_connection; + pthread_mutex_t listen_lock; + pthread_mutex_t ht_lock; + pthread_mutex_t process_lock; + pthread_mutex_t media_udp_port_lock; + pthread_mutex_t thread_count_lock; + call_signal_connection_t mcon; + call_signal_connection_t mconp; + struct woomera_listener *listeners; + char media_ip[WOOMERA_STRLEN]; + int port; + int next_media_port; + int debug; + int panic; + int thread_count; + char *logfile_path; + FILE *log; + char boost_local_ip[25]; + int boost_local_port; + char boost_remote_ip[25]; + int boost_remote_port; + pthread_t monitor_thread; + char *config_file; + int max_calls; + int call_count; + uint32_t out_tx_test; + uint32_t rxgain; + uint32_t txgain; + uint32_t hw_coding; + uint32_t loop_trace; + uint32_t hungup_waiting; + int all_ckt_gap; + int all_ckt_busy; + struct timeval all_ckt_busy_time; + int dtmf_on; + int dtmf_off; + int dtmf_intr_ch; + int dtmf_size; +} server; + +struct woomera_config { + FILE *file; + char *path; + char category[256]; + char buf[1024]; + int lineno; +}; + + +static inline void smg_get_current_priority(int *policy, int *priority) +{ + struct sched_param param; + pthread_getschedparam(pthread_self(), policy, ¶m); + *priority = param.sched_priority; + return; +} + +static inline int smg_calc_elapsed(struct timeval *started, struct timeval *ended) +{ + return (((ended->tv_sec * 1000) + ended->tv_usec / 1000) - + ((started->tv_sec * 1000) + started->tv_usec / 1000)); +} + +static inline int smg_check_all_busy(void) +{ + struct timeval ended; + int elapsed; + + if (server.all_ckt_gap) { + return server.all_ckt_gap; + } + + if (server.all_ckt_busy==0) { + return 0; + } + + gettimeofday(&ended,NULL); + elapsed = smg_calc_elapsed(&server.all_ckt_busy_time,&ended); + + /* seconds elapsed */ + if (elapsed > server.all_ckt_busy) { + server.all_ckt_busy=0; + return 0; + } else { + return 1; + } + +#if 0 + + if (server.all_ckt_busy > 50) { + /* When in GAP mode wait 10s */ + return server.all_ckt_busy; + } + + --server.all_ckt_busy; + if (server.all_ckt_busy < 0) { + server.all_ckt_busy=0; + } + + return server.all_ckt_busy; +#endif +} + + +static inline void smg_all_ckt_busy(void) +{ + + if (server.call_count*10 < 1500) { + server.all_ckt_busy+=1500; + } else { + server.all_ckt_busy+=server.call_count*15; + } +<<<<<<< .mine + +#if defined(BRI_PROT) + if (server.all_ckt_busy > 5000) { + server.all_ckt_busy = 5000; + } +#endif + +======= +>>>>>>> .r59 + + if (server.all_ckt_busy > 60000) { + server.all_ckt_busy = 60000; + } + +#if 0 + if (server.all_ckt_busy >= 5) { + server.all_ckt_busy=10; + } else if (server.all_ckt_busy >= 10) { + server.all_ckt_busy=15; + } else if (server.all_ckt_busy == 0) { + server.all_ckt_busy=5; + } +#endif + gettimeofday(&server.all_ckt_busy_time,NULL); +} + +static inline void smg_all_ckt_gap(void) +{ + server.all_ckt_gap=1; +} + +static inline void smg_clear_ckt_gap(void) +{ + server.all_ckt_gap=0; + gettimeofday(&server.all_ckt_busy_time,NULL); +} + + +static inline int smg_validate_span_chan(int span, int chan) +{ + if (span < 0 || span > WOOMERA_MAX_SPAN) { + return -1; + } + + if (chan < 0 || chan > WOOMERA_MAX_CHAN) { + return -1; + } + + return 0; +} + + +static inline void close_socket(int *sp) +{ + if (*sp > -1) { + close(*sp); + *sp = -1; + } +} + +static inline FILE *safe_fopen(char *path, char *flags) +{ + char buf[512] = ""; + + if (readlink(path, buf, sizeof(buf)) > 0) { + fprintf(stderr, "Symlinks not allowed! [%s] != [%s]\n", buf, path); + return NULL; + } + + return fopen(path, flags); + +} + +static inline int get_pid_from_file(char *path) +{ + FILE *tmp; + int pid; + + if (!(tmp = safe_fopen(path, "r"))) { + return 0; + } else { + fscanf(tmp, "%d", &pid); + fclose(tmp); + tmp = NULL; + } + + return pid; +} + + +static inline int woomera_open_file(struct woomera_config *cfg, char *path) +{ + FILE *f; + + if (!(f = fopen(path, "r"))) { + log_printf(0, stderr, "Cannot open file %s\n", path); + return 0; + } + + memset(cfg, 0, sizeof(*cfg)); + cfg->file = f; + cfg->path = path; + return 1; + +} + + +static inline void woomera_close_file(struct woomera_config *cfg) +{ + + if (cfg->file) { + fclose(cfg->file); + } + + memset(cfg, 0, sizeof(*cfg)); +} + + +static inline void woomera_message_init (struct woomera_message *wmsg) +{ + memset (wmsg,0,sizeof(struct woomera_message)); + pthread_mutex_init(&wmsg->flags_lock, NULL); +} + +static inline void woomera_message_clear (struct woomera_message *wmsg) +{ + pthread_mutex_destroy(&wmsg->flags_lock); +} + + +static inline void woomera_set_raw(struct woomera_interface *woomera, char *raw) +{ + char *oldraw=woomera->raw; + + if (raw) { + woomera->raw = strdup(raw); + } else { + woomera->raw = NULL; + } + + if (oldraw) { + free(oldraw); + } +} + +static inline struct media_session * woomera_get_ms(struct woomera_interface *woomera) +{ + struct media_session *ms; + pthread_mutex_lock(&woomera->ms_lock); + ms=woomera->ms; + pthread_mutex_unlock(&woomera->ms_lock); + return ms; +} + +static inline void woomera_set_ms(struct woomera_interface *woomera,struct media_session *ms) +{ + pthread_mutex_lock(&woomera->ms_lock); + woomera->ms=ms; + pthread_mutex_unlock(&woomera->ms_lock); + return; +} + +static inline void woomera_set_interface(struct woomera_interface *woomera, char *interface) +{ + char *iface = woomera->interface; + + if (interface) { + woomera->interface = strdup(interface); + } else { + woomera->interface = NULL; + } + + if (iface) { + free(iface); + } +} + +static inline void woomera_set_cause_tosig(struct woomera_interface *woomera, int cause) +{ + if (!cause) { + cause=SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + woomera->q931_rel_cause_tosig=cause; +} + +static inline void woomera_set_cause_topbx(struct woomera_interface *woomera, int cause) +{ + + if (!cause) { + cause=SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + cause=34; + } + + woomera->q931_rel_cause_topbx=cause; + +} + + +static inline struct woomera_event *new_woomera_event(void) +{ + struct woomera_event *event = NULL; + + if ((event = malloc(sizeof(*event)))) { + memset(event, 0, sizeof(*event)); + _woomera_set_flag(event, WFLAG_MALLOC); + } + + return event; +} + + +static inline void destroy_woomera_event_data(struct woomera_event *event) +{ + if (event->data) { + free (event->data); + event->data=NULL; + } +} + +static inline void destroy_woomera_event(struct woomera_event **event, event_args free_data) +{ + if (free_data) { + free ((*event)->data); + } + if (woomera_test_flag((*event), WFLAG_MALLOC)) { + free (*event); + *event = NULL; + } +} + + +/* disable nagle's algorythm */ +static inline void no_nagle(int socket) +{ + int flag = 1; + setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); +} + + + + +#endif + diff --git a/ssmg/sangoma_mgd.trunk/sangoma_mgd-2008-03-07.c b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.15.tmp similarity index 99% rename from ssmg/sangoma_mgd.trunk/sangoma_mgd-2008-03-07.c rename to ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.15.tmp index 83e4a35..c105874 100644 --- a/ssmg/sangoma_mgd.trunk/sangoma_mgd-2008-03-07.c +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.15.tmp @@ -189,7 +189,7 @@ static int tc = 0; hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; #endif -#undef SMG_CALLING_NAME +#define SMG_CALLING_NAME 1 const char WELCOME_TEXT[] = "================================================================================\n" @@ -3246,7 +3246,6 @@ static void handle_call_start_nack(call_signal_event_t *event) ack++; } - if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { log_printf(0, server.log, "WARNING: All ckt busy!\n"); smg_all_ckt_busy(); @@ -3376,7 +3375,11 @@ static void handle_call_start(call_signal_event_t *event) "Unique-Call-Id: %s%s" "Remote-Number: %s%s" "Remote-Name: %s%s" +#if defined(BRI_PROT) + "Protocol: BRI%s" +#else "Protocol: SS7%s" +#endif "User-Agent: sangoma_mgd%s" "Local-Number: %s%s" "Channel-Name: g%d/%d%s" @@ -3428,17 +3431,22 @@ static void handle_call_start(call_signal_event_t *event) -1, SIGBOOST_EVENT_CALL_STOPPED, SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } else { isup_exec_command(event->span, event->chan, -1, SIGBOOST_EVENT_CALL_START_NACK, SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + } - log_printf(0, server.log, - "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", - event->span+1, event->chan+1); } destroy_woomera_event_data(&wevent); @@ -3579,6 +3587,9 @@ static void handle_call_start_nack_ack(call_signal_event_t *event) if (woomera) { woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else if (autoacm==0){ + log_printf(2, server.log, "Nack Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id); } else { log_printf(0, server.log, "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.16.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.16.tmp new file mode 100644 index 0000000..41e24d0 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.16.tmp @@ -0,0 +1,600 @@ +/********************************************************************************* + * sangoma_mgd.h -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-07, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * =============================================*/ + +#ifndef __SANGOMA_MGD_H_ +#define __SANGOMA_MGD_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sangoma_mgd_memdbg.h" + +#ifdef __LINUX__ +#include +#endif + + +#include +#include + + +#define WOOMERA_MAX_SPAN 16 +#define WOOMERA_MAX_CHAN 31 + +#define SMG_SESSION_NAME_SZ 100 +#define SMG_CHAN_NAME_SZ 20 + +#define PIDFILE "/var/run/sangoma_mgd.pid" +#define CORE_EVENT_LEN 512 +#define WOOMERA_STRLEN 256 +#define WOOMERA_ARRAY_LEN 50 +#define WOOMERA_BODYLEN 2048 +#define WOOMERA_MIN_MEDIA_PORT 9000 +#define WOOMERA_MAX_MEDIA_PORT 9899 +#define WOOMERA_HARD_TIMEOUT 0 +#define WOOMERA_LINE_SEPERATOR "\r\n" +#define WOOMERA_RECORD_SEPERATOR "\r\n\r\n" +#define WOOMERA_DEBUG_PREFIX "[DEBUG] " +#define WOOMERA_DEBUG_LINE "------------------------------------------------------------------------------------------------" + + + + +#define STDERR fileno(stderr) +#define MAXPENDING 500 +#define MGD_STACK_SIZE 1024 * 240 + + +typedef enum { + WFLAG_RUNNING = (1 << 0), + WFLAG_LISTENING = (1 << 1), + WFLAG_MASTER_DEV = (1 << 2), + WFLAG_EVENT = (1 << 3), + WFLAG_MALLOC = (1 << 4), + WFLAG_MEDIA_RUNNING = (1 << 5), + WFLAG_MEDIA_END = (1 << 6), + WFLAG_MONITOR_RUNNING = (1 << 7), + WFLAG_HANGUP = (1 << 8), + WFLAG_ANSWER = (1 << 9), + WFLAG_MEDIA_TDM_RUNNING = (1 << 10), + WFLAG_HANGUP_ACK = (1 << 11), + WFLAG_HANGUP_NACK_ACK = (1 << 12), + WFLAG_WAIT_FOR_NACK_ACK = (1 << 13), + WFLAG_WAIT_FOR_STOPPED_ACK = (1 << 14), + WFLAG_RAW_MEDIA_STARTED = (1 << 15), + WFLAG_CALL_ACKED = (1 << 16), + WFLAG_WAIT_FOR_NACK_ACK_SENT = (1 << 17), + WFLAG_WAIT_FOR_STOPPED_ACK_SENT = (1 << 18), +} WFLAGS; + +typedef enum { + MFLAG_EXISTS = (1 << 0), + MFLAG_CONTENT = (1 << 1), +} MFLAGS; + +typedef enum { + EVENT_FREE_DATA = 1, + EVENT_KEEP_DATA = 0 +} event_args; + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...); + +#define ysleep(usec) sched_yield() ; usleep(usec); +#define log_printf(level, fp, fmt, ...) __log_printf(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) + + +#define woomera_test_flag(p,flag) ({ \ + ((p)->flags & (flag)); \ + }) + +#define _woomera_set_flag(p,flag) do { \ + ((p)->flags |= (flag)); \ + } while (0) + +#define _woomera_clear_flag(p,flag) do { \ + ((p)->flags &= ~(flag)); \ + } while (0) + +#define woomera_set_flag(p,flag) do { \ + pthread_mutex_lock(&(p)->flags_lock); \ + ((p)->flags |= (flag)); \ + pthread_mutex_unlock(&(p)->flags_lock); \ + } while (0) + +#define woomera_clear_flag(p,flag) do { \ + pthread_mutex_lock(&(p)->flags_lock); \ + ((p)->flags &= ~(flag)); \ + pthread_mutex_unlock(&(p)->flags_lock); \ + } while (0) + +#define woomera_copy_flags(dest,src,flagz) do { \ + pthread_mutex_lock(&(p)->flags_lock); \ + (dest)->flags &= ~(flagz); \ + (dest)->flags |= ((src)->flags & (flagz)); \ + pthread_mutex_unlock(&(p)->flags_lock); \ + } while (0) + + +struct media_session { + int udp_sock; + int sangoma_sock; + char *ip; + int port; + time_t started; + time_t answered; + pthread_t thread; + int socket; + struct woomera_interface *woomera; + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + struct hostent remote_hp; + struct hostent local_hp; + int skip_read_frames; + int skip_write_frames; + int hw_coding; + int udp_sync_cnt; + +#ifdef WP_HPTDM_API + hp_tdm_api_chan_t *tdmchan; +#endif + + teletone_dtmf_detect_state_t dtmf_detect; + teletone_generation_session_t tone_session; + switch_buffer_t *dtmf_buffer; + +}; + +struct woomera_message { + char callid[WOOMERA_STRLEN]; + char command[WOOMERA_STRLEN]; + char command_args[WOOMERA_STRLEN]; + char names[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN]; + char values[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN]; + char body[WOOMERA_BODYLEN]; + uint32_t flags; + pthread_mutex_t flags_lock; + int last; + struct woomera_message *next; +}; + +struct woomera_event { + char *data; + uint32_t flags; + struct woomera_event *next; +}; + +struct woomera_listener { + struct woomera_interface *woomera; + struct woomera_listener *next; +}; + +struct woomera_interface { + int socket; + char *raw; + char *interface; + time_t timeout; + struct sockaddr_in addr; + struct media_session *ms; + pthread_mutex_t queue_lock; + pthread_mutex_t ms_lock; + pthread_mutex_t dtmf_lock; + struct woomera_event *event_queue; + struct woomera_event *incoming_event_queue; + pthread_t thread; + uint32_t flags; + pthread_mutex_t flags_lock; + int debug; + int call_id; + FILE *log; + pthread_mutex_t vlock; + int index; + int index_hold; + int span; + int chan; + int trunk_group; + int call_count; + int q931_rel_cause_tosig; + int q931_rel_cause_topbx; + int loop_tdm; + char session[SMG_SESSION_NAME_SZ]; + struct woomera_interface *next; +}; + +struct woomera_session { + struct woomera_interface *dev; + char session[SMG_SESSION_NAME_SZ]; +}; + +#define CORE_TANK_LEN CORE_MAX_CHAN_PER_SPAN*CORE_MAX_SPANS + +struct woomera_server { + struct woomera_session process_table[CORE_MAX_CHAN_PER_SPAN][CORE_MAX_SPANS]; + struct woomera_interface *holding_tank[CORE_TANK_LEN]; + int holding_tank_index; + struct woomera_interface master_connection; + pthread_mutex_t listen_lock; + pthread_mutex_t ht_lock; + pthread_mutex_t process_lock; + pthread_mutex_t media_udp_port_lock; + pthread_mutex_t thread_count_lock; + call_signal_connection_t mcon; + call_signal_connection_t mconp; + struct woomera_listener *listeners; + char media_ip[WOOMERA_STRLEN]; + int port; + int next_media_port; + int debug; + int panic; + int thread_count; + char *logfile_path; + FILE *log; + char boost_local_ip[25]; + int boost_local_port; + char boost_remote_ip[25]; + int boost_remote_port; + pthread_t monitor_thread; + char *config_file; + int max_calls; + int call_count; + uint32_t out_tx_test; + uint32_t rxgain; + uint32_t txgain; + uint32_t hw_coding; + uint32_t loop_trace; + uint32_t hungup_waiting; + int all_ckt_gap; + int all_ckt_busy; + struct timeval all_ckt_busy_time; + int dtmf_on; + int dtmf_off; + int dtmf_intr_ch; + int dtmf_size; + int strip_cid_non_digits; +} server; + +struct woomera_config { + FILE *file; + char *path; + char category[256]; + char buf[1024]; + int lineno; +}; + + +static inline void smg_get_current_priority(int *policy, int *priority) +{ + struct sched_param param; + pthread_getschedparam(pthread_self(), policy, ¶m); + *priority = param.sched_priority; + return; +} + +static inline int smg_calc_elapsed(struct timeval *started, struct timeval *ended) +{ + return (((ended->tv_sec * 1000) + ended->tv_usec / 1000) - + ((started->tv_sec * 1000) + started->tv_usec / 1000)); +} + +static inline int smg_check_all_busy(void) +{ + struct timeval ended; + int elapsed; + + if (server.all_ckt_gap) { + return server.all_ckt_gap; + } + + if (server.all_ckt_busy==0) { + return 0; + } + + gettimeofday(&ended,NULL); + elapsed = smg_calc_elapsed(&server.all_ckt_busy_time,&ended); + + /* seconds elapsed */ + if (elapsed > server.all_ckt_busy) { + server.all_ckt_busy=0; + return 0; + } else { + return 1; + } + +#if 0 + + if (server.all_ckt_busy > 50) { + /* When in GAP mode wait 10s */ + return server.all_ckt_busy; + } + + --server.all_ckt_busy; + if (server.all_ckt_busy < 0) { + server.all_ckt_busy=0; + } + + return server.all_ckt_busy; +#endif +} + + +static inline void smg_all_ckt_busy(void) +{ + + if (server.call_count*10 < 1500) { + server.all_ckt_busy+=1500; + } else { + server.all_ckt_busy+=server.call_count*15; + } +#if defined(BRI_PROT) + if (server.all_ckt_busy > 5000) { + server.all_ckt_busy = 5000; + } +#endif + + if (server.all_ckt_busy > 60000) { + server.all_ckt_busy = 60000; + } + +#if 0 + if (server.all_ckt_busy >= 5) { + server.all_ckt_busy=10; + } else if (server.all_ckt_busy >= 10) { + server.all_ckt_busy=15; + } else if (server.all_ckt_busy == 0) { + server.all_ckt_busy=5; + } +#endif + gettimeofday(&server.all_ckt_busy_time,NULL); +} + +static inline void smg_all_ckt_gap(void) +{ + server.all_ckt_gap=1; +} + +static inline void smg_clear_ckt_gap(void) +{ + server.all_ckt_gap=0; + gettimeofday(&server.all_ckt_busy_time,NULL); +} + + +static inline int smg_validate_span_chan(int span, int chan) +{ + if (span < 0 || span > WOOMERA_MAX_SPAN) { + return -1; + } + + if (chan < 0 || chan > WOOMERA_MAX_CHAN) { + return -1; + } + + return 0; +} + + +static inline void close_socket(int *sp) +{ + if (*sp > -1) { + close(*sp); + *sp = -1; + } +} + +static inline FILE *safe_fopen(char *path, char *flags) +{ + char buf[512] = ""; + + if (readlink(path, buf, sizeof(buf)) > 0) { + fprintf(stderr, "Symlinks not allowed! [%s] != [%s]\n", buf, path); + return NULL; + } + + return fopen(path, flags); + +} + +static inline int get_pid_from_file(char *path) +{ + FILE *tmp; + int pid; + + if (!(tmp = safe_fopen(path, "r"))) { + return 0; + } else { + fscanf(tmp, "%d", &pid); + fclose(tmp); + tmp = NULL; + } + + return pid; +} + + +static inline int woomera_open_file(struct woomera_config *cfg, char *path) +{ + FILE *f; + + if (!(f = fopen(path, "r"))) { + log_printf(0, stderr, "Cannot open file %s\n", path); + return 0; + } + + memset(cfg, 0, sizeof(*cfg)); + cfg->file = f; + cfg->path = path; + return 1; + +} + + +static inline void woomera_close_file(struct woomera_config *cfg) +{ + + if (cfg->file) { + fclose(cfg->file); + } + + memset(cfg, 0, sizeof(*cfg)); +} + + +static inline void woomera_message_init (struct woomera_message *wmsg) +{ + memset (wmsg,0,sizeof(struct woomera_message)); + pthread_mutex_init(&wmsg->flags_lock, NULL); +} + +static inline void woomera_message_clear (struct woomera_message *wmsg) +{ + pthread_mutex_destroy(&wmsg->flags_lock); +} + + +static inline void woomera_set_raw(struct woomera_interface *woomera, char *raw) +{ + char *oldraw=woomera->raw; + + if (raw) { + woomera->raw = smg_strdup(raw); + } else { + woomera->raw = NULL; + } + + if (oldraw) { + smg_free(oldraw); + } +} + +static inline struct media_session * woomera_get_ms(struct woomera_interface *woomera) +{ + struct media_session *ms; + pthread_mutex_lock(&woomera->ms_lock); + ms=woomera->ms; + pthread_mutex_unlock(&woomera->ms_lock); + return ms; +} + +static inline void woomera_set_ms(struct woomera_interface *woomera,struct media_session *ms) +{ + pthread_mutex_lock(&woomera->ms_lock); + woomera->ms=ms; + pthread_mutex_unlock(&woomera->ms_lock); + return; +} + +static inline void woomera_set_interface(struct woomera_interface *woomera, char *interface) +{ + char *iface = woomera->interface; + + if (interface) { + woomera->interface = smg_strdup(interface); + } else { + woomera->interface = NULL; + } + + if (iface) { + smg_free(iface); + } +} + +static inline void woomera_set_cause_tosig(struct woomera_interface *woomera, int cause) +{ + if (!cause) { + cause=SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + woomera->q931_rel_cause_tosig=cause; +} + +static inline void woomera_set_cause_topbx(struct woomera_interface *woomera, int cause) +{ + + if (!cause) { + cause=SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + cause=34; + } + + woomera->q931_rel_cause_topbx=cause; + +} + + +static inline struct woomera_event *new_woomera_event(void) +{ + struct woomera_event *event = NULL; + + if ((event = smg_malloc(sizeof(*event)))) { + memset(event, 0, sizeof(*event)); + _woomera_set_flag(event, WFLAG_MALLOC); + } + + return event; +} + + +static inline void destroy_woomera_event_data(struct woomera_event *event) +{ + if (event->data) { + smg_free (event->data); + event->data=NULL; + } +} + +static inline void destroy_woomera_event(struct woomera_event **event, event_args free_data) +{ + if (free_data) { + smg_free ((*event)->data); + } + + (*event)->data=NULL; + if (woomera_test_flag((*event), WFLAG_MALLOC)) { + smg_free (*event); + *event = NULL; + } +} + + +/* disable nagle's algorythm */ +static inline void no_nagle(int socket) +{ + int flag = 1; + setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); +} + + + + +#endif + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.17.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.17.tmp new file mode 100644 index 0000000..3deebd9 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.17.tmp @@ -0,0 +1,119 @@ +################################################################################ +# Sangoma MGD +# +# Author: Anthony Minessale II +# Nenad Corbic +# +# Copyright: (c) 2005 Anthony Minessale II +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. +################################################################################ + +SMG_DTMF=YES + +#Default kernel directory to be overwritten by user +#Kernel version and location +ifndef KVER + KVER=$(shell uname -r) +endif +ifndef KMOD + KMOD=/lib/modules/$(KVER) +endif +ifndef KDIR + KDIR=$(KMOD)/build +endif +ifndef KINSTDIR + KINSTDIR=$(KMOD)/kernel +endif + +CC = gcc +INSTALLPREFIX= + +INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src + +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 +CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g +LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm + +#Enable memory leak subsystem +#Not to be used in production +#CFLAGS += -DSMG_MEMORY_DEBUG + + +ifeq "${SMG_DTMF}" "YES" +LDFLAGS+= -lteletone +CFLAGS+= -DSMG_DTMF_ENABLE +endif + + +all: sangoma_mgd + +libs: + $(shell cd lib/libteletone; ./configure --prefix=$(INSTALLPREFIX); cd ../../; ) + $(MAKE) -C lib/libteletone all + +switch_buffer.o: switch_buffer.c switch_buffer.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o switch_buffer.o switch_buffer.c + +call_signal.o: call_signal.c call_signal.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o call_signal.o call_signal.c + +sangoma_mgd_memdbg.o: sangoma_mgd_memdbg.c sangoma_mgd_memdbg.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o sangoma_mgd_memdbg.o sangoma_mgd_memdbg.c + +sangoma_mgd.o: sangoma_mgd.c sangoma_mgd.h sigboost.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o sangoma_mgd.o sangoma_mgd.c + +sangoma_mgd: sangoma_mgd.o sangoma_mgd_memdbg.o call_signal.o switch_buffer.o sigboost.h sangoma_mgd_memdbg.h + rm -fr core* + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -o sangoma_mgd sangoma_mgd.o sangoma_mgd_memdbg.o switch_buffer.o call_signal.o $(LDFLAGS) + + + +clean: old_cleanup + make -C lib/libteletone clean + find . -name '*.o' | xargs rm -f + rm -fr sangoma_mgd pritest *.o *.so *~ *core* *.so* *.a + +distclean: clean + @echo OK + +install: all install_smg old_cleanup + +install_smg: old_cleanup + install -D -m 755 sangoma_mgd $(INSTALLPREFIX)/usr/sbin/sangoma_mgd + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi +ifeq "${NO_SS7}" "YES" + @echo "BRI control scripts installed" + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample.bri $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi + install -D -m 755 ../sangoma_bri/smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl +else + @echo "SS7 control scripts installed" + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample.ss7 $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi + install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/usr/sbin/smgss7_init_ctrl + +endif + @echo "sangoma_mgd Installed" + +old_cleanup: + ./scripts/old_cleanup.sh + + +install_all: all install_smg + +uninstall: + /bin/rm $(INSTALLPREFIX)/usr/sbin/sangoma_mgd $(INSTALLPREFIX)/etc/sangoma_mgd.conf + + + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.2.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.2.tmp index 9bc5b49..2d0c940 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.2.tmp +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.2.tmp @@ -1,108 +1,4711 @@ -################################################################################ -# Sangoma MGD -# -# Author: Anthony Minessale II -# Nenad Corbic -# -# Copyright: (c) 2005 Anthony Minessale II -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -################################################################################ +/********************************************************************************* + * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-07, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * ============================================= + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + *********************************************************************************/ + +#include "sangoma_mgd.h" +#include "q931_cause.h" + + +#define USE_SYSLOG 1 +#define CODEC_LAW_DEFAULT 1 + +#ifdef CODEC_LAW_DEFAULT +static uint32_t codec_sample=8; +#else +static uint32_t codec_sample=16; +#endif + +static char ps_progname[]="sangoma_mgd"; + +static struct woomera_interface woomera_dead_dev; + +#if 0 +#define DOTRACE +#endif + + +#define SMG_VERSION "v1.19" + +/* enable early media */ +#if 1 +#define WOOMERA_EARLY_MEDIA 1 +#endif + + +#define SMG_DTMF_ON 60 +#define SMG_DTMF_OFF 10 +#define SMG_DTMF_RATE 8000 + +#if 0 +#warning "NENAD: MEDIA SHUTDOWN" +#define MEDIA_SOCK_SHUTDOWN 1 +#endif + + +#ifdef DOTRACE +static int tc = 0; +#endif + +#if 0 +#warning "NENAD: HPTDM API" +#define WP_HPTDM_API 1 +#else +#undef WP_HPTDM_API +#endif + +#ifdef WP_HPTDM_API +hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; +#endif + +const char WELCOME_TEXT[] = +"================================================================================\n" +"Sangoma Media Gateway Daemon v1.19 \n" +"TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" +"Copyright 2005, 2006, 2007 \n" +"Nenad Corbic , Anthony Minessale II \n" +"This program is free software, distributed under the terms of\n" +"the GNU General Public License\n" +"================================================================================\n" +""; + + +static int master_reset=0; + +static int coredump=1; + +static int launch_media_tdm_thread(struct woomera_interface *woomera); +static int launch_woomera_thread(struct woomera_interface *woomera); +static struct woomera_interface *alloc_woomera(void); + +q931_cause_to_str_array_t q931_cause_to_str_array[255]; + + +#if 0 +static uint32_t string_to_release(char *code) +{ + if (code) { + if (!strcasecmp(code, "CHANUNAVAIL")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "INVALID")) { + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "ERROR")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + if (!strcasecmp(code, "CONGESTION")) { + //return SIGBOOST_RELEASE_CAUSE_BUSY; + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "BUSY")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "NOANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "ANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (!strcasecmp(code, "CANCEL")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "UNKNOWN")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + } + return SIGBOOST_RELEASE_CAUSE_NORMAL; +} + +static char * release_to_string(uint32_t rel_cause) +{ + switch (rel_cause) { + + case SIGBOOST_RELEASE_CAUSE_UNDEFINED: + return "UNKNOWN"; + case SIGBOOST_RELEASE_CAUSE_NORMAL: + return "NORMAL"; + case SIGBOOST_RELEASE_CAUSE_BUSY: + return "BUSY"; + case SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST: + return "CHANUNAVAIL"; + case SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET: + return "CANCEL"; + case SIGBOOST_RELEASE_CAUSE_NOANSWER: + return "NOANSWER"; + case SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT: + return "TIMEOUT"; + case SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY: + return "CONGESTION"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL: + return "ERROR"; + } + + return "NORMAL"; +} +#endif + + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return; + } + + if (level && level > server.debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + } else { + char date[80] = ""; + struct tm now; + time_t epoch; + + if (time(&epoch) && localtime_r(&epoch, &now)) { + strftime(date, sizeof(date), "%Y-%m-%d %T", &now); + } + +#ifdef USE_SYSLOG + syslog(LOG_DEBUG | LOG_LOCAL2, data); +#else + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + + + + +static int isup_exec_command(int span, int chan, int id, int cmd, int cause) +{ + call_signal_event_t oevent; + int retry=5; + + call_signal_event_init(&oevent, cmd, chan, span); + oevent.release_cause = cause; + + if (id >= 0) { + oevent.call_setup_id = id; + } +isup_exec_cmd_retry: + if (call_signal_connection_write(&server.mcon, &oevent) <= 0){ + + --retry; + if (retry <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket: %s\n", + strerror(errno)); + return -1; + } else { + log_printf(0, server.log, + "System Warning: Failed to tx on ISUP socket: %s :retry %i\n", + strerror(errno),retry); + } + + goto isup_exec_cmd_retry; + } + + return 0; +} + +static int socket_printf(int socket, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return -1; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + log_printf(0, server.log, "Crtical ERROR: Memory Error!\n"); + } else { + int err; + int len = strlen(data); + err=send(socket, data, strlen(data), 0); + if (err != strlen(data)) { + log_printf(2, server.log, "ERROR: Failed to send data to woomera socket(%i): err=%i len=%d %s\n", + socket,err,len,strerror(errno)); + ret = err; + } else { + ret = 0; + } + + free(data); + } + + return ret; +} + + + +static int woomera_next_pair(struct woomera_config *cfg, char **var, char **val) +{ + int ret = 0; + char *p, *end; + + *var = *val = NULL; + + for(;;) { + cfg->lineno++; + + if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { + ret = 0; + break; + } + + *var = cfg->buf; + + if (**var == '[' && (end = strchr(*var, ']'))) { + *end = '\0'; + (*var)++; + strncpy(cfg->category, *var, sizeof(cfg->category) - 1); + continue; + } + + if (**var == '#' || **var == '\n' || **var == '\r') { + continue; + } + + if ((end = strchr(*var, '#'))) { + *end = '\0'; + end--; + } else if ((end = strchr(*var, '\n'))) { + if (*end - 1 == '\r') { + end--; + } + *end = '\0'; + } + + p = *var; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *var = p; + + if (!(*val = strchr(*var, '='))) { + ret = -1; + log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); + continue; + } else { + p = *val - 1; + *(*val) = '\0'; + (*val)++; + if (*(*val) == '>') { + *(*val) = '\0'; + (*val)++; + } + + while ((*p == ' ' || *p == '\t') && p != *var) { + *p = '\0'; + p--; + } + + p = *val; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *val = p; + ret = 1; + break; + } + } + + return ret; + +} + + +#if 0 +static void woomera_set_span_chan(struct woomera_interface *woomera, int span, int chan) +{ + pthread_mutex_lock(&woomera->vlock); + woomera->span = span; + woomera->chan = chan; + pthread_mutex_unlock(&woomera->vlock); + +} +#endif + + +static struct woomera_event *new_woomera_event_printf(struct woomera_event *ebuf, char *fmt, ...) +{ + struct woomera_event *event = NULL; + int ret = 0; + va_list ap; + + if (ebuf) { + event = ebuf; + } else if (!(event = new_woomera_event())) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + return NULL; + } else { + return NULL; + } + + va_start(ap, fmt); +#ifdef SOLARIS + event->data = (char *) malloc(2048); + vsnprintf(event->data, 2048, fmt, ap); +#else + ret = vasprintf(&event->data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + destroy_woomera_event(&event, EVENT_FREE_DATA); + return NULL; + } + + return event; + +} + +static struct woomera_event *woomera_clone_event(struct woomera_event *event) +{ + struct woomera_event *clone; + + if (!(clone = new_woomera_event())) { + return NULL; + } + + memcpy(clone, event, sizeof(*event)); + clone->next = NULL; + clone->data = strdup(event->data); + + return clone; +} + +static void enqueue_event(struct woomera_interface *woomera, + struct woomera_event *event, + event_args free_data) +{ + struct woomera_event *ptr, *clone = NULL; + + assert(woomera != NULL); + assert(event != NULL); + + if (!(clone = woomera_clone_event(event))) { + log_printf(0, server.log, "Error Cloning Event\n"); + return; + } + + pthread_mutex_lock(&woomera->queue_lock); + + for (ptr = woomera->event_queue; ptr && ptr->next ; ptr = ptr->next); + + if (ptr) { + ptr->next = clone; + } else { + woomera->event_queue = clone; + } + + pthread_mutex_unlock(&woomera->queue_lock); + + woomera_set_flag(woomera, WFLAG_EVENT); + + if (free_data && event->data) { + /* The event has been duplicated, the original data + * should be freed */ + free(event->data); + event->data=NULL; + } +} + +static char *dequeue_event(struct woomera_interface *woomera) +{ + struct woomera_event *event; + char *data = NULL; + + if (!woomera) { + return NULL; + } + + pthread_mutex_lock(&woomera->queue_lock); + if (woomera->event_queue) { + event = woomera->event_queue; + woomera->event_queue = event->next; + data = event->data; + pthread_mutex_unlock(&woomera->queue_lock); + + destroy_woomera_event(&event, EVENT_KEEP_DATA); + return data; + } + pthread_mutex_unlock(&woomera->queue_lock); + + return data; +} + + +static int enqueue_event_on_listeners(struct woomera_event *event) +{ + struct woomera_listener *ptr; + int x = 0; + + assert(event != NULL); + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + enqueue_event(ptr->woomera, event, EVENT_KEEP_DATA); + x++; + } + pthread_mutex_unlock(&server.listen_lock); + + return x; +} + + +static void del_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *ptr, *last = NULL; + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + if (ptr->woomera == woomera) { + if (last) { + last->next = ptr->next; + } else { + server.listeners = ptr->next; + } + free(ptr); + break; + } + last = ptr; + } + pthread_mutex_unlock(&server.listen_lock); +} + +static void add_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *new; + + pthread_mutex_lock(&server.listen_lock); + + if ((new = malloc(sizeof(*new)))) { + memset(new, 0, sizeof(*new)); + new->woomera = woomera; + new->next = server.listeners; + server.listeners = new; + } else { + log_printf(0, server.log, "Memory Error adding listener!\n"); + } + + pthread_mutex_unlock(&server.listen_lock); +} + + +#ifdef SMG_DTMF_ENABLE +static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) +{ + struct media_session *ms = woomera_get_ms(woomera); + char *cur = NULL; + int wrote = 0; + int err; + + if (!ms) { + return -EINVAL; + } + + if (!ms->dtmf_buffer) { + log_printf(3, woomera->log, "Allocate DTMF Buffer...."); + + err=switch_buffer_create_dynamic(&ms->dtmf_buffer, 1024, server.dtmf_size, 0); + + if (err != 0) { + log_printf(0, woomera->log, "Failed to allocate DTMF Buffer!\n"); + return -ENOMEM; + } else { + log_printf(3, woomera->log, "SUCCESS!\n"); + } + + } + + log_printf(3, woomera->log, "Sending DTMF %s\n",digits); + for (cur = digits; *cur; cur++) { + if ((wrote = teletone_mux_tones(&ms->tone_session, + &ms->tone_session.TONES[(int)*cur]))) { + + pthread_mutex_lock(&woomera->dtmf_lock); + + err=switch_buffer_write(ms->dtmf_buffer, ms->tone_session.buffer, wrote * 2); + + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3, woomera->log, "Sending DTMF %s Wrote=%i (err=%i)\n", + digits,wrote*2,err); + } else { + log_printf(0, woomera->log, "Error: Sending DTMF %s (err=%i)\n", + digits,wrote); + } + } + + ms->skip_read_frames = 200; + return 0; +} +#endif + +static struct woomera_interface *alloc_woomera(void) +{ + struct woomera_interface *woomera = NULL; + + if ((woomera = malloc(sizeof(struct woomera_interface)))) { + + memset(woomera, 0, sizeof(struct woomera_interface)); + + woomera->chan = -1; + woomera->span = -1; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->q931_rel_cause_topbx=SIGBOOST_RELEASE_CAUSE_NORMAL; + woomera->q931_rel_cause_tosig=SIGBOOST_RELEASE_CAUSE_NORMAL; + + woomera_set_interface(woomera, "w-1g-1"); + + + + } + + return woomera; + +} + + +static struct woomera_interface *new_woomera_interface(int socket, struct sockaddr_in *sock_addr, int len) +{ + struct woomera_interface *woomera = NULL; + + if (socket < 0) { + log_printf(0, server.log, "Critical: Invalid Socket on new interface!\n"); + return NULL; + } + + if ((woomera = alloc_woomera())) { + if (socket >= 0) { + no_nagle(socket); + woomera->socket = socket; + } + + if (sock_addr && len) { + memcpy(&woomera->addr, sock_addr, len); + } + } + + return woomera; + +} + +static char *woomera_message_header(struct woomera_message *wmsg, char *key) +{ + int x = 0; + char *value = NULL; + + for (x = 0 ; x < wmsg->last ; x++) { + if (!strcasecmp(wmsg->names[x], key)) { + value = wmsg->values[x]; + break; + } + } + + return value; +} + + +#if 1 + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + +#else + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags | errflags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & errflags)) { + res = -1; + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X)!\n", + pfds[0].revents); +#endif + res = -1; + } + } + + return res; +} + +#endif + +#if 1 +static int waitfor_2sockets(int fda, int fdb, char *a, char *b, int timeout) +{ + struct pollfd pfds[2]; + int res = 0; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + if (fda < 0 || fdb < 0) { + return -1; + } + + *a=0; + *b=0; + + memset(pfds, 0, sizeof(pfds)); + pfds[0].fd = fda; + pfds[1].fd = fdb; + pfds[0].events = POLLIN | errflags; + pfds[1].events = POLLIN | errflags; + if ((res = poll(pfds, 2, timeout)) > 0) { + res = 1; + if ((pfds[0].revents & errflags) || (pfds[1].revents & errflags)) { + res = -1; + } else { + if ((pfds[0].revents & POLLIN)) { + *a=1; + res++; + } + if ((pfds[1].revents & POLLIN)) { + *b=1; + res++; + } + } + + if (res == 1) { + /* No event found what to do */ + res=-1; + } + } + + return res; +} +#endif + + +static struct media_session *media_session_new(struct woomera_interface *woomera) +{ + struct media_session *ms = NULL; + int x; + char *p; + int span,chan; + + span=woomera->span; + chan=woomera->chan; + + log_printf(2, server.log,"Starting new MEDIA session [%s] [%s]\n", + woomera->interface,woomera->raw?woomera->raw:"N/A"); + + if ((ms = malloc(sizeof(struct media_session)))) { + memset(ms, 0, sizeof(struct media_session)); + + if (woomera->loop_tdm != 1) { + for(x = 0; x < strlen(woomera->raw) ; x++) { + if (woomera->raw[x] == ':') { + break; + } + if (woomera->raw[x] == '/') { + break; + } + } + + ms->ip = strndup(woomera->raw, x); + time(&ms->started); + p = woomera->raw + (x+1); + ms->port = atoi(p); + } + + time(&ms->started); + woomera_set_ms(woomera,ms); + ms->woomera = woomera; + +#ifdef SMG_DTMF_ENABLE + /* Setup artificial DTMF stuff */ + memset(&ms->tone_session, 0, sizeof(ms->tone_session)); + if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { + log_printf(0, server.log, "ERROR: Failed to initialize TONE [w%ig%i]!\n", + span+1,chan+1); + } + + ms->tone_session.rate = SMG_DTMF_RATE; + ms->tone_session.duration = server.dtmf_on * (ms->tone_session.rate / 1000); + ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); + + teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); +#endif + + } else { + log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", + span+1,chan+1); + } + + return ms; +} + +static void media_session_free(struct media_session *ms) +{ + if (ms->ip) { + free(ms->ip); + } + +#ifdef SMG_DTMF_ENABLE + teletone_destroy_session(&ms->tone_session); + switch_buffer_destroy(&ms->dtmf_buffer); +#endif + + ms->woomera = NULL; + + free(ms); +} + + +static int create_udp_socket(struct media_session *ms, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + log_printf(5,server.log,"LocalIP %s:%d IP %s:%d \n",local_ip, local_port, ip, port); + + memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); + memset(&ms->local_hp, 0, sizeof(ms->local_hp)); + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0))) { + gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + ms->remote_addr.sin_family = ms->remote_hp.h_addrtype; + memcpy((char *) &ms->remote_addr.sin_addr.s_addr, ms->remote_hp.h_addr_list[0], ms->remote_hp.h_length); + ms->remote_addr.sin_port = htons(port); + + ms->local_addr.sin_family = ms->local_hp.h_addrtype; + memcpy((char *) &ms->local_addr.sin_addr.s_addr, ms->local_hp.h_addr_list[0], ms->local_hp.h_length); + ms->local_addr.sin_port = htons(local_port); + + rc = bind(ms->socket, (struct sockaddr *) &ms->local_addr, sizeof(ms->local_addr)); + if (rc < 0) { + close(ms->socket); + ms->socket = -1; + + log_printf(5,server.log, + "Failed to bind LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + + /* OK */ + + } else { + log_printf(0,server.log, + "Failed to get hostbyname LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + } else { + log_printf(0,server.log, + "Failed to create/allocate UDP socket\n"); + } + + return ms->socket; +} + +static int next_media_port(void) +{ + int port; + + pthread_mutex_lock(&server.media_udp_port_lock); + port = ++server.next_media_port; + if (port > WOOMERA_MAX_MEDIA_PORT) { + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + port = WOOMERA_MIN_MEDIA_PORT; + } + pthread_mutex_unlock(&server.media_udp_port_lock); + + return port; +} + +#ifdef SMG_DTMF_ENABLE + +static int woomera_dtmf_transmit(struct media_session *ms, int mtu) +{ + struct woomera_interface *woomera = ms->woomera; + int bread; + unsigned char dtmf[1024]; + unsigned char dtmf_law[1024]; + sangoma_api_hdr_t hdrframe; + int i; + int slin_len = mtu*2; + short *data; + int used; + memset(&hdrframe,0,sizeof(hdrframe)); + + if (!ms->dtmf_buffer) { + return -1; + } + + for (;;) { + +#ifdef CODEC_LAW_DEFAULT + + pthread_mutex_lock(&woomera->dtmf_lock); + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + pthread_mutex_unlock(&woomera->dtmf_lock); + break; + } + + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, slin_len); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread <= 0) { + break; + } + +#if 0 + if (bread < slin_len) { + while (bread < slin_len) { + dtmf[bread++] = 0xFF; + } + } +#endif + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", + woomera->interface,bread,mtu,ms->hw_coding,used); + + data=(short*)dtmf; + for (i=0;ihw_coding) { + /* ALAW */ + dtmf_law[i] = linear_to_alaw((int)data[i]); + } else { + /* ULAW */ + dtmf_law[i] = linear_to_ulaw((int)data[i]); + } + } + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf_law, mtu, 0); + + ms->skip_write_frames+=server.dtmf_intr_ch; +#else +... + pthread_mutex_lock(&woomera->dtmf_lock); + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread < mtu) { + while (bread < mtu) { + dtmf[bread++] = 0; + } + } + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", + woomera->interface,bread); + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf, mtu, 0); + ms->skip_write_frames++; +#endif + return 0; + } + + return -1; +} +#endif + +static void media_loop_run(struct media_session *ms) +{ + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int errs=0; + int res=0; + wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + char filename[100]; + FILE *filed=NULL; + int loops=0; + + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + + log_printf(1, server.log, "Media Loop Started %s fd=%i\n", + woomera->interface,ms->sangoma_sock); + + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "WANPIPE MEDIA Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + + + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } + + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + sangoma_tdm_disable_hwec(ms->sangoma_sock,&tdm_api); + + } + + if (errs) { + + log_printf(0, server.log, "Media Loop: failed to open tdm device %s\n", + woomera->interface); + return; + } + + if (server.loop_trace) { + sprintf(filename,"/smg/w%ig%i-loop.trace",woomera->span+1,woomera->chan+1); + unlink(filename); + filed = safe_fopen(filename, "w"); + } + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + ((res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2)) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + log_printf(0, server.log, "Media Loop Restart %s\n", + woomera->interface); + continue; + } + + if (res < 0 ){ + log_printf(0, server.log, "Media Loop Socket error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM Loop ReadMsg Error: %s\n", + strerror(errno), woomera->interface); + break; + } + + if (server.loop_trace && filed != NULL) { + int i; + for (i=0;isangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + res, 0); + + res=0; + + loops++; + } + + + if (res < 0) { + log_printf(2, server.log, "Media Loop: socket error %s (fd=%i)!\n", + woomera->interface, ms->sangoma_sock); + } + + + if (server.loop_trace && filed != NULL) { + fclose(filed); + } + + sangoma_tdm_enable_hwec(ms->sangoma_sock,&tdm_api); + + sleep(1); + + close_socket(&ms->sangoma_sock); + + log_printf(1, server.log, "Media Loop Finished %s Master=%i MediaEnd=%i Loops=%i\n", + woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_MEDIA_END),loops); + + return; + +} + +#ifdef WP_HPTDM_API +static int media_rx_ready(void *p, unsigned char *data, int len) +{ + struct media_session *ms = (struct media_session *)p; + + if (ms->udp_sock < 0) { + return -1; + } + + return sendto(ms->udp_sock, + data,len, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + +} +#endif + +static void *media_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int local_port, x = 0, errs = 0, res = 0, packet_len = 0; + //int udp_cnt=0; + struct woomera_event wevent; + wanpipe_tdm_api_t tdm_api; + FILE *tx_fd=NULL; + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + !woomera->interface || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(2, server.log, + "MEDIA session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(ms); + pthread_exit(NULL); + return NULL; + } + + + log_printf(2, server.log, "MEDIA session for [%s] started (ptr=%p loop=%i)\n", + woomera->interface,woomera,woomera->loop_tdm); + + if (woomera->loop_tdm) { + media_loop_run(ms); + ms->udp_sock=-1; + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + goto media_thread_exit; + } + + for(x = 0; x < 1000 ; x++) { + local_port = next_media_port(); + if ((ms->udp_sock = create_udp_socket(ms, server.media_ip, local_port, ms->ip, ms->port)) > -1) { + break; + } + } + + if (ms->udp_sock < 0) { + log_printf(0, server.log, "UDP Socket Error (%s) [%s] LocalPort=%d\n", + strerror(errno), woomera->interface, local_port); + + errs++; + } else { + +#ifdef WP_HPTDM_API + hp_tdm_api_span_t *span=hptdmspan[woomera->span+1]; + if (!span || !span->init) { + errs++; + } else { + hp_tdm_api_usr_callback_t usr_callback; + memset(&usr_callback,0,sizeof(usr_callback)); + usr_callback.p = ms; + usr_callback.rx_avail = media_rx_ready; + if (span->open_chan(span, &usr_callback, &ms->tdmchan,woomera->chan+1)) { + errs++; + } + } +#else + if ((ms->sangoma_sock = sangoma_create_socket_by_name(woomera->interface, NULL)) < 0) { + log_printf(0, server.log, "WANPIPE Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + +# ifdef CODEC_LAW_DEFAULT + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } +# else + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_SLINEAR) < 0 ) { + errs++; + } +# endif + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + +# ifdef CODEC_LAW_DEFAULT +# ifdef LIBSANGOMA_GET_HWCODING + ms->hw_coding=sangoma_tdm_get_hw_coding(ms->sangoma_sock, &tdm_api); + if (ms->hw_coding < 0) { + errs++; + } +# else +# error "libsangoma missing hwcoding feature: not up to date!" +# endif +# endif + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + } +#endif + } + + + +#ifdef WP_HPTDM_API + /* No tdm thread */ +#else + if (!errs && + launch_media_tdm_thread(woomera)) { + errs++; + } +#endif + + if (!errs) { + + unsigned char udp_frame[4096]; + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(udp_frame,0,sizeof(udp_frame)); +#ifdef DOTRACE + int fdin, fdout; + char path_in[512], path_out[512]; +#endif + + + +#if 0 + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: %s%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + ms->hw_coding ?"ALAW":"ULAW", + WOOMERA_RECORD_SEPERATOR + ); +#else + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Unique-Call-Id: %s%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: PCM-16%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + WOOMERA_RECORD_SEPERATOR + ); +#endif + + + enqueue_event(woomera, &wevent, EVENT_FREE_DATA); + +#ifdef DOTRACE + sprintf(path_in, "/tmp/debug-in.%d.raw", tc); + sprintf(path_out, "/tmp/debug-out.%d.raw", tc++); + fdin = open(path_in, O_WRONLY | O_CREAT, O_TRUNC, 0600); + fdout = open(path_out, O_WRONLY | O_CREAT, O_TRUNC, 0600); +#endif + + if (server.out_tx_test) { + tx_fd=fopen("/smg/sound.raw","rb"); + if (!tx_fd){ + log_printf(0,server.log, "FAILED TO OPEN Sound file!\n"); + } + } + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + (res = waitfor_socket(ms->udp_sock, 1000, POLLERR | POLLIN)) >= 0) { + + unsigned int fromlen = sizeof(struct sockaddr_in); + + + if (res == 0) { + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", + woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if ((packet_len = recvfrom(ms->udp_sock, udp_frame, sizeof(udp_frame), + MSG_DONTWAIT, (struct sockaddr *) &ms->local_addr, &fromlen)) < 1) { + log_printf(2, server.log, "UDP Recv Error: %s\n",strerror(errno)); + break; + } + +#if 0 + log_printf(6, server.log, "%s: UDP Receive %i !!!\n", + woomera->interface,packet_len); +#endif + + if (packet_len > 0) { + + if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { + /* Assume that we will always receive SLINEAR here */ + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, packet_len/codec_sample); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + log_printf(0, server.log, + "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", + woomera->interface,sangoma_frame_len, + sangoma_frame_len/codec_sample,packet_len); + + + if (++ms->udp_sync_cnt >= 6) { + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, 20); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + log_printf(0, server.log, + "%s: UDP TDM Period Force ReSync to 20ms \n", + woomera->interface); + } + + } + +#ifdef SMG_DTMF_ENABLE + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ + if (!server.out_tx_test) { + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + continue; + } + } + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } +#endif + + if (server.out_tx_test && tx_fd && + fread((void*)udp_frame, + sizeof(char), + packet_len,tx_fd) <= 0) { + + sangoma_get_full_cfg(ms->sangoma_sock,&tdm_api); + fclose(tx_fd); + tx_fd=NULL; + } + +#ifdef WP_HPTDM_API + if (ms->tdmchan->push) { + ms->tdmchan->push(ms->tdmchan,udp_frame,packet_len); + } +#else + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + udp_frame, + packet_len, 0); +#endif + + } + +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + udp_cnt++; + if (udp_cnt && udp_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA UDP TX RX CNT %i %i\n", + woomera->interface,udp_cnt,packet_len); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media Thread: socket error !\n"); + } + } + + + + new_woomera_event_printf(&wevent, + "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Start-Time: %ld%s" + "End-Time: %ld%s" + "Answer-Time: %ld%s" + "Call-ID: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + woomera->session, + WOOMERA_LINE_SEPERATOR, + + time(&ms->started), + WOOMERA_LINE_SEPERATOR, + + time(NULL), + WOOMERA_LINE_SEPERATOR, + + time(&ms->answered), + WOOMERA_LINE_SEPERATOR, + + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + +media_thread_exit: + + if (woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + usleep(1000); + sched_yield(); + } + } + + + close_socket(&ms->udp_sock); + close_socket(&ms->sangoma_sock); + + if (tx_fd){ + fclose(tx_fd); + tx_fd=NULL; + } + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + + woomera_set_ms(woomera,NULL); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + + media_session_free(ms); + + log_printf(2, server.log, "MEDIA session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + + pthread_exit(NULL); + return NULL; +} + + + + +static void *media_tdm_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int res = 0; + //int tdm_cnt=0; + //wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + sangoma_api_hdr_t hdrframe; + + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || !woomera->interface) { + log_printf(2, server.log, "MEDIA TDM session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + pthread_exit(NULL); + return NULL; + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] started (ptr=%p)\n", + woomera->interface,woomera); + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + (res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } else if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "Media TDM Restart Failed%s\n", + woomera->interface); + break; + } + log_printf(0, server.log, "Media TDM Restart %s\n", + woomera->interface); + continue; + } else if (res < 0) { + log_printf(0, server.log, "Media TDM Sangoma Socket Error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM ReadMsg Error: %s\n", strerror(errno)); + break; + } + + res = sendto(ms->udp_sock, + circuit_frame, + res, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + if (res < 0) { + log_printf(2, server.log, "UDP Sento Error: %s\n", strerror(errno)); + break; + } +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + tdm_cnt++; + if (tdm_cnt && tdm_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA TDM TX RX CNT %i %i\n", + woomera->interface,tdm_cnt,res); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media TDM Thread: socket error !\n"); + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + + pthread_exit(NULL); + return NULL; + +} + + +/* This function must be called with process_lock + * because it modifies shared process_table */ + +static int launch_media_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms; + + if ((ms = media_session_new(woomera))) { + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_RUNNING); + result = pthread_create(&ms->thread, &attr, media_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(woomera->ms); + + } + pthread_attr_destroy(&attr); + + } else { + log_printf(0, server.log, "Failed to start new media session\n"); + } + + return result; + +} + +static int launch_media_tdm_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms = woomera_get_ms(woomera); + + if (!ms) { + return result; + } + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + result = pthread_create(&ms->thread, &attr, media_tdm_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + char callid[20]; + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + + if ((woomera = alloc_woomera())) { + + woomera->chan = event->chan; + woomera->span = event->span; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->loop_tdm=1; + + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + woomera_set_interface(woomera,callid); + + if (launch_woomera_thread(woomera)) { + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + free(woomera); + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + return woomera; +} + +static int woomera_message_parse(struct woomera_interface *woomera, struct woomera_message *wmsg, int timeout) +{ + char *cur, *cr, *next = NULL, *eor = NULL; + char buf[2048]; + int res = 0, bytes = 0, sanity = 0; + struct timeval started, ended; + int elapsed, loops = 0; + int failto = 0; + int packet = 0; + + memset(wmsg, 0, sizeof(*wmsg)); + + if (woomera->socket < 0 ) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Invalid Socket! %d\n", + woomera->interface,woomera->socket); + return -1; + } + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP !\n", + woomera->interface); + return -1; + } + + gettimeofday(&started, NULL); + memset(buf, 0, sizeof(buf)); + + if (timeout < 0) { + timeout = abs(timeout); + failto = 1; + } else if (timeout == 0) { + timeout = -1; + } + + + while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) { + if (sanity > 1000) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Failed Sanity Check!\n[%s]\n\n", woomera->interface, buf); + return -1; + } + + if ((res = waitfor_socket(woomera->socket, 1000, POLLERR | POLLIN) > 0)) { + res = recv(woomera->socket, buf, sizeof(buf), MSG_PEEK); + + if (res > 1) { + packet++; + } + if (!strncmp(buf, WOOMERA_LINE_SEPERATOR, 2)) { + res = read(woomera->socket, buf, 2); + return 0; + } + if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } else if (res < 0) { + log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX + "%s error during packet retry #%d\n", + woomera->interface, loops); + return res; + } else if (loops) { + ysleep(100000); + } + } + + gettimeofday(&ended, NULL); + elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000)); + + if (res < 0) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Bad RECV\n", + woomera->interface); + return res; + } else if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } + + if (packet && loops > 150) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout waiting for packet.\n", + woomera->interface); + return -1; + } + + if (timeout > 0 && (elapsed > timeout)) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout [%d] reached\n", + woomera->interface, timeout); + return failto ? -1 : 0; + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)) { + /* BRB! we have an Event to deliver....*/ + return 0; + } + + /* what're we still doing here? */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + !woomera_test_flag(woomera, WFLAG_RUNNING)) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MASTER RUNNING or RUNNING!\n", woomera->interface); + return -1; + } + loops++; + } + + *eor = '\0'; + bytes = strlen(buf) + 4; + + memset(buf, 0, sizeof(buf)); + res = read(woomera->socket, buf, bytes); + next = buf; + + if (woomera->debug > 1) { + log_printf(3, woomera->log, "%s:WOOMERA RX MSG: %s\n",woomera->interface,buf); + + } + + while ((cur = next)) { + + if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) { + *cr = '\0'; + next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1); + if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) { + break; + } + } + if (!cur || !*cur) { + break; + } + + if (!wmsg->last) { + char *cmd, *id, *args; + woomera_set_flag(wmsg, MFLAG_EXISTS); + cmd = cur; + + if ((id = strchr(cmd, ' '))) { + *id = '\0'; + id++; + if ((args = strchr(id, ' '))) { + *args = '\0'; + args++; + strncpy(wmsg->command_args, args, sizeof(wmsg->command_args)-1); + } + strncpy(wmsg->callid, id, sizeof(wmsg->callid)-1); + } + + strncpy(wmsg->command, cmd, sizeof(wmsg->command)-1); + } else { + char *name, *val; + name = cur; + + if ((val = strchr(name, ':'))) { + *val = '\0'; + val++; + while (*val == ' ') { + *val = '\0'; + val++; + } + strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN); + } + strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN); + if (name && val && !strcasecmp(name, "content-type")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + if (name && val && !strcasecmp(name, "content-length")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + + + } + wmsg->last++; + } + + wmsg->last--; + + if (bytes && woomera_test_flag(wmsg, MFLAG_CONTENT)) { + read(woomera->socket, wmsg->body, + (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes); + } + + return woomera_test_flag(wmsg, MFLAG_EXISTS); + +} + +static struct woomera_interface *pull_from_holding_tank(int index, int span , int chan) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + + /* Block this index until the call is completed */ + server.holding_tank[index] = &woomera_dead_dev; + + woomera->timeout = 0; + woomera->index = 0; + woomera->span=span; + woomera->chan=chan; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static void clear_from_holding_tank(int index) +{ + + if (index < 1 || index >= CORE_TANK_LEN) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + return; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] == &woomera_dead_dev) { + server.holding_tank[index] = NULL; + } + pthread_mutex_unlock(&server.ht_lock); + + return; +} + +static struct woomera_interface *peek_from_holding_tank(int index) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static int add_to_holding_tank(struct woomera_interface *woomera) +{ + int next, i, found=0; + + pthread_mutex_lock(&server.ht_lock); + + for (i=0;i= CORE_TANK_LEN) { + next = server.holding_tank_index = 1; + } + + if (next == 0) { + log_printf(0, server.log, "\nCritical Error on TANK INDEX == 0\n"); + continue; + } + + if (server.holding_tank[next]) { + continue; + } + + found=1; + break; + } + + if (!found) { + /* This means all tank vales are busy + * should never happend */ + pthread_mutex_unlock(&server.ht_lock); + log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); + return 0; + } + + server.holding_tank[next] = woomera; + woomera->timeout = time(NULL) + 100; + + pthread_mutex_unlock(&server.ht_lock); + return next; +} + +static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, + struct woomera_message *wmsg, + int media, int answer, int accept) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + + log_printf(4, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + + if (woomera_test_flag(woomera, WFLAG_HANGUP) || + !woomera_test_flag(woomera, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END)) { + + log_printf(2, server.log, + "ERROR! call was cancelled MEDIA on HANGUP or MEDIA END!\n"); + + woomera->timeout=0; + return -1; + } + + log_printf(3, server.log,"WOOMERA: GOT %s EVENT: [%s] RAW=%s\n", + wmsg->command,wmsg->callid,raw); + + + if (raw && + woomera->raw == NULL && + !woomera_test_flag(woomera, WFLAG_RAW_MEDIA_STARTED)) { + + woomera_set_flag(woomera, WFLAG_RAW_MEDIA_STARTED); + + woomera_set_raw(woomera, raw); + + if (launch_media_thread(woomera)) { + struct woomera_event wevent; + + log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + woomera->timeout=0; + return -1; + } + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + + } else { + if (answer) { + struct media_session *ms; + + pthread_mutex_lock(&woomera->ms_lock); + if ((ms=woomera->ms)) { + time(&woomera->ms->answered); + } + pthread_mutex_unlock(&woomera->ms_lock); + + if (ms) { + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_ANSWERED, + 0); + log_printf(2, server.log, + "Sent SIGBOOST_EVENT_CALL_ANSWERED [w%dg%d]\n", + woomera->span+1,woomera->chan+1); + } else { + struct woomera_event wevent; + log_printf(0, server.log, + "WOOMERA ANSWER: FAILED [%s] no Media \n", + wmsg->command,wmsg->callid); + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera->timeout=0; + return -1; + } + } + } + + { + struct woomera_event wevent; + new_woomera_event_printf(&wevent, "200 %s OK%s" + "Unique-Call-Id: %s%s", + answer ? "ANSWER" : + accept ? "ACCEPT" : "MEDIA", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + + return 0; +} + +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); + char *presentation = woomera_message_header(wmsg, "Presentation"); + char *screening = woomera_message_header(wmsg, "Screening"); + char *rdnis = woomera_message_header(wmsg, "RDNIS"); + //char *callerid = woomera_message_header(wmsg, "local-name"); + char *called = wmsg->callid; + char *grp = wmsg->callid; + char *p; + int tg = 0; + + if (smg_check_all_busy()) { + socket_printf(woomera->socket, + "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); + log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", + server.call_count, server.all_ckt_busy); + return -1; + } + + log_printf(2, woomera->log, "New Call %d/%d\n", server.call_count, server.max_calls); + + if ((p = strchr(called, '/'))) { + *p = '\0'; + called = p+1; + tg = atoi(grp+1) - 1; + if (tg < 0) { + tg=0; + } + } + + if (raw) { + woomera_set_raw(woomera, raw); + } + + woomera->index = add_to_holding_tank(woomera); + if (woomera->index < 1) { + socket_printf(woomera->socket, + "405 SMG Server All Tanks Busy!%s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0, woomera->log, "Error: Call Tank Full (Call Cnt=%i)\n", + server.call_count); + return -1; + } + + + woomera->index_hold = woomera->index; + + call_signal_call_init(&event, calling, called, woomera->index); + + if (presentation) { + event.calling_number_presentation = atoi(presentation); + } else { + event.calling_number_presentation = 0; + } + + if (screening) { + event.calling_number_screening_ind = atoi(screening); + } else { + event.calling_number_screening_ind = 0; + } + + if (rdnis && strlen(rdnis)) { + strncpy((char*)event.redirection_string,rdnis, + sizeof(event.redirection_string)-1); + log_printf(0,server.log,"RDNIS %s\n", rdnis); + + } + + event.trunk_group = tg; + + if (call_signal_connection_write(&server.mcon, &event) <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + socket_printf(woomera->socket, + "405 SMG Signalling Contestion!%s", + WOOMERA_RECORD_SEPERATOR); + return -1; + } + + socket_printf(woomera->socket, "100 Trying%s", WOOMERA_RECORD_SEPERATOR); + + log_printf(2, server.log, "Call Called Event [Setup ID: %d] TG=%d\n", + woomera->index,tg); + + return 0; +} + + +static void interpret_command(struct woomera_interface *woomera, struct woomera_message *wmsg) +{ + int answer = 0, media = 0, accept=0; + char *unique_id; + + + if (!strcasecmp(wmsg->command, "call")) { + int err; + if (strlen(woomera->session) != 0) { + /* Call has already been placed */ + socket_printf(woomera->socket, "400 Error Call already in progress %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0,server.log,"Woomera RX Call Even while call in progress!\n"); + return; + } + + err=handle_woomera_call_start(woomera,wmsg); + if (err) { + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + return; + + } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + if (cause) { + log_printf(3, woomera->log, "Bye Cause Received: [%s]\n", cause); + } + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + log_printf(2, woomera->log, "WOOMERA CMD: Bye Received: [%s]\n", woomera->interface); + + woomera_clear_flag(woomera, WFLAG_RUNNING); + socket_printf(woomera->socket, "200 Connection closed%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + + } else if (!strcasecmp(wmsg->command, "listen")) { + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + socket_printf(woomera->socket, "405 Listener already started%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + } else { + char *event_string; + + woomera_set_flag(woomera, WFLAG_LISTENING); + add_listener(woomera); + + if (!strcmp(wmsg->callid,"MASTER")) { + woomera_set_flag(woomera, WFLAG_MASTER_DEV); + log_printf(0,woomera->log, "Starting MASTER Listen Device!\n"); + master_reset=0; + } + + + socket_printf(woomera->socket, "%s", + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "200 Listener enabled%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + if ((event_string = dequeue_event(&server.master_connection))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + event_string = NULL; + } + } + return; + + } else if ((media = !strcasecmp(wmsg->command, "debug"))) { + + int debug_level=atoi(wmsg->callid); + + if (debug_level < 10) { + server.debug=debug_level; + log_printf(0,server.log,"SMG Debugging set to %i (window=%i)\n",server.debug,server.mcon.txwindow); + } + + return; + } + + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); + if (!unique_id) { + socket_printf(woomera->socket, "400 Error no unique id found %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0,server.log,"Woomera RX Even (%s) without unique id!\n",wmsg->command); + + if (!strcasecmp(wmsg->command, "hangup")) { + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + return; + } + + if (strlen(woomera->session) == 0) { + struct woomera_interface *session_woomera=NULL; + char *session=NULL; + int span, chan; + char ifname[100]; + /* If session does not exist this is an incoming call */ + sscanf(unique_id, "w%dg%d", &span, &chan); + span--; + chan--; + + log_printf(3, woomera->log, + "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", + wmsg->command,span,chan,unique_id); + + + if (smg_validate_span_chan(span,chan) != 0) { + socket_printf(woomera->socket, + "400 Error invalid span chan in session! %s", + WOOMERA_RECORD_SEPERATOR); + + log_printf(0, woomera->log, + "WOOMERA Error invalid span chan in session %s\n", + wmsg->command,unique_id); + return; + } + + pthread_mutex_lock(&server.process_lock); + session = server.process_table[span][chan].session; + session_woomera = server.process_table[span][chan].dev; + + if (session_woomera) { + pthread_mutex_unlock(&server.process_lock); + + socket_printf(woomera->socket, "400 Error channel in use! %s", + WOOMERA_RECORD_SEPERATOR); + + log_printf(0, woomera->log, "WOOMERA Error channel in use %s\n", + wmsg->command,unique_id); + return; + } + + if (!session || strlen(session) == 0 || + strncmp(session,unique_id,sizeof(woomera->session))){ + pthread_mutex_unlock(&server.process_lock); + + socket_printf(woomera->socket, "400 Error no such session %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0, woomera->log, + "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", + wmsg->command,unique_id,session?session:"N/A"); + return; + } + + server.process_table[span][chan].dev=woomera; + strncpy(woomera->session,unique_id,sizeof(woomera->session)); + sprintf(ifname,"w%dg%d",span+1,chan+1); + woomera_set_interface(woomera, ifname); + + woomera->span=span; + woomera->chan=chan; + + pthread_mutex_unlock(&server.process_lock); + + + log_printf(3, woomera->log, "WOOMERA Got New If=%s Session %s\n", + woomera->interface, woomera->session); + + + } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { + socket_printf(woomera->socket, "400 Error session missmatch %s", + WOOMERA_RECORD_SEPERATOR); + return; + } + + + if (!strcasecmp(wmsg->command, "dtmf")) { + + log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", + woomera->interface, wmsg->command_args, wmsg->body); + +#ifdef SMG_DTMF_ENABLE + wanpipe_send_dtmf(woomera,wmsg->body); +#endif + socket_printf(woomera->socket, "200 DTMF OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "hangup")) { + + int chan = -1, span = -1; + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + span=woomera->span; + chan=woomera->chan; + + log_printf(3, woomera->log, "WOOMERA CMD: Hangup Received: [%s] MEDIA EXIST Cause=%s\n", + woomera->interface,cause); + + if (smg_validate_span_chan(span,chan) != 0) { + socket_printf(woomera->socket, "405 No Such Channel%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + } + + + log_printf(2, woomera->log, "Hangup Received: [w%dg%d]\n", + span+1,chan+1); + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + + socket_printf(woomera->socket, "200 HANGUP OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "proceed")) { + + log_printf(3, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + socket_printf(woomera->socket, + "200 %s PROCEED OK%s" + "Unique-Call-Id: %s%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + } else if ((media = !strcasecmp(wmsg->command, "media")) || + (answer = !strcasecmp(wmsg->command, "answer")) || + (accept = !strcasecmp(wmsg->command, "accept"))) { + + handle_woomera_media_accept_answer(woomera, wmsg, media,answer,accept); + + + + } else { + log_printf(0, server.log,"WOOMERA INVALID EVENT: %s [%s] \n", + wmsg->command,wmsg->callid); + socket_printf(woomera->socket, "501 Command '%s' not implemented%s", + wmsg->command, WOOMERA_RECORD_SEPERATOR); + } +} + + +/* + EVENT INCOMING 1 + Remote-Address: 10.3.3.104 + Remote-Number: + Remote-Name: Anthony Minessale!8668630501 + Protocol: H.323 + User-Agent: Post Increment Woomera 1.0alpha1 (OpenH323 v1.17.2) 9/61 + H323-Call-Id: 887b1ff8-bb1f-da11-85c0-0007e98988c4 + Local-Number: 996 + Start-Time: Fri, 09 Sep 2005 12:25:14 -0400 + Local-Name: root +*/ + + +static void handle_call_answer(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int kill = 0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + pthread_mutex_unlock(&server.process_lock); + + if (woomera && woomera->raw) { + char callid[80]; + struct woomera_event wevent; + + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { + log_printf(1, server.log, "Refusing to double-answer a call!\n"); + return; + } + + woomera_set_flag(woomera, WFLAG_ANSWER); + + if (woomera->span != event->span || woomera->chan != event->chan) { + log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); + kill++; + return; + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to answer a dead call!\n"); + kill++; + } else { + int err; + err=0; + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + woomera_set_interface(woomera, callid); +#ifndef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; + } +#endif + + if (!kill) { + new_woomera_event_printf(&wevent, "EVENT CONNECT w%dg%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + } + } else { + log_printf(1, server.log, "Answer requested on non-existant session. [w%dg%d]\n", + event->span+1, event->chan+1); + kill++; + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_ack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + struct woomera_event wevent; + int kill = 0; + + if ((woomera = pull_from_holding_tank(event->call_setup_id,event->span,event->chan))) { + char callid[80]; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to ack a dead call!\n"); + kill++; + } else { + int err, span, chan; + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + + span = event->span; + chan = event->chan; + + woomera_set_interface(woomera, callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[span][chan].dev = woomera; + sprintf(woomera->session,"%s-%i-%i",callid,rand(),rand()); + sprintf(server.process_table[span][chan].session,"%s-%s", + callid,woomera->session); + pthread_mutex_unlock(&server.process_lock); + + + +#ifdef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id:%s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera,WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; + } +#endif + if (!kill) { + new_woomera_event_printf(&wevent, "201 Accepted%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + log_printf(2, server.log, "Call Answered Event ID = %d Device = w%dg%d!\n", + event->call_setup_id,woomera->span+1,woomera->chan+1); + } + } + } else { + log_printf(1, server.log, + "Event (START ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id, event->call_setup_id,event->span+1, event->chan+1); + kill++; + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_nack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int span=-1, chan=-1; + int ack=0; + + /* Always ACK the incoming NACK + * Send out the NACK ACK before pulling the TANK, because + * if we send after the pull, the outgoing call could send + * a message to boost with the pulled TANK value before + * we send a NACK ACK */ + + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + if (event->call_setup_id > 0) { + woomera=pull_from_holding_tank(event->call_setup_id,-1,-1); + } + + if (woomera) { + + struct woomera_event wevent; + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(0, + 0, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", + event->call_setup_id); + } else { + + woomera_set_cause_topbx(woomera,event->release_cause); + + new_woomera_event_printf(&wevent, "501 Error!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + } + + /* We already did the NACK */ + ack=0; + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + + log_printf(0, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + + isup_exec_command(event->span, + event->chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + +#ifdef MEDIA_SOCK_SHUTDOWN + pthread_mutex_lock(&woomera->ms_lock); + if (woomera->ms) { + shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); + shutdown(woomera->ms->udp_sock, SHUT_RDWR); + } + pthread_mutex_unlock(&woomera->ms_lock); +#endif + + + /* We already did the NACK */ + ack=0; + } else { + + ack++; + log_printf(0, server.log, "Error: No Device on valid Span Chan [w%dg%d]!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(0, server.log, + "Error: Start Nack Invalid State Should not happen [%d] [w%dg%d]!\n", + event->call_setup_id, event->span+1, event->chan+1); + ack++; + } +#if 0 + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + log_printf(0, server.log, "WARNING: All ckt busy!\n"); + smg_all_ckt_busy(); + } +#endif +#warning "Ignoring CALL GAP" +#if 0 + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { + log_printf(0, server.log, "WARNING: Call Gapping Detected!\n"); + smg_all_ckt_gap(); + } +#endif + + if (ack) { + span=0; + chan=0; + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + isup_exec_command(span, + chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + + log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } +} + +static void handle_call_loop_start(call_signal_event_t *event) +{ + + struct woomera_interface *woomera; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + pthread_mutex_unlock(&server.process_lock); + + woomera=launch_woomera_loop_thread(event); + if (woomera == NULL) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + } + + + return; +} + +static void handle_call_start(call_signal_event_t *event) +{ + struct woomera_event wevent; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(0, server.log, + "Sent (From Handle START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + + + new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" + "Unique-Call-Id: %s%s" + "Remote-Number: %s%s" + "Remote-Name: %s%s" + "Protocol: SS7%s" + "User-Agent: sangoma_mgd%s" + "Local-Number: %s%s" + "Channel-Name: SMG-g%ds%dc%d%s" + "Trunk-Group: %d%s" + "Presentation: %d%s" + "Screening: %d%s" + "RDNIS: %s%s" + , + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + session, + WOOMERA_LINE_SEPERATOR, + event->calling_number_digits, + WOOMERA_LINE_SEPERATOR, + "", + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + event->called_number_digits, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + WOOMERA_LINE_SEPERATOR, + event->calling_number_presentation, + WOOMERA_LINE_SEPERATOR, + event->calling_number_screening_ind, + WOOMERA_LINE_SEPERATOR, + event->redirection_string, + WOOMERA_RECORD_SEPERATOR + ); + + if (enqueue_event_on_listeners(&wevent)) { + enqueue_event(&server.master_connection, &wevent, EVENT_KEEP_DATA); + } else { + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } + + destroy_woomera_event_data(&wevent); + +} + +static void handle_gap_abate(call_signal_event_t *event) +{ + log_printf(0, server.log, "NOTICE: GAP Cleared!\n", + event->span+1, event->chan+1); + smg_clear_ckt_gap(); +} + +static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_t *event) +{ + mcon->rxseq_reset =0; +} + +static void handle_call_stop(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP)); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + +#ifdef MEDIA_SOCK_SHUTDOWN + pthread_mutex_lock(&woomera->ms_lock); + if (woomera->ms) { + shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); + shutdown(woomera->ms->udp_sock, SHUT_RDWR); + } + pthread_mutex_unlock(&woomera->ms_lock); +#endif + + log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + } else { + + /* At this point we have already sent our STOP so its safe to ACK */ + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } + + if (!woomera){ + /* This is allowed on incoming call if remote app does not answer it */ + log_printf(3, server.log, "Event CALL STOP referrs to a non-existant session [w%dg%d]!\n", + event->span+1, event->chan+1); + } +} + +static void handle_heartbeat(call_signal_event_t *event) +{ + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + } else { + int err=call_signal_connection_write(&server.mcon, event); + if (err <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + } + } + return; +} + +static void handle_call_stop_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + log_printf(2, server.log, "Stop Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id, + woomera->interface); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + } else { + log_printf(2, server.log, "Event CALL_STOP_ACK(%d) referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->event_id, event->span+1, event->chan+1, event->call_setup_id); + } + + /* No need for us to do any thing here */ + return; +} + +static void handle_call_start_nack_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + if ((woomera=pull_from_holding_tank(event->call_setup_id,-1,-1))) { + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + + } else { + log_printf(2, server.log, + "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } + +#if 1 + if (event->call_setup_id > 0) { + clear_from_holding_tank(event->call_setup_id); + } +#endif + + /* No need for us to do any thing here */ + return; +} + +#if 0 +static void validate_number(unsigned char *s) +{ + unsigned char *p; + for (p = s; *p; p++) { + if (*p < 48 || *p > 57) { + log_printf(2, server.log, "Encountered a non-numeric character [%c]!\n", *p); + *p = '\0'; + break; + } + } +} +#endif + +static int parse_ss7_event(call_signal_connection_t *mcon, call_signal_event_t *event) +{ + int ret = 0; + +#if 0 + validate_number((unsigned char*)event->called_number_digits); + validate_number((unsigned char*)event->calling_number_digits); +#endif + +#if 1 + log_printf(2, server.log, + "RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + +#if 0 + log_printf(2, server.log, "RX EVENT\n"); + log_printf(2, server.log, "===================================\n"); + log_printf(2, server.log, " rType: %s (%0x HEX)\n", + call_signal_event_id_name(event->event_id),event->event_id); + log_printf(2, server.log, " rSpan: [%d]\n",event->span+1); + log_printf(2, server.log, " rChan: [%d]\n",event->chan+1); + log_printf(2, server.log, " rCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + log_printf(2, server.log, " rCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + log_printf(2, server.log, " rCause: %d\n",event->release_cause); + log_printf(2, server.log, " rInterface: [w%dg%d]\n",event->span+1,event->chan+1); + log_printf(2, server.log, " rEvent ID: [%d]\n",event->event_id); + log_printf(2, server.log, " rSetup ID: [%d]\n",event->call_setup_id); + log_printf(2, server.log, " rSeq: [%d]\n",event->fseqno); + log_printf(2, server.log, "===================================\n"); + +#endif + +#if 0 + log_printf(2, server.log, + "\nRX EVENT\n" + "===================================\n" + " rType: %s (%0x HEX)\n" + " rSpan: [%d]\n" + " rChan: [%d]\n" + " rCalledNum: %s\n" + " rCallingNum: %s\n" + " rCause: %s\n" + " rInterface : [w%dg%d]\n" + " rEvent ID : [%d]\n" + " rSetup ID: [%d]\n" + " rSeq: [%d]\n" + "===================================\n" + "\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), + release_to_string(event->release_cause), + event->span+1, + event->chan+1, + event->event_id, + event->call_setup_id, + event->fseqno + ); +#endif + + + switch(event->event_id) { + + case SIGBOOST_EVENT_CALL_START: + handle_call_start(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_CALL_START_ACK: + handle_call_start_ack(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK: + handle_call_start_nack(event); + break; + case SIGBOOST_EVENT_CALL_ANSWERED: + handle_call_answer(event); + break; + case SIGBOOST_EVENT_HEARTBEAT: + handle_heartbeat(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK_ACK: + handle_call_start_nack_ack(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED_ACK: + handle_call_stop_ack(event); + break; + case SIGBOOST_EVENT_INSERT_CHECK_LOOP: + handle_call_loop_start(event); + break; + case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: + handle_restart_ack(mcon,event); + break; + case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: + handle_gap_abate(event); + break; + default: + log_printf(0, server.log, "Warning no handler implemented for [%s]\n", + call_signal_event_id_name(event->event_id)); + break; + } + + return ret; +} + + +static void *monitor_thread_run(void *obj) +{ + int ss = 0; + int policy=0,priority=0; + char a=0,b=0; + call_signal_connection_t *mcon=&server.mcon; + call_signal_connection_t *mconp=&server.mconp; + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + + if (call_signal_connection_open(mcon, + mcon->cfg.local_ip, + mcon->cfg.local_port, + mcon->cfg.remote_ip, + mcon->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCON Socket [%d] %s\n", + mcon->socket,strerror(errno)); + exit(-1); + } + + if (call_signal_connection_open(mconp, + mconp->cfg.local_ip, + mconp->cfg.local_port, + mconp->cfg.remote_ip, + mconp->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCONP Socket [%d] %s\n", + mconp->socket,strerror(errno)); + exit(-1); + } + + mcon->log = server.log; + mconp->log = server.log; + + isup_exec_command(0, + 0, + -1, + SIGBOOST_EVENT_SYSTEM_RESTART, + 0); + + mcon->rxseq_reset=1; + + smg_get_current_priority(&policy,&priority); + + log_printf(1, server.log, "Open udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + log_printf(1, server.log, "Monitor Thread Started (%i:%i)\n",policy,priority); + + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { +#if 0 + ss = waitfor_socket(server.mcon.socket, 1000, POLLERR | POLLIN); +#else + ss = waitfor_2sockets(mcon->socket, + mconp->socket, + &a, &b, 1000); +#endif + + if (ss > 0) { + + call_signal_event_t *event=NULL; + int i=0; + + if (b) { +mcon_retry_priority: + if ((event = call_signal_connection_readp(mconp,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event P [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mconp,event); + if (++i < 10) { + goto mcon_retry_priority; + } + + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost P Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + i=0; + + if (a) { +mcon_retry: + if ((event = call_signal_connection_read(mcon,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mcon,event); + + if (++i < 50) { + goto mcon_retry; + } + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + } + + if (ss < 0){ + log_printf(0, server.log, "Thread Run: Select Socket Error!\n"); + break; + } + + } + + log_printf(1, server.log, "Close udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + call_signal_connection_close(&server.mcon); + call_signal_connection_close(&server.mconp); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + log_printf(0, server.log, "Monitor Thread Ended\n"); + + return NULL; +} + +static void woomera_loop_thread_run(struct woomera_interface *woomera) +{ + int err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log, "Failed to start loop media thread\n"); + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + return; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP)) { + + sleep(1); + continue; + + } + + log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); + + + + return; +} + +static void *woomera_thread_run(void *obj) +{ + struct woomera_interface *woomera = obj; + struct woomera_message wmsg; + struct woomera_event wevent; + char *event_string; + int mwi; + int err; + int policy=0, priority=0; + int span = -1, chan = -1; + + woomera_message_init(&wmsg); + + //smg_get_current_priority(&policy,&priority); + + log_printf(2, server.log, "WOOMERA session for started (ptr=%p : loop=%i)(%i:%i)\n", + woomera,woomera->loop_tdm,policy,priority); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_mutex_init(&woomera->queue_lock, NULL); + pthread_mutex_init(&woomera->ms_lock, NULL); + pthread_mutex_init(&woomera->dtmf_lock, NULL); + pthread_mutex_init(&woomera->vlock, NULL); + pthread_mutex_init(&woomera->flags_lock, NULL); + + if (woomera->loop_tdm) { + woomera_loop_thread_run(woomera); + goto woomera_session_close; + } + + err=socket_printf(woomera->socket, + "EVENT HELLO Sangoma Media Gateway%s" + "Supported-Protocols: TDM%s" + "Version: %s%s" + "Remote-Address: %s%s" + "Remote-Port: %d%s" + "Raw-Format: %s%s", + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + SMG_VERSION, WOOMERA_LINE_SEPERATOR, + inet_ntoa(woomera->addr.sin_addr), WOOMERA_LINE_SEPERATOR, + ntohs(woomera->addr.sin_port), WOOMERA_LINE_SEPERATOR, + server.hw_coding?"ALAW":"ULAW", WOOMERA_RECORD_SEPERATOR + ); + + if (err) { + log_printf(0, server.log, "Woomera session socket failure! (ptr=%p)\n", + woomera); + woomera_clear_flag(woomera, WFLAG_RUNNING); + goto woomera_session_close; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + woomera_test_flag(woomera, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + !master_reset) { + + + mwi = woomera_message_parse(woomera, &wmsg, WOOMERA_HARD_TIMEOUT); + if (mwi >= 0) { + + if (mwi) { + interpret_command(woomera, &wmsg); + } else if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + if (socket_printf(woomera->socket, "%s", event_string)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + free(event_string); + log_printf(4, server.log, + "WOOMERA session (ptr=%p) print string error\n", + woomera); + break; + } + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + if (woomera->timeout > 0 && time(NULL) >= woomera->timeout) { + + /* Sent the hangup only after we sent a NACK */ + + log_printf(2, server.log, + "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", + woomera,woomera->interface,woomera->timeout); + + /* NENAD Let the Index check run a nak */ + if (woomera->index) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + break; + } + + } else { + log_printf(3, server.log, "WOOMERA session (ptr=%p) [%s] READ MSG Error %i \n", + woomera,woomera->interface,mwi); + break; + } + + } + +woomera_session_close: + + log_printf(2, server.log, "WOOMERA session (ptr=%p) is dying [%s]: SR=%d WR=%d WF=0x%04X\n", + woomera,woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_RUNNING), + woomera->flags); + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + usleep(100); + sched_yield(); + } + } + + + /*********************************************** + * Identify the SPAN CHAN to be used below + ***********************************************/ + + chan = woomera->chan; + span = woomera->span; + + + if (!woomera_test_flag(woomera, WFLAG_HANGUP)) { + + /* The call was not HUNGUP. This is the last check, + If the call is valid, hungup the call if the call + was never up the keep going */ + woomera_set_flag(woomera, WFLAG_HANGUP); + + if (smg_validate_span_chan(span,chan) == 0) { + + if (!woomera->index) { + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + + } + }else{ + /* This can happend if an outgoing call times out + or gets hungup before it gets acked. Its not a + failure */ + + log_printf(3, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + } + +woo_re_hangup: + + + /* We must send a STOP ACK to boost telling it that we are done */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + + /* SMG received a HANGUP from boost. + We must now send back the ACK to the HANGUP. + Boost will not release channel until we + ACK the hangup */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Ack) to SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + }else{ + /* This should never happen! If it does + we broke protocol */ + log_printf(0, woomera->log, + "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); + + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + + /* SMG received a NACK from boost during call startup. + We must now send back the ACK to the NACK. + Boost will not release channel until we + ACK the NACK */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + + } else { + log_printf(0, woomera->log, + "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + } + + if (woomera->index) { + + int index = woomera->index; + int timeout_cnt=0; + int overall_cnt=0; + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Timeout: %ld%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + woomera->timeout, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(18), + WOOMERA_LINE_SEPERATOR, + 18, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + + if (peek_from_holding_tank(index)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(0, + 0, + index, + SIGBOOST_EVENT_CALL_START_NACK, + 0); + + log_printf(2, woomera->log, + "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", + index); + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 40000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] ... \n", + index); + } + + if (overall_cnt > 10) { //100sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); + } + + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } + } + + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent HANGUP to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + log_printf(2, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + timeout_cnt++; + if (timeout_cnt > 40000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i] ... \n", + woomera->interface,woomera->index_hold); + } + + if (overall_cnt > 10) { //100sec + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + server.process_table[span][chan].dev != woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + usleep(5000); + sched_yield(); + } + + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + } + } + } + + /***************************************************** + * We must wait for WFLAG_WAIT_FOR_STOPPED_ACK here + * so that STOP_ACK can access the woomera + *****************************************************/ + + if (smg_validate_span_chan(span,chan) == 0) { + log_printf(2, woomera->log, + "WOOMERA Clearing Processs Table ... \n", + woomera->interface); + pthread_mutex_lock(&server.process_lock); + if (server.process_table[span][chan].dev == woomera){ + server.process_table[span][chan].dev = NULL; + memset(server.process_table[span][chan].session,0,SMG_SESSION_NAME_SZ); + } + pthread_mutex_unlock(&server.process_lock); + } + +#if 0 +//Used for testing + if (1) { + int chan = woomera->chan; + int span = woomera->span; + if (smg_validate_span_chan(span,chan) == 0) { + pthread_mutex_lock(&server.process_lock); + /* This is possible in case media thread dies on startup */ + + if (server.process_table[span][chan]){ + log_printf(0, server.log, + "Sanity Span Chan Still in use: [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + //server.process_table[span][chan] = NULL; + } + pthread_mutex_unlock(&server.process_lock); + } + } +#endif + + usleep(3000000); + + /* Sanity Check */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP ACK\n"); + goto woo_re_hangup; + } + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP NACK ACK\n"); + goto woo_re_hangup; + } + + /* This is where we actually pull the index + * out of the tank. We had to keep the tank + * value until the end of the call. Tank is only + * used on outgoing calls. */ + if (woomera->index_hold >= 1) { + clear_from_holding_tank(woomera->index_hold); + woomera->index_hold=0; + } + + log_printf(2, woomera->log, "Woomera Thread Finished %u\n", (unsigned long) woomera->thread); + close_socket(&woomera->socket); + woomera->socket=-1; + + /* delete queue */ + while ((event_string = dequeue_event(woomera))) { + free(event_string); + } + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + del_listener(woomera); + } + + log_printf(2, server.log, "WOOMERA session for [%s] stopped (ptr=%p)\n", + woomera->interface,woomera); + + if (woomera_test_flag(woomera, WFLAG_MASTER_DEV)) { + log_printf(0,server.log,"MASTER Thread Stopped (ptr=%p)\n",woomera); + master_reset=0; + } + + + pthread_mutex_destroy(&woomera->queue_lock); + pthread_mutex_destroy(&woomera->ms_lock); + pthread_mutex_destroy(&woomera->dtmf_lock); + pthread_mutex_destroy(&woomera->vlock); + pthread_mutex_destroy(&woomera->flags_lock); + woomera_set_raw(woomera, NULL); + woomera_set_interface(woomera, NULL); + + woomera_message_clear(&wmsg); + + free(woomera); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count--; + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_exit(NULL); + return NULL; +} + + +static int launch_woomera_thread(struct woomera_interface *woomera) +{ + int result = 0; + pthread_attr_t attr; + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_RUNNING); + result = pthread_create(&woomera->thread, &attr, woomera_thread_run, woomera); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! (%i) %s\n", + __FUNCTION__,result,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + +static int launch_monitor_thread(void) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 10; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + log_printf(0,server.log,"%s: Old Priority =%i res=%i \n",__FUNCTION__, + param.sched_priority,result); + + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + result = pthread_create(&server.monitor_thread, &attr, monitor_thread_run, NULL); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +#ifdef WP_HPTDM_API +static void *hp_tdmapi_span_run(void *obj) +{ + hp_tdm_api_span_t *span = obj; + int err; + + log_printf(0,server.log,"Starting %s span!\n",span->ifname); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + break; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + sleep(3); + log_printf(0,server.log,"Stopping %s span!\n",span->ifname); + + pthread_exit(NULL); +} + + +static int launch_hptdm_api_span_thread(int span) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 5; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + result = pthread_create(&server.monitor_thread, &attr, hp_tdmapi_span_run, &hptdmspan[span]); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} +#endif + +static int configure_server(void) +{ + struct woomera_config cfg; + char *var, *val; + int cnt = 0; + + server.dtmf_intr_ch = -1; + + if (!woomera_open_file(&cfg, server.config_file)) { + log_printf(0, server.log, "open of %s failed\n", server.config_file); + return 0; + } + + while (woomera_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(var, "boost_local_ip")) { + strncpy(server.mcon.cfg.local_ip, val, + sizeof(server.mcon.cfg.local_ip) -1); + strncpy(server.mconp.cfg.local_ip, val, + sizeof(server.mconp.cfg.local_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_local_port")) { + server.mcon.cfg.local_port = atoi(val); + server.mconp.cfg.local_port = + server.mcon.cfg.local_port+1; + cnt++; + } else if (!strcasecmp(var, "boost_remote_ip")) { + strncpy(server.mcon.cfg.remote_ip, val, + sizeof(server.mcon.cfg.remote_ip) -1); + strncpy(server.mconp.cfg.remote_ip, val, + sizeof(server.mconp.cfg.remote_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_remote_port")) { + server.mcon.cfg.remote_port = atoi(val); + server.mconp.cfg.remote_port = + server.mcon.cfg.remote_port+1; + cnt++; + } else if (!strcasecmp(var, "logfile_path")) { + if (!server.logfile_path) { + server.logfile_path = strdup(val); + } + } else if (!strcasecmp(var, "woomera_port")) { + server.port = atoi(val); + } else if (!strcasecmp(var, "debug_level")) { + server.debug = atoi(val); + } else if (!strcasecmp(var, "out_tx_test")) { + server.out_tx_test = atoi(val); + } else if (!strcasecmp(var, "loop_trace")) { + server.loop_trace = atoi(val); + } else if (!strcasecmp(var, "rxgain")) { + server.rxgain = atoi(val); + } else if (!strcasecmp(var, "txgain")) { + server.txgain = atoi(val); + } else if (!strcasecmp(var, "dtmf_on_duration")){ + server.dtmf_on = atoi(val); + } else if (!strcasecmp(var, "dtmf_off_duration")){ + server.dtmf_off = atoi(val); + } else if (!strcasecmp(var, "dtmf_inter_ch_duration")){ + server.dtmf_intr_ch = atoi(val); + } else if (!strcasecmp(var, "max_calls")) { + int max = atoi(val); + if (max > 0) { + server.max_calls = max; + } + } else if (!strcasecmp(var, "media_ip")) { + strncpy(server.media_ip, val, sizeof(server.media_ip) -1); + } else { + log_printf(0, server.log, "Invalid Option %s at line %d!\n", var, cfg.lineno); + } + } + + /* Post initialize */ + if (server.dtmf_on == 0){ + server.dtmf_on=SMG_DTMF_ON; + } + if (server.dtmf_off == 0) { + server.dtmf_off=SMG_DTMF_OFF; + } + if (server.dtmf_intr_ch == -1) { + server.dtmf_intr_ch = server.dtmf_on/server.dtmf_off; + } + server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; + + log_printf(0,server.log, "DTMF On=%i Off=%i IntrCh=%i Size=%i\n", + server.dtmf_on,server.dtmf_off,server.dtmf_intr_ch,server.dtmf_size); + + woomera_close_file(&cfg); + return cnt == 4 ? 1 : 0; +} + + + +static int main_thread(void) +{ + + struct sockaddr_in sock_addr, client_addr; + struct woomera_interface *new_woomera; + int client_sock = -1, pid = 0; + unsigned int len = 0; + FILE *tmp; + + if ((server.master_connection.socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + log_printf(0, server.log, "socket() failed\n"); + return 1; + } + + memset(&sock_addr, 0, sizeof(sock_addr)); /* Zero out structure */ + sock_addr.sin_family = AF_INET; /* Internet address family */ + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + sock_addr.sin_port = htons(server.port); /* Local port */ + + /* Bind to the local address */ + if (bind(server.master_connection.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) { + log_printf(0, server.log, "bind(%d) failed\n", server.port); + return 1; + } + + /* Mark the socket so it will listen for incoming connections */ + if (listen(server.master_connection.socket, MAXPENDING) < 0) { + log_printf(0, server.log, "listen() failed\n"); + return 1; + } + + if ((pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "pid %d already exists.\n", pid); + exit(0); + } + + if (!(tmp = safe_fopen(PIDFILE, "w"))) { + log_printf(0, stderr, "Error creating pidfile %s\n", PIDFILE); + return 1; + } else { + fprintf(tmp, "%d", getpid()); + fclose(tmp); + tmp = NULL; + } + + no_nagle(server.master_connection.socket); + +#if 0 + if (1) { + int span,chan; + call_signal_event_t event; +#if 0 + span=1; + chan=30; + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); +#else + for (span=0;span<8;span++) { + for (chan=0;chan<31;chan++) { + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); + } + } +#endif + } +#endif + +#ifdef WP_HPTDM_API + if (1) { + int span; + for (span=0;span<16;span++) { + hptdmspan[span] = sangoma_hptdm_api_span_init(span); + if (!hptdmspan[span]) { + break; + } else { + log_printf(0, server.log, "HP TDM API Span: %d configured...\n", + span); + launch_hptdm_api_span_thread(span); + } + } + } +#endif + + log_printf(1, server.log, "Main Process Started: Woomera Ready port: %d\n", server.port); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + /* Set the size of the in-out parameter */ + len = sizeof(client_addr); + + /* Wait for a client to connect */ + if ((client_sock = accept(server.master_connection.socket, (struct sockaddr *) &client_addr, &len)) < 0) { + log_printf(0, server.log, "accpet() failed\n"); + return 1; + } + + if ((new_woomera = new_woomera_interface(client_sock, &client_addr, len))) { + log_printf(2, server.log, "Starting Thread for New Connection %s:%d Sock=%d\n", + inet_ntoa(new_woomera->addr.sin_addr), + ntohs(new_woomera->addr.sin_port), + client_sock); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count++; + pthread_mutex_unlock(&server.thread_count_lock); + if (launch_woomera_thread(new_woomera)) { + socket_printf(new_woomera->socket, + "501 call was cancelled!%s", + WOOMERA_RECORD_SEPERATOR); + + close_socket(&new_woomera->socket); + new_woomera->socket=-1; + free(new_woomera); + } + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + } + } + + log_printf(1, server.log, "Main Process End\n"); + + return 0; +} + +static int do_ignore(int sig) +{ + return 0; +} + +static int do_shut(int sig) +{ + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + close_socket(&server.master_connection.socket); + log_printf(1, server.log, "Caught SIG %d, Closing Master Socket!\n", sig); + return 0; +} + +static int sangoma_tdm_init (int span) +{ +#ifdef LIBSANGOMA_GET_HWCODING + wanpipe_tdm_api_t tdm_api; + int fd=sangoma_open_tdmapi_span(span); + if (fd < 0 ){ + return -1; + } else { + server.hw_coding=sangoma_tdm_get_hw_coding(fd,&tdm_api); + close_socket(&fd); + } +#else +#error "libsangoma missing hwcoding feature: not up to date!" +#endif + return 0; +} + + +static int woomera_startup(int argc, char **argv) +{ + int x = 0, pid = 0, bg = 0; + char *cfg=NULL, *debug=NULL, *arg=NULL; + + while((arg = argv[x++])) { + + if (!strcasecmp(arg, "-hup")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGHUP); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-term") || !strcasecmp(arg, "--term")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGTERM); + unlink(PIDFILE); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-version")) { + fprintf(stdout, "\nSangoma Media Gateway: Version %s\n\n", SMG_VERSION); + exit(0); + + } else if (!strcasecmp(arg, "-help")) { + fprintf(stdout, "%s\n%s [-help] | [ -version] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(0); + } else if (!strcasecmp(arg, "-wipe")) { + unlink(PIDFILE); + } else if (!strcasecmp(arg, "-bg")) { + bg = 1; + + } else if (!strcasecmp(arg, "-g")) { + coredump = 1; + + } else if (!strcasecmp(arg, "-debug")) { + if (argv[x] && *(argv[x]) != '-') { + debug = argv[x++]; + } + } else if (!strcasecmp(arg, "-cfg")) { + if (argv[x] && *(argv[x]) != '-') { + cfg = argv[x++]; + } + } else if (!strcasecmp(arg, "-log")) { + if (argv[x] && *(argv[x]) != '-') { + server.logfile_path = strdup(argv[x++]); + } + } else if (*arg == '-') { + log_printf(0, stderr, "Unknown Option %s\n", arg); + fprintf(stdout, "%s\n%s [-help] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(1); + } + } + + if (1){ + int spn; + for (spn=1;spn<=WOOMERA_MAX_SPAN;spn++) { + if (sangoma_tdm_init(spn) == 0) { + break; + } + } + if (spn>WOOMERA_MAX_SPAN) { + printf("\nError: Failed to access a channel on spans 1-16\n"); + printf(" Please start Wanpipe TDM API drivers\n"); + return 0; + } + } + + if (bg && (pid = fork())) { + log_printf(0, stderr, "Backgrounding!\n"); + return 0; + } + + q931_cause_setup(); + + server.port = 42420; + server.debug = 0; + strcpy(server.media_ip, "127.0.0.1"); + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + server.log = stdout; + server.master_connection.socket = -1; + server.master_connection.event_queue = NULL; + server.config_file = cfg ? cfg : "/etc/sangoma_mgd.conf"; + pthread_mutex_init(&server.listen_lock, NULL); + pthread_mutex_init(&server.ht_lock, NULL); + pthread_mutex_init(&server.process_lock, NULL); + pthread_mutex_init(&server.media_udp_port_lock, NULL); + pthread_mutex_init(&server.thread_count_lock, NULL); + pthread_mutex_init(&server.master_connection.queue_lock, NULL); + pthread_mutex_init(&server.master_connection.flags_lock, NULL); + pthread_mutex_init(&server.mcon.lock, NULL); + server.master_connection.chan = -1; + server.master_connection.span = -1; + + if (!configure_server()) { + log_printf(0, server.log, "configuration failed!\n"); + return 0; + } + +#ifndef USE_SYSLOG + if (server.logfile_path) { + if (!(server.log = safe_fopen(server.logfile_path, "a"))) { + log_printf(0, stderr, "Error setting logfile %s!\n", server.logfile_path); + server.log = stderr; + return 0; + } + } +#endif + + + if (debug) { + server.debug = atoi(debug); + } + + if (coredump) { + struct rlimit l; + memset(&l, 0, sizeof(l)); + l.rlim_cur = RLIM_INFINITY; + l.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &l)) { + log_printf(0, stderr, "Warning: Failed to disable core size limit: %s\n", + strerror(errno)); + } + } + +#ifdef __LINUX__ + if (geteuid() && coredump) { + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { + log_printf(0, stderr, "Warning: Failed to disable core size limit for non-root: %s\n", + strerror(errno)); + } + } +#endif + + + + (void) signal(SIGINT,(void *) do_shut); + (void) signal(SIGPIPE,(void *) do_ignore); + (void) signal(SIGHUP,(void *) do_shut); + -SMG_DTMF=YES -<<<<<<< .mine + woomera_set_flag(&server.master_connection, WFLAG_RUNNING); + if (launch_monitor_thread()) { + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + return 0; + } + + fprintf(stderr, "%s", WELCOME_TEXT); + log_printf(0, stderr, "Woomera STARTUP Complete.\n"); -======= - ->>>>>>> .r15 -#Default kernel directory to be overwritten by user -#Kernel version and location -ifndef KVER - KVER=$(shell uname -r) -endif -ifndef KMOD - KMOD=/lib/modules/$(KVER) -endif -ifndef KDIR - KDIR=$(KMOD)/build -endif -ifndef KINSTDIR - KINSTDIR=$(KMOD)/kernel -endif + return 1; +} -CC = gcc +static int woomera_shutdown(void) +{ + char *event_string; + int told = 0, loops = 0; -INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src - -CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 -CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g -LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm + close_socket(&server.master_connection.socket); + pthread_mutex_destroy(&server.listen_lock); + pthread_mutex_destroy(&server.ht_lock); + pthread_mutex_destroy(&server.process_lock); + pthread_mutex_destroy(&server.media_udp_port_lock); + pthread_mutex_destroy(&server.thread_count_lock); + pthread_mutex_destroy(&server.master_connection.queue_lock); + pthread_mutex_destroy(&server.master_connection.flags_lock); + pthread_mutex_destroy(&server.mcon.lock); + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); -ifeq "${SMG_DTMF}" "YES" -LDFLAGS+= -lteletone -CFLAGS+= -DSMG_DTMF_ENABLE -endif + if (server.logfile_path) { + free(server.logfile_path); + server.logfile_path = NULL; + } + /* delete queue */ + while ((event_string = dequeue_event(&server.master_connection))) { + free(event_string); + } -all: sangoma_mgd + while(server.thread_count > 0) { + loops++; -libs: - $(shell cd lib/libteletone; ./configure; cd ../../; ) - $(MAKE) -C lib/libteletone all + if (loops % 1000 == 0) { + told = 0; + } -switch_buffer.o: switch_buffer.c switch_buffer.h - $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o switch_buffer.o switch_buffer.c + if (loops > 10000) { + log_printf(0, server.log, "Red Alert! threads did not stop\n"); + assert(server.thread_count == 0); + } -call_signal.o: call_signal.c call_signal.h - $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o call_signal.o call_signal.c + if (told != server.thread_count) { + log_printf(1, server.log, "Waiting For %d thread%s.\n", + server.thread_count, server.thread_count == 1 ? "" : "s"); + told = server.thread_count; + } + ysleep(10000); + } + unlink(PIDFILE); + log_printf(0, stderr, "Woomera SHUTDOWN Complete.\n"); + return 0; +} -sangoma_mgd: sangoma_mgd.o call_signal.o switch_buffer.o sigboost.h - rm -fr core* - $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -o sangoma_mgd sangoma_mgd.o switch_buffer.o call_signal.o $(LDFLAGS) +int main(int argc, char *argv[]) +{ + int ret = 0; + + mlockall(MCL_FUTURE); + -sangoma_mgd.o: sangoma_mgd.c sangoma_mgd.h sigboost.h - $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o sangoma_mgd.o sangoma_mgd.c + server.hw_coding=0; + openlog (ps_progname ,LOG_PID, LOG_LOCAL2); + + if (! (ret = woomera_startup(argc, argv))) { + exit(0); + } + ret = main_thread(); -clean: old_cleanup - make -C lib/libteletone clean - find . -name '*.o' | xargs rm -f - rm -fr sangoma_mgd pritest *.o *.so *~ *core* *.so* *.a - -distclean: clean - @echo OK - -install: all install_smg old_cleanup - -install_smg: old_cleanup - install -D -m 755 sangoma_mgd $(INSTALLPREFIX)/usr/sbin/sangoma_mgd - @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ - install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ - fi - install -D -m 755 smg_ctrl /usr/sbin/smg_ctrl - install -D -m 755 scripts/init.d/smgss7_init_ctrl /etc/init.d - @echo "sangoma_mgd Installed" - -old_cleanup: - ./scripts/old_cleanup.sh - - -install_woomera: - install -D -m 755 chan_woomera.so $(INSTALLPREFIX)/usr/lib/asterisk/modules/chan_woomera.so - @if [ ! -e $(INSTALLPREFIX)/etc/asterisk/woomera.conf ]; then \ - install -D -m 755 woomera.conf $(INSTALLPREFIX)/etc/asterisk/woomera.conf; \ - fi - @echo "chan_woomera Installed" - - -install_all: all install_smg install_woomera - -uninstall: - /bin/rm /usr/sbin/sangoma_mgd /etc/sangoma_mgd.conf + woomera_shutdown(); + return ret; +} +/** EMACS ** + * Local variables: + * mode: C + * c-basic-offset: 4 + * End: + */ diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp index c8d853a..b9f500e 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.3.tmp @@ -30,7 +30,6 @@ ifndef KINSTDIR endif CC = gcc -INSTALLPREFIX= INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src @@ -48,7 +47,7 @@ endif all: sangoma_mgd libs: - $(shell cd lib/libteletone; ./configure --prefix=$(INSTALLPREFIX); cd ../../; ) + $(shell cd lib/libteletone; ./configure; cd ../../; ) $(MAKE) -C lib/libteletone all switch_buffer.o: switch_buffer.c switch_buffer.h @@ -80,16 +79,26 @@ install_smg: old_cleanup @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ fi +<<<<<<< .mine +======= install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl - install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/usr/sbin/smgss7_init_ctrl +>>>>>>> .r24 @echo "sangoma_mgd Installed" old_cleanup: ./scripts/old_cleanup.sh -install_all: all install_smg +install_woomera: + install -D -m 755 chan_woomera.so $(INSTALLPREFIX)/usr/lib/asterisk/modules/chan_woomera.so + @if [ ! -e $(INSTALLPREFIX)/etc/asterisk/woomera.conf ]; then \ + install -D -m 755 woomera.conf $(INSTALLPREFIX)/etc/asterisk/woomera.conf; \ + fi + @echo "chan_woomera Installed" + + +install_all: all install_smg install_woomera uninstall: /bin/rm $(INSTALLPREFIX)/usr/sbin/sangoma_mgd $(INSTALLPREFIX)/etc/sangoma_mgd.conf diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp index 3599227..c8061da 100644 --- a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.4.tmp @@ -8,27 +8,6 @@ * the GNU General Public License * * ============================================= -<<<<<<< .mine - * v1.22 Nenad Corbic - * Bug fix on socket open. Check for retun code >= 0 - * -======= - * v1.22 Nenad Corbic - * Nov 27 2007 - * Updated DTMF Tx function - * Fixed - dtmf tx without voice - * Fxied - dtmf clipping. - * ->>>>>>> .r41 - * v1.21 Nenad Corbic - * Nov 25 2007 - * Major unit testing of each state - * Numerous bug fixes for non autoacm mode. - * Changed "Channel-Name" to tg/cic - * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel - * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) - * instead of WOOMERA (for example) - * * v1.20 Nenad Corbic * Added option for Auto ACM response mode. * @@ -123,7 +102,7 @@ static struct woomera_interface woomera_dead_dev; #endif -#define SMG_VERSION "v1.22" +#define SMG_VERSION "v1.20" /* enable early media */ #if 1 @@ -136,9 +115,11 @@ static struct woomera_interface woomera_dead_dev; #define SMG_DTMF_RATE 8000 #if 0 +#warning "NENAD: MEDIA SHUTDOWN" #define MEDIA_SOCK_SHUTDOWN 1 #endif + #ifdef DOTRACE static int tc = 0; #endif @@ -154,11 +135,9 @@ static int tc = 0; hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; #endif -#undef SMG_CALLING_NAME - const char WELCOME_TEXT[] = "================================================================================\n" -"Sangoma Media Gateway Daemon v1.22 \n" +"Sangoma Media Gateway Daemon v1.20 \n" "TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" "Copyright 2005, 2006, 2007 \n" "Nenad Corbic , Anthony Minessale II \n" @@ -639,7 +618,7 @@ static void add_listener(struct woomera_interface *woomera) } - +#ifdef SMG_DTMF_ENABLE static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) { struct media_session *ms = woomera_get_ms(woomera); @@ -687,6 +666,7 @@ static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) ms->skip_read_frames = 200; return 0; } +#endif static struct woomera_interface *alloc_woomera(void) { @@ -791,41 +771,6 @@ static int waitfor_socket(int fd, int timeout, int flags) return res; } - -static int waitfor_tx_socket(int fd, int timeout, int flags) -{ - struct pollfd pfds[1]; - int res; - - memset(&pfds[0], 0, sizeof(pfds[0])); - pfds[0].fd = fd; - pfds[0].events = flags; - res = poll(pfds, 1, timeout); - - if (res > 0) { - if (pfds[0].revents & POLLOUT) { - res = 1; - } else if ((pfds[0].revents & POLLERR)) { - res = -1; - } else if ((pfds[0].revents & POLLNVAL)) { - res = -2; -#if 0 - log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", - pfds[0].revents, fd); -#endif - } else { -#if 0 - log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", - pfds[0].revents,fd); -#endif - res = -1; - } - } - - return res; -} - - #else static int waitfor_socket(int fd, int timeout, int flags) @@ -939,6 +884,7 @@ static struct media_session *media_session_new(struct woomera_interface *woomera woomera_set_ms(woomera,ms); ms->woomera = woomera; +#ifdef SMG_DTMF_ENABLE /* Setup artificial DTMF stuff */ memset(&ms->tone_session, 0, sizeof(ms->tone_session)); if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { @@ -951,6 +897,7 @@ static struct media_session *media_session_new(struct woomera_interface *woomera ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); +#endif } else { log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", @@ -966,8 +913,10 @@ static void media_session_free(struct media_session *ms) free(ms->ip); } +#ifdef SMG_DTMF_ENABLE teletone_destroy_session(&ms->tone_session); switch_buffer_destroy(&ms->dtmf_buffer); +#endif ms->woomera = NULL; @@ -986,7 +935,7 @@ static int create_udp_socket(struct media_session *ms, char *local_ip, int local memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); memset(&ms->local_hp, 0, sizeof(ms->local_hp)); - if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0))) { gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); if (result && local_result) { @@ -1038,7 +987,7 @@ static int next_media_port(void) return port; } - +#ifdef SMG_DTMF_ENABLE static int woomera_dtmf_transmit(struct media_session *ms, int mtu) { @@ -1051,9 +1000,6 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) int slin_len = mtu*2; short *data; int used; - int res; - int err; - int txdtmf=0; memset(&hdrframe,0,sizeof(hdrframe)); if (!ms->dtmf_buffer) { @@ -1061,17 +1007,8 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) } for (;;) { - - if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { - break; - } - res = waitfor_tx_socket(ms->sangoma_sock, -1, POLLERR | POLLOUT); - if (res <= 0) { - break; - } - -#ifdef CODEC_LAW_DEFAULT +#ifdef CODEC_LAW_DEFAULT pthread_mutex_lock(&woomera->dtmf_lock); if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { @@ -1085,6 +1022,14 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) if (bread <= 0) { break; } + +#if 0 + if (bread < slin_len) { + while (bread < slin_len) { + dtmf[bread++] = 0xFF; + } + } +#endif log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", woomera->interface,bread,mtu,ms->hw_coding,used); @@ -1100,23 +1045,24 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) } } - err=sangoma_sendmsg_socket(ms->sangoma_sock, + sangoma_sendmsg_socket(ms->sangoma_sock, &hdrframe, sizeof(hdrframe), dtmf_law, mtu, 0); - - if (err != mtu) { - log_printf(0, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu); - } - - txdtmf++; - ms->skip_write_frames++; + + ms->skip_write_frames+=server.dtmf_intr_ch; #else ... pthread_mutex_lock(&woomera->dtmf_lock); bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); pthread_mutex_unlock(&woomera->dtmf_lock); + if (bread < mtu) { + while (bread < mtu) { + dtmf[bread++] = 0; + } + } + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", woomera->interface,bread); @@ -1124,18 +1070,14 @@ static int woomera_dtmf_transmit(struct media_session *ms, int mtu) &hdrframe, sizeof(hdrframe), dtmf, mtu, 0); - txdtmf++; ms->skip_write_frames++; #endif - - } - - if (txdtmf) { return 0; - } else { - return -1; - } + } + + return -1; } +#endif static void media_loop_run(struct media_session *ms) { @@ -1308,7 +1250,6 @@ static void *media_thread_run(void *obj) struct woomera_event wevent; wanpipe_tdm_api_t tdm_api; FILE *tx_fd=NULL; - int sock_timeout=200; if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || @@ -1463,7 +1404,7 @@ static void *media_thread_run(void *obj) local_port, WOOMERA_LINE_SEPERATOR, woomera->interface, - WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, WOOMERA_RECORD_SEPERATOR ); #endif @@ -1489,23 +1430,12 @@ static void *media_thread_run(void *obj) while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && !woomera_test_flag(woomera, WFLAG_MEDIA_END) && !woomera_test_flag(woomera, WFLAG_HANGUP) && - (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { + (res = waitfor_socket(ms->udp_sock, 1000, POLLERR | POLLIN)) >= 0) { unsigned int fromlen = sizeof(struct sockaddr_in); if (res == 0) { - - if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { - sock_timeout=(sangoma_frame_len/codec_sample); - } else { - sock_timeout=200; - } - - if (ms->skip_write_frames > 0) { - ms->skip_write_frames--; - } - log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", woomera->interface); /* NENAD Timeout thus just continue */ @@ -1550,26 +1480,22 @@ static void *media_thread_run(void *obj) } - if (!server.out_tx_test) { - - if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { - sock_timeout=(sangoma_frame_len/codec_sample); - /* For sanity sake if we are doing the out test - * dont take any chances force tx udp data */ +#ifdef SMG_DTMF_ENABLE + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ + if (!server.out_tx_test) { if (ms->skip_write_frames > 0) { - ms->skip_write_frames--; + ms->skip_write_frames--; } continue; - } else { - sock_timeout=200; } - - if (ms->skip_write_frames > 0) { - ms->skip_write_frames--; - continue; - } - - } + } + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } +#endif if (server.out_tx_test && tx_fd && fread((void*)udp_frame, @@ -1877,10 +1803,6 @@ static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t } woomera_set_interface(woomera,callid); - - pthread_mutex_lock(&server.process_lock); - server.process_table[event->span][event->chan].dev = woomera; - pthread_mutex_unlock(&server.process_lock); if (launch_woomera_thread(woomera)) { pthread_mutex_lock(&server.process_lock); @@ -2106,10 +2028,8 @@ static struct woomera_interface *pull_from_holding_tank(int index, int span , in struct woomera_interface *woomera = NULL; if (index < 1 || index >= CORE_TANK_LEN) { - if (index != 0) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); - } + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); return NULL; } @@ -2131,25 +2051,18 @@ static struct woomera_interface *pull_from_holding_tank(int index, int span , in return woomera; } -static void clear_from_holding_tank(int index, struct woomera_interface *woomera) +static void clear_from_holding_tank(int index) { if (index < 1 || index >= CORE_TANK_LEN) { - if (index != 0) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); - } + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); return; } pthread_mutex_lock(&server.ht_lock); if (server.holding_tank[index] == &woomera_dead_dev) { - server.holding_tank[index] = NULL; - } else if (woomera && server.holding_tank[index] == woomera) { - server.holding_tank[index] = NULL; - } else if (server.holding_tank[index]) { - log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", - index, server.holding_tank[index]); + server.holding_tank[index] = NULL; } pthread_mutex_unlock(&server.ht_lock); @@ -2161,10 +2074,8 @@ static struct woomera_interface *peek_from_holding_tank(int index) struct woomera_interface *woomera = NULL; if (index < 1 || index >= CORE_TANK_LEN) { - if (index != 0) { - log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", - __FUNCTION__,index); - } + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); return NULL; } @@ -2257,7 +2168,6 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); -#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2265,7 +2175,7 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); -#endif + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" @@ -2378,20 +2288,18 @@ static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - } + } - return 0; + return 0; } -static int handle_woomera_call_start (struct woomera_interface *woomera, - struct woomera_message *wmsg) +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) { - char *raw = woomera_message_header(wmsg, "raw-audio"); - call_signal_event_t event; - char *calling = woomera_message_header(wmsg, "local-number"); -#ifdef SMG_CALLING_NAME - char *calling_name = woomera_message_header(wmsg, "local-name"); -#endif + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); + char *calling_name = woomera_message_header(wmsg, "local-name"); char *presentation = woomera_message_header(wmsg, "Presentation"); char *screening = woomera_message_header(wmsg, "Screening"); char *rdnis = woomera_message_header(wmsg, "RDNIS"); @@ -2419,8 +2327,6 @@ static int handle_woomera_call_start (struct woomera_interface *woomera, } } - woomera->trunk_group=tg; - if (raw) { woomera_set_raw(woomera, raw); } @@ -2459,12 +2365,10 @@ static int handle_woomera_call_start (struct woomera_interface *woomera, } -#ifdef SMG_CALLING_NAME if (calling_name) { strncpy((char*)event.calling_name,calling_name, sizeof(event.calling_name)-1); } -#endif event.trunk_group = tg; @@ -2492,7 +2396,6 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ { int answer = 0, media = 0, accept=0; char *unique_id; - int cause=0; if (!strcasecmp(wmsg->command, "call")) { @@ -2507,7 +2410,7 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ err=handle_woomera_call_start(woomera,wmsg); if (err) { - woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_RUNNING); } return; @@ -2584,21 +2487,13 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); if (!unique_id) { - - cause=111; - socket_printf(woomera->socket, "EVENT HANGUP %s" - "Cause: %s%s" - "Q931-Cause-Code: %d%s", - WOOMERA_LINE_SEPERATOR, - q931_rel_to_str(cause), - WOOMERA_LINE_SEPERATOR, - cause, - WOOMERA_RECORD_SEPERATOR); - socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + socket_printf(woomera->socket, "400 Error no unique id found %s", WOOMERA_RECORD_SEPERATOR); + log_printf(2,server.log,"Woomera RX Even (%s) without unique id!\n",wmsg->command); - log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); - woomera_set_flag(woomera, WFLAG_HANGUP); + if (!strcasecmp(wmsg->command, "hangup")) { + woomera_clear_flag(woomera, WFLAG_RUNNING); + } return; } @@ -2616,24 +2511,15 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", wmsg->command,span,chan,unique_id); + if (smg_validate_span_chan(span,chan) != 0) { - - cause=34; - socket_printf(woomera->socket, "EVENT HANGUP %s" - "Cause: %s%s" - "Q931-Cause-Code: %d%s", - WOOMERA_LINE_SEPERATOR, - q931_rel_to_str(cause), - WOOMERA_LINE_SEPERATOR, - cause, - WOOMERA_RECORD_SEPERATOR); - socket_printf(woomera->socket, "404 Invalid span/chan in session%s" + socket_printf(woomera->socket, + "400 Error invalid span chan in session! %s", WOOMERA_RECORD_SEPERATOR); - + log_printf(2, woomera->log, "WOOMERA Warning invalid span chan in session %s %s\n", wmsg->command,unique_id); - woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2644,22 +2530,11 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ if (session_woomera) { pthread_mutex_unlock(&server.process_lock); - cause=34; - socket_printf(woomera->socket, "EVENT HANGUP %s" - "Cause: %s%s" - "Q931-Cause-Code: %d%s", - WOOMERA_LINE_SEPERATOR, - q931_rel_to_str(cause), - WOOMERA_LINE_SEPERATOR, - cause, - WOOMERA_RECORD_SEPERATOR); - socket_printf(woomera->socket, "404 Session not found%s" + socket_printf(woomera->socket, "400 Error channel in use! %s", WOOMERA_RECORD_SEPERATOR); - log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", wmsg->command,unique_id); - woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2667,23 +2542,11 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ strncmp(session,unique_id,sizeof(woomera->session))){ pthread_mutex_unlock(&server.process_lock); - cause=34; - socket_printf(woomera->socket, "EVENT HANGUP %s" - "Cause: %s%s" - "Q931-Cause-Code: %d%s", - WOOMERA_LINE_SEPERATOR, - q931_rel_to_str(cause), - WOOMERA_LINE_SEPERATOR, - cause, - WOOMERA_RECORD_SEPERATOR); - - socket_printf(woomera->socket, "404 Invalid/Expired Session%s" + socket_printf(woomera->socket, "400 Error no such session %s", WOOMERA_RECORD_SEPERATOR); - - log_printf(3, woomera->log, + log_printf(2, woomera->log, "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", wmsg->command,unique_id,session?session:"N/A"); - woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2703,20 +2566,8 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { - - cause=34; - socket_printf(woomera->socket, "EVENT HANGUP %s" - "Cause: %s%s" - "Q931-Cause-Code: %d%s", - WOOMERA_LINE_SEPERATOR, - q931_rel_to_str(cause), - WOOMERA_LINE_SEPERATOR, - cause, - WOOMERA_RECORD_SEPERATOR); - - socket_printf(woomera->socket, "404 Session Mis-match%s" + socket_printf(woomera->socket, "400 Error session missmatch %s", WOOMERA_RECORD_SEPERATOR); - woomera_set_flag(woomera, WFLAG_HANGUP); return; } @@ -2726,8 +2577,9 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", woomera->interface, wmsg->command_args, wmsg->body); +#ifdef SMG_DTMF_ENABLE wanpipe_send_dtmf(woomera,wmsg->body); - +#endif socket_printf(woomera->socket, "200 DTMF OK%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2753,7 +2605,6 @@ static void interpret_command(struct woomera_interface *woomera, struct woomera_ woomera->interface,cause); if (smg_validate_span_chan(span,chan) != 0) { - socket_printf(woomera->socket, "405 No Such Channel%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2861,7 +2712,6 @@ static void handle_call_answer(call_signal_event_t *event) if (err) { log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); -#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2869,8 +2719,7 @@ static void handle_call_answer(call_signal_event_t *event) WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); -#endif - + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" "Q931-Cause-Code: %d%s" @@ -2946,7 +2795,7 @@ static void handle_call_start_ack(call_signal_event_t *event) struct woomera_event wevent; int kill = 0; - if ((woomera = peek_from_holding_tank(event->call_setup_id))) { + if ((woomera = pull_from_holding_tank(event->call_setup_id,event->span,event->chan))) { char callid[80]; if (woomera_test_flag(woomera, WFLAG_HANGUP)) { @@ -2954,14 +2803,11 @@ static void handle_call_start_ack(call_signal_event_t *event) kill++; } else { int err, span, chan; - - pull_from_holding_tank(event->call_setup_id,event->span,event->chan); sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); span = event->span; chan = event->chan; - woomera_set_flag(woomera,WFLAG_CALL_ACKED); woomera_set_interface(woomera, callid); pthread_mutex_lock(&server.process_lock); @@ -2979,8 +2825,6 @@ static void handle_call_start_ack(call_signal_event_t *event) log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", woomera->interface); - -#if 0 new_woomera_event_printf(&wevent, "501 call was cancelled!%s" "Unique-Call-Id: %s%s", WOOMERA_LINE_SEPERATOR, @@ -2988,8 +2832,7 @@ static void handle_call_start_ack(call_signal_event_t *event) WOOMERA_RECORD_SEPERATOR); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); -#endif - + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id:%s%s" "Q931-Cause-Code: %d%s" @@ -3021,14 +2864,10 @@ static void handle_call_start_ack(call_signal_event_t *event) enqueue_event(woomera, &wevent,EVENT_FREE_DATA); new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" - "Channel-Name: g%d/%d%s" "Unique-Call-Id: %s%s", event->span+1, event->chan+1, WOOMERA_LINE_SEPERATOR, - woomera->trunk_group+1, - (event->span*31)+event->chan+1, - WOOMERA_LINE_SEPERATOR, woomera->session, WOOMERA_RECORD_SEPERATOR ); @@ -3090,7 +2929,7 @@ static void handle_call_start_nack(call_signal_event_t *event) } if (event->call_setup_id > 0) { - woomera=peek_from_holding_tank(event->call_setup_id); + woomera=pull_from_holding_tank(event->call_setup_id,-1,-1); } if (woomera) { @@ -3098,20 +2937,15 @@ static void handle_call_start_nack(call_signal_event_t *event) struct woomera_event wevent; woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); - - /* Only pull the index if we have not sent a NACK. - If NACK was already sent out we must wait for ACK - from the other side */ - if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { - pull_from_holding_tank(event->call_setup_id,-1,-1); - } - + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); isup_exec_command(0, 0, event->call_setup_id, SIGBOOST_EVENT_CALL_START_NACK_ACK, 0); + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", event->call_setup_id); @@ -3119,6 +2953,14 @@ static void handle_call_start_nack(call_signal_event_t *event) woomera_set_cause_topbx(woomera,event->release_cause); + new_woomera_event_printf(&wevent, "501 Error!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" "Unique-Call-Id: %s%s" "Cause: %s%s" @@ -3135,7 +2977,6 @@ static void handle_call_start_nack(call_signal_event_t *event) ); enqueue_event(woomera, &wevent,EVENT_FREE_DATA); - woomera_set_flag(woomera, WFLAG_HANGUP); woomera_clear_flag(woomera, WFLAG_RUNNING); @@ -3149,36 +2990,37 @@ static void handle_call_start_nack(call_signal_event_t *event) pthread_mutex_lock(&server.process_lock); woomera = server.process_table[event->span][event->chan].dev; - - if (woomera && - !woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK) && - !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { - /* Only if we are not already waiting for hangup */ - server.process_table[event->span][event->chan].dev=NULL; - } - + server.process_table[event->span][event->chan].dev=NULL; memset(server.process_table[event->span][event->chan].session, 0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); - if (woomera) { log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", woomera->span+1,woomera->chan+1,woomera,woomera->ms); - - if (woomera_test_flag(woomera,WFLAG_HANGUP)){ - ack++; - goto handle_call_start_nack_skip; - } - - - woomera_set_cause_topbx(woomera,event->release_cause); - + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); woomera_set_flag(woomera, - (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + (WFLAG_HANGUP|WFLAG_MEDIA_END)); - /* Nack Ack will be sent by the woomera thread */ + isup_exec_command(event->span, + event->chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + +#ifdef MEDIA_SOCK_SHUTDOWN + pthread_mutex_lock(&woomera->ms_lock); + if (woomera->ms) { + shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); + shutdown(woomera->ms->udp_sock, SHUT_RDWR); + } + pthread_mutex_unlock(&woomera->ms_lock); +#endif + + + /* We already did the NACK */ ack=0; } else { /* Valid state when we are not in autoacm mode */ @@ -3193,14 +3035,16 @@ static void handle_call_start_nack(call_signal_event_t *event) event->call_setup_id, event->span+1, event->chan+1); ack++; } +<<<<<<< .mine +#if 0 +======= -handle_call_start_nack_skip: - +>>>>>>> .r33 if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { log_printf(0, server.log, "WARNING: All ckt busy!\n"); smg_all_ckt_busy(); } - +#endif #warning "Ignoring CALL GAP" #if 0 if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { @@ -3222,18 +3066,16 @@ handle_call_start_nack_skip: SIGBOOST_EVENT_CALL_START_NACK_ACK, 0); - if (!woomera) { + log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", event->event_id,event->call_setup_id, event->span+1, event->chan+1); - } } } static void handle_call_loop_start(call_signal_event_t *event) { + struct woomera_interface *woomera; - char callid[20]; - char *session; pthread_mutex_lock(&server.process_lock); if (server.process_table[event->span][event->chan].dev) { @@ -3253,14 +3095,7 @@ static void handle_call_loop_start(call_signal_event_t *event) return; } - - sprintf(callid, "w%dg%d", event->span+1,event->chan+1); - sprintf(server.process_table[event->span][event->chan].session, - "%s-%i-%i",callid,rand(),rand()); - session=server.process_table[event->span][event->chan].session; - server.process_table[event->span][event->chan].dev = NULL; - pthread_mutex_unlock(&server.process_lock); - + pthread_mutex_unlock(&server.process_lock); woomera=launch_woomera_loop_thread(event); if (woomera == NULL) { @@ -3274,7 +3109,6 @@ static void handle_call_loop_start(call_signal_event_t *event) event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); } - woomera_set_flag(woomera,WFLAG_CALL_ACKED); return; } @@ -3326,7 +3160,7 @@ static void handle_call_start(call_signal_event_t *event) "Protocol: SS7%s" "User-Agent: sangoma_mgd%s" "Local-Number: %s%s" - "Channel-Name: g%d/%d%s" + "Channel-Name: SMG-g%ds%dc%d%s" "Trunk-Group: %d%s" "Presentation: %d%s" "Screening: %d%s" @@ -3339,18 +3173,15 @@ static void handle_call_start(call_signal_event_t *event) WOOMERA_LINE_SEPERATOR, event->calling_number_digits, WOOMERA_LINE_SEPERATOR, -#ifdef SMG_CALLING_NAME event->calling_name, -#else - "", -#endif WOOMERA_LINE_SEPERATOR, WOOMERA_LINE_SEPERATOR, WOOMERA_LINE_SEPERATOR, event->called_number_digits, WOOMERA_LINE_SEPERATOR, event->trunk_group+1, - (event->span*31)+event->chan+1, + event->span+1, + event->chan+1, WOOMERA_LINE_SEPERATOR, event->trunk_group+1, WOOMERA_LINE_SEPERATOR, @@ -3409,44 +3240,33 @@ static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_ static void handle_call_stop(call_signal_event_t *event) { struct woomera_interface *woomera; - int ack=0; - + pthread_mutex_lock(&server.process_lock); woomera = server.process_table[event->span][event->chan].dev; - if (woomera && - !woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK) && - !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { - /* Only if we are not already waiting for hangup */ - server.process_table[event->span][event->chan].dev=NULL; - } + server.process_table[event->span][event->chan].dev=NULL; memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); pthread_mutex_unlock(&server.process_lock); if (woomera) { - - if (woomera_test_flag(woomera,WFLAG_HANGUP)) { - ack++; - goto handle_call_stop_skip; - } - + woomera_set_cause_topbx(woomera,event->release_cause); - - woomera_set_flag(woomera, - (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); - /* We have to close the socket because - At this point we are release span chan */ + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP)); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); #ifdef MEDIA_SOCK_SHUTDOWN pthread_mutex_lock(&woomera->ms_lock); if (woomera->ms) { - log_printf(3, server.log, "Event CALL STOP [w%dg%d] closing sockets\n", - woomera->span+1,woomera->chan+1); - - close_socket(&woomera->ms->sangoma_sock); - close_socket(&woomera->ms->udp_sock); - // shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); - // shutdown(woomera->ms->udp_sock, SHUT_RDWR); + shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); + shutdown(woomera->ms->udp_sock, SHUT_RDWR); } pthread_mutex_unlock(&woomera->ms_lock); #endif @@ -3455,12 +3275,7 @@ static void handle_call_stop(call_signal_event_t *event) woomera->span+1,woomera->chan+1,woomera,woomera->ms); } else { - ack++; - } - -handle_call_stop_skip: - - if (ack) { + /* At this point we have already sent our STOP so its safe to ACK */ isup_exec_command(event->span, event->chan, @@ -3519,7 +3334,6 @@ static void handle_call_stop_ack(call_signal_event_t *event) return; } - static void handle_call_start_nack_ack(call_signal_event_t *event) { @@ -3529,33 +3343,17 @@ static void handle_call_start_nack_ack(call_signal_event_t *event) woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - } else if (event->call_setup_id == 0 && - smg_validate_span_chan(event->span,event->chan) == 0) { - - pthread_mutex_lock(&server.process_lock); - woomera = server.process_table[event->span][event->chan].dev; - server.process_table[event->span][event->chan].dev=NULL; - memset(server.process_table[event->span][event->chan].session, - 0,SMG_SESSION_NAME_SZ); - pthread_mutex_unlock(&server.process_lock); - - if (woomera) { - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - } else { - log_printf(0, server.log, - "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", - event->span+1, event->chan+1); - } - } else { log_printf(2, server.log, "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", event->span+1, event->chan+1, event->call_setup_id); } +#if 1 if (event->call_setup_id > 0) { - clear_from_holding_tank(event->call_setup_id, NULL); + clear_from_holding_tank(event->call_setup_id); } +#endif /* No need for us to do any thing here */ return; @@ -3860,8 +3658,6 @@ static void woomera_loop_thread_run(struct woomera_interface *woomera) continue; } - - woomera_clear_flag(woomera, WFLAG_RUNNING); log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); @@ -3962,7 +3758,7 @@ static void *woomera_thread_run(void *obj) "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", woomera,woomera->interface,woomera->timeout); - /* Let the Index check below send a NACK */ + /* NENAD Let the Index check run a nak */ if (woomera->index) { woomera_set_flag(woomera, WFLAG_HANGUP); } @@ -4046,12 +3842,9 @@ woomera_session_close: /* This can happend if an outgoing call times out or gets hungup before it gets acked. Its not a failure */ - if (!woomera->index) { - /* In this case we really failed to tx STOP */ - log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + log_printf(3, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", span+1, chan+1, woomera->interface, woomera->index, woomera); - } } } @@ -4124,7 +3917,8 @@ woo_re_hangup: if (woomera->index) { int index = woomera->index; - + int timeout_cnt=0; + int overall_cnt=0; new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" "Unique-Call-Id: %s%s" @@ -4161,53 +3955,47 @@ woo_re_hangup: log_printf(2, woomera->log, "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", index); - } - } - - if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { - int timeout_cnt=0; - int overall_cnt=0; + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 40000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] ... \n", + index); + } - /* SMG sent NACK to boost, however we have to wait - for boost to give us the ACK back before we - release resources. */ - - while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { - timeout_cnt++; - if (timeout_cnt > 4000) { //30sec timeout - timeout_cnt=0; - overall_cnt++; + if (overall_cnt > 10) { //100sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); + } + + if (overall_cnt > 10) { log_printf(0, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] ... \n", + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", index); - } - if (overall_cnt > 10) { //300sec timeotu - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - break; } - - if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { - break; - } - - usleep(5000); - sched_yield(); } - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); - if (overall_cnt > 10) { - log_printf(0, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", - index); - - } else { - log_printf(2, woomera->log, - "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", - index); - - } } if (woomera_test_flag(woomera, WFLAG_EVENT)){ @@ -4233,7 +4021,7 @@ woo_re_hangup: while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { timeout_cnt++; - if (timeout_cnt > 4000) { //10sec timeout + if (timeout_cnt > 40000) { //10sec timeout timeout_cnt=0; overall_cnt++; log_printf(0, woomera->log, @@ -4256,18 +4044,18 @@ woo_re_hangup: usleep(5000); sched_yield(); } - - woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); - if (overall_cnt > 10) { - log_printf(0, woomera->log, - "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", - woomera->interface,woomera->index_hold); + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); - } else { - log_printf(2, woomera->log, - "Wait GOT STOPPED ACK [%s] [id=%i]... \n", - woomera->interface,woomera->index_hold); + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + } } } @@ -4327,7 +4115,7 @@ woo_re_hangup: * value until the end of the call. Tank is only * used on outgoing calls. */ if (woomera->index_hold >= 1) { - clear_from_holding_tank(woomera->index_hold, woomera); + clear_from_holding_tank(woomera->index_hold); woomera->index_hold=0; } @@ -4572,7 +4360,7 @@ static int configure_server(void) server.dtmf_off=SMG_DTMF_OFF; } if (server.dtmf_intr_ch == -1) { - server.dtmf_intr_ch = 0; + server.dtmf_intr_ch = server.dtmf_on/server.dtmf_off; } server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.5.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.5.tmp new file mode 100644 index 0000000..b9316c8 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.5.tmp @@ -0,0 +1,228 @@ +#!/bin/sh + +home=`pwd`; + +force="false" +noss7="true" +rootdir="" +pbxdir=/usr/src/asterisk + +while [ ! -z $1 ] +do + if [ $1 = '-force' ]; then + force="force" + elif [ $1 = '-noss7' ]; then + noss7="true" + elif [ $1 = '-pbxdir' ]; then + shift + pbxdir=$1 + if [ "$pbxdir" = "" ]; then + echo "Error: Invalid Asterisk dir: $pbxdir!"; + exit 1 + elif [ ! -d $pbxdir ]; then + echo "Error: Asterisk dir does not exist: $pbxdir!"; + exit 1 + fi + + elif [ $1 = '-rootdir' ]; then + shift + rootdir=$1 + if [ "$rootdir" = "" ]; then + echo "Error: Invalid root dir: $rootdir!"; + exit 1 + elif [ ! -d $rootdir ]; then + echo "Error: root dir does not exist: $rootdir!"; + exit 1 + fi + + else + echo "Invalid option: $1"; + echo + echo "Usage: ./install " + echo + exit 1 + fi + shift +done + +if [ $noss7 != 'true' ]; then + if [ ! -e /usr/local/ss7box/$ss7boost ]; then + echo "Error: ss7boost not found in /usr/local/ss7box dir"; + exit 1 + fi + if [ ! -e /usr/local/ss7box/$ss7boxd ]; then + echo "Error: ss7boxd not found in /usr/local/ss7box dir"; + exit 1 + fi +fi + +if [ $force = "force" ]; then + echo "Stopping SMG..." + eval "sangoma_mgd -term" + kill -TERM $(pidof asterisk); + echo "OK." + echo +else + if [ -f /var/run/sangoma_mgd.pid ]; then + echo "Error: sangoma_mgd is running!" + exit 1 + fi + if [ -f /var/run/asterisk.pid ]; then + echo "Error: asterisk is running" + exit 1 + fi +fi + +echo +echo "Checking Syslog ...." +if [ -e /etc/syslog.conf ]; then +eval "grep "local2.*sangoma_mgd" /etc/syslog.conf" > /dev/null 2> /dev/null +if [ $? -ne 0 ]; then + eval "grep "local2" /etc/syslog.conf " > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + echo + echo "Warning : local2 is already used in syslog.conf" + echo + fi + echo -e "\nlocal2.* /var/log/sangoma_mgd.log\n" > tmp.$$ + eval "cat /etc/syslog.conf tmp.$$ > tmp1.$$" + \cp -f tmp1.$$ /etc/syslog.conf + eval "/etc/init.d/syslog restart" +fi + +else + echo "Warning: /etc/syslog.conf not found" +fi + +if [ -f tmp1.$$ ]; then + rm -f tmp1.$$ +fi +if [ -f tmp.$$ ]; then + rm -f tmp.$$ +fi + +echo "Ok" +echo + +echo "Checking logrotate ..." +eval "type logrotate" > /dev/null 2> /dev/null +if [ $? -ne 0 ]; then + echo "Error: Logrotate not found !" +fi + +if [ -e /etc/logrotate.d ] && [ -e /etc/logrotate.d/syslog ]; then + + eval "grep sangoma_mgd /etc/logrotate.d/syslog" > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + eval "sed -e 's/messages/messages \/var\/log\/sangoma_mgd.log/' /etc/logrotate.d/syslog >tmp2.$$ 2>/dev/null" + eval "cp -f tmp2.$$ /etc/logrotate.d/syslog" + eval "logrotate -f /etc/logrotate.d/syslog" + if [ $? -ne 0 ]; then + echo "Error: logrotate restart failed!"; + exit 1; + fi + echo "Logrotate is being changed and restarted!" + else + echo "Logrotate is configured!" + fi + +else + echo "Error: Logrotate dir: /etc/logrotate.d not found !" +fi +echo "OK." +echo + +echo "Checking for SCTP Utilities...." +if [ ! -e /usr/include/netinet/sctp.h ]; then + if [ -d ../libs ]; then + echo -n "Installing SCTP RPMS ..." + eval "rpm -i ../libs/lksctp-tools-1.0.6-1.el5.1.i386.rpm ../libs/lksctp-tools-devel-1.0.6-1.el5.1.i386.rpm" + if [ ! -e /usr/include/netinet/sctp.h ]; then + echo "Error" + echo + echo "Please install SCTP devel package: yum install lksctp-tools-devel" + echo + exit 1 + fi + echo "OK" + else + echo "Please install SCTP devel package: yum install lksctp-tools-devel" + echo + exit 1 + fi +fi +echo "OK." +echo + +echo "Checking for SCTP modules..." +eval "modprobe -l | grep \"\/sctp.ko\" >/dev/null 2>/dev/null" +if [ $? -ne 0 ]; then + if [ ! -e /proc/net/sctp ]; then + echo "Warning: Your Kernel does not support SCTP Protocol!" + echo "SCTP is needed by SMG!" + echo + echo "Please contact sangoma support!" + echo + exit 1 + fi +fi +echo "OK." +echo + + +echo "Compiling Sangoma MGD ..." +eval "make clean 2> /dev/null > /dev/null" +eval "make" +if [ $? -ne 0 ]; then + exit 1; +fi +make INSTALLPREFIX=$rootdir install +echo "Ok." + +if [ -d chan_woomera.trunk ]; then + + cd chan_woomera.trunk + + echo "Compiling Woomera Channel ..." + + if [ ! -e $pbxdir ]; then + echo + echo "Error: $pbxdir directory does not exist!" + echo " Please create symlink /usr/src/asterisk and" + echo " point to existing asterisk source!" + echo " Then re run ./install.sh " + echo + exit 1 + fi + + eval "make clean 2> /dev/null > /dev/null" + eval "make PBXDIR=$pbxdir" + if [ $? -ne 0 ]; then + exit 1; + fi + + make INSTALLPREFIX=$rootdir install + echo "Ok." + +else + echo "Warning: chan_woomera directory does not exist!" + exit 1 +fi + + +echo "---------------------------------" +echo +echo " SMG Install Done" +echo +echo "--> Config: /etc/sangoma_mgd.conf" +echo "--> Start: sangoma_mgd -bg" +echo +echo " Chan Woomera Install Done" +echo +echo "--> Config: /etc/asterisk/woomera.conf" +echo "--> Start: Part of Asterisk (start asterisk)" +echo +echo "---------------------------------" + +exit 0 + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.6.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.6.tmp new file mode 100644 index 0000000..e6a8462 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.6.tmp @@ -0,0 +1,97 @@ +################################################################################ +# Sangoma MGD +# +# Author: Anthony Minessale II +# Nenad Corbic +# +# Copyright: (c) 2005 Anthony Minessale II +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. +################################################################################ + +SMG_DTMF=YES + +#Default kernel directory to be overwritten by user +#Kernel version and location +ifndef KVER + KVER=$(shell uname -r) +endif +ifndef KMOD + KMOD=/lib/modules/$(KVER) +endif +ifndef KDIR + KDIR=$(KMOD)/build +endif +ifndef KINSTDIR + KINSTDIR=$(KMOD)/kernel +endif + +CC = gcc +INSTALLPREFIX= + +INCLUDES = -I$(KDIR)/include -I ../../ssmg/libsangoma.trunk -I. -I ../../patches/kdrivers/include -I ../../patches/kdrivers/wanec/oct6100_api/include -I ../../patches/kdrivers/wanec -I/usr/local/include -I../../patches/kdrivers/include -I/usr/include/wanpipe -Ilib/libteletone/src + +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 +CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g +LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm + + +ifeq "${SMG_DTMF}" "YES" +LDFLAGS+= -lteletone +CFLAGS+= -DSMG_DTMF_ENABLE +endif + + +all: sangoma_mgd + +libs: + $(shell cd lib/libteletone; ./configure --prefix=$(INSTALLPREFIX); cd ../../; ) + $(MAKE) -C lib/libteletone all + +switch_buffer.o: switch_buffer.c switch_buffer.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o switch_buffer.o switch_buffer.c + +call_signal.o: call_signal.c call_signal.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o call_signal.o call_signal.c + +sangoma_mgd: sangoma_mgd.o call_signal.o switch_buffer.o sigboost.h + rm -fr core* + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -o sangoma_mgd sangoma_mgd.o switch_buffer.o call_signal.o $(LDFLAGS) + +sangoma_mgd.o: sangoma_mgd.c sangoma_mgd.h sigboost.h + $(CC) $(CCFLAGS) $(INCLUDES) $(CFLAGS) -c -o sangoma_mgd.o sangoma_mgd.c + + +clean: old_cleanup + make -C lib/libteletone clean + find . -name '*.o' | xargs rm -f + rm -fr sangoma_mgd pritest *.o *.so *~ *core* *.so* *.a + +distclean: clean + @echo OK + +install: all install_smg old_cleanup + +install_smg: old_cleanup + install -D -m 755 sangoma_mgd $(INSTALLPREFIX)/usr/sbin/sangoma_mgd + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi + install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl + install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl + @echo "sangoma_mgd Installed" + +old_cleanup: + ./scripts/old_cleanup.sh + + +install_all: all install_smg + +uninstall: + /bin/rm $(INSTALLPREFIX)/usr/sbin/sangoma_mgd $(INSTALLPREFIX)/etc/sangoma_mgd.conf + + + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.7.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.7.tmp new file mode 100644 index 0000000..8cdf915 --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.7.tmp @@ -0,0 +1,4940 @@ +/********************************************************************************* + * sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards + * + * Copyright 05-07, Nenad Corbic + * Anthony Minessale II + * + * This program is free software, distributed under the terms of + * the GNU General Public License + * + * ============================================= +<<<<<<< .mine + * v1.21 Nenad Corbic + * Added caller name option + * +======= + * v1.21 Nenad Corbic + * Major unit testing of each state + * Numerous bug fixes for non autoacm mode. + * Changed "Channel-Name" to tg/cic + * Added compile option WANPIPE_CHAN_NAME to change Asterisk channel + * name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE}) + * instead of WOOMERA (for example) + * +>>>>>>> .r40 + * v1.20 Nenad Corbic + * Added option for Auto ACM response mode. + * + * v1.19 Nenad Corbic + * Configurable DTMF + * Bug fix in release codes (all ckt busy) + * + * v1.18 Nenad Corbic + * Added new rel cause support based on + * digits instead of strings. + * + * v1.17 Nenad Corbic + * Added session support + * + * v1.16 Nenad Corbic + * Added hwec disable on loop ccr + * + * v1.15 Nenad Corbic + * Updated DTMF Locking + * Added delay between digits + * + * v1.14 Nenad Corbic + * Updated DTMF Library + * Fixed DTMF synchronization + * + * v1.13 Nenad Corbic + * Woomera OPAL Dialect + * Added Congestion control + * Added SCTP + * Added priority ISUP queue + * Fixed presentation + * + * v1.12 Nenad Corbic + * Fixed CCR + * Removed socket shutdown on end call. + * Let Media thread shutodwn sockets. + * + * v1.11 Nenad Corbic + * Fixed Remote asterisk/woomera connection + * Increased socket timeouts + * + * v1.10 Nenad Corbic + * Added Woomera OPAL dialect. + * Start montor thread in priority + * + * v1.9 Nenad Corbic + * Added Loop mode for ccr + * Added remote debug enable + * Fixed syslog logging. + * + * v1.8 Nenad Corbic + * Added a ccr loop mode for each channel. + * Boost can set any channel in loop mode + * + * v1.7 Nenad Corbic + * Pass trunk group number to incoming call + * chan woomera will use it to append to context + * name. Added presentation feature. + * + * v1.6 Nenad Corbic + * Use only ALAW and MLAW not SLIN. + * This reduces the load quite a bit. + * Send out ALAW/ULAW format on HELLO message. + * RxTx Gain is done now in chan_woomera. + * + * v1.5 Nenad Corbic + * Bug fix in START_NACK_ACK handling. + * When we receive START_NACK we must alwasy pull tank before + * we send out NACK_ACK this way we will not try to send NACK + * ourself. + *********************************************************************************/ + +#include "sangoma_mgd.h" +#include "q931_cause.h" + + +#define USE_SYSLOG 1 +#define CODEC_LAW_DEFAULT 1 + +#ifdef CODEC_LAW_DEFAULT +static uint32_t codec_sample=8; +#else +static uint32_t codec_sample=16; +#endif + +static char ps_progname[]="sangoma_mgd"; + +static struct woomera_interface woomera_dead_dev; + +#if 0 +#define DOTRACE +#endif + + +#define SMG_VERSION "v1.21" + +/* enable early media */ +#if 1 +#define WOOMERA_EARLY_MEDIA 1 +#endif + + +#define SMG_DTMF_ON 60 +#define SMG_DTMF_OFF 10 +#define SMG_DTMF_RATE 8000 + +#if 0 +#define MEDIA_SOCK_SHUTDOWN 1 +#endif + +#ifdef DOTRACE +static int tc = 0; +#endif + +#if 0 +#warning "NENAD: HPTDM API" +#define WP_HPTDM_API 1 +#else +#undef WP_HPTDM_API +#endif + +#ifdef WP_HPTDM_API +hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; +#endif + +#undef SMG_CALLING_NAME + +const char WELCOME_TEXT[] = +"================================================================================\n" +"Sangoma Media Gateway Daemon v1.21 \n" +"TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" +"Copyright 2005, 2006, 2007 \n" +"Nenad Corbic , Anthony Minessale II \n" +"This program is free software, distributed under the terms of\n" +"the GNU General Public License\n" +"================================================================================\n" +""; + + +static int master_reset=0; + +static int coredump=1; +static int autoacm=1; + +static int launch_media_tdm_thread(struct woomera_interface *woomera); +static int launch_woomera_thread(struct woomera_interface *woomera); +static struct woomera_interface *alloc_woomera(void); + +q931_cause_to_str_array_t q931_cause_to_str_array[255]; + + +#if 0 +static uint32_t string_to_release(char *code) +{ + if (code) { + if (!strcasecmp(code, "CHANUNAVAIL")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "INVALID")) { + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "ERROR")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + if (!strcasecmp(code, "CONGESTION")) { + //return SIGBOOST_RELEASE_CAUSE_BUSY; + return SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST; + } + + if (!strcasecmp(code, "BUSY")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "NOANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NOANSWER; + } + + if (!strcasecmp(code, "ANSWER")) { + return SIGBOOST_RELEASE_CAUSE_NORMAL; + } + + if (!strcasecmp(code, "CANCEL")) { + return SIGBOOST_RELEASE_CAUSE_BUSY; + } + + if (!strcasecmp(code, "UNKNOWN")) { + return SIGBOOST_RELEASE_CAUSE_UNDEFINED; + } + + } + return SIGBOOST_RELEASE_CAUSE_NORMAL; +} + +static char * release_to_string(uint32_t rel_cause) +{ + switch (rel_cause) { + + case SIGBOOST_RELEASE_CAUSE_UNDEFINED: + return "UNKNOWN"; + case SIGBOOST_RELEASE_CAUSE_NORMAL: + return "NORMAL"; + case SIGBOOST_RELEASE_CAUSE_BUSY: + return "BUSY"; + case SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST: + return "CHANUNAVAIL"; + case SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET: + return "CANCEL"; + case SIGBOOST_RELEASE_CAUSE_NOANSWER: + return "NOANSWER"; + case SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT: + return "TIMEOUT"; + case SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY: + return "CONGESTION"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL: + return "ERROR"; + case SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL: + return "ERROR"; + } + + return "NORMAL"; +} +#endif + + + +void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return; + } + + if (level && level > server.debug) { + return; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + } else { + char date[80] = ""; + struct tm now; + time_t epoch; + + if (time(&epoch) && localtime_r(&epoch, &now)) { + strftime(date, sizeof(date), "%Y-%m-%d %T", &now); + } + +#ifdef USE_SYSLOG + syslog(LOG_DEBUG | LOG_LOCAL2, data); +#else + fprintf(fp, "[%d] %s %s:%d %s() %s", getpid(), date, file, line, func, data); +#endif + free(data); + } +#ifndef USE_SYSLOG + fflush(fp); +#endif +} + + + + +static int isup_exec_command(int span, int chan, int id, int cmd, int cause) +{ + call_signal_event_t oevent; + int retry=5; + + call_signal_event_init(&oevent, cmd, chan, span); + oevent.release_cause = cause; + + if (id >= 0) { + oevent.call_setup_id = id; + } +isup_exec_cmd_retry: + if (call_signal_connection_write(&server.mcon, &oevent) <= 0){ + + --retry; + if (retry <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket: %s\n", + strerror(errno)); + return -1; + } else { + log_printf(0, server.log, + "System Warning: Failed to tx on ISUP socket: %s :retry %i\n", + strerror(errno),retry); + } + + goto isup_exec_cmd_retry; + } + + return 0; +} + +static int socket_printf(int socket, char *fmt, ...) +{ + char *data; + int ret = 0; + va_list ap; + + if (socket < 0) { + return -1; + } + + va_start(ap, fmt); +#ifdef SOLARIS + data = (char *) malloc(2048); + vsnprintf(data, 2048, fmt, ap); +#else + ret = vasprintf(&data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + fprintf(stderr, "Memory Error\n"); + log_printf(0, server.log, "Crtical ERROR: Memory Error!\n"); + } else { + int err; + int len = strlen(data); + err=send(socket, data, strlen(data), 0); + if (err != strlen(data)) { + log_printf(2, server.log, "ERROR: Failed to send data to woomera socket(%i): err=%i len=%d %s\n", + socket,err,len,strerror(errno)); + ret = err; + } else { + ret = 0; + } + + free(data); + } + + return ret; +} + + + +static int woomera_next_pair(struct woomera_config *cfg, char **var, char **val) +{ + int ret = 0; + char *p, *end; + + *var = *val = NULL; + + for(;;) { + cfg->lineno++; + + if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) { + ret = 0; + break; + } + + *var = cfg->buf; + + if (**var == '[' && (end = strchr(*var, ']'))) { + *end = '\0'; + (*var)++; + strncpy(cfg->category, *var, sizeof(cfg->category) - 1); + continue; + } + + if (**var == '#' || **var == '\n' || **var == '\r') { + continue; + } + + if ((end = strchr(*var, '#'))) { + *end = '\0'; + end--; + } else if ((end = strchr(*var, '\n'))) { + if (*end - 1 == '\r') { + end--; + } + *end = '\0'; + } + + p = *var; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *var = p; + + if (!(*val = strchr(*var, '='))) { + ret = -1; + log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); + continue; + } else { + p = *val - 1; + *(*val) = '\0'; + (*val)++; + if (*(*val) == '>') { + *(*val) = '\0'; + (*val)++; + } + + while ((*p == ' ' || *p == '\t') && p != *var) { + *p = '\0'; + p--; + } + + p = *val; + while ((*p == ' ' || *p == '\t') && p != end) { + *p = '\0'; + p++; + } + *val = p; + ret = 1; + break; + } + } + + return ret; + +} + + +#if 0 +static void woomera_set_span_chan(struct woomera_interface *woomera, int span, int chan) +{ + pthread_mutex_lock(&woomera->vlock); + woomera->span = span; + woomera->chan = chan; + pthread_mutex_unlock(&woomera->vlock); + +} +#endif + + +static struct woomera_event *new_woomera_event_printf(struct woomera_event *ebuf, char *fmt, ...) +{ + struct woomera_event *event = NULL; + int ret = 0; + va_list ap; + + if (ebuf) { + event = ebuf; + } else if (!(event = new_woomera_event())) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + return NULL; + } else { + return NULL; + } + + va_start(ap, fmt); +#ifdef SOLARIS + event->data = (char *) malloc(2048); + vsnprintf(event->data, 2048, fmt, ap); +#else + ret = vasprintf(&event->data, fmt, ap); +#endif + va_end(ap); + if (ret == -1) { + log_printf(0, server.log, "Memory Error queuing event!\n"); + destroy_woomera_event(&event, EVENT_FREE_DATA); + return NULL; + } + + return event; + +} + +static struct woomera_event *woomera_clone_event(struct woomera_event *event) +{ + struct woomera_event *clone; + + if (!(clone = new_woomera_event())) { + return NULL; + } + + memcpy(clone, event, sizeof(*event)); + clone->next = NULL; + clone->data = strdup(event->data); + + return clone; +} + +static void enqueue_event(struct woomera_interface *woomera, + struct woomera_event *event, + event_args free_data) +{ + struct woomera_event *ptr, *clone = NULL; + + assert(woomera != NULL); + assert(event != NULL); + + if (!(clone = woomera_clone_event(event))) { + log_printf(0, server.log, "Error Cloning Event\n"); + return; + } + + pthread_mutex_lock(&woomera->queue_lock); + + for (ptr = woomera->event_queue; ptr && ptr->next ; ptr = ptr->next); + + if (ptr) { + ptr->next = clone; + } else { + woomera->event_queue = clone; + } + + pthread_mutex_unlock(&woomera->queue_lock); + + woomera_set_flag(woomera, WFLAG_EVENT); + + if (free_data && event->data) { + /* The event has been duplicated, the original data + * should be freed */ + free(event->data); + event->data=NULL; + } +} + +static char *dequeue_event(struct woomera_interface *woomera) +{ + struct woomera_event *event; + char *data = NULL; + + if (!woomera) { + return NULL; + } + + pthread_mutex_lock(&woomera->queue_lock); + if (woomera->event_queue) { + event = woomera->event_queue; + woomera->event_queue = event->next; + data = event->data; + pthread_mutex_unlock(&woomera->queue_lock); + + destroy_woomera_event(&event, EVENT_KEEP_DATA); + return data; + } + pthread_mutex_unlock(&woomera->queue_lock); + + return data; +} + + +static int enqueue_event_on_listeners(struct woomera_event *event) +{ + struct woomera_listener *ptr; + int x = 0; + + assert(event != NULL); + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + enqueue_event(ptr->woomera, event, EVENT_KEEP_DATA); + x++; + } + pthread_mutex_unlock(&server.listen_lock); + + return x; +} + + +static void del_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *ptr, *last = NULL; + + pthread_mutex_lock(&server.listen_lock); + for (ptr = server.listeners ; ptr ; ptr = ptr->next) { + if (ptr->woomera == woomera) { + if (last) { + last->next = ptr->next; + } else { + server.listeners = ptr->next; + } + free(ptr); + break; + } + last = ptr; + } + pthread_mutex_unlock(&server.listen_lock); +} + +static void add_listener(struct woomera_interface *woomera) +{ + struct woomera_listener *new; + + pthread_mutex_lock(&server.listen_lock); + + if ((new = malloc(sizeof(*new)))) { + memset(new, 0, sizeof(*new)); + new->woomera = woomera; + new->next = server.listeners; + server.listeners = new; + } else { + log_printf(0, server.log, "Memory Error adding listener!\n"); + } + + pthread_mutex_unlock(&server.listen_lock); +} + + +#ifdef SMG_DTMF_ENABLE +static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits) +{ + struct media_session *ms = woomera_get_ms(woomera); + char *cur = NULL; + int wrote = 0; + int err; + + if (!ms) { + return -EINVAL; + } + + if (!ms->dtmf_buffer) { + log_printf(3, woomera->log, "Allocate DTMF Buffer...."); + + err=switch_buffer_create_dynamic(&ms->dtmf_buffer, 1024, server.dtmf_size, 0); + + if (err != 0) { + log_printf(0, woomera->log, "Failed to allocate DTMF Buffer!\n"); + return -ENOMEM; + } else { + log_printf(3, woomera->log, "SUCCESS!\n"); + } + + } + + log_printf(3, woomera->log, "Sending DTMF %s\n",digits); + for (cur = digits; *cur; cur++) { + if ((wrote = teletone_mux_tones(&ms->tone_session, + &ms->tone_session.TONES[(int)*cur]))) { + + pthread_mutex_lock(&woomera->dtmf_lock); + + err=switch_buffer_write(ms->dtmf_buffer, ms->tone_session.buffer, wrote * 2); + + pthread_mutex_unlock(&woomera->dtmf_lock); + + log_printf(3, woomera->log, "Sending DTMF %s Wrote=%i (err=%i)\n", + digits,wrote*2,err); + } else { + log_printf(0, woomera->log, "Error: Sending DTMF %s (err=%i)\n", + digits,wrote); + } + } + + ms->skip_read_frames = 200; + return 0; +} +#endif + +static struct woomera_interface *alloc_woomera(void) +{ + struct woomera_interface *woomera = NULL; + + if ((woomera = malloc(sizeof(struct woomera_interface)))) { + + memset(woomera, 0, sizeof(struct woomera_interface)); + + woomera->chan = -1; + woomera->span = -1; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->q931_rel_cause_topbx=SIGBOOST_RELEASE_CAUSE_NORMAL; + woomera->q931_rel_cause_tosig=SIGBOOST_RELEASE_CAUSE_NORMAL; + + woomera_set_interface(woomera, "w-1g-1"); + + + + } + + return woomera; + +} + + +static struct woomera_interface *new_woomera_interface(int socket, struct sockaddr_in *sock_addr, int len) +{ + struct woomera_interface *woomera = NULL; + + if (socket < 0) { + log_printf(0, server.log, "Critical: Invalid Socket on new interface!\n"); + return NULL; + } + + if ((woomera = alloc_woomera())) { + if (socket >= 0) { + no_nagle(socket); + woomera->socket = socket; + } + + if (sock_addr && len) { + memcpy(&woomera->addr, sock_addr, len); + } + } + + return woomera; + +} + +static char *woomera_message_header(struct woomera_message *wmsg, char *key) +{ + int x = 0; + char *value = NULL; + + for (x = 0 ; x < wmsg->last ; x++) { + if (!strcasecmp(wmsg->names[x], key)) { + value = wmsg->values[x]; + break; + } + } + + return value; +} + + +#if 1 + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & POLLERR)) { + res = -1; + } else if ((pfds[0].revents & POLLNVAL)) { + res = -2; +#if 0 + log_printf(0, server.log,"System Warning: Poll Event NVAL (0x%X) (fd=%i)!\n", + pfds[0].revents, fd); +#endif + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X) (fd=%i)!\n", + pfds[0].revents,fd); +#endif + res = -1; + } + } + + return res; +} + +#else + +static int waitfor_socket(int fd, int timeout, int flags) +{ + struct pollfd pfds[1]; + int res; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + memset(&pfds[0], 0, sizeof(pfds[0])); + pfds[0].fd = fd; + pfds[0].events = flags | errflags; + res = poll(pfds, 1, timeout); + + if (res > 0) { + if(pfds[0].revents & POLLIN) { + res = 1; + } else if ((pfds[0].revents & errflags)) { + res = -1; + } else { +#if 0 + log_printf(0, server.log,"System Error: Poll Event Error no event (0x%X)!\n", + pfds[0].revents); +#endif + res = -1; + } + } + + return res; +} + +#endif + +#if 1 +static int waitfor_2sockets(int fda, int fdb, char *a, char *b, int timeout) +{ + struct pollfd pfds[2]; + int res = 0; + int errflags = (POLLERR | POLLHUP | POLLNVAL); + + if (fda < 0 || fdb < 0) { + return -1; + } + + *a=0; + *b=0; + + memset(pfds, 0, sizeof(pfds)); + pfds[0].fd = fda; + pfds[1].fd = fdb; + pfds[0].events = POLLIN | errflags; + pfds[1].events = POLLIN | errflags; + if ((res = poll(pfds, 2, timeout)) > 0) { + res = 1; + if ((pfds[0].revents & errflags) || (pfds[1].revents & errflags)) { + res = -1; + } else { + if ((pfds[0].revents & POLLIN)) { + *a=1; + res++; + } + if ((pfds[1].revents & POLLIN)) { + *b=1; + res++; + } + } + + if (res == 1) { + /* No event found what to do */ + res=-1; + } + } + + return res; +} +#endif + + +static struct media_session *media_session_new(struct woomera_interface *woomera) +{ + struct media_session *ms = NULL; + int x; + char *p; + int span,chan; + + span=woomera->span; + chan=woomera->chan; + + log_printf(2, server.log,"Starting new MEDIA session [%s] [%s]\n", + woomera->interface,woomera->raw?woomera->raw:"N/A"); + + if ((ms = malloc(sizeof(struct media_session)))) { + memset(ms, 0, sizeof(struct media_session)); + + if (woomera->loop_tdm != 1) { + for(x = 0; x < strlen(woomera->raw) ; x++) { + if (woomera->raw[x] == ':') { + break; + } + if (woomera->raw[x] == '/') { + break; + } + } + + ms->ip = strndup(woomera->raw, x); + time(&ms->started); + p = woomera->raw + (x+1); + ms->port = atoi(p); + } + + time(&ms->started); + woomera_set_ms(woomera,ms); + ms->woomera = woomera; + +#ifdef SMG_DTMF_ENABLE + /* Setup artificial DTMF stuff */ + memset(&ms->tone_session, 0, sizeof(ms->tone_session)); + if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) { + log_printf(0, server.log, "ERROR: Failed to initialize TONE [w%ig%i]!\n", + span+1,chan+1); + } + + ms->tone_session.rate = SMG_DTMF_RATE; + ms->tone_session.duration = server.dtmf_on * (ms->tone_session.rate / 1000); + ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000); + + teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE); +#endif + + } else { + log_printf(0, server.log, "ERROR: Memory Alloc Failed [w%ig%i]!\n", + span+1,chan+1); + } + + return ms; +} + +static void media_session_free(struct media_session *ms) +{ + if (ms->ip) { + free(ms->ip); + } + +#ifdef SMG_DTMF_ENABLE + teletone_destroy_session(&ms->tone_session); + switch_buffer_destroy(&ms->dtmf_buffer); +#endif + + ms->woomera = NULL; + + free(ms); +} + + +static int create_udp_socket(struct media_session *ms, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + log_printf(5,server.log,"LocalIP %s:%d IP %s:%d \n",local_ip, local_port, ip, port); + + memset(&ms->remote_hp, 0, sizeof(ms->remote_hp)); + memset(&ms->local_hp, 0, sizeof(ms->local_hp)); + if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0))) { + gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + ms->remote_addr.sin_family = ms->remote_hp.h_addrtype; + memcpy((char *) &ms->remote_addr.sin_addr.s_addr, ms->remote_hp.h_addr_list[0], ms->remote_hp.h_length); + ms->remote_addr.sin_port = htons(port); + + ms->local_addr.sin_family = ms->local_hp.h_addrtype; + memcpy((char *) &ms->local_addr.sin_addr.s_addr, ms->local_hp.h_addr_list[0], ms->local_hp.h_length); + ms->local_addr.sin_port = htons(local_port); + + rc = bind(ms->socket, (struct sockaddr *) &ms->local_addr, sizeof(ms->local_addr)); + if (rc < 0) { + close(ms->socket); + ms->socket = -1; + + log_printf(5,server.log, + "Failed to bind LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + + /* OK */ + + } else { + log_printf(0,server.log, + "Failed to get hostbyname LocalIP %s:%d IP %s:%d (%s)\n", + local_ip, local_port, ip, port,strerror(errno)); + } + } else { + log_printf(0,server.log, + "Failed to create/allocate UDP socket\n"); + } + + return ms->socket; +} + +static int next_media_port(void) +{ + int port; + + pthread_mutex_lock(&server.media_udp_port_lock); + port = ++server.next_media_port; + if (port > WOOMERA_MAX_MEDIA_PORT) { + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + port = WOOMERA_MIN_MEDIA_PORT; + } + pthread_mutex_unlock(&server.media_udp_port_lock); + + return port; +} + +#ifdef SMG_DTMF_ENABLE + +static int woomera_dtmf_transmit(struct media_session *ms, int mtu) +{ + struct woomera_interface *woomera = ms->woomera; + int bread; + unsigned char dtmf[1024]; + unsigned char dtmf_law[1024]; + sangoma_api_hdr_t hdrframe; + int i; + int slin_len = mtu*2; + short *data; + int used; + memset(&hdrframe,0,sizeof(hdrframe)); + + if (!ms->dtmf_buffer) { + return -1; + } + + for (;;) { + +#ifdef CODEC_LAW_DEFAULT + + pthread_mutex_lock(&woomera->dtmf_lock); + if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) { + pthread_mutex_unlock(&woomera->dtmf_lock); + break; + } + + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, slin_len); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread <= 0) { + break; + } + +#if 0 + if (bread < slin_len) { + while (bread < slin_len) { + dtmf[bread++] = 0xFF; + } + } +#endif + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n", + woomera->interface,bread,mtu,ms->hw_coding,used); + + data=(short*)dtmf; + for (i=0;ihw_coding) { + /* ALAW */ + dtmf_law[i] = linear_to_alaw((int)data[i]); + } else { + /* ULAW */ + dtmf_law[i] = linear_to_ulaw((int)data[i]); + } + } + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf_law, mtu, 0); + + ms->skip_write_frames+=server.dtmf_intr_ch; +#else +... + pthread_mutex_lock(&woomera->dtmf_lock); + bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu); + pthread_mutex_unlock(&woomera->dtmf_lock); + + if (bread < mtu) { + while (bread < mtu) { + dtmf[bread++] = 0; + } + } + + log_printf(3,woomera->log,"%s: Write DTMF Got %d bytes\n", + woomera->interface,bread); + + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + dtmf, mtu, 0); + ms->skip_write_frames++; +#endif + return 0; + } + + return -1; +} +#endif + +static void media_loop_run(struct media_session *ms) +{ + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int errs=0; + int res=0; + wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + char filename[100]; + FILE *filed=NULL; + int loops=0; + + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + + log_printf(1, server.log, "Media Loop Started %s fd=%i\n", + woomera->interface,ms->sangoma_sock); + + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "WANPIPE MEDIA Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + + + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } + + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + sangoma_tdm_disable_hwec(ms->sangoma_sock,&tdm_api); + + } + + if (errs) { + + log_printf(0, server.log, "Media Loop: failed to open tdm device %s\n", + woomera->interface); + return; + } + + if (server.loop_trace) { + sprintf(filename,"/smg/w%ig%i-loop.trace",woomera->span+1,woomera->chan+1); + unlink(filename); + filed = safe_fopen(filename, "w"); + } + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + ((res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2)) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + log_printf(0, server.log, "Media Loop Restart %s\n", + woomera->interface); + continue; + } + + if (res < 0 ){ + log_printf(0, server.log, "Media Loop Socket error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM Loop ReadMsg Error: %s\n", + strerror(errno), woomera->interface); + break; + } + + if (server.loop_trace && filed != NULL) { + int i; + for (i=0;isangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + res, 0); + + res=0; + + loops++; + } + + + if (res < 0) { + log_printf(2, server.log, "Media Loop: socket error %s (fd=%i)!\n", + woomera->interface, ms->sangoma_sock); + } + + + if (server.loop_trace && filed != NULL) { + fclose(filed); + } + + sangoma_tdm_enable_hwec(ms->sangoma_sock,&tdm_api); + + sleep(1); + + close_socket(&ms->sangoma_sock); + + log_printf(1, server.log, "Media Loop Finished %s Master=%i MediaEnd=%i Loops=%i\n", + woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_MEDIA_END),loops); + + return; + +} + +#ifdef WP_HPTDM_API +static int media_rx_ready(void *p, unsigned char *data, int len) +{ + struct media_session *ms = (struct media_session *)p; + + if (ms->udp_sock < 0) { + return -1; + } + + return sendto(ms->udp_sock, + data,len, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + +} +#endif + +static void *media_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int sangoma_frame_len = 160; + int local_port, x = 0, errs = 0, res = 0, packet_len = 0; + //int udp_cnt=0; + struct woomera_event wevent; + wanpipe_tdm_api_t tdm_api; + FILE *tx_fd=NULL; + int sock_timeout=200; + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + !woomera->interface || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(2, server.log, + "MEDIA session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(ms); + pthread_exit(NULL); + return NULL; + } + + + log_printf(2, server.log, "MEDIA session for [%s] started (ptr=%p loop=%i)\n", + woomera->interface,woomera,woomera->loop_tdm); + + if (woomera->loop_tdm) { + media_loop_run(ms); + ms->udp_sock=-1; + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + goto media_thread_exit; + } + + for(x = 0; x < 1000 ; x++) { + local_port = next_media_port(); + if ((ms->udp_sock = create_udp_socket(ms, server.media_ip, local_port, ms->ip, ms->port)) > -1) { + break; + } + } + + if (ms->udp_sock < 0) { + log_printf(0, server.log, "UDP Socket Error (%s) [%s] LocalPort=%d\n", + strerror(errno), woomera->interface, local_port); + + errs++; + } else { + +#ifdef WP_HPTDM_API + hp_tdm_api_span_t *span=hptdmspan[woomera->span+1]; + if (!span || !span->init) { + errs++; + } else { + hp_tdm_api_usr_callback_t usr_callback; + memset(&usr_callback,0,sizeof(usr_callback)); + usr_callback.p = ms; + usr_callback.rx_avail = media_rx_ready; + if (span->open_chan(span, &usr_callback, &ms->tdmchan,woomera->chan+1)) { + errs++; + } + } +#else + if ((ms->sangoma_sock = sangoma_create_socket_by_name(woomera->interface, NULL)) < 0) { + log_printf(0, server.log, "WANPIPE Socket Error (%s) if=[%s] [w%ig%i]\n", + strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1); + errs++; + } else { + +# ifdef CODEC_LAW_DEFAULT + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) { + errs++; + } +# else + if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_SLINEAR) < 0 ) { + errs++; + } +# endif + if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) { + errs++; + } + + if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) { + errs++; + } + +# ifdef CODEC_LAW_DEFAULT +# ifdef LIBSANGOMA_GET_HWCODING + ms->hw_coding=sangoma_tdm_get_hw_coding(ms->sangoma_sock, &tdm_api); + if (ms->hw_coding < 0) { + errs++; + } +# else +# error "libsangoma missing hwcoding feature: not up to date!" +# endif +# endif + + sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + } +#endif + } + + + +#ifdef WP_HPTDM_API + /* No tdm thread */ +#else + if (!errs && + launch_media_tdm_thread(woomera)) { + errs++; + } +#endif + + if (!errs) { + + unsigned char udp_frame[4096]; + sangoma_api_hdr_t hdrframe; + memset(&hdrframe,0,sizeof(hdrframe)); + memset(udp_frame,0,sizeof(udp_frame)); +#ifdef DOTRACE + int fdin, fdout; + char path_in[512], path_out[512]; +#endif + + + +#if 0 + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: %s%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + ms->hw_coding ?"ALAW":"ULAW", + WOOMERA_RECORD_SEPERATOR + ); +#else + new_woomera_event_printf(&wevent, + "EVENT MEDIA %s AUDIO%s" + "Unique-Call-Id: %s%s" + "Raw-Audio: %s:%d%s" + "Call-ID: %s%s" + "Raw-Format: PCM-16%s" + , + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + server.media_ip, + local_port, + WOOMERA_LINE_SEPERATOR, + woomera->interface, + WOOMERA_LINE_SEPERATOR, + WOOMERA_RECORD_SEPERATOR + ); +#endif + + + enqueue_event(woomera, &wevent, EVENT_FREE_DATA); + +#ifdef DOTRACE + sprintf(path_in, "/tmp/debug-in.%d.raw", tc); + sprintf(path_out, "/tmp/debug-out.%d.raw", tc++); + fdin = open(path_in, O_WRONLY | O_CREAT, O_TRUNC, 0600); + fdout = open(path_out, O_WRONLY | O_CREAT, O_TRUNC, 0600); +#endif + + if (server.out_tx_test) { + tx_fd=fopen("/smg/sound.raw","rb"); + if (!tx_fd){ + log_printf(0,server.log, "FAILED TO OPEN Sound file!\n"); + } + } + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + (res = waitfor_socket(ms->udp_sock, sock_timeout, POLLERR | POLLIN)) >= 0) { + + unsigned int fromlen = sizeof(struct sockaddr_in); + + + if (res == 0) { + + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=sangoma_frame_len/codec_sample; + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + } else { + sock_timeout=200; + } + + log_printf(4, server.log, "%s: UDP Sock Timeout !!!\n", + woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } + + if ((packet_len = recvfrom(ms->udp_sock, udp_frame, sizeof(udp_frame), + MSG_DONTWAIT, (struct sockaddr *) &ms->local_addr, &fromlen)) < 1) { + log_printf(2, server.log, "UDP Recv Error: %s\n",strerror(errno)); + break; + } + +#if 0 + log_printf(6, server.log, "%s: UDP Receive %i !!!\n", + woomera->interface,packet_len); +#endif + + if (packet_len > 0) { + + if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { + /* Assume that we will always receive SLINEAR here */ + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, packet_len/codec_sample); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + + log_printf(0, server.log, + "%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n", + woomera->interface,sangoma_frame_len, + sangoma_frame_len/codec_sample,packet_len); + + + if (++ms->udp_sync_cnt >= 6) { + sangoma_tdm_set_usr_period(ms->sangoma_sock, + &tdm_api, 20); + sangoma_frame_len = + sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api); + log_printf(0, server.log, + "%s: UDP TDM Period Force ReSync to 20ms \n", + woomera->interface); + } + + } + +#ifdef SMG_DTMF_ENABLE + if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { + sock_timeout=sangoma_frame_len/codec_sample; + /* For sanity sake if we are doing the out test + * dont take any chances force tx udp data */ + if (!server.out_tx_test) { + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + } + continue; + } + } else { + sock_timeout=200; + } + + if (ms->skip_write_frames > 0) { + ms->skip_write_frames--; + continue; + } +#endif + + if (server.out_tx_test && tx_fd && + fread((void*)udp_frame, + sizeof(char), + packet_len,tx_fd) <= 0) { + + sangoma_get_full_cfg(ms->sangoma_sock,&tdm_api); + fclose(tx_fd); + tx_fd=NULL; + } + +#ifdef WP_HPTDM_API + if (ms->tdmchan->push) { + ms->tdmchan->push(ms->tdmchan,udp_frame,packet_len); + } +#else + sangoma_sendmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + udp_frame, + packet_len, 0); +#endif + + } + +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + udp_cnt++; + if (udp_cnt && udp_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA UDP TX RX CNT %i %i\n", + woomera->interface,udp_cnt,packet_len); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media Thread: socket error !\n"); + } + } + + + + new_woomera_event_printf(&wevent, + "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Start-Time: %ld%s" + "End-Time: %ld%s" + "Answer-Time: %ld%s" + "Call-ID: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + woomera->session, + WOOMERA_LINE_SEPERATOR, + + time(&ms->started), + WOOMERA_LINE_SEPERATOR, + + time(NULL), + WOOMERA_LINE_SEPERATOR, + + time(&ms->answered), + WOOMERA_LINE_SEPERATOR, + + woomera->interface, + WOOMERA_LINE_SEPERATOR, + + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + +media_thread_exit: + + if (woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) { + usleep(1000); + sched_yield(); + } + } + + + close_socket(&ms->udp_sock); + close_socket(&ms->sangoma_sock); + + if (tx_fd){ + fclose(tx_fd); + tx_fd=NULL; + } + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + + woomera_set_ms(woomera,NULL); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + + media_session_free(ms); + + log_printf(2, server.log, "MEDIA session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + + pthread_exit(NULL); + return NULL; +} + + + + +static void *media_tdm_thread_run(void *obj) +{ + struct media_session *ms = obj; + struct woomera_interface *woomera = ms->woomera; + int res = 0; + //int tdm_cnt=0; + //wanpipe_tdm_api_t tdm_api; + unsigned char circuit_frame[1024]; + sangoma_api_hdr_t hdrframe; + + memset(&hdrframe,0,sizeof(hdrframe)); + memset(circuit_frame,0,sizeof(circuit_frame)); + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || !woomera->interface) { + log_printf(2, server.log, "MEDIA TDM session for [%s] Cancelled! (ptr=%p)\n", + woomera->interface,woomera); + /* In this case the call will be closed via woomera_thread_run + * function. And the process table will be cleard there */ + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + pthread_exit(NULL); + return NULL; + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] started (ptr=%p)\n", + woomera->interface,woomera); + + + while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + (res = waitfor_socket(ms->sangoma_sock, 1000, POLLERR | POLLIN)) >= -2) { + + if (res == 0) { + //log_printf(4, server.log, "%s: TDM UDP Timeout !!!\n", + // woomera->interface); + /* NENAD Timeout thus just continue */ + continue; + } else if (res == -2) { + close_socket(&ms->sangoma_sock); + ms->sangoma_sock = sangoma_open_tdmapi_span_chan(woomera->span+1, woomera->chan+1); + if (ms->sangoma_sock < 0) { + log_printf(0, server.log, "Media TDM Restart Failed%s\n", + woomera->interface); + break; + } + log_printf(0, server.log, "Media TDM Restart %s\n", + woomera->interface); + continue; + } else if (res < 0) { + log_printf(0, server.log, "Media TDM Sangoma Socket Error %s\n", + woomera->interface); + break; + } + + res = sangoma_readmsg_socket(ms->sangoma_sock, + &hdrframe, + sizeof(hdrframe), + circuit_frame, + sizeof(circuit_frame), 0); + if (res < 0) { + log_printf(0, server.log, "TDM ReadMsg Error: %s\n", strerror(errno)); + break; + } + + res = sendto(ms->udp_sock, + circuit_frame, + res, 0, + (struct sockaddr *) &ms->remote_addr, + sizeof(ms->remote_addr)); + + if (res < 0) { + log_printf(2, server.log, "UDP Sento Error: %s\n", strerror(errno)); + break; + } +#if 0 + if (woomera->span == 1 && woomera->chan == 1) { + tdm_cnt++; + if (tdm_cnt && tdm_cnt % 1000 == 0) { + log_printf(0, server.log, "%s: MEDIA TDM TX RX CNT %i %i\n", + woomera->interface,tdm_cnt,res); + } + } +#endif + } + + if (res < 0) { + log_printf(2, server.log, "Media TDM Thread: socket error !\n"); + } + + log_printf(2, server.log, "MEDIA TDM session for [%s] ended (ptr=%p)\n", + woomera->interface,woomera); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + + pthread_exit(NULL); + return NULL; + +} + + +/* This function must be called with process_lock + * because it modifies shared process_table */ + +static int launch_media_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms; + + if ((ms = media_session_new(woomera))) { + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_RUNNING); + result = pthread_create(&ms->thread, &attr, media_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING); + media_session_free(woomera->ms); + + } + pthread_attr_destroy(&attr); + + } else { + log_printf(0, server.log, "Failed to start new media session\n"); + } + + return result; + +} + +static int launch_media_tdm_thread(struct woomera_interface *woomera) +{ + pthread_attr_t attr; + int result = -1; + struct media_session *ms = woomera_get_ms(woomera); + + if (!ms) { + return result; + } + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + result = pthread_create(&ms->thread, &attr, media_tdm_thread_run, ms); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +static struct woomera_interface * launch_woomera_loop_thread(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + char callid[20]; + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + + if ((woomera = alloc_woomera())) { + + woomera->chan = event->chan; + woomera->span = event->span; + woomera->log = server.log; + woomera->debug = server.debug; + woomera->call_id = 1; + woomera->event_queue = NULL; + woomera->loop_tdm=1; + + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + woomera_set_interface(woomera,callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = woomera; + pthread_mutex_unlock(&server.process_lock); + + if (launch_woomera_thread(woomera)) { + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + free(woomera); + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + return NULL; + } + + return woomera; +} + +static int woomera_message_parse(struct woomera_interface *woomera, struct woomera_message *wmsg, int timeout) +{ + char *cur, *cr, *next = NULL, *eor = NULL; + char buf[2048]; + int res = 0, bytes = 0, sanity = 0; + struct timeval started, ended; + int elapsed, loops = 0; + int failto = 0; + int packet = 0; + + memset(wmsg, 0, sizeof(*wmsg)); + + if (woomera->socket < 0 ) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Invalid Socket! %d\n", + woomera->interface,woomera->socket); + return -1; + } + + if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP !\n", + woomera->interface); + return -1; + } + + gettimeofday(&started, NULL); + memset(buf, 0, sizeof(buf)); + + if (timeout < 0) { + timeout = abs(timeout); + failto = 1; + } else if (timeout == 0) { + timeout = -1; + } + + + while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) { + if (sanity > 1000) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Failed Sanity Check!\n[%s]\n\n", woomera->interface, buf); + return -1; + } + + if ((res = waitfor_socket(woomera->socket, 1000, POLLERR | POLLIN) > 0)) { + res = recv(woomera->socket, buf, sizeof(buf), MSG_PEEK); + + if (res > 1) { + packet++; + } + if (!strncmp(buf, WOOMERA_LINE_SEPERATOR, 2)) { + res = read(woomera->socket, buf, 2); + return 0; + } + if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } else if (res < 0) { + log_printf(3, woomera->log, WOOMERA_DEBUG_PREFIX + "%s error during packet retry #%d\n", + woomera->interface, loops); + return res; + } else if (loops) { + ysleep(100000); + } + } + + gettimeofday(&ended, NULL); + elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000)); + + if (res < 0) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX "%s Bad RECV\n", + woomera->interface); + return res; + } else if (res == 0) { + sanity++; + /* Looks Like it's time to go! */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END) || + woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(5, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MEDIA END or HANGUP \n", woomera->interface); + return -1; + } + ysleep(1000); + continue; + } + + if (packet && loops > 150) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout waiting for packet.\n", + woomera->interface); + return -1; + } + + if (timeout > 0 && (elapsed > timeout)) { + log_printf(1, woomera->log, WOOMERA_DEBUG_PREFIX + "%s Timeout [%d] reached\n", + woomera->interface, timeout); + return failto ? -1 : 0; + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)) { + /* BRB! we have an Event to deliver....*/ + return 0; + } + + /* what're we still doing here? */ + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + !woomera_test_flag(woomera, WFLAG_RUNNING)) { + log_printf(2, woomera->log, WOOMERA_DEBUG_PREFIX + "%s MASTER RUNNING or RUNNING!\n", woomera->interface); + return -1; + } + loops++; + } + + *eor = '\0'; + bytes = strlen(buf) + 4; + + memset(buf, 0, sizeof(buf)); + res = read(woomera->socket, buf, bytes); + next = buf; + + if (woomera->debug > 1) { + log_printf(3, woomera->log, "%s:WOOMERA RX MSG: %s\n",woomera->interface,buf); + + } + + while ((cur = next)) { + + if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) { + *cr = '\0'; + next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1); + if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) { + break; + } + } + if (!cur || !*cur) { + break; + } + + if (!wmsg->last) { + char *cmd, *id, *args; + woomera_set_flag(wmsg, MFLAG_EXISTS); + cmd = cur; + + if ((id = strchr(cmd, ' '))) { + *id = '\0'; + id++; + if ((args = strchr(id, ' '))) { + *args = '\0'; + args++; + strncpy(wmsg->command_args, args, sizeof(wmsg->command_args)-1); + } + strncpy(wmsg->callid, id, sizeof(wmsg->callid)-1); + } + + strncpy(wmsg->command, cmd, sizeof(wmsg->command)-1); + } else { + char *name, *val; + name = cur; + + if ((val = strchr(name, ':'))) { + *val = '\0'; + val++; + while (*val == ' ') { + *val = '\0'; + val++; + } + strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN); + } + strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN); + if (name && val && !strcasecmp(name, "content-type")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + if (name && val && !strcasecmp(name, "content-length")) { + woomera_set_flag(wmsg, MFLAG_CONTENT); + bytes = atoi(val); + } + + + } + wmsg->last++; + } + + wmsg->last--; + + if (bytes && woomera_test_flag(wmsg, MFLAG_CONTENT)) { + read(woomera->socket, wmsg->body, + (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes); + } + + return woomera_test_flag(wmsg, MFLAG_EXISTS); + +} + +static struct woomera_interface *pull_from_holding_tank(int index, int span , int chan) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + + /* Block this index until the call is completed */ + server.holding_tank[index] = &woomera_dead_dev; + + woomera->timeout = 0; + woomera->index = 0; + woomera->span=span; + woomera->chan=chan; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static void clear_from_holding_tank(int index, struct woomera_interface *woomera) +{ + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] == &woomera_dead_dev) { + server.holding_tank[index] = NULL; + } else if (woomera && server.holding_tank[index] == woomera) { + server.holding_tank[index] = NULL; + } else if (server.holding_tank[index]) { + log_printf(0, server.log, "Error: Holding tank index %i not cleared %p !\n", + index, server.holding_tank[index]); + } + pthread_mutex_unlock(&server.ht_lock); + + return; +} + +static struct woomera_interface *peek_from_holding_tank(int index) +{ + struct woomera_interface *woomera = NULL; + + if (index < 1 || index >= CORE_TANK_LEN) { + if (index != 0) { + log_printf(0, server.log, "%s Error on invalid TANK INDEX = %i\n", + __FUNCTION__,index); + } + return NULL; + } + + pthread_mutex_lock(&server.ht_lock); + if (server.holding_tank[index] && + server.holding_tank[index] != &woomera_dead_dev) { + woomera = server.holding_tank[index]; + } + pthread_mutex_unlock(&server.ht_lock); + + return woomera; +} + +static int add_to_holding_tank(struct woomera_interface *woomera) +{ + int next, i, found=0; + + pthread_mutex_lock(&server.ht_lock); + + for (i=0;i= CORE_TANK_LEN) { + next = server.holding_tank_index = 1; + } + + if (next == 0) { + log_printf(0, server.log, "\nCritical Error on TANK INDEX == 0\n"); + continue; + } + + if (server.holding_tank[next]) { + continue; + } + + found=1; + break; + } + + if (!found) { + /* This means all tank vales are busy + * should never happend */ + pthread_mutex_unlock(&server.ht_lock); + log_printf(0, server.log, "\nCritical Error failed to obtain a TANK INDEX\n"); + return 0; + } + + server.holding_tank[next] = woomera; + woomera->timeout = time(NULL) + 100; + + pthread_mutex_unlock(&server.ht_lock); + return next; +} + +static int handle_woomera_media_accept_answer(struct woomera_interface *woomera, + struct woomera_message *wmsg, + int media, int answer, int accept) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + + log_printf(4, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + + if (woomera_test_flag(woomera, WFLAG_HANGUP) || + !woomera_test_flag(woomera, WFLAG_RUNNING) || + woomera_test_flag(woomera, WFLAG_MEDIA_END)) { + + log_printf(2, server.log, + "ERROR! call was cancelled MEDIA on HANGUP or MEDIA END!\n"); + + woomera->timeout=0; + return -1; + } + + log_printf(3, server.log,"WOOMERA: GOT %s EVENT: [%s] RAW=%s\n", + wmsg->command,wmsg->callid,raw); + + + if (raw && + woomera->raw == NULL && + !woomera_test_flag(woomera, WFLAG_RAW_MEDIA_STARTED)) { + + woomera_set_flag(woomera, WFLAG_RAW_MEDIA_STARTED); + + woomera_set_raw(woomera, raw); + + if (launch_media_thread(woomera)) { + struct woomera_event wevent; + + log_printf(4, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + woomera->timeout=0; + return -1; + } + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + + } else { + + if (accept) { + if (!autoacm) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + } + + if (answer) { + struct media_session *ms; + + pthread_mutex_lock(&woomera->ms_lock); + if ((ms=woomera->ms)) { + time(&woomera->ms->answered); + } + pthread_mutex_unlock(&woomera->ms_lock); + + if (ms) { + + if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + isup_exec_command(woomera->span, + woomera->chan, + -1, + SIGBOOST_EVENT_CALL_ANSWERED, + 0); + log_printf(2, server.log, + "Sent SIGBOOST_EVENT_CALL_ANSWERED [w%dg%d]\n", + woomera->span+1,woomera->chan+1); + } else { + struct woomera_event wevent; + log_printf(0, server.log, + "WOOMERA ANSWER: FAILED [%s] no Media \n", + wmsg->command,wmsg->callid); + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + woomera->timeout=0; + return -1; + } + } + } + + { + struct woomera_event wevent; + new_woomera_event_printf(&wevent, "200 %s OK%s" + "Unique-Call-Id: %s%s", + answer ? "ANSWER" : + accept ? "ACCEPT" : "MEDIA", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + + return 0; +} + +static int handle_woomera_call_start (struct woomera_interface *woomera, + struct woomera_message *wmsg) +{ + char *raw = woomera_message_header(wmsg, "raw-audio"); + call_signal_event_t event; + char *calling = woomera_message_header(wmsg, "local-number"); +#ifdef SMG_CALLING_NAME + char *calling_name = woomera_message_header(wmsg, "local-name"); +#endif + char *presentation = woomera_message_header(wmsg, "Presentation"); + char *screening = woomera_message_header(wmsg, "Screening"); + char *rdnis = woomera_message_header(wmsg, "RDNIS"); + char *called = wmsg->callid; + char *grp = wmsg->callid; + char *p; + int tg = 0; + + if (smg_check_all_busy()) { + socket_printf(woomera->socket, + "405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR); + log_printf(3, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n", + server.call_count, server.all_ckt_busy); + return -1; + } + + log_printf(2, woomera->log, "New Call %d/%d\n", server.call_count, server.max_calls); + + if ((p = strchr(called, '/'))) { + *p = '\0'; + called = p+1; + tg = atoi(grp+1) - 1; + if (tg < 0) { + tg=0; + } + } + + woomera->trunk_group=tg; + + if (raw) { + woomera_set_raw(woomera, raw); + } + + woomera->index = add_to_holding_tank(woomera); + if (woomera->index < 1) { + socket_printf(woomera->socket, + "405 SMG Server All Tanks Busy!%s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0, woomera->log, "Error: Call Tank Full (Call Cnt=%i)\n", + server.call_count); + return -1; + } + + + woomera->index_hold = woomera->index; + + call_signal_call_init(&event, calling, called, woomera->index); + + if (presentation) { + event.calling_number_presentation = atoi(presentation); + } else { + event.calling_number_presentation = 0; + } + + if (screening) { + event.calling_number_screening_ind = atoi(screening); + } else { + event.calling_number_screening_ind = 0; + } + + if (rdnis && strlen(rdnis)) { + strncpy((char*)event.redirection_string,rdnis, + sizeof(event.redirection_string)-1); + log_printf(0,server.log,"RDNIS %s\n", rdnis); + + } + +#ifdef SMG_CALLING_NAME + if (calling_name) { + strncpy((char*)event.calling_name,calling_name, + sizeof(event.calling_name)-1); + } +#endif + + event.trunk_group = tg; + + + if (call_signal_connection_write(&server.mcon, &event) <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + socket_printf(woomera->socket, + "405 SMG Signalling Contestion!%s", + WOOMERA_RECORD_SEPERATOR); + return -1; + } + + socket_printf(woomera->socket, "100 Trying%s", WOOMERA_RECORD_SEPERATOR); + + log_printf(2, server.log, "Call Called Event [Setup ID: %d] TG=%d\n", + woomera->index,tg); + + return 0; +} + + +static void interpret_command(struct woomera_interface *woomera, struct woomera_message *wmsg) +{ + int answer = 0, media = 0, accept=0; + char *unique_id; + int cause=0; + + + if (!strcasecmp(wmsg->command, "call")) { + int err; + if (strlen(woomera->session) != 0) { + /* Call has already been placed */ + socket_printf(woomera->socket, "400 Error Call already in progress %s", + WOOMERA_RECORD_SEPERATOR); + log_printf(0,server.log,"Woomera RX Call Even while call in progress!\n"); + return; + } + + err=handle_woomera_call_start(woomera,wmsg); + if (err) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + return; + + } else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) { + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + if (cause) { + log_printf(3, woomera->log, "Bye Cause Received: [%s]\n", cause); + } + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + log_printf(2, woomera->log, "WOOMERA CMD: Bye Received: [%s]\n", woomera->interface); + + woomera_clear_flag(woomera, WFLAG_RUNNING); + socket_printf(woomera->socket, "200 Connection closed%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + + } else if (!strcasecmp(wmsg->command, "listen")) { + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + socket_printf(woomera->socket, "405 Listener already started%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + } else { + char *event_string; + + woomera_set_flag(woomera, WFLAG_LISTENING); + add_listener(woomera); + + if (!strcmp(wmsg->callid,"MASTER")) { + woomera_set_flag(woomera, WFLAG_MASTER_DEV); + log_printf(0,woomera->log, "Starting MASTER Listen Device!\n"); + master_reset=0; + } + + + socket_printf(woomera->socket, "%s", + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "200 Listener enabled%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + if ((event_string = dequeue_event(&server.master_connection))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + event_string = NULL; + } + } + return; + + } else if ((media = !strcasecmp(wmsg->command, "debug"))) { + + int debug_level=atoi(wmsg->callid); + + if (debug_level < 10) { + server.debug=debug_level; + log_printf(0,server.log,"SMG Debugging set to %i (window=%i)\n",server.debug,server.mcon.txwindow); + } + + return; + } + + unique_id = woomera_message_header(wmsg, "Unique-Call-Id"); + if (!unique_id) { + + cause=111; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (strlen(woomera->session) == 0) { + struct woomera_interface *session_woomera=NULL; + char *session=NULL; + int span, chan; + char ifname[100]; + /* If session does not exist this is an incoming call */ + sscanf(unique_id, "w%dg%d", &span, &chan); + span--; + chan--; + + log_printf(3, woomera->log, + "WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n", + wmsg->command,span,chan,unique_id); + + if (smg_validate_span_chan(span,chan) != 0) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Invalid span/chan in session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(2, woomera->log, + "WOOMERA Warning invalid span chan in session %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + pthread_mutex_lock(&server.process_lock); + session = server.process_table[span][chan].session; + session_woomera = server.process_table[span][chan].dev; + + if (session_woomera) { + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + socket_printf(woomera->socket, "404 Session not found%s" + WOOMERA_RECORD_SEPERATOR); + + + log_printf(0, woomera->log, "WOOMERA Error channel in use %s %s\n", + wmsg->command,unique_id); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + if (!session || strlen(session) == 0 || + strncmp(session,unique_id,sizeof(woomera->session))){ + pthread_mutex_unlock(&server.process_lock); + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Invalid/Expired Session%s" + WOOMERA_RECORD_SEPERATOR); + + log_printf(3, woomera->log, + "WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n", + wmsg->command,unique_id,session?session:"N/A"); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + server.process_table[span][chan].dev=woomera; + strncpy(woomera->session,unique_id,sizeof(woomera->session)); + sprintf(ifname,"w%dg%d",span+1,chan+1); + woomera_set_interface(woomera, ifname); + + woomera->span=span; + woomera->chan=chan; + + pthread_mutex_unlock(&server.process_lock); + + + log_printf(3, woomera->log, "WOOMERA Got New If=%s Session %s\n", + woomera->interface, woomera->session); + + + } else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) { + + cause=34; + socket_printf(woomera->socket, "EVENT HANGUP %s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(cause), + WOOMERA_LINE_SEPERATOR, + cause, + WOOMERA_RECORD_SEPERATOR); + + socket_printf(woomera->socket, "404 Session Mis-match%s" + WOOMERA_RECORD_SEPERATOR); + woomera_set_flag(woomera, WFLAG_HANGUP); + return; + } + + + if (!strcasecmp(wmsg->command, "dtmf")) { + + log_printf(3, woomera->log, "WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n", + woomera->interface, wmsg->command_args, wmsg->body); + +#ifdef SMG_DTMF_ENABLE + wanpipe_send_dtmf(woomera,wmsg->body); +#endif + socket_printf(woomera->socket, "200 DTMF OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "hangup")) { + + int chan = -1, span = -1; + char *cause = woomera_message_header(wmsg, "cause"); + char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code"); + + + if (q931cause && atoi(q931cause)) { + woomera_set_cause_tosig(woomera,atoi(q931cause)); + } + + span=woomera->span; + chan=woomera->chan; + + log_printf(3, woomera->log, "WOOMERA CMD: Hangup Received: [%s] MEDIA EXIST Cause=%s\n", + woomera->interface,cause); + + if (smg_validate_span_chan(span,chan) != 0) { + + socket_printf(woomera->socket, "405 No Such Channel%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + return; + } + + + log_printf(2, woomera->log, "Hangup Received: [w%dg%d]\n", + span+1,chan+1); + + + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + + socket_printf(woomera->socket, "200 HANGUP OK%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + + } else if (!strcasecmp(wmsg->command, "proceed")) { + + log_printf(3, woomera->log, "WOOMERA CMD: %s [%s]\n", + wmsg->command, woomera->interface); + + socket_printf(woomera->socket, + "200 %s PROCEED OK%s" + "Unique-Call-Id: %s%s", + wmsg->callid, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + } else if ((media = !strcasecmp(wmsg->command, "media")) || + (answer = !strcasecmp(wmsg->command, "answer")) || + (accept = !strcasecmp(wmsg->command, "accept"))) { + + handle_woomera_media_accept_answer(woomera, wmsg, media,answer,accept); + + + + } else { + log_printf(0, server.log,"WOOMERA INVALID EVENT: %s [%s] \n", + wmsg->command,wmsg->callid); + socket_printf(woomera->socket, "501 Command '%s' not implemented%s", + wmsg->command, WOOMERA_RECORD_SEPERATOR); + } +} + + +/* + EVENT INCOMING 1 + Remote-Address: 10.3.3.104 + Remote-Number: + Remote-Name: Anthony Minessale!8668630501 + Protocol: H.323 + User-Agent: Post Increment Woomera 1.0alpha1 (OpenH323 v1.17.2) 9/61 + H323-Call-Id: 887b1ff8-bb1f-da11-85c0-0007e98988c4 + Local-Number: 996 + Start-Time: Fri, 09 Sep 2005 12:25:14 -0400 + Local-Name: root +*/ + + +static void handle_call_answer(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int kill = 0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + pthread_mutex_unlock(&server.process_lock); + + if (woomera && woomera->raw) { + char callid[80]; + struct woomera_event wevent; + + if (woomera_test_flag(woomera, WFLAG_ANSWER)) { + log_printf(1, server.log, "Refusing to double-answer a call!\n"); + return; + } + + woomera_set_flag(woomera, WFLAG_ANSWER); + + if (woomera->span != event->span || woomera->chan != event->chan) { + log_printf(1, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n"); + kill++; + return; + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to answer a dead call!\n"); + kill++; + } else { + int err; + err=0; + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + woomera_set_interface(woomera, callid); +#ifndef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; + } +#endif + + if (!kill) { + new_woomera_event_printf(&wevent, "EVENT CONNECT w%dg%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + } + } + } else { + log_printf(1, server.log, "Answer requested on non-existant session. [w%dg%d]\n", + event->span+1, event->chan+1); + kill++; + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_ack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + struct woomera_event wevent; + int kill = 0; + + if ((woomera = peek_from_holding_tank(event->call_setup_id))) { + char callid[80]; + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(1, server.log, "Refusing to ack a dead call!\n"); + kill++; + } else { + int err, span, chan; + + pull_from_holding_tank(event->call_setup_id,event->span,event->chan); + sprintf(callid, "w%dg%d", event->span + 1, event->chan + 1); + + span = event->span; + chan = event->chan; + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + woomera_set_interface(woomera, callid); + + pthread_mutex_lock(&server.process_lock); + server.process_table[span][chan].dev = woomera; + sprintf(woomera->session,"%s-%i-%i",callid,rand(),rand()); + sprintf(server.process_table[span][chan].session,"%s-%s", + callid,woomera->session); + pthread_mutex_unlock(&server.process_lock); + + + +#ifdef WOOMERA_EARLY_MEDIA + err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log,"ERROR: Failed to Launch Call [%s]\n", + woomera->interface); + + +#if 0 + new_woomera_event_printf(&wevent, "501 call was cancelled!%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); +#endif + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id:%s%s" + "Q931-Cause-Code: %d%s" + "Cause: %s%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + 21, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(21), + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + woomera_set_flag(woomera,WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + kill++; + } +#endif + if (!kill) { + new_woomera_event_printf(&wevent, "201 Accepted%s" + "Unique-Call-Id: %s%s", + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + new_woomera_event_printf(&wevent, "EVENT PROCEED w%dg%d%s" + "Channel-Name: g%d/%d%s" + "Unique-Call-Id: %s%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_RECORD_SEPERATOR + ); + + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + log_printf(2, server.log, "Call Answered Event ID = %d Device = w%dg%d!\n", + event->call_setup_id,woomera->span+1,woomera->chan+1); + } + } + } else { + log_printf(1, server.log, + "Event (START ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id, event->call_setup_id,event->span+1, event->chan+1); + kill++; + } + +#if 0 + if (kill) { + call_signal_event_t oevent; + + if (woomera) { + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + /* Do not hangup if this call was already hungup */ + return; + } + + woomera_set_flag(woomera, WFLAG_HANGUP); + } + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_NORMAL); + + log_printf(2, server.log, "Sent Refusal SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } +#endif + +} + +static void handle_call_start_nack(call_signal_event_t *event) +{ + struct woomera_interface *woomera = NULL; + int span=-1, chan=-1; + int ack=0; + + /* Always ACK the incoming NACK + * Send out the NACK ACK before pulling the TANK, because + * if we send after the pull, the outgoing call could send + * a message to boost with the pulled TANK value before + * we send a NACK ACK */ + + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + + if (event->call_setup_id > 0) { + woomera=peek_from_holding_tank(event->call_setup_id); + } + + if (woomera) { + + struct woomera_event wevent; + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + /* Only pull the index if we have not sent a NACK. + If NACK was already sent out we must wait for ACK + from the other side */ + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + pull_from_holding_tank(event->call_setup_id,-1,-1); + } + + isup_exec_command(0, + 0, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + if (woomera_test_flag(woomera, WFLAG_HANGUP)) { + log_printf(0, server.log, "Event CALL START NACK on hungup call [%d]!\n", + event->call_setup_id); + } else { + + woomera_set_cause_topbx(woomera,event->release_cause); + + new_woomera_event_printf(&wevent, "EVENT HANGUP w%dg%d%s" + "Unique-Call-Id: %s%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(woomera->q931_rel_cause_topbx), + WOOMERA_LINE_SEPERATOR, + woomera->q931_rel_cause_topbx, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + + woomera_set_flag(woomera, WFLAG_HANGUP); + woomera_clear_flag(woomera, WFLAG_RUNNING); + + } + + /* We already did the NACK */ + ack=0; + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + + if (woomera && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } + + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + + log_printf(2, server.log, "Event START NACK on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + if (woomera_test_flag(woomera,WFLAG_HANGUP)){ + ack++; + goto handle_call_start_nack_skip; + } + + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK)); + + /* Nack Ack will be sent by the woomera thread */ + ack=0; + } else { + /* Valid state when we are not in autoacm mode */ + ack++; + log_printf(3, server.log, "Event: NACK no woomera on span chan [w%dg%d]!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(0, server.log, + "Error: Start Nack Invalid State Should not happen [%d] [w%dg%d]!\n", + event->call_setup_id, event->span+1, event->chan+1); + ack++; + } +handle_call_start_nack_skip: + + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { + log_printf(0, server.log, "WARNING: All ckt busy!\n"); + smg_all_ckt_busy(); + } + +#warning "Ignoring CALL GAP" +#if 0 + if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) { + log_printf(0, server.log, "WARNING: Call Gapping Detected!\n"); + smg_all_ckt_gap(); + } +#endif + + if (ack) { + span=0; + chan=0; + if (smg_validate_span_chan(event->span,event->chan) == 0) { + span=event->span; + chan=event->chan; + } + isup_exec_command(span, + chan, + event->call_setup_id, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + 0); + + if (!woomera) { + log_printf(2, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [w%dg%d]!\n", + event->event_id,event->call_setup_id, event->span+1, event->chan+1); + } + } +} + +static void handle_call_loop_start(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + + woomera=launch_woomera_loop_thread(event); + if (woomera == NULL) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + log_printf(1, server.log, + "Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg] ptr=%d\n", + event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev); + } + + woomera_set_flag(woomera,WFLAG_CALL_ACKED); + + return; +} + +static void handle_call_start(call_signal_event_t *event) +{ + struct woomera_event wevent; + char callid[20]; + char *session; + + pthread_mutex_lock(&server.process_lock); + if (server.process_table[event->span][event->chan].dev) { + + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + + + log_printf(0, server.log, + "Sent (From Handle START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [w%dg%d]\n", + event->span+1, event->chan+1); + + pthread_mutex_unlock(&server.process_lock); + return; + + } + + sprintf(callid, "w%dg%d", event->span+1,event->chan+1); + sprintf(server.process_table[event->span][event->chan].session, + "%s-%i-%i",callid,rand(),rand()); + session=server.process_table[event->span][event->chan].session; + server.process_table[event->span][event->chan].dev = NULL; + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_ACK, + 0); + } + + new_woomera_event_printf(&wevent, "EVENT INCOMING w%dg%d%s" + "Unique-Call-Id: %s%s" + "Remote-Number: %s%s" + "Remote-Name: %s%s" + "Protocol: SS7%s" + "User-Agent: sangoma_mgd%s" + "Local-Number: %s%s" + "Channel-Name: g%d/%d%s" + "Trunk-Group: %d%s" + "Presentation: %d%s" + "Screening: %d%s" + "RDNIS: %s%s" + , + event->span+1, + event->chan+1, + WOOMERA_LINE_SEPERATOR, + session, + WOOMERA_LINE_SEPERATOR, + event->calling_number_digits, + WOOMERA_LINE_SEPERATOR, +#ifdef SMG_CALLING_NAME + event->calling_name, +#else + "", +#endif + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + event->called_number_digits, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + (event->span*31)+event->chan+1, + WOOMERA_LINE_SEPERATOR, + event->trunk_group+1, + WOOMERA_LINE_SEPERATOR, + event->calling_number_presentation, + WOOMERA_LINE_SEPERATOR, + event->calling_number_screening_ind, + WOOMERA_LINE_SEPERATOR, + event->redirection_string, + WOOMERA_RECORD_SEPERATOR + ); + + if (enqueue_event_on_listeners(&wevent)) { + enqueue_event(&server.master_connection, &wevent, EVENT_KEEP_DATA); + } else { + + pthread_mutex_lock(&server.process_lock); + server.process_table[event->span][event->chan].dev = NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (autoacm) { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + SIGBOOST_RELEASE_CAUSE_BUSY); + } else { + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + SIGBOOST_RELEASE_CAUSE_BUSY); + } + + log_printf(0, server.log, + "CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d]\n", + event->span+1, event->chan+1); + } + + destroy_woomera_event_data(&wevent); + +} + +static void handle_gap_abate(call_signal_event_t *event) +{ + log_printf(0, server.log, "NOTICE: GAP Cleared!\n", + event->span+1, event->chan+1); + smg_clear_ckt_gap(); +} + +static void handle_restart_ack(call_signal_connection_t *mcon,call_signal_event_t *event) +{ + mcon->rxseq_reset =0; +} + +static void handle_call_stop(call_signal_event_t *event) +{ + struct woomera_interface *woomera; + int ack=0; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + if (woomera && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK) && + !woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + /* Only if we are not already waiting for hangup */ + server.process_table[event->span][event->chan].dev=NULL; + } + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + + if (woomera_test_flag(woomera,WFLAG_HANGUP)) { + ack++; + goto handle_call_stop_skip; + } + + woomera_set_cause_topbx(woomera,event->release_cause); + + woomera_set_flag(woomera, + (WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK)); + + /* We have to close the socket because + At this point we are release span chan */ + +#ifdef MEDIA_SOCK_SHUTDOWN + pthread_mutex_lock(&woomera->ms_lock); + if (woomera->ms) { + log_printf(3, server.log, "Event CALL STOP [w%dg%d] closing sockets\n", + woomera->span+1,woomera->chan+1); + + close_socket(&woomera->ms->sangoma_sock); + close_socket(&woomera->ms->udp_sock); + // shutdown(woomera->ms->sangoma_sock, SHUT_RDWR); + // shutdown(woomera->ms->udp_sock, SHUT_RDWR); + } + pthread_mutex_unlock(&woomera->ms_lock); +#endif + + log_printf(3, server.log, "Event CALL STOP on w%dg%d ptr=%p ms=%p\n", + woomera->span+1,woomera->chan+1,woomera,woomera->ms); + + } else { + ack++; + } + +handle_call_stop_skip: + + if (ack) { + /* At this point we have already sent our STOP so its safe to ACK */ + isup_exec_command(event->span, + event->chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + 0); + } + + if (!woomera){ + /* This is allowed on incoming call if remote app does not answer it */ + log_printf(3, server.log, "Event CALL STOP referrs to a non-existant session [w%dg%d]!\n", + event->span+1, event->chan+1); + } +} + +static void handle_heartbeat(call_signal_event_t *event) +{ + if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + log_printf(0, server.log,"ERROR! Monitor Thread not running!\n"); + } else { + int err=call_signal_connection_write(&server.mcon, event); + if (err <= 0) { + log_printf(0, server.log, + "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", + strerror(errno)); + } + } + return; +} + +static void handle_call_stop_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + + if (woomera) { + log_printf(2, server.log, "Stop Ack on [w%dg%d] [Setup ID: %d] [%s]!\n", + event->span+1, event->chan+1, event->call_setup_id, + woomera->interface); + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + + } else { + log_printf(2, server.log, "Event CALL_STOP_ACK(%d) referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->event_id, event->span+1, event->chan+1, event->call_setup_id); + } + + /* No need for us to do any thing here */ + return; +} + + +static void handle_call_start_nack_ack(call_signal_event_t *event) +{ + + struct woomera_interface *woomera = NULL; + + if ((woomera=pull_from_holding_tank(event->call_setup_id,-1,-1))) { + + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + + } else if (event->call_setup_id == 0 && + smg_validate_span_chan(event->span,event->chan) == 0) { + + pthread_mutex_lock(&server.process_lock); + woomera = server.process_table[event->span][event->chan].dev; + server.process_table[event->span][event->chan].dev=NULL; + memset(server.process_table[event->span][event->chan].session, + 0,SMG_SESSION_NAME_SZ); + pthread_mutex_unlock(&server.process_lock); + + if (woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + } else { + log_printf(0, server.log, + "Event NACK ACK [w%dg%d] with valid span/chan no dev!\n", + event->span+1, event->chan+1); + } + + } else { + log_printf(2, server.log, + "Event NACK ACK referrs to a non-existant session [w%dg%d] [Setup ID: %d]!\n", + event->span+1, event->chan+1, event->call_setup_id); + } + + if (event->call_setup_id > 0) { + clear_from_holding_tank(event->call_setup_id, NULL); + } + + /* No need for us to do any thing here */ + return; +} + +#if 0 +static void validate_number(unsigned char *s) +{ + unsigned char *p; + for (p = s; *p; p++) { + if (*p < 48 || *p > 57) { + log_printf(2, server.log, "Encountered a non-numeric character [%c]!\n", *p); + *p = '\0'; + break; + } + } +} +#endif + +static int parse_ss7_event(call_signal_connection_t *mcon, call_signal_event_t *event) +{ + int ret = 0; + +#if 0 + validate_number((unsigned char*)event->called_number_digits); + validate_number((unsigned char*)event->calling_number_digits); +#endif + +#if 1 + log_printf(2, server.log, + "RX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + +#if 0 + log_printf(2, server.log, "RX EVENT\n"); + log_printf(2, server.log, "===================================\n"); + log_printf(2, server.log, " rType: %s (%0x HEX)\n", + call_signal_event_id_name(event->event_id),event->event_id); + log_printf(2, server.log, " rSpan: [%d]\n",event->span+1); + log_printf(2, server.log, " rChan: [%d]\n",event->chan+1); + log_printf(2, server.log, " rCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + log_printf(2, server.log, " rCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + log_printf(2, server.log, " rCause: %d\n",event->release_cause); + log_printf(2, server.log, " rInterface: [w%dg%d]\n",event->span+1,event->chan+1); + log_printf(2, server.log, " rEvent ID: [%d]\n",event->event_id); + log_printf(2, server.log, " rSetup ID: [%d]\n",event->call_setup_id); + log_printf(2, server.log, " rSeq: [%d]\n",event->fseqno); + log_printf(2, server.log, "===================================\n"); + +#endif + +#if 0 + log_printf(2, server.log, + "\nRX EVENT\n" + "===================================\n" + " rType: %s (%0x HEX)\n" + " rSpan: [%d]\n" + " rChan: [%d]\n" + " rCalledNum: %s\n" + " rCallingNum: %s\n" + " rCause: %s\n" + " rInterface : [w%dg%d]\n" + " rEvent ID : [%d]\n" + " rSetup ID: [%d]\n" + " rSeq: [%d]\n" + "===================================\n" + "\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), + release_to_string(event->release_cause), + event->span+1, + event->chan+1, + event->event_id, + event->call_setup_id, + event->fseqno + ); +#endif + + + switch(event->event_id) { + + case SIGBOOST_EVENT_CALL_START: + handle_call_start(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_CALL_START_ACK: + handle_call_start_ack(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK: + handle_call_start_nack(event); + break; + case SIGBOOST_EVENT_CALL_ANSWERED: + handle_call_answer(event); + break; + case SIGBOOST_EVENT_HEARTBEAT: + handle_heartbeat(event); + break; + case SIGBOOST_EVENT_CALL_START_NACK_ACK: + handle_call_start_nack_ack(event); + break; + case SIGBOOST_EVENT_CALL_STOPPED_ACK: + handle_call_stop_ack(event); + break; + case SIGBOOST_EVENT_INSERT_CHECK_LOOP: + handle_call_loop_start(event); + break; + case SIGBOOST_EVENT_REMOVE_CHECK_LOOP: + handle_call_stop(event); + break; + case SIGBOOST_EVENT_SYSTEM_RESTART_ACK: + handle_restart_ack(mcon,event); + break; + case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE: + handle_gap_abate(event); + break; + default: + log_printf(0, server.log, "Warning no handler implemented for [%s]\n", + call_signal_event_id_name(event->event_id)); + break; + } + + return ret; +} + + +static void *monitor_thread_run(void *obj) +{ + int ss = 0; + int policy=0,priority=0; + char a=0,b=0; + call_signal_connection_t *mcon=&server.mcon; + call_signal_connection_t *mconp=&server.mconp; + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + + if (call_signal_connection_open(mcon, + mcon->cfg.local_ip, + mcon->cfg.local_port, + mcon->cfg.remote_ip, + mcon->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCON Socket [%d] %s\n", + mcon->socket,strerror(errno)); + exit(-1); + } + + if (call_signal_connection_open(mconp, + mconp->cfg.local_ip, + mconp->cfg.local_port, + mconp->cfg.remote_ip, + mconp->cfg.remote_port) < 0) { + log_printf(0, server.log, "Error: Opening MCONP Socket [%d] %s\n", + mconp->socket,strerror(errno)); + exit(-1); + } + + mcon->log = server.log; + mconp->log = server.log; + + isup_exec_command(0, + 0, + -1, + SIGBOOST_EVENT_SYSTEM_RESTART, + 0); + + mcon->rxseq_reset=1; + + smg_get_current_priority(&policy,&priority); + + log_printf(1, server.log, "Open udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + log_printf(1, server.log, "Monitor Thread Started (%i:%i)\n",policy,priority); + + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { +#if 0 + ss = waitfor_socket(server.mcon.socket, 1000, POLLERR | POLLIN); +#else + ss = waitfor_2sockets(mcon->socket, + mconp->socket, + &a, &b, 1000); +#endif + + if (ss > 0) { + + call_signal_event_t *event=NULL; + int i=0; + + if (b) { +mcon_retry_priority: + if ((event = call_signal_connection_readp(mconp,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event P [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mconp,event); + if (++i < 10) { + goto mcon_retry_priority; + } + + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost P Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + i=0; + + if (a) { +mcon_retry: + if ((event = call_signal_connection_read(mcon,i))) { + struct timeval current; + struct timeval difftime; + gettimeofday(¤t,NULL); + timersub (¤t, &event->tv, &difftime); + log_printf(3, server.log, "Socket Event [%s] T=%d:%d\n", + call_signal_event_id_name(event->event_id), + difftime.tv_sec, difftime.tv_usec); + parse_ss7_event(mcon,event); + + if (++i < 50) { + goto mcon_retry; + } + } else if (errno != EAGAIN) { + ss=-1; + log_printf(0, server.log, + "Error: Reading from Boost Socket! (%i) %s\n", + errno,strerror(errno)); + break; + } + } + + } + + if (ss < 0){ + log_printf(0, server.log, "Thread Run: Select Socket Error!\n"); + break; + } + + } + + log_printf(1, server.log, "Close udp socket [%d] [%d]\n", + mcon->socket,mconp->socket); + call_signal_connection_close(&server.mcon); + call_signal_connection_close(&server.mconp); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + log_printf(0, server.log, "Monitor Thread Ended\n"); + + return NULL; +} + +static void woomera_loop_thread_run(struct woomera_interface *woomera) +{ + int err=launch_media_thread(woomera); + if (err) { + log_printf(0, server.log, "Failed to start loop media thread\n"); + woomera_set_flag(woomera, + (WFLAG_HANGUP|WFLAG_MEDIA_END)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + return; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP)) { + + sleep(1); + continue; + + } + + woomera_clear_flag(woomera, WFLAG_RUNNING); + + log_printf(2, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface); + + + + return; +} + +static void *woomera_thread_run(void *obj) +{ + struct woomera_interface *woomera = obj; + struct woomera_message wmsg; + struct woomera_event wevent; + char *event_string; + int mwi; + int err; + int policy=0, priority=0; + int span = -1, chan = -1; + + woomera_message_init(&wmsg); + + //smg_get_current_priority(&policy,&priority); + + log_printf(2, server.log, "WOOMERA session for started (ptr=%p : loop=%i)(%i:%i)\n", + woomera,woomera->loop_tdm,policy,priority); + + pthread_mutex_lock(&server.thread_count_lock); + server.thread_count++; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_mutex_init(&woomera->queue_lock, NULL); + pthread_mutex_init(&woomera->ms_lock, NULL); + pthread_mutex_init(&woomera->dtmf_lock, NULL); + pthread_mutex_init(&woomera->vlock, NULL); + pthread_mutex_init(&woomera->flags_lock, NULL); + + if (woomera->loop_tdm) { + woomera_loop_thread_run(woomera); + goto woomera_session_close; + } + + err=socket_printf(woomera->socket, + "EVENT HELLO Sangoma Media Gateway%s" + "Supported-Protocols: TDM%s" + "Version: %s%s" + "Remote-Address: %s%s" + "Remote-Port: %d%s" + "Raw-Format: %s%s", + WOOMERA_LINE_SEPERATOR, + WOOMERA_LINE_SEPERATOR, + SMG_VERSION, WOOMERA_LINE_SEPERATOR, + inet_ntoa(woomera->addr.sin_addr), WOOMERA_LINE_SEPERATOR, + ntohs(woomera->addr.sin_port), WOOMERA_LINE_SEPERATOR, + server.hw_coding?"ALAW":"ULAW", WOOMERA_RECORD_SEPERATOR + ); + + if (err) { + log_printf(0, server.log, "Woomera session socket failure! (ptr=%p)\n", + woomera); + woomera_clear_flag(woomera, WFLAG_RUNNING); + goto woomera_session_close; + } + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) && + woomera_test_flag(woomera, WFLAG_RUNNING) && + !woomera_test_flag(woomera, WFLAG_MEDIA_END) && + !woomera_test_flag(woomera, WFLAG_HANGUP) && + !master_reset) { + + + mwi = woomera_message_parse(woomera, &wmsg, WOOMERA_HARD_TIMEOUT); + if (mwi >= 0) { + + if (mwi) { + interpret_command(woomera, &wmsg); + } else if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + if (socket_printf(woomera->socket, "%s", event_string)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + woomera_clear_flag(woomera, WFLAG_RUNNING); + free(event_string); + log_printf(4, server.log, + "WOOMERA session (ptr=%p) print string error\n", + woomera); + break; + } + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + if (woomera->timeout > 0 && time(NULL) >= woomera->timeout) { + + /* Sent the hangup only after we sent a NACK */ + + log_printf(2, server.log, + "WOOMERA session (ptr=%p) Call Timedout ! [%s] (Timeout=%d)\n", + woomera,woomera->interface,woomera->timeout); + + /* Let the Index check below send a NACK */ + if (woomera->index) { + woomera_set_flag(woomera, WFLAG_HANGUP); + } + break; + } + + } else { + log_printf(3, server.log, "WOOMERA session (ptr=%p) [%s] READ MSG Error %i \n", + woomera,woomera->interface,mwi); + break; + } + + } + +woomera_session_close: + + log_printf(2, server.log, "WOOMERA session (ptr=%p) is dying [%s]: SR=%d WR=%d WF=0x%04X\n", + woomera,woomera->interface, + woomera_test_flag(&server.master_connection, WFLAG_RUNNING), + woomera_test_flag(woomera, WFLAG_RUNNING), + woomera->flags); + + + if (woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + woomera_set_flag(woomera, WFLAG_MEDIA_END); + while(woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) { + usleep(100); + sched_yield(); + } + } + + + /*********************************************** + * Identify the SPAN CHAN to be used below + ***********************************************/ + + chan = woomera->chan; + span = woomera->span; + + + if (!woomera_test_flag(woomera, WFLAG_HANGUP)) { + + /* The call was not HUNGUP. This is the last check, + If the call is valid, hungup the call if the call + was never up the keep going */ + woomera_set_flag(woomera, WFLAG_HANGUP); + + if (smg_validate_span_chan(span,chan) == 0) { + + if (!woomera->index) { + + if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED, + woomera->q931_rel_cause_tosig); + + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } else { + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + } + } else { + log_printf(0, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [w%dg%d] [%s] ptr=%p\n", + span+1, chan+1,woomera->interface,woomera); + + } + }else{ + /* This can happend if an outgoing call times out + or gets hungup before it gets acked. Its not a + failure */ + if (!woomera->index) { + + /* In this case we really failed to tx STOP */ + log_printf(0, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + } + + } + +woo_re_hangup: + + + /* We must send a STOP ACK to boost telling it that we are done */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + + /* SMG received a HANGUP from boost. + We must now send back the ACK to the HANGUP. + Boost will not release channel until we + ACK the hangup */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_STOPPED_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Ack) to SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + }else{ + /* This should never happen! If it does + we broke protocol */ + log_printf(0, woomera->log, + "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_ACK); + + } + + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + + /* SMG received a NACK from boost during call startup. + We must now send back the ACK to the NACK. + Boost will not release channel until we + ACK the NACK */ + + if (smg_validate_span_chan(span,chan) == 0) { + + isup_exec_command(span, + chan, + -1, + SIGBOOST_EVENT_CALL_START_NACK_ACK, + woomera->q931_rel_cause_tosig); + + log_printf(3, woomera->log, + "Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] ptr=%p\n", + span+1,chan+1,woomera->interface,woomera); + + + } else { + log_printf(0, woomera->log, + "FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + } + + woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK); + + } + + if (woomera->index) { + + int index = woomera->index; + + + new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s" + "Unique-Call-Id: %s%s" + "Timeout: %ld%s" + "Cause: %s%s" + "Q931-Cause-Code: %d%s", + woomera->interface, + WOOMERA_LINE_SEPERATOR, + woomera->session, + WOOMERA_LINE_SEPERATOR, + woomera->timeout, + WOOMERA_LINE_SEPERATOR, + q931_rel_to_str(18), + WOOMERA_LINE_SEPERATOR, + 18, + WOOMERA_RECORD_SEPERATOR + ); + enqueue_event(woomera, &wevent,EVENT_FREE_DATA); + + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + + if (peek_from_holding_tank(index)) { + + woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + isup_exec_command(0, + 0, + index, + SIGBOOST_EVENT_CALL_START_NACK, + 0); + + log_printf(2, woomera->log, + "Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n", + index); + } + + } + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent NACK to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //30sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] ... \n", + index); + } + + if (overall_cnt > 10) { //300sec timeotu + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK); + break; + } + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) { + break; + } + + usleep(5000); + sched_yield(); + } + + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n", + index); + + } else { + log_printf(2, woomera->log, + "Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n", + index); + + } + } + + if (woomera_test_flag(woomera, WFLAG_EVENT)){ + while ((event_string = dequeue_event(woomera))) { + socket_printf(woomera->socket, "%s", event_string); + free(event_string); + } + woomera_clear_flag(woomera, WFLAG_EVENT); + } + + + if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + int timeout_cnt=0; + int overall_cnt=0; + + /* SMG sent HANGUP to boost, however we have to wait + for boost to give us the ACK back before we + release resources. */ + + log_printf(2, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + timeout_cnt++; + if (timeout_cnt > 4000) { //10sec timeout + timeout_cnt=0; + overall_cnt++; + log_printf(0, woomera->log, + "Waiting for STOPPED ACK [%s] [id=%i] ... \n", + woomera->interface,woomera->index_hold); + } + + if (overall_cnt > 10) { //100sec + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + + if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) || + server.process_table[span][chan].dev != woomera) { + woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK); + break; + } + + usleep(5000); + sched_yield(); + } + + if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) { + if (overall_cnt > 10) { + log_printf(0, woomera->log, + "Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + + } else { + log_printf(2, woomera->log, + "Wait GOT STOPPED ACK [%s] [id=%i]... \n", + woomera->interface,woomera->index_hold); + } + } + } + + /***************************************************** + * We must wait for WFLAG_WAIT_FOR_STOPPED_ACK here + * so that STOP_ACK can access the woomera + *****************************************************/ + + if (smg_validate_span_chan(span,chan) == 0) { + log_printf(2, woomera->log, + "WOOMERA Clearing Processs Table ... \n", + woomera->interface); + pthread_mutex_lock(&server.process_lock); + if (server.process_table[span][chan].dev == woomera){ + server.process_table[span][chan].dev = NULL; + memset(server.process_table[span][chan].session,0,SMG_SESSION_NAME_SZ); + } + pthread_mutex_unlock(&server.process_lock); + } + +#if 0 +//Used for testing + if (1) { + int chan = woomera->chan; + int span = woomera->span; + if (smg_validate_span_chan(span,chan) == 0) { + pthread_mutex_lock(&server.process_lock); + /* This is possible in case media thread dies on startup */ + + if (server.process_table[span][chan]){ + log_printf(0, server.log, + "Sanity Span Chan Still in use: [w%dg%d] [%s] Index=%d ptr=%p\n", + span+1, chan+1, woomera->interface, woomera->index, woomera); + //server.process_table[span][chan] = NULL; + } + pthread_mutex_unlock(&server.process_lock); + } + } +#endif + + usleep(3000000); + + /* Sanity Check */ + if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP ACK\n"); + goto woo_re_hangup; + } + if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) { + log_printf(0, woomera->log, + "Woomera MISSED HANGUP ACK: Retry HANGUP NACK ACK\n"); + goto woo_re_hangup; + } + + /* This is where we actually pull the index + * out of the tank. We had to keep the tank + * value until the end of the call. Tank is only + * used on outgoing calls. */ + if (woomera->index_hold >= 1) { + clear_from_holding_tank(woomera->index_hold, woomera); + woomera->index_hold=0; + } + + log_printf(2, woomera->log, "Woomera Thread Finished %u\n", (unsigned long) woomera->thread); + close_socket(&woomera->socket); + woomera->socket=-1; + + /* delete queue */ + while ((event_string = dequeue_event(woomera))) { + free(event_string); + } + + if (woomera_test_flag(woomera, WFLAG_LISTENING)) { + del_listener(woomera); + } + + log_printf(2, server.log, "WOOMERA session for [%s] stopped (ptr=%p)\n", + woomera->interface,woomera); + + if (woomera_test_flag(woomera, WFLAG_MASTER_DEV)) { + log_printf(0,server.log,"MASTER Thread Stopped (ptr=%p)\n",woomera); + master_reset=0; + } + + + pthread_mutex_destroy(&woomera->queue_lock); + pthread_mutex_destroy(&woomera->ms_lock); + pthread_mutex_destroy(&woomera->dtmf_lock); + pthread_mutex_destroy(&woomera->vlock); + pthread_mutex_destroy(&woomera->flags_lock); + woomera_set_raw(woomera, NULL); + woomera_set_interface(woomera, NULL); + + woomera_message_clear(&wmsg); + + free(woomera); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count--; + server.thread_count--; + pthread_mutex_unlock(&server.thread_count_lock); + + pthread_exit(NULL); + return NULL; +} + + +static int launch_woomera_thread(struct woomera_interface *woomera) +{ + int result = 0; + pthread_attr_t attr; + + result = pthread_attr_init(&attr); + //pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + //pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + woomera_set_flag(woomera, WFLAG_RUNNING); + result = pthread_create(&woomera->thread, &attr, woomera_thread_run, woomera); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! (%i) %s\n", + __FUNCTION__,result,strerror(errno)); + woomera_clear_flag(woomera, WFLAG_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + +static int launch_monitor_thread(void) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 10; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + log_printf(0,server.log,"%s: Old Priority =%i res=%i \n",__FUNCTION__, + param.sched_priority,result); + + + woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + result = pthread_create(&server.monitor_thread, &attr, monitor_thread_run, NULL); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING); + } + pthread_attr_destroy(&attr); + + return result; +} + + +#ifdef WP_HPTDM_API +static void *hp_tdmapi_span_run(void *obj) +{ + hp_tdm_api_span_t *span = obj; + int err; + + log_printf(0,server.log,"Starting %s span!\n",span->ifname); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + if (!span->run_span) { + break; + } + + err = span->run_span(span); + if (err) { + break; + } + + } + + if (span->close_span) { + span->close_span(span); + } + + sleep(3); + log_printf(0,server.log,"Stopping %s span!\n",span->ifname); + + pthread_exit(NULL); +} + + +static int launch_hptdm_api_span_thread(int span) +{ + pthread_attr_t attr; + int result = 0; + struct sched_param param; + + param.sched_priority = 5; + result = pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, MGD_STACK_SIZE); + + result = pthread_attr_setschedparam (&attr, ¶m); + + result = pthread_create(&server.monitor_thread, &attr, hp_tdmapi_span_run, &hptdmspan[span]); + if (result) { + log_printf(0, server.log, "%s: Error: Creating Thread! %s\n", + __FUNCTION__,strerror(errno)); + } + pthread_attr_destroy(&attr); + + return result; +} +#endif + +static int configure_server(void) +{ + struct woomera_config cfg; + char *var, *val; + int cnt = 0; + + server.dtmf_intr_ch = -1; + + if (!woomera_open_file(&cfg, server.config_file)) { + log_printf(0, server.log, "open of %s failed\n", server.config_file); + return 0; + } + + while (woomera_next_pair(&cfg, &var, &val)) { + if (!strcasecmp(var, "boost_local_ip")) { + strncpy(server.mcon.cfg.local_ip, val, + sizeof(server.mcon.cfg.local_ip) -1); + strncpy(server.mconp.cfg.local_ip, val, + sizeof(server.mconp.cfg.local_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_local_port")) { + server.mcon.cfg.local_port = atoi(val); + server.mconp.cfg.local_port = + server.mcon.cfg.local_port+1; + cnt++; + } else if (!strcasecmp(var, "boost_remote_ip")) { + strncpy(server.mcon.cfg.remote_ip, val, + sizeof(server.mcon.cfg.remote_ip) -1); + strncpy(server.mconp.cfg.remote_ip, val, + sizeof(server.mconp.cfg.remote_ip) -1); + cnt++; + } else if (!strcasecmp(var, "boost_remote_port")) { + server.mcon.cfg.remote_port = atoi(val); + server.mconp.cfg.remote_port = + server.mcon.cfg.remote_port+1; + cnt++; + } else if (!strcasecmp(var, "logfile_path")) { + if (!server.logfile_path) { + server.logfile_path = strdup(val); + } + } else if (!strcasecmp(var, "woomera_port")) { + server.port = atoi(val); + } else if (!strcasecmp(var, "debug_level")) { + server.debug = atoi(val); + } else if (!strcasecmp(var, "out_tx_test")) { + server.out_tx_test = atoi(val); + } else if (!strcasecmp(var, "loop_trace")) { + server.loop_trace = atoi(val); + } else if (!strcasecmp(var, "rxgain")) { + server.rxgain = atoi(val); + } else if (!strcasecmp(var, "txgain")) { + server.txgain = atoi(val); + } else if (!strcasecmp(var, "dtmf_on_duration")){ + server.dtmf_on = atoi(val); + } else if (!strcasecmp(var, "dtmf_off_duration")){ + server.dtmf_off = atoi(val); + } else if (!strcasecmp(var, "dtmf_inter_ch_duration")){ + server.dtmf_intr_ch = atoi(val); + } else if (!strcasecmp(var, "max_calls")) { + int max = atoi(val); + if (max > 0) { + server.max_calls = max; + } + } else if (!strcasecmp(var, "autoacm")) { + int max = atoi(val); + if (max >= 0) { + autoacm=max; + } + + } else if (!strcasecmp(var, "media_ip")) { + strncpy(server.media_ip, val, sizeof(server.media_ip) -1); + } else { + log_printf(0, server.log, "Invalid Option %s at line %d!\n", var, cfg.lineno); + } + } + + /* Post initialize */ + if (server.dtmf_on == 0){ + server.dtmf_on=SMG_DTMF_ON; + } + if (server.dtmf_off == 0) { + server.dtmf_off=SMG_DTMF_OFF; + } + if (server.dtmf_intr_ch == -1) { + server.dtmf_intr_ch = 0; + } + server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2; + + log_printf(0,server.log, "DTMF On=%i Off=%i IntrCh=%i Size=%i\n", + server.dtmf_on,server.dtmf_off,server.dtmf_intr_ch,server.dtmf_size); + + woomera_close_file(&cfg); + return cnt == 4 ? 1 : 0; +} + + + +static int main_thread(void) +{ + + struct sockaddr_in sock_addr, client_addr; + struct woomera_interface *new_woomera; + int client_sock = -1, pid = 0; + unsigned int len = 0; + FILE *tmp; + + if ((server.master_connection.socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + log_printf(0, server.log, "socket() failed\n"); + return 1; + } + + memset(&sock_addr, 0, sizeof(sock_addr)); /* Zero out structure */ + sock_addr.sin_family = AF_INET; /* Internet address family */ + sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ + sock_addr.sin_port = htons(server.port); /* Local port */ + + /* Bind to the local address */ + if (bind(server.master_connection.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) { + log_printf(0, server.log, "bind(%d) failed\n", server.port); + return 1; + } + + /* Mark the socket so it will listen for incoming connections */ + if (listen(server.master_connection.socket, MAXPENDING) < 0) { + log_printf(0, server.log, "listen() failed\n"); + return 1; + } + + if ((pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "pid %d already exists.\n", pid); + exit(0); + } + + if (!(tmp = safe_fopen(PIDFILE, "w"))) { + log_printf(0, stderr, "Error creating pidfile %s\n", PIDFILE); + return 1; + } else { + fprintf(tmp, "%d", getpid()); + fclose(tmp); + tmp = NULL; + } + + no_nagle(server.master_connection.socket); + +#if 0 + if (1) { + int span,chan; + call_signal_event_t event; +#if 0 + span=1; + chan=30; + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); +#else + for (span=0;span<8;span++) { + for (chan=0;chan<31;chan++) { + event.span=span; + event.chan=chan; + launch_woomera_loop_thread(&event); + } + } +#endif + } +#endif + +#ifdef WP_HPTDM_API + if (1) { + int span; + for (span=0;span<16;span++) { + hptdmspan[span] = sangoma_hptdm_api_span_init(span); + if (!hptdmspan[span]) { + break; + } else { + log_printf(0, server.log, "HP TDM API Span: %d configured...\n", + span); + launch_hptdm_api_span_thread(span); + } + } + } +#endif + + log_printf(1, server.log, "Main Process Started: Woomera Ready port: %d\n", server.port); + + while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) && + woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) { + + /* Set the size of the in-out parameter */ + len = sizeof(client_addr); + + /* Wait for a client to connect */ + if ((client_sock = accept(server.master_connection.socket, (struct sockaddr *) &client_addr, &len)) < 0) { + log_printf(0, server.log, "accpet() failed\n"); + return 1; + } + + if ((new_woomera = new_woomera_interface(client_sock, &client_addr, len))) { + log_printf(2, server.log, "Starting Thread for New Connection %s:%d Sock=%d\n", + inet_ntoa(new_woomera->addr.sin_addr), + ntohs(new_woomera->addr.sin_port), + client_sock); + pthread_mutex_lock(&server.thread_count_lock); + server.call_count++; + pthread_mutex_unlock(&server.thread_count_lock); + if (launch_woomera_thread(new_woomera)) { + socket_printf(new_woomera->socket, + "501 call was cancelled!%s", + WOOMERA_RECORD_SEPERATOR); + + close_socket(&new_woomera->socket); + new_woomera->socket=-1; + free(new_woomera); + } + } else { + log_printf(0, server.log, "Critical ERROR: memory/socket error\n"); + } + } + + log_printf(1, server.log, "Main Process End\n"); + + return 0; +} + +static int do_ignore(int sig) +{ + return 0; +} + +static int do_shut(int sig) +{ + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + close_socket(&server.master_connection.socket); + log_printf(1, server.log, "Caught SIG %d, Closing Master Socket!\n", sig); + return 0; +} + +static int sangoma_tdm_init (int span) +{ +#ifdef LIBSANGOMA_GET_HWCODING + wanpipe_tdm_api_t tdm_api; + int fd=sangoma_open_tdmapi_span(span); + if (fd < 0 ){ + return -1; + } else { + server.hw_coding=sangoma_tdm_get_hw_coding(fd,&tdm_api); + close_socket(&fd); + } +#else +#error "libsangoma missing hwcoding feature: not up to date!" +#endif + return 0; +} + + +static int woomera_startup(int argc, char **argv) +{ + int x = 0, pid = 0, bg = 0; + char *cfg=NULL, *debug=NULL, *arg=NULL; + + while((arg = argv[x++])) { + + if (!strcasecmp(arg, "-hup")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGHUP); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-term") || !strcasecmp(arg, "--term")) { + if (! (pid = get_pid_from_file(PIDFILE))) { + log_printf(0, stderr, "Error reading pidfile %s\n", PIDFILE); + exit(1); + } else { + log_printf(0, stderr, "Killing PID %d\n", pid); + kill(pid, SIGTERM); + unlink(PIDFILE); + sleep(1); + exit(0); + } + + } else if (!strcasecmp(arg, "-version")) { + fprintf(stdout, "\nSangoma Media Gateway: Version %s\n\n", SMG_VERSION); + exit(0); + + } else if (!strcasecmp(arg, "-help")) { + fprintf(stdout, "%s\n%s [-help] | [ -version] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(0); + } else if (!strcasecmp(arg, "-wipe")) { + unlink(PIDFILE); + } else if (!strcasecmp(arg, "-bg")) { + bg = 1; + + } else if (!strcasecmp(arg, "-g")) { + coredump = 1; + + } else if (!strcasecmp(arg, "-debug")) { + if (argv[x] && *(argv[x]) != '-') { + debug = argv[x++]; + } + } else if (!strcasecmp(arg, "-cfg")) { + if (argv[x] && *(argv[x]) != '-') { + cfg = argv[x++]; + } + } else if (!strcasecmp(arg, "-log")) { + if (argv[x] && *(argv[x]) != '-') { + server.logfile_path = strdup(argv[x++]); + } + } else if (*arg == '-') { + log_printf(0, stderr, "Unknown Option %s\n", arg); + fprintf(stdout, "%s\n%s [-help] | [-hup] | [-wipe] | [[-bg] | [-debug ] | [-cfg ] | [-log ]]\n\n", WELCOME_TEXT, argv[0]); + exit(1); + } + } + + if (1){ + int spn; + for (spn=1;spn<=WOOMERA_MAX_SPAN;spn++) { + if (sangoma_tdm_init(spn) == 0) { + break; + } + } + if (spn>WOOMERA_MAX_SPAN) { + printf("\nError: Failed to access a channel on spans 1-16\n"); + printf(" Please start Wanpipe TDM API drivers\n"); + return 0; + } + } + + if (bg && (pid = fork())) { + log_printf(0, stderr, "Backgrounding!\n"); + return 0; + } + + q931_cause_setup(); + + server.port = 42420; + server.debug = 0; + strcpy(server.media_ip, "127.0.0.1"); + server.next_media_port = WOOMERA_MIN_MEDIA_PORT; + server.log = stdout; + server.master_connection.socket = -1; + server.master_connection.event_queue = NULL; + server.config_file = cfg ? cfg : "/etc/sangoma_mgd.conf"; + pthread_mutex_init(&server.listen_lock, NULL); + pthread_mutex_init(&server.ht_lock, NULL); + pthread_mutex_init(&server.process_lock, NULL); + pthread_mutex_init(&server.media_udp_port_lock, NULL); + pthread_mutex_init(&server.thread_count_lock, NULL); + pthread_mutex_init(&server.master_connection.queue_lock, NULL); + pthread_mutex_init(&server.master_connection.flags_lock, NULL); + pthread_mutex_init(&server.mcon.lock, NULL); + server.master_connection.chan = -1; + server.master_connection.span = -1; + + if (!configure_server()) { + log_printf(0, server.log, "configuration failed!\n"); + return 0; + } + +#ifndef USE_SYSLOG + if (server.logfile_path) { + if (!(server.log = safe_fopen(server.logfile_path, "a"))) { + log_printf(0, stderr, "Error setting logfile %s!\n", server.logfile_path); + server.log = stderr; + return 0; + } + } +#endif + + + if (debug) { + server.debug = atoi(debug); + } + + if (coredump) { + struct rlimit l; + memset(&l, 0, sizeof(l)); + l.rlim_cur = RLIM_INFINITY; + l.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_CORE, &l)) { + log_printf(0, stderr, "Warning: Failed to disable core size limit: %s\n", + strerror(errno)); + } + } + +#ifdef __LINUX__ + if (geteuid() && coredump) { + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { + log_printf(0, stderr, "Warning: Failed to disable core size limit for non-root: %s\n", + strerror(errno)); + } + } +#endif + + + + (void) signal(SIGINT,(void *) do_shut); + (void) signal(SIGPIPE,(void *) do_ignore); + (void) signal(SIGHUP,(void *) do_shut); + + + woomera_set_flag(&server.master_connection, WFLAG_RUNNING); + if (launch_monitor_thread()) { + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + return 0; + } + + fprintf(stderr, "%s", WELCOME_TEXT); + log_printf(0, stderr, "Woomera STARTUP Complete. [AutoACM=%i]\n",autoacm); + + return 1; +} + +static int woomera_shutdown(void) +{ + char *event_string; + int told = 0, loops = 0; + + close_socket(&server.master_connection.socket); + pthread_mutex_destroy(&server.listen_lock); + pthread_mutex_destroy(&server.ht_lock); + pthread_mutex_destroy(&server.process_lock); + pthread_mutex_destroy(&server.media_udp_port_lock); + pthread_mutex_destroy(&server.thread_count_lock); + pthread_mutex_destroy(&server.master_connection.queue_lock); + pthread_mutex_destroy(&server.master_connection.flags_lock); + pthread_mutex_destroy(&server.mcon.lock); + woomera_clear_flag(&server.master_connection, WFLAG_RUNNING); + + + if (server.logfile_path) { + free(server.logfile_path); + server.logfile_path = NULL; + } + + /* delete queue */ + while ((event_string = dequeue_event(&server.master_connection))) { + free(event_string); + } + + while(server.thread_count > 0) { + loops++; + + if (loops % 1000 == 0) { + told = 0; + } + + if (loops > 10000) { + log_printf(0, server.log, "Red Alert! threads did not stop\n"); + assert(server.thread_count == 0); + } + + if (told != server.thread_count) { + log_printf(1, server.log, "Waiting For %d thread%s.\n", + server.thread_count, server.thread_count == 1 ? "" : "s"); + told = server.thread_count; + } + ysleep(10000); + } + unlink(PIDFILE); + log_printf(0, stderr, "Woomera SHUTDOWN Complete.\n"); + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + + mlockall(MCL_FUTURE); + + + server.hw_coding=0; + + openlog (ps_progname ,LOG_PID, LOG_LOCAL2); + + if (! (ret = woomera_startup(argc, argv))) { + exit(0); + } + ret = main_thread(); + + woomera_shutdown(); + + return ret; +} + +/** EMACS ** + * Local variables: + * mode: C + * c-basic-offset: 4 + * End: + */ + diff --git a/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.8.tmp b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.8.tmp new file mode 100644 index 0000000..f54443c --- /dev/null +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.8.tmp @@ -0,0 +1,388 @@ +/***************************************************************************** + * call_signal.c -- Signal Specifics + * + * Author(s): Anthony Minessale II + * Nenad Corbic + * + * Copyright: (c) 2005 Nenad Corbic + * Anthony Minessale II + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * ============================================================================ + */ + +#include + +extern void __log_printf(int level, FILE *fp, char *file, const char *func, int line, char *fmt, ...); +#define clog_printf(level, fp, fmt, ...) __log_printf(level, fp, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) + + +struct call_signal_map { + uint32_t event_id; + char *name; +}; + +static struct call_signal_map call_signal_table[] = { + {SIGBOOST_EVENT_CALL_START, "CALL_START"}, + {SIGBOOST_EVENT_CALL_START_ACK, "CALL_START_ACK"}, + {SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"}, + {SIGBOOST_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"}, + {SIGBOOST_EVENT_CALL_ANSWERED, "CALL_ANSWERED"}, + {SIGBOOST_EVENT_CALL_STOPPED, "CALL_STOPPED"}, + {SIGBOOST_EVENT_CALL_STOPPED_ACK, "CALL_STOPPED_ACK"}, + {SIGBOOST_EVENT_SYSTEM_RESTART, "SYSTEM_RESTART"}, + {SIGBOOST_EVENT_SYSTEM_RESTART_ACK, "SYSTEM_RESTART_ACK"}, + {SIGBOOST_EVENT_HEARTBEAT, "HEARTBEAT"}, + {SIGBOOST_EVENT_INSERT_CHECK_LOOP, "LOOP START"}, + {SIGBOOST_EVENT_REMOVE_CHECK_LOOP, "LOOP STOP"} +}; + +#define USE_SCTP 1 + +static int create_udp_socket(call_signal_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) +{ + int rc; + struct hostent *result, *local_result; + char buf[512], local_buf[512]; + int err = 0; + + memset(&mcon->remote_hp, 0, sizeof(mcon->remote_hp)); + memset(&mcon->local_hp, 0, sizeof(mcon->local_hp)); +#ifdef USE_SCTP + mcon->socket = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); +#else + mcon->socket = socket(AF_INET, SOCK_DGRAM, 0); +#endif + + clog_printf(3,mcon->log,"Creating L=%s:%d R=%s:%d\n", + local_ip,local_port,ip,port); + + if (mcon->socket >= 0) { + int flag=1; + gethostbyname_r(ip, &mcon->remote_hp, buf, sizeof(buf), &result, &err); + gethostbyname_r(local_ip, &mcon->local_hp, local_buf, sizeof(local_buf), &local_result, &err); + if (result && local_result) { + mcon->remote_addr.sin_family = mcon->remote_hp.h_addrtype; + memcpy((char *) &mcon->remote_addr.sin_addr.s_addr, mcon->remote_hp.h_addr_list[0], mcon->remote_hp.h_length); + mcon->remote_addr.sin_port = htons(port); + + mcon->local_addr.sin_family = mcon->local_hp.h_addrtype; + memcpy((char *) &mcon->local_addr.sin_addr.s_addr, mcon->local_hp.h_addr_list[0], mcon->local_hp.h_length); + mcon->local_addr.sin_port = htons(local_port); + +#ifdef USE_SCTP + setsockopt(mcon->socket, IPPROTO_SCTP, SCTP_NODELAY, + (char *)&flag, sizeof(int)); +#endif + + if ((rc = bind(mcon->socket, + (struct sockaddr *) &mcon->local_addr, + sizeof(mcon->local_addr))) < 0) { + close(mcon->socket); + mcon->socket = -1; + } else { +#ifdef USE_SCTP + rc=listen(mcon->socket,100); + if (rc) { + close(mcon->socket); + mcon->socket = -1; + } +#endif + } + } + } + + return mcon->socket; +} + +int call_signal_connection_close(call_signal_connection_t *mcon) +{ + close(mcon->socket); + mcon->socket = -1; + memset(mcon, 0, sizeof(*mcon)); + + return 0; +} + +int call_signal_connection_open(call_signal_connection_t *mcon, char *local_ip, int local_port, char *ip, int port) +{ + create_udp_socket(mcon, local_ip, local_port, ip, port); + return mcon->socket; +} + +call_signal_event_t *call_signal_connection_read(call_signal_connection_t *mcon, int iteration) +{ + unsigned int fromlen = sizeof(struct sockaddr_in); +<<<<<<< .mine + //call_signal_event_t *event = &mcon->event; +======= +#if 0 + call_signal_event_t *event = &mcon->event; +>>>>>>> .r53 +#endif + int bytes = 0; + + bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, + (struct sockaddr *) &mcon->local_addr, &fromlen); + + if (bytes == sizeof(mcon->event) || + bytes == (sizeof(mcon->event)-sizeof(uint32_t))) { + + if (mcon->rxseq_reset) { + if (mcon->event.event_id == SIGBOOST_EVENT_SYSTEM_RESTART_ACK) { + clog_printf(0,mcon->log,"Rx sync ok\n"); + mcon->rxseq=mcon->event.fseqno; + return &mcon->event; + } + errno=EAGAIN; + clog_printf(0,mcon->log,"Waiting for rx sync...\n"); + return NULL; + } + + mcon->txwindow = mcon->txseq - mcon->event.bseqno; + mcon->rxseq++; + + if (mcon->rxseq != mcon->event.fseqno) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: Invalid Sequence Number Expect=%i Rx=%i\n", + mcon->rxseq,mcon->event.fseqno); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + } + +#if 0 +/* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: RX Cmd=%s Invalid Span=%i Chan=%i\n", + call_signal_event_id_name(event->event_id), event->span,event->chan); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + + + + + return &mcon->event; + } else { + if (iteration == 0) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: Invalid Event lenght from boost rxlen=%i evsz=%i\n", + bytes, sizeof(mcon->event)); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + } + } + + return NULL; +} + +call_signal_event_t *call_signal_connection_readp(call_signal_connection_t *mcon, int iteration) +{ + unsigned int fromlen = sizeof(struct sockaddr_in); +<<<<<<< .mine + //call_signal_event_t *event = &mcon->event; +======= +#if 0 + call_signal_event_t *event = &mcon->event; +>>>>>>> .r53 +#endif + int bytes = 0; + + bytes = recvfrom(mcon->socket, &mcon->event, sizeof(mcon->event), MSG_DONTWAIT, + (struct sockaddr *) &mcon->local_addr, &fromlen); + + if (bytes == sizeof(mcon->event) || + bytes == (sizeof(mcon->event)-sizeof(uint32_t))) { + +#if 0 + /* Debugging only not to be used in production because span/chan can be invalid */ + if (mcon->event.span < 0 || mcon->event.chan < 0 || mcon->event.span > 16 || mcon->event.chan > 31) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: RXp Cmd=%s Invalid Span=%i Chan=%i\n", + call_signal_event_id_name(event->event_id), event->span,event->chan); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + + errno=EAGAIN; + return NULL; + } +#endif + + return &mcon->event; + } else { + if (iteration == 0) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: PQ Invalid Event lenght from boost rxlen=%i evsz=%i\n", + bytes, sizeof(mcon->event)); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + } + } + + return NULL; +} + + +int call_signal_connection_write(call_signal_connection_t *mcon, call_signal_event_t *event) +{ + int err; + if (!event) { + clog_printf(0, mcon->log, "Critical Error: No Event Device\n"); + return -EINVAL; + } + + if (event->span < 0 || event->chan < 0 || event->span > 16 || event->chan > 31) { + clog_printf(0, mcon->log, + "------------------------------------------\n"); + clog_printf(0, mcon->log, + "Critical Error: TX Cmd=%s Invalid Span=%i Chan=%i\n", + call_signal_event_id_name(event->event_id), event->span,event->chan); + clog_printf(0, mcon->log, + "------------------------------------------\n"); + + return -1; + } + + gettimeofday(&event->tv,NULL); + + pthread_mutex_lock(&mcon->lock); + event->fseqno=mcon->txseq++; + event->bseqno=mcon->rxseq; + err=sendto(mcon->socket, event, sizeof(call_signal_event_t), 0, + (struct sockaddr *) &mcon->remote_addr, sizeof(mcon->remote_addr)); + pthread_mutex_unlock(&mcon->lock); + + if (err != sizeof(call_signal_event_t)) { + err = -1; + } + +#if 0 + clog_printf(2, mcon->log, "TX EVENT\n"); + clog_printf(2, mcon->log, "===================================\n"); + clog_printf(2, mcon->log, " tType: %s (%0x HEX)\n", + call_signal_event_id_name(event->event_id),event->event_id); + clog_printf(2, mcon->log, " tSpan: [%d]\n",event->span+1); + clog_printf(2, mcon->log, " tChan: [%d]\n",event->chan+1); + clog_printf(2, mcon->log, " tCalledNum: %s\n", + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A")); + clog_printf(2, mcon->log, " tCallingNum: %s\n", + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")); + clog_printf(2, mcon->log, " tCause: %d\n",event->release_cause); + clog_printf(2, mcon->log, " tInterface: [w%dg%d]\n",event->span+1,event->chan+1); + clog_printf(2, mcon->log, " tEvent ID: [%d]\n",event->event_id); + clog_printf(2, mcon->log, " tSetup ID: [%d]\n",event->call_setup_id); + clog_printf(2, mcon->log, " tSeq: [%d]\n",event->fseqno); + clog_printf(2, mcon->log, "===================================\n"); +#endif + +#if 1 + clog_printf(2, mcon->log, + "TX EVENT: %s:(%X) [w%dg%d] Rc=%i CSid=%i Seq=%i Cd=[%s] Ci=[%s]\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + event->release_cause, + event->call_setup_id, + event->fseqno, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A") + ); +#endif + + +#if 0 + + clog_printf(2, mcon->log, + "\nTX EVENT\n" + "===================================\n" + " tType: %s (%0x HEX)\n" + " tSpan: [%d]\n" + " tChan: [%d]\n" + " tCalledNum: %s\n" + " tCallingNum: %s\n" + " tCause: %d\n" + " tInterface: [w%dg%d]\n" + " tEvent ID: [%d]\n" + " tSetup ID: [%d]\n" + " tSeq: [%d]\n" + "===================================\n" + "\n", + call_signal_event_id_name(event->event_id), + event->event_id, + event->span+1, + event->chan+1, + (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"), + (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"), + event->release_cause, + event->span+1, + event->chan+1, + event->event_id, + event->call_setup_id, + event->fseqno + ); +#endif + + + return err; +} + +void call_signal_call_init(call_signal_event_t *event, char *calling, char *called, int setup_id) +{ + memset(event, 0, sizeof(call_signal_event_t)); + event->event_id = SIGBOOST_EVENT_CALL_START; + + if (calling) { + strncpy((char*)event->calling_number_digits, calling, sizeof(event->calling_number_digits)-1); + event->calling_number_digits_count = strlen(calling); + } + + if (called) { + strncpy((char*)event->called_number_digits, called, sizeof(event->called_number_digits)-1); + event->called_number_digits_count = strlen(called); + } + + event->call_setup_id = setup_id; + +} + +void call_signal_event_init(call_signal_event_t *event, call_signal_event_id_t event_id, int chan, int span) +{ + memset(event, 0, sizeof(call_signal_event_t)); + event->event_id = event_id; + event->chan = chan; + event->span = span; +} + +char *call_signal_event_id_name(uint32_t event_id) +{ + int x; + char *ret = NULL; + + for (x = 0 ; x < sizeof(call_signal_table)/sizeof(struct call_signal_map); x++) { + if (call_signal_table[x].event_id == event_id) { + ret = call_signal_table[x].name; + break; + } + } + + return ret; +} diff --git a/ssmg/sangoma_mgd.trunk/sangoma_mgd.orig.c b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.9.tmp similarity index 99% rename from ssmg/sangoma_mgd.trunk/sangoma_mgd.orig.c rename to ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.9.tmp index ff7c8ca..dd1ea32 100644 --- a/ssmg/sangoma_mgd.trunk/sangoma_mgd.orig.c +++ b/ssmg/sangoma_mgd.trunk/.svn/tmp/tempfile.9.tmp @@ -8,6 +8,11 @@ * the GNU General Public License * * ============================================= + * v1.25 Nenad Corbic + * Dec 31 2007 + * Removed UDP Resync it can cause skb_over errors. + * Moved RDNIS message to higher debug level + * * v1.24 Nenad Corbic * Nov 30 2007 * Bug fix on return code on ALL ckt busy @@ -124,7 +129,7 @@ static struct woomera_interface woomera_dead_dev; #endif -#define SMG_VERSION "v1.24" +#define SMG_VERSION "v1.25" /* enable early media */ #if 1 @@ -155,11 +160,11 @@ static int tc = 0; hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN]; #endif -#undef SMG_CALLING_NAME +#define SMG_CALLING_NAME 1 const char WELCOME_TEXT[] = "================================================================================\n" -"Sangoma Media Gateway Daemon v1.24 \n" +"Sangoma Media Gateway Daemon v1.25 \n" "TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n" "Copyright 2005, 2006, 2007 \n" "Nenad Corbic , Anthony Minessale II \n" @@ -1526,6 +1531,8 @@ static void *media_thread_run(void *obj) if (packet_len > 0) { +#if 0 +/* NC: This can cause skb_over panic must be retested */ if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) { /* Assume that we will always receive SLINEAR here */ sangoma_tdm_set_usr_period(ms->sangoma_sock, @@ -1550,7 +1557,7 @@ static void *media_thread_run(void *obj) } } - +#endif if (!server.out_tx_test) { if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) { @@ -2473,7 +2480,7 @@ static int handle_woomera_call_start (struct woomera_interface *woomera, if (rdnis && strlen(rdnis)) { strncpy((char*)event.redirection_string,rdnis, sizeof(event.redirection_string)-1); - log_printf(0,server.log,"RDNIS %s\n", rdnis); + log_printf(3,server.log,"RDNIS %s\n", rdnis); } @@ -3217,7 +3224,6 @@ static void handle_call_start_nack(call_signal_event_t *event) ack++; } - if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) { log_printf(0, server.log, "WARNING: All ckt busy!\n"); smg_all_ckt_busy(); diff --git a/ssmg/sangoma_mgd.trunk/Makefile b/ssmg/sangoma_mgd.trunk/Makefile index fac0dab..3deebd9 100644 --- a/ssmg/sangoma_mgd.trunk/Makefile +++ b/ssmg/sangoma_mgd.trunk/Makefile @@ -89,11 +89,20 @@ install_smg: old_cleanup install -D -m 755 sangoma_mgd.conf.sample $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ fi ifeq "${NO_SS7}" "YES" - @echo"SS7 control and service script not installed" -else + @echo "BRI control scripts installed" + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample.bri $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi + install -D -m 755 ../sangoma_bri/smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl +else + @echo "SS7 control scripts installed" + @if [ ! -e $(INSTALLPREFIX)/etc/sangoma_mgd.conf ]; then \ + install -D -m 755 sangoma_mgd.conf.sample.ss7 $(INSTALLPREFIX)/etc/sangoma_mgd.conf; \ + fi install -D -m 755 smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/etc/init.d/smgss7_init_ctrl install -D -m 755 scripts/init.d/smgss7_init_ctrl $(INSTALLPREFIX)/usr/sbin/smgss7_init_ctrl + endif @echo "sangoma_mgd Installed" diff --git a/ssmg/sangoma_mgd.trunk/app/.svn/entries b/ssmg/sangoma_mgd.trunk/app/.svn/entries index 13580ac..a6cd174 100644 --- a/ssmg/sangoma_mgd.trunk/app/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/app/.svn/entries @@ -1,9 +1,9 @@ 8 dir -65 -https://www.sangomapbx.com:/svn/sangoma_mgd/trunk/app -https://www.sangomapbx.com:/svn/sangoma_mgd +66 +https://www.sangomapbx.com/svn/sangoma_mgd/trunk/app +https://www.sangomapbx.com/svn/sangoma_mgd @@ -32,7 +32,7 @@ file -2008-01-11T19:07:46.000000Z +2007-11-30T16:39:49.000000Z 0b2da6b313f90b443457c4815ab95dab 2007-09-21T20:53:51.260136Z 1 @@ -45,7 +45,7 @@ file -2008-01-11T19:07:46.000000Z +2007-11-30T16:39:49.000000Z 604a892b5a763fef18fe92aa29f82bc9 2007-09-21T20:53:51.260136Z 1 diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir index aa0d569..4d2816d 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.pbxdir @@ -1 +1 @@ -/usr/src/ast1.4/asterisk-1.4.11 +/usr/src/asterisk diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops index f569430..2c50032 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/all-wcprops @@ -1,13 +1,13 @@ K 25 svn:wc:ra_dav:version-url V 35 -/svn/chan_woomera/!svn/ver/44/trunk +/svn/chan_woomera/!svn/ver/45/trunk END chan_woomera.c K 25 svn:wc:ra_dav:version-url V 50 -/svn/chan_woomera/!svn/ver/44/trunk/chan_woomera.c +/svn/chan_woomera/!svn/ver/50/trunk/chan_woomera.c END g711.h K 25 @@ -19,19 +19,7 @@ Changelog.chan_woomera K 25 svn:wc:ra_dav:version-url V 58 -/svn/chan_woomera/!svn/ver/43/trunk/Changelog.chan_woomera -END -Makefile -K 25 -svn:wc:ra_dav:version-url -V 44 -/svn/chan_woomera/!svn/ver/29/trunk/Makefile -END -README -K 25 -svn:wc:ra_dav:version-url -V 42 -/svn/chan_woomera/!svn/ver/14/trunk/README +/svn/chan_woomera/!svn/ver/49/trunk/Changelog.chan_woomera END woomera.conf K 25 @@ -39,3 +27,15 @@ svn:wc:ra_dav:version-url V 47 /svn/chan_woomera/!svn/ver/2/trunk/woomera.conf END +README +K 25 +svn:wc:ra_dav:version-url +V 42 +/svn/chan_woomera/!svn/ver/14/trunk/README +END +Makefile +K 25 +svn:wc:ra_dav:version-url +V 44 +/svn/chan_woomera/!svn/ver/45/trunk/Makefile +END diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries index 9a92d27..b5faea1 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/entries @@ -1,14 +1,14 @@ 8 dir -44 -https://www.sangomapbx.com:/svn/chan_woomera/trunk -https://www.sangomapbx.com:/svn/chan_woomera +45 +https://www.sangomapbx.com/svn/chan_woomera/trunk +https://www.sangomapbx.com/svn/chan_woomera -2008-02-06T23:34:48.342150Z -44 +2008-02-13T18:54:06.884970Z +45 ncorbic @@ -28,14 +28,14 @@ b26a191e-ab3a-0410-a271-b1e04e243bf1 chan_woomera.c file +50 - -2008-02-06T23:42:07.000000Z -addee4a05c90a34d09faf9aa243d3a89 -2008-02-06T23:34:48.342150Z -44 +2008-02-13T21:58:55.000000Z +ba9205aebeac14f550d1ad25c67c6ffa +2008-02-13T21:50:57.705432Z +50 ncorbic g711.h @@ -44,7 +44,7 @@ file -2008-01-11T19:07:46.000000Z +2008-01-24T17:23:02.000000Z 0f725f95ced42af15dcaef21f3a1722b 2007-09-21T20:29:00.887216Z 1 @@ -52,26 +52,26 @@ root Changelog.chan_woomera file +49 - -2008-02-06T23:39:56.000000Z -f97db784fdeb41fcb933c91e083b6256 -2008-02-06T23:32:32.062055Z -43 +2008-02-13T21:01:28.000000Z +1fee9ae858e70d2fd245ecde0cb16425 +2008-02-13T20:52:53.736809Z +49 ncorbic -Makefile +woomera.conf file -2008-01-11T19:07:46.000000Z -39268f5baaa58f6391cba2f506e41f18 -2007-12-18T20:11:15.703141Z -29 +2008-01-24T17:23:02.000000Z +356d6fc18e0670efac6de6001e58648e +2007-09-24T15:52:51.889664Z +2 ncorbic README @@ -80,21 +80,21 @@ file -2008-01-11T19:07:46.000000Z +2008-01-24T17:23:02.000000Z 6b44396eddae33cda9cdb078e5030a1f 2007-10-30T20:04:39.055688Z 14 svnanon -woomera.conf +Makefile file -2008-01-11T19:07:46.000000Z -356d6fc18e0670efac6de6001e58648e -2007-09-24T15:52:51.889664Z -2 +2008-02-13T19:13:00.000000Z +03f330a361fe8308a90ff2aef6b7cd77 +2008-02-13T18:54:06.884970Z +45 ncorbic diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Changelog.chan_woomera.svn-base b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Changelog.chan_woomera.svn-base index a79010c..c857d67 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Changelog.chan_woomera.svn-base +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Changelog.chan_woomera.svn-base @@ -1,5 +1,16 @@ chan_woomera.c ====================================== + +Feb 13 2008 +* v1.27 David Yat Sin +* Fixed issue channel type not defined when calling tech_call +* + +Feb 13 2008 +* v1.26 Nenad Corbic +* Compilation Update for callweaver 1.2-rc5 +* + Feb 06 2008 * v1.25 Nenad Corbic * Bug fix in woomera message declaration diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base index 3ac561c..3885b53 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/Makefile.svn-base @@ -26,10 +26,14 @@ $(shell echo $(PBXDIR) > .pbxdir) PBXMODDIR=/usr/lib/asterisk/modules PBXCFGDIR=/etc/asterisk + ifneq (,$(wildcard $(PBXDIR)/include/callweaver.h)) PBXFLAGS_EXTRA=-DCALLWEAVER -DHAVE_CONFIG_H PBXMODDIR=/usr/local/lib/callweaver/modules PBXCFGDIR=/usr/local/etc/callweaver + +#Enable this for callweaver 1.2-rc5 +# PBXFLAGS_EXTRA += -DCALLWEAVER_1_2 endif ifneq (,$(wildcard $(PBXDIR)/include/asterisk.h)) @@ -49,6 +53,7 @@ CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm + PBXFLAGS= $(INCLUDES) -I$(PBXDIR) -I$(PBXDIR)/include -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -DWOOMERA_CHAN_NAME=\"$(CHAN_NAME)\" -D_GNU_SOURCE -O6 -fomit-frame-pointer -fPIC diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base index e2b5714..572cb63 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/text-base/chan_woomera.c.svn-base @@ -13,6 +13,16 @@ * This program is free software, distributed under the terms of * the GNU General Public License * ============================================= + * v1.27 David Yat Sin + * Feb 13 2008 + * Fix for ast_channel type not defined on + * outgoing calls, causing PHP agi scripts + * to fail + * + * v1.26 Nenad Corbic + * Feb 13 2008 + * Compilation Update for callweaver 1.2-rc5 + * * v1.25 Nenad Corbic * Feb 06 2008 * Bug fix in woomera message declaration @@ -155,7 +165,7 @@ #include "asterisk/dsp.h" #include "asterisk/musiconhold.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.25 $") +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.27 $") #else @@ -176,8 +186,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.25 $") #include "callweaver/causes.h" #include "callweaver/dsp.h" #include "callweaver.h" +#include "confdefs.h" -CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.25 $") +CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.27 $") // strings... @@ -191,10 +202,21 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.25 $") #define AST_CONTROL_UNHOLD OPBX_CONTROL_UNHOLD #define AST_CONTROL_VIDUPDATE OPBX_CONTROL_VIDUPDATE +#ifdef OPBX_LOG_NOTICE #define LOG_NOTICE OPBX_LOG_NOTICE +#endif + +#ifdef OPBX_LOG_DEBUG #define LOG_DEBUG OPBX_LOG_DEBUG +#endif + +#ifdef OPBX_LOG_ERROR #define LOG_ERROR OPBX_LOG_ERROR +#endif + +#ifdef OPBX_LOG_WARNING #define LOG_WARNING OPBX_LOG_WARNING +#endif #define AST_FORMAT_SLINEAR OPBX_FORMAT_SLINEAR #define AST_FORMAT_ULAW OPBX_FORMAT_ULAW @@ -300,7 +322,7 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.25 $") extern int option_verbose; -#define WOOMERA_VERSION "v1.25" +#define WOOMERA_VERSION "v1.27" #ifndef WOOMERA_CHAN_NAME #define WOOMERA_CHAN_NAME "SS7" #endif @@ -3165,6 +3187,9 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) char *p; char *c; +#ifndef AST14 + self->type = WOOMERA_CHAN_NAME; +#endif self->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; if (globals.panic) { @@ -3178,7 +3203,7 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) dest); } - + if (self->cid.cid_name) { strncpy(tech_pvt->cid_name, self->cid.cid_name, sizeof(tech_pvt->cid_name)-1); @@ -4035,7 +4060,11 @@ static int woomera_cli(int fd, int argc, char *argv[]) } #ifdef CALLWEAVER +#ifdef CALLWEAVER_1_2 +static struct opbx_cli_entry cli_woomera[] = { +# else static struct opbx_clicmd cli_woomera[] = { +#endif { .cmda = { "woomera", "default", "version", NULL }, .handler = woomera_cli, @@ -4044,6 +4073,7 @@ static struct opbx_clicmd cli_woomera[] = { //.generator = complete_span_4, }, }; + #else static struct ast_cli_entry cli_woomera = { { "woomera", NULL }, woomera_cli, "Woomera", "Woomera" }; #endif @@ -4652,7 +4682,16 @@ int unload_module(void) #ifdef CALLWEAVER +#ifdef CALLWEAVER_1_2 +char *description() +{ + return (char *) desc; +} + + +#else MODULE_INFO(load_module, reload, unload_module, NULL, desc); +#endif #else diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.2.tmp b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.2.tmp index 1545d06..c075d8c 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.2.tmp +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.2.tmp @@ -19,6 +19,8 @@ ifneq (,$(wildcard ./.pbxdir)) endif endif +CHAN_NAME=WOOMERA + $(shell echo $(PBXDIR) > .pbxdir) PBXMODDIR=/usr/lib/asterisk/modules @@ -43,11 +45,11 @@ CC = gcc INCLUDES= -I/usr/include -I./ -CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 +CFLAGS = -D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 CCFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g LDFLAGS=-L lib/libteletone/.libs -L. -L/usr/local/lib -L ../../ssmg/libsangoma.trunk/.libs -lpthread -lsangoma -lm -PBXFLAGS= $(INCLUDES) -I$(PBXDIR) -I$(PBXDIR)/include -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -D_GNU_SOURCE -O6 -march=i686 -fomit-frame-pointer -fPIC +PBXFLAGS= $(INCLUDES) -I$(PBXDIR) -I$(PBXDIR)/include -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -Iinclude -I../include -D_REENTRANT -DWOOMERA_CHAN_NAME=\"$(CHAN_NAME)\" -D_GNU_SOURCE -O6 -march=i686 -fomit-frame-pointer -fPIC all: chan_woomera.so @@ -65,7 +67,13 @@ distclean: clean @echo OK install: all + @if [ ! -d $(INSTALLPREFIX)$(PBXMODDIR) ]; then \ + mkdir -p $(INSTALLPREFIX)$(PBXMODDIR); \ + fi; install -D -m 755 chan_woomera.so $(INSTALLPREFIX)$(PBXMODDIR)/chan_woomera.so + @if [ ! -d $(INSTALLPREFIX)$(PBXCFGDIR) ]; then \ + mkdir -p $(INSTALLPREFIX)$(PBXCFGDIR); \ + fi; @if [ -f woomera.conf ] && [ ! -e $(INSTALLPREFIX)$(PBXCFGDIR)/woomera.conf ]; then \ install -D -m 755 woomera.conf $(INSTALLPREFIX)$(PBXCFGDIR)/woomera.conf; \ fi diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.3.tmp b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.3.tmp index a70d7bf..eacf6f0 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.3.tmp +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.3.tmp @@ -13,21 +13,6 @@ * This program is free software, distributed under the terms of * the GNU General Public License * ============================================= - - * v1.22 David Yat Sin - * Jan 11 2007 - * rxgain and txgain configuration parameters - * are ignored if coding is not specified in woomera.conf - * - * v1.21 David Yat Sin - * Dec 27 2007 - * Support for language - * - * v1.20 David Yat Sin - * Dec 20 2007 - * Support for call confirmation - * Support for default context - * * v1.19 Nenad Corbic * Nov 30 2007 * Updated for latest CallWeaver @@ -139,9 +124,8 @@ #include "asterisk/translate.h" #include "asterisk/causes.h" #include "asterisk/dsp.h" -#include "asterisk/musiconhold.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.21 $") +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.19 $") #else @@ -163,7 +147,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.21 $") #include "callweaver/dsp.h" #include "callweaver.h" -CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.21 $") +CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.19 $") // strings... @@ -178,7 +162,6 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.21 $") #define AST_CONTROL_VIDUPDATE OPBX_CONTROL_VIDUPDATE #define LOG_NOTICE OPBX_LOG_NOTICE -#define LOG_DEBUG OPBX_LOG_DEBUG #define LOG_ERROR OPBX_LOG_ERROR #define LOG_WARNING OPBX_LOG_WARNING @@ -286,7 +269,7 @@ CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.21 $") extern int option_verbose; -#define WOOMERA_VERSION "v1.21" +#define WOOMERA_VERSION "v1.19" #ifndef WOOMERA_CHAN_NAME #define WOOMERA_CHAN_NAME "SS7" #endif @@ -399,10 +382,7 @@ typedef enum { TFLAG_DESTROYED = (1 << 13), TFLAG_UP = (1 << 14), TFLAG_ACCEPT = (1 << 15), - TFLAG_ACCEPTED = (1 << 16), - TFLAG_ANSWER_RECEIVED = (1 << 17), - TFLAG_CONFIRM_ANSWER = (1 << 18), - TFLAG_CONFIRM_ANSWER_ENABLED = (1 << 19) + TFLAG_ACCEPTED = (1 << 16) } TFLAGS; static int usecnt = 0; @@ -467,8 +447,6 @@ struct woomera_profile { int call_abort; char default_context[WOOMERA_STRLEN]; char* tg_context [WOOMERA_MAX_TRUNKGROUPS+1]; - char language[WOOMERA_STRLEN]; - char* tg_language [WOOMERA_MAX_TRUNKGROUPS+1]; }; @@ -493,8 +471,6 @@ struct private_object { char dtmfbuf[WOOMERA_STRLEN]; char cid_name[WOOMERA_STRLEN]; char cid_num[WOOMERA_STRLEN]; - char mohinterpret[MAX_MUSICCLASS]; - char mohsuggest[MAX_MUSICCLASS]; char *cid_rdnis; int cid_pres; char ds[WOOMERA_STRLEN]; @@ -511,6 +487,7 @@ struct private_object { struct woomera_event_queue event_queue; unsigned int coding; int pri_cause; + unsigned int confirmanswer; #ifdef AST_JB struct ast_jb_conf jbconf; #endif /* AST_JB */ @@ -1378,9 +1355,7 @@ static int tech_init(private_object *tech_pvt, woomera_profile *profile, int fla self->nativeformats = tech_pvt->coding; self->writeformat = self->rawwriteformat = self->readformat = tech_pvt->coding; tech_pvt->frame.subclass = tech_pvt->coding; - ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); - ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); - ast_clear_flag(tech_pvt, TFLAG_ANSWER_RECEIVED); + tech_pvt->confirmanswer=0; if (profile->dtmf_enable) { @@ -2461,13 +2436,7 @@ static void woomera_config_gain(woomera_profile *profile, float gain_val, int rx int k; float linear_gain = pow(10.0, gain_val / 20.0); unsigned char *gain; - - if (profile->coding == AST_FORMAT_SLINEAR){ - ast_log(LOG_WARNING, "Coding not specified, %s value ignored\n", (rx)? "rxgain":"txgain"); - return; - } - if (gain_val == 0) { goto woomera_config_gain_skip; } @@ -2523,9 +2492,6 @@ static void destroy_woomera_profile(woomera_profile *profile) if(profile->tg_context[i] != NULL){ free(profile->tg_context[i]); } - if(profile->tg_language[i] != NULL){ - free(profile->tg_language[i]); - } } ast_mutex_destroy(&profile->iolock); ast_mutex_destroy(&profile->call_count_lock); @@ -2655,16 +2621,7 @@ static int config_woomera(void) free(profile->tg_context[group_num]); } profile->tg_context[group_num] = strdup(profile->context); - - if(profile->tg_language[group_num] != NULL){ - free(profile->tg_language[group_num]); - } - if(strlen(profile->language)){ - profile->tg_language[group_num] = strdup(profile->language); - } } - } else if (!strcmp(v->name, "language")) { - strncpy(profile->language, v->value, sizeof(profile->language) - 1); } else if (!strcmp(v->name, "dtmf_enable")) { profile->dtmf_enable = atoi(v->value); } else if (!strcmp(v->name, "jb_enable")) { @@ -2996,10 +2953,8 @@ static struct ast_channel *woomera_new(const char *type, int format, chan->nativeformats = tech_pvt->coding; chan->writeformat = chan->rawwriteformat = chan->readformat = tech_pvt->coding; tech_pvt->frame.subclass = tech_pvt->coding; - + tech_pvt->pri_cause=AST_CAUSE_NORMAL_CLEARING; - - ast_copy_string(tech_pvt->mohinterpret,"default",sizeof(tech_pvt->mohinterpret)); ASTOBJ_CONTAINER_LINK(&private_object_list, tech_pvt); @@ -3235,8 +3190,7 @@ static int tech_call(struct ast_channel *self, char *dest, int timeout) if ((p = strrchr(self->name, '/'))) { c = p-1; if(*c == 'c' || *c== 'C'){ - ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); - ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); + tech_pvt->confirmanswer=1; } } #endif @@ -3517,44 +3471,36 @@ tech_read_again: if (tech_pvt->owner && (tech_pvt->faxdetect || tech_pvt->ast_dsp)) { f = ast_dsp_process(tech_pvt->owner, tech_pvt->dsp, &tech_pvt->frame); if (f && f->frametype == AST_FRAME_DTMF){ - int answer = 0; - if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED)){ - ast_mutex_lock(&tech_pvt->iolock); - if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER)){ - ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); - if(ast_test_flag(tech_pvt, TFLAG_ANSWER_RECEIVED)){ - answer = 1; - } - } - ast_mutex_unlock(&tech_pvt->iolock); - if(answer){ - struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; - struct ast_channel *owner = tech_get_owner(tech_pvt); - ast_log(LOG_DEBUG, "Confirm answer on %s!\n", self->name); + if(tech_pvt->confirmanswer){ + struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; + struct ast_channel *owner = tech_get_owner(tech_pvt); + ast_log(LOG_DEBUG, "Confirm answer on %s!\n", self->name); - if (owner) { - ast_setstate(owner, AST_STATE_UP); - ast_queue_frame(owner, &answer_frame); - ast_set_flag(tech_pvt, TFLAG_UP); + tech_pvt->confirmanswer = 0; + if (owner) { + ast_setstate(owner, AST_STATE_UP); + ast_queue_frame(owner, &answer_frame); + ast_set_flag(tech_pvt, TFLAG_UP); + + ast_mutex_lock(&tech_pvt->profile->call_count_lock); + tech_pvt->profile->call_ok++; + ast_mutex_unlock(&tech_pvt->profile->call_count_lock); + } else { + ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); + tech_pvt->pri_cause=44; + ast_set_flag(tech_pvt, TFLAG_ABORT); - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_ok++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - } else { - ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=44; - ast_set_flag(tech_pvt, TFLAG_ABORT); - - } } - } - if (answer == 0 && globals.debug > 2) { + + + } else { + if (globals.debug > 2) { ast_log(LOG_NOTICE, "%s: Detected inband DTMF digit: %c\n", self->name, f->subclass); + } } } - //woomera_tx2ast_frm(tech_pvt, tech_pvt->frame.data, tech_pvt->frame.datalen); } @@ -3709,9 +3655,6 @@ static int tech_indicate(struct ast_channel *self, int condition) if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { ast_set_flag(tech_pvt, TFLAG_ACCEPT); } -#ifdef AST14 - ast_moh_start(self, data, tech_pvt->mohinterpret); -#endif break; case AST_CONTROL_UNHOLD: if (globals.debug > 3) { @@ -3720,8 +3663,6 @@ static int tech_indicate(struct ast_channel *self, int condition) if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { ast_set_flag(tech_pvt, TFLAG_ACCEPT); } - ast_moh_stop(self); - res=0; break; case AST_CONTROL_VIDUPDATE: if (globals.debug > 3) { @@ -4248,18 +4189,11 @@ static int woomera_event_incoming (private_object *tech_pvt) owner = tech_get_owner(tech_pvt); if (owner) { +#if 1 +/* Support for custom contextes per span */ int group = atoi(tg_string); - if(group >= 0 && - group <= WOOMERA_MAX_TRUNKGROUPS && - tech_pvt->profile->tg_context[group] != NULL){ - + if (tech_pvt->profile->tg_context[group] != NULL){ strncpy(owner->context, tech_pvt->profile->tg_context[group], sizeof(owner->context) - 1); - - if(tech_pvt->profile->tg_language[group] != NULL && - strlen(tech_pvt->profile->tg_language[group])){ - strncpy(owner->language, tech_pvt->profile->tg_language[group], sizeof(owner->language) - 1); - } - }else { snprintf(owner->context, sizeof(owner->context) - 1, "%s%s", @@ -4267,6 +4201,12 @@ static int woomera_event_incoming (private_object *tech_pvt) tg_string); } +#else + snprintf(owner->context, sizeof(owner->context) - 1, + "%s%s", + tech_pvt->profile->context, + tg_string); +#endif strncpy(owner->exten, exten, sizeof(owner->exten) - 1); ast_set_callerid(owner, cid_num, cid_name, cid_num); owner->cid.cid_pres=presentation; @@ -4297,24 +4237,33 @@ static int woomera_event_incoming (private_object *tech_pvt) if (validext == 0) { +#if 1 +/* Support for custom contextes per span */ if (globals.debug > 1){ - int group = atoi(tg_string); - if(group >= 0 && - group <= WOOMERA_MAX_TRUNKGROUPS && - tech_pvt->profile->tg_context[group] != NULL){ - + if(tech_pvt->profile->tg_context[atoi(tg_string)] != NULL){ ast_log(LOG_ERROR, "Error: Invalid exten %s@%s called %s!\n", exten, owner->context, tech_pvt->callid); - }else{ + }else{ ast_log(LOG_ERROR, "Error: Invalid exten %s@%s%s called %s!\n", exten, tech_pvt->profile->context, tg_string, tech_pvt->callid); - } - } + } + } +#else + if (globals.debug > 1){ + ast_log(LOG_ERROR, "Error: Invalid exten %s@%s%s called %s!\n", + exten, + tech_pvt->profile->context, + tg_string, + tech_pvt->callid); + } + +#endif + return -1; } @@ -4436,20 +4385,9 @@ static void woomera_check_event (private_object *tech_pvt, int res, woomera_mess struct ast_channel *owner = tech_get_owner(tech_pvt); if (owner) { - int answer = 0; - if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED)){ - ast_mutex_lock(&tech_pvt->iolock); - ast_set_flag(tech_pvt, TFLAG_ANSWER_RECEIVED); - if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER)){ - ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %s!\n", woomera_message_header(wmsg, "Channel-Name")); - } else { - answer = 1; - } - ast_mutex_unlock(&tech_pvt->iolock); + if(tech_pvt->confirmanswer){ + ast_log(LOG_DEBUG, "Waiting on answer confirmation on channel %s!\n", woomera_message_header(wmsg, "Channel-Name")); } else { - answer = 1; - } - if(answer){ ast_setstate(owner, AST_STATE_UP); ast_queue_frame(owner, &answer_frame); ast_set_flag(tech_pvt, TFLAG_UP); @@ -4457,7 +4395,8 @@ static void woomera_check_event (private_object *tech_pvt, int res, woomera_mess ast_mutex_lock(&tech_pvt->profile->call_count_lock); tech_pvt->profile->call_ok++; ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - } + } + }else{ ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); tech_pvt->pri_cause=44; diff --git a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.4.tmp b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.4.tmp index 71fea38..3ac561c 100644 --- a/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.4.tmp +++ b/ssmg/sangoma_mgd.trunk/chan_woomera.trunk/.svn/tmp/tempfile.4.tmp @@ -1,4687 +1,81 @@ - -/* - * Asterisk -- A telephony toolkit for Linux. - * - * Woomera Channel Driver - * - * Copyright (C) 05-08 Nenad Corbic - * Anthony Minessale II - * - * Nenad Corbic - * Anthony Minessale II - * - * This program is free software, distributed under the terms of - * the GNU General Public License - * ============================================= - * v1.24 Nenad Corbic - * Jan 23 2008 - * Removed LISTEN on every woomera channel. Listen - * only on master. Fixed jitterbuffer support on AST1.4 - * - * v1.23 Nenad Corbic - * Jan 22 2008 - * Implemented Music on Hold. - * - * v1.22 David Yat Sin - * Jan 11 2008 - * rxgain and txgain configuration parameters - * are ignored if coding is not specified in - * woomera.conf - * - * v1.21 David Yat Sin - * Dec 27 2007 - * Support for language - * - * v1.20 David Yat Sin - * Dec 20 2007 - * Support for call confirmation - * Support for default context - * - * v1.19 Nenad Corbic - * Nov 30 2007 - * Updated for latest CallWeaver - * Updated smgversion update on master socket - * restart. - * - * v1.18 Nenad Corbic - * Updated Channel-Name on outbound call - * Check queued events on ABORT - * Major Unit Testing done - * Ability to change chan name from Makefile - * - * v1.17 Nenad Corbic - * Updates for Asterisk 1.4 - * Updated the release causes - * Updated for tech_indication - * - * v1.16 Nenad Corbic - * Added support for Asterisk 1.4 - * Updated support for Callweaver - * - * v1.15 Nenad Corbic - * Added PRI_CAUSE and Q931-Cause-Code - * in woomera protocol. - * - * v1.14 Nenad Corbic - * Updated for session support - * - * v1.13 Nenad Corbic - * Added CallWeaver Support - * |->(thanks to Andre Schwaller) - * Updated codec negotiation for - * mutliple profiles. - * - * v1.12 Nenad Corbic - * Updated DTMF locking - * - * v1.11 Nenad Corbic - * Updated multiple profiles - * Updated Dialect for OPAL Woomera - * Added call logging/debugging - * - * v1.10 Nenad Corbic - * Bug fix in incoming hangup - * - * v1.9 Nenad Corbic - * Fixed remote asterisk/woomera - * setup. - * - * v1.8 Nenad Corbic - * Added Woomera OPAL dialect. - * Code cleanup. - * Added cli call_status - * - * v1.7 Nenad Corbic - * Added smgdebug to enable smg debugging - * Added rdnis - * - * v1.6 Nenad Corbic - * Added incoming trunk group context - * The trunk number will be added to the - * profile context name. - * Added presentation feature. - * - * v1.5 Nenad Corbic - * Use only ALAW and MLAW not SLIN. - * This reduces the load quite a bit. - * Autodetect Format from HELLO Message. - * RxTx Gain supported in woomera.conf as well - * from CLI. - */ - - -#if defined(CALLWEAVER) && defined(HAVE_CONFIG_H) -#include "confdefs.h" -#endif - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifndef CALLWEAVER - -#include "asterisk.h" -#include "asterisk/sched.h" -#include "asterisk/astobj.h" -#include "asterisk/lock.h" -#include "asterisk/manager.h" -#include "asterisk/pbx.h" -#include "asterisk/cli.h" -#include "asterisk/logger.h" -#include "asterisk/frame.h" -#include "asterisk/config.h" -#include "asterisk/module.h" -#include "asterisk/lock.h" -#include "asterisk/translate.h" -#include "asterisk/causes.h" -#include "asterisk/dsp.h" -#include "asterisk/musiconhold.h" - -ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.24 $") - -#else - -#include "callweaver.h" -#include "callweaver/sched.h" -#include "callweaver/astobj.h" -#include "callweaver/lock.h" -#include "callweaver/manager.h" -#include "callweaver/channel.h" -#include "callweaver/pbx.h" -#include "callweaver/cli.h" -#include "callweaver/logger.h" -#include "callweaver/frame.h" -#include "callweaver/config.h" -#include "callweaver/module.h" -#include "callweaver/lock.h" -#include "callweaver/translate.h" -#include "callweaver/causes.h" -#include "callweaver/dsp.h" -#include "callweaver.h" - -CALLWEAVER_FILE_VERSION(__FILE__, "$Revision: 1.24 $") - -// strings... - -#define ast_config opbx_config -#define AST_CONTROL_RINGING OPBX_CONTROL_RINGING -#define AST_CONTROL_BUSY OPBX_CONTROL_BUSY -#define AST_CONTROL_CONGESTION OPBX_CONTROL_CONGESTION -#define AST_CONTROL_PROCEEDING OPBX_CONTROL_PROCEEDING -#define AST_CONTROL_PROGRESS OPBX_CONTROL_PROGRESS -#define AST_CONTROL_HOLD OPBX_CONTROL_HOLD -#define AST_CONTROL_UNHOLD OPBX_CONTROL_UNHOLD -#define AST_CONTROL_VIDUPDATE OPBX_CONTROL_VIDUPDATE - -#define LOG_NOTICE OPBX_LOG_NOTICE -#define LOG_DEBUG OPBX_LOG_DEBUG -#define LOG_ERROR OPBX_LOG_ERROR -#define LOG_WARNING OPBX_LOG_WARNING - -#define AST_FORMAT_SLINEAR OPBX_FORMAT_SLINEAR -#define AST_FORMAT_ULAW OPBX_FORMAT_ULAW -#define AST_FORMAT_ALAW OPBX_FORMAT_ALAW -#define ast_mutex_t opbx_mutex_t -#define ast_frame opbx_frame -#define ast_verbose opbx_verbose -#define AST_FRIENDLY_OFFSET OPBX_FRIENDLY_OFFSET -#define AST_MUTEX_DEFINE_STATIC OPBX_MUTEX_DEFINE_STATIC -#define AST_CONTROL_PROGRESS OPBX_CONTROL_PROGRESS -#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL OPBX_CAUSE_REQUESTED_CHAN_UNAVAIL -#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION OPBX_CAUSE_NORMAL_CIRCUIT_CONGESTION -#define AST_CAUSE_USER_BUSY OPBX_CAUSE_USER_BUSY -#define AST_CAUSE_NO_ANSWER OPBX_CAUSE_NO_ANSWER -#define AST_CAUSE_NORMAL_CLEARING OPBX_CAUSE_NORMAL_CLEARING -#define AST_SOFTHANGUP_EXPLICIT OPBX_SOFTHANGUP_EXPLICIT -#define AST_SOFTHANGUP_DEV OPBX_SOFTHANGUP_DEV -#define AST_CAUSE_NORMAL_CLEARING OPBX_CAUSE_NORMAL_CLEARING -#define AST_FRAME_DTMF OPBX_FRAME_DTMF -#define AST_FRAME_CONTROL OPBX_FRAME_CONTROL -#define AST_CONTROL_ANSWER OPBX_CONTROL_ANSWER -#define AST_STATE_UP OPBX_STATE_UP -#define AST_STATE_RINGING OPBX_STATE_RINGING -#define AST_STATE_DOWN OPBX_STATE_DOWN -#define AST_FLAGS_ALL OPBX_FLAGS_ALL -#define AST_FRAME_VOICE OPBX_FRAME_VOICE -#define ASTERISK_GPL_KEY 0 -#define ast_channel_tech opbx_channel_tech -#define ast_test_flag opbx_test_flag -#define ast_queue_frame opbx_queue_frame -#define ast_frdup opbx_frdup -#define ast_channel opbx_channel -#define ast_exists_extension opbx_exists_extension -#define ast_hostent opbx_hostent -#define ast_clear_flag opbx_clear_flag -#define ast_log opbx_log -#define ast_set_flag opbx_set_flag -#define ast_copy_string opbx_copy_string -#define ast_set_flag opbx_set_flag -#define ast_set2_flag opbx_set2_flag -#define ast_setstate opbx_setstate -#define ast_test_flag opbx_test_flag -#define ast_softhangup opbx_softhangup -#define ast_true opbx_true -#define ast_false opbx_false -#define ast_strlen_zero opbx_strlen_zero -#define ast_exists_extension opbx_exists_extension -#define ast_frame opbx_frame -#define ast_jb_conf opbx_jb_conf -#define ast_carefulwrite opbx_carefulwrite -#define ast_channel_unregister opbx_channel_unregister -#define ast_cli opbx_cli -#define ast_cli_register opbx_cli_register -#define ast_cli_unregister opbx_cli_unregister -#define ast_jb_read_conf opbx_jb_read_conf -#define ast_mutex_destroy opbx_mutex_destroy -#define ast_mutex_init opbx_mutex_init -#define ast_mutex_lock opbx_mutex_lock -#define ast_mutex_unlock opbx_mutex_unlock -#define ast_mutex_t opbx_mutex_t -#define ast_queue_control opbx_queue_control -#define ast_queue_frame opbx_queue_frame -#define ast_queue_hangup opbx_queue_hangup -#define ast_set_callerid opbx_set_callerid -#define ast_variable opbx_variable -#define ast_pthread_create opbx_pthread_create -#define ast_cli_entry opbx_cli_entry -#define ast_channel_register opbx_channel_register -#define ast_config_load opbx_config_load -#define ast_config_destroy opbx_config_destroy -#define ast_category_browse opbx_category_browse -#define ast_variable_browse opbx_variable_browse -#define ast_gethostbyname opbx_gethostbyname -#define ast_channel_alloc opbx_channel_alloc -#define ast_dsp_new opbx_dsp_new -#define ast_dsp opbx_dsp -#define ast_dsp_set_features opbx_dsp_set_features -#define ast_dsp_digitmode opbx_dsp_digitmode -#define ast_dsp_set_call_progress_zone opbx_dsp_set_call_progress_zone -#define ast_dsp_set_busy_count opbx_dsp_set_busy_count -#define ast_dsp_set_busy_pattern opbx_dsp_set_busy_pattern -#define ast_dsp_process opbx_dsp_process -#define ast_strdupa opbx_strdupa -#define ast_mutex_trylock opbx_mutex_trylock -#define ast_cause2str opbx_cause2str -#define ast_pbx_start opbx_pbx_start -#define ast_hangup opbx_hangup - -#endif - -#include "g711.h" -#include - -#define USE_TECH_INDICATE 1 -#ifdef USE_TECH_INDICATE - #define MEDIA_ANSWER "MEDIA" -#else - #define MEDIA_ANSWER "ACCEPT" -#endif - -#define USE_ANSWER 1 - - -extern int option_verbose; - -#define WOOMERA_VERSION "v1.24" -#ifndef WOOMERA_CHAN_NAME -#define WOOMERA_CHAN_NAME "SS7" -#endif - - -static int tech_count = 0; - -static const char desc[] = "Woomera Channel Driver"; -//static const char type[] = "WOOMERA"; -static const char tdesc[] = "Woomera Channel Driver"; -static char configfile[] = "woomera.conf"; -static char smgversion_init=0; -static char smgversion[100] = "N/A"; - -static char mohinterpret[MAX_MUSICCLASS] = "default"; -static char mohsuggest[MAX_MUSICCLASS] = ""; - -<<<<<<< .mine -#ifdef AST14 -# ifndef AST_JB -# define AST_JB 1 -# endif -#endif -======= -#ifdef AST14 - #ifndef AST_JB - #define AST_JB 1 - #endif -#endif ->>>>>>> .r41 - -#ifdef AST_JB -#include "asterisk/abstract_jb.h" -/* Global jitterbuffer configuration - by default, jb is disabled */ -static struct ast_jb_conf default_jbconf = -{ - .flags = 0, - .max_size = -1, - .resync_threshold = -1, - .impl = "" -}; -static struct ast_jb_conf global_jbconf; -#endif /* AST_JB */ - -#define WOOMERA_SLINEAR 0 -#define WOOMERA_ULAW 1 -#define WOOMERA_ALAW 2 - -#define WOOMERA_STRLEN 256 -#define WOOMERA_ARRAY_LEN 50 -#define WOOMERA_MIN_PORT 9900 -#define WOOMERA_MAX_PORT 10799 -#define WOOMERA_BODYLEN 2048 -#define WOOMERA_LINE_SEPARATOR "\r\n" -#define WOOMERA_RECORD_SEPARATOR "\r\n\r\n" -#define WOOMERA_DEBUG_PREFIX "**[WOOMERA]** " -#define WOOMERA_DEBUG_LINE "--------------------------------------------------------------------------------" -#define WOOMERA_HARD_TIMEOUT -2000 -#define WOOMERA_QLEN 10 -#define WOOMERA_MAX_TRUNKGROUPS 16 - -/* this macro is not in all versions of asterisk */ -#ifdef OLDERAST -#define ASTOBJ_CONTAINER_UNLINK(container,obj) \ - ({ \ - typeof((container)->head) found = NULL; \ - typeof((container)->head) prev = NULL; \ - ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \ - if (iterator== obj) { \ - found = iterator; \ - found->next[0] = NULL; \ - ASTOBJ_CONTAINER_WRLOCK(container); \ - if (prev) \ - prev->next[0] = next; \ - else \ - (container)->head = next; \ - ASTOBJ_CONTAINER_UNLOCK(container); \ - } \ - prev = iterator; \ - } while (0)); \ - found; \ - }) -#endif - - -#define FRAME_LEN 480 - -#if 0 -static int WFORMAT = AST_FORMAT_ALAW; //AST_FORMAT_SLINEAR; -#else -static int WFORMAT = AST_FORMAT_SLINEAR; -#endif - -typedef enum { - WFLAG_EXISTS = (1 << 0), - WFLAG_EVENT = (1 << 1), - WFLAG_CONTENT = (1 << 2), -} WFLAGS; - - -typedef enum { - WCFLAG_NOWAIT = (1 << 0) -} WCFLAGS; - - -typedef enum { - PFLAG_INBOUND = (1 << 0), - PFLAG_OUTBOUND = (1 << 1), - PFLAG_DYNAMIC = (1 << 2), - PFLAG_DISABLED = (1 << 3) -} PFLAGS; - -typedef enum { - TFLAG_MEDIA = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_INCOMING = (1 << 3), - TFLAG_PARSE_INCOMING = (1 << 4), - TFLAG_ACTIVATE = (1 << 5), - TFLAG_DTMF = (1 << 6), - TFLAG_DESTROY = (1 << 7), - TFLAG_ABORT = (1 << 8), - TFLAG_PBX = (1 << 9), - TFLAG_ANSWER = (1 << 10), - TFLAG_INTHREAD = (1 << 11), - TFLAG_TECHHANGUP = (1 << 12), - TFLAG_DESTROYED = (1 << 13), - TFLAG_UP = (1 << 14), - TFLAG_ACCEPT = (1 << 15), - TFLAG_ACCEPTED = (1 << 16), - TFLAG_ANSWER_RECEIVED = (1 << 17), - TFLAG_CONFIRM_ANSWER = (1 << 18), - TFLAG_CONFIRM_ANSWER_ENABLED = (1 << 19) -} TFLAGS; - -static int usecnt = 0; - -struct woomera_message { - char callid[WOOMERA_STRLEN]; - int mval; - char command[WOOMERA_STRLEN]; - char command_args[WOOMERA_STRLEN]; - char names[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN]; - char values[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN]; - char body[WOOMERA_BODYLEN]; - char cause[WOOMERA_STRLEN]; - unsigned int flags; - int last; - unsigned int queue_id; - struct woomera_message *next; -}; - - -static struct { - int next_woomera_port; - int debug; - int panic; - int more_threads; - ast_mutex_t woomera_port_lock; -} globals; - -struct woomera_event_queue { - struct woomera_message *head; - ast_mutex_t lock; -}; - -struct woomera_profile { - ASTOBJ_COMPONENTS(struct woomera_profile); - ast_mutex_t iolock; - ast_mutex_t call_count_lock; - char woomera_host[WOOMERA_STRLEN]; - int max_calls; - int call_count; - int woomera_port; - char audio_ip[WOOMERA_STRLEN]; - char context[WOOMERA_STRLEN]; - pthread_t thread; - unsigned int flags; - int thread_running; - int dtmf_enable; - int faxdetect; - int woomera_socket; - struct woomera_event_queue event_queue; - int jb_enable; - int progress_enable; - int coding; - float rxgain_val; - float txgain_val; - unsigned char rxgain[256]; - unsigned char txgain[256]; - int call_out; - int call_in; - int call_ok; - int call_end; - int call_abort; - char default_context[WOOMERA_STRLEN]; - char* tg_context [WOOMERA_MAX_TRUNKGROUPS+1]; - char language[WOOMERA_STRLEN]; - char* tg_language [WOOMERA_MAX_TRUNKGROUPS+1]; -}; - - -struct private_object { - ASTOBJ_COMPONENTS(struct private_object); - ast_mutex_t iolock; - struct ast_channel *owner; - struct sockaddr_in udpread; - struct sockaddr_in udpwrite; - int command_channel; - int udp_socket; - unsigned int flags; - struct ast_frame frame; - short fdata[FRAME_LEN + AST_FRIENDLY_OFFSET]; - struct woomera_message call_info; - struct woomera_profile *profile; - char dest[WOOMERA_STRLEN]; - char proto[WOOMERA_STRLEN]; - int port; - struct timeval started; - int timeout; - char dtmfbuf[WOOMERA_STRLEN]; - char cid_name[WOOMERA_STRLEN]; - char cid_num[WOOMERA_STRLEN]; - char mohinterpret[MAX_MUSICCLASS]; - char mohsuggest[MAX_MUSICCLASS]; - char *cid_rdnis; - int cid_pres; - char ds[WOOMERA_STRLEN]; - struct ast_dsp *dsp; - int ast_dsp; - int dsp_features; - int faxdetect; - int faxhandled; - int call_count; - char callid[WOOMERA_STRLEN]; - pthread_t thread; - unsigned int callno; - int refcnt; - struct woomera_event_queue event_queue; - unsigned int coding; - int pri_cause; -#ifdef AST_JB - struct ast_jb_conf jbconf; -#endif /* AST_JB */ - -}; - -typedef struct private_object private_object; -typedef struct woomera_message woomera_message; -typedef struct woomera_profile woomera_profile; -typedef struct woomera_event_queue woomera_event_queue; - - -static void my_ast_softhangup(struct ast_channel *chan, private_object *tech_pvt, int cause) -{ -#if 1 - ast_queue_hangup(chan); - //ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT); -#else - struct ast_frame f = { AST_FRAME_NULL }; - - if (chan) { - chan->_softhangup |= cause; - ast_queue_frame(chan, &f); - } - - ast_set_flag(tech_pvt, TFLAG_ABORT); -#endif - -#if 0 - if (tech_pvt->dsp) { - tech_pvt->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; - ast_dsp_set_features(tech_pvt->dsp, tech_pvt->dsp_features); - tech_pvt->ast_dsp=0; - } -#endif - -} - -//static struct sched_context *sched; - -static struct private_object_container { - ASTOBJ_CONTAINER_COMPONENTS(private_object); -} private_object_list; - -static struct woomera_profile_container { - ASTOBJ_CONTAINER_COMPONENTS(woomera_profile); -} woomera_profile_list; - -static woomera_profile default_profile; - -/* some locks you will use for use count and for exclusive access to the main linked-list of private objects */ -AST_MUTEX_DEFINE_STATIC(usecnt_lock); -AST_MUTEX_DEFINE_STATIC(lock); - -/* local prototypes */ -static void woomera_close_socket(int *socket); -static void global_set_flag(int flags); -static void woomera_printf(woomera_profile *profile, int fd, char *fmt, ...); -static char *woomera_message_header(woomera_message *wmsg, char *key); -static int woomera_enqueue_event(woomera_event_queue *event_queue, woomera_message *wmsg); -static int woomera_dequeue_event(woomera_event_queue *event_queue, woomera_message *wmsg); -static int woomera_message_parse(int fd, woomera_message *wmsg, int timeout, woomera_profile *profile, woomera_event_queue *event_queue); -static int woomera_message_parse_wait(private_object *tech_pvt,woomera_message *wmsg); -static int waitfor_socket(int fd, int timeout); -static int woomera_profile_thread_running(woomera_profile *profile, int set, int new); -static int woomera_locate_socket(woomera_profile *profile, int *woomera_socket); -static void *woomera_thread_run(void *obj); -static void launch_woomera_thread(woomera_profile *profile); -static void destroy_woomera_profile(woomera_profile *profile); -static woomera_profile *clone_woomera_profile(woomera_profile *new_profile, woomera_profile *default_profile); -static woomera_profile *create_woomera_profile(woomera_profile *default_profile); -static int config_woomera(void); -static int create_udp_socket(char *ip, int port, struct sockaddr_in *sockaddr, int client); -static int connect_woomera(int *new_socket, woomera_profile *profile, int flags); -static int init_woomera(void); -static int woomera_cli(int fd, int argc, char *argv[]); -static void tech_destroy(private_object *tech_pvt, struct ast_channel *owner); -static struct ast_channel *woomera_new(const char *type, int format, void *data, int *cause, woomera_profile *profile); -static int launch_tech_thread(private_object *tech_pvt); -static int tech_create_read_socket(private_object *tech_pvt); -static int tech_activate(private_object *tech_pvt); -static int tech_init(private_object *tech_pvt, woomera_profile *profile, int flags); -static void *tech_monitor_thread(void *obj); -static void tech_monitor_in_one_thread(void); -static struct ast_channel * tech_get_owner( private_object *tech_pvt); -int usecount(void); -#if 0 -static char *key(void); -static char *description(void); -#endif -int load_module(void); -int unload_module(void); -int reload(void); - - - - -/********************CHANNEL METHOD PROTOTYPES******************* - * You may or may not need all of these methods, remove any unnecessary functions/protos/mappings as needed. - * - */ -static struct ast_channel *tech_requester(const char *type, int format, void *data, int *cause); -static int tech_send_digit(struct ast_channel *self, char digit); -#ifdef AST14 -static int tech_digit_end(struct ast_channel *ast, char digit, unsigned int duration); -#endif -static int tech_call(struct ast_channel *self, char *dest, int timeout); -static int tech_hangup(struct ast_channel *self); -static int tech_answer(struct ast_channel *self); -static struct ast_frame *tech_read(struct ast_channel *self); -static struct ast_frame *tech_exception(struct ast_channel *self); -static int tech_write(struct ast_channel *self, struct ast_frame *frame); -#ifdef USE_TECH_INDICATE -# ifdef AST14 -static int tech_indicate(struct ast_channel *self, int condition, const void *data, size_t datalen); -# else -static int tech_indicate(struct ast_channel *self, int condition); -# endif -#endif -static int tech_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); -static int tech_send_html(struct ast_channel *self, int subclass, const char *data, int datalen); -static int tech_send_text(struct ast_channel *self, const char *text); -static int tech_send_image(struct ast_channel *self, struct ast_frame *frame); -static int tech_setoption(struct ast_channel *self, int option, void *data, int datalen); -static int tech_queryoption(struct ast_channel *self, int option, void *data, int *datalen); -//static enum ast_bridge_result tech_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms); -static int tech_transfer(struct ast_channel *self, const char *newdest); -static int tech_write_video(struct ast_channel *self, struct ast_frame *frame); -//static struct ast_channel *tech_bridged_channel(struct ast_channel *self, struct ast_channel *bridge); - -static int woomera_event_incoming (private_object *tech_pvt); -static int woomera_event_media (private_object *tech_pvt, woomera_message *wmsg); -static void woomera_check_event (private_object *tech_pvt, int res, woomera_message *wmsg); - -/******************************************************************************** - * Constant structure for mapping local methods to the core interface. - * This structure only needs to contain the methods the channel requires to operate - * Not every channel needs all of them defined. - */ - -static const struct ast_channel_tech technology = { - .type = WOOMERA_CHAN_NAME, - .description = tdesc, - .capabilities = (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW), - .requester = tech_requester, -#ifdef AST14 - .send_digit_begin = tech_send_digit, - .send_digit_end = tech_digit_end, -#else - .send_digit = tech_send_digit, -#endif - .call = tech_call, - //.bridge = tech_bridge, - .hangup = tech_hangup, - .answer = tech_answer, - .transfer = tech_transfer, - .write_video = tech_write_video, - .read = tech_read, - .write = tech_write, - .exception = tech_exception, -#ifdef USE_TECH_INDICATE - .indicate = tech_indicate, -#endif - .fixup = tech_fixup, - .send_html = tech_send_html, - .send_text = tech_send_text, - .send_image = tech_send_image, - .setoption = tech_setoption, - .queryoption = tech_queryoption, - //.bridged_channel = tech_bridged_channel, - .transfer = tech_transfer, -}; - - -static void woomera_close_socket(int *socket) -{ - - if (*socket > -1) { - close(*socket); - } - *socket = -1; -} - -static int woomera_message_reply_ok(woomera_message *wmsg) -{ - - if (!(wmsg->mval >= 200 && wmsg->mval <= 299)) { - return -1; - } - - return 0; -} - - -static void global_set_flag(int flags) -{ - private_object *tech_pvt; - - ASTOBJ_CONTAINER_TRAVERSE(&private_object_list, 1, do { - ASTOBJ_RDLOCK(iterator); - tech_pvt = iterator; - ast_set_flag(tech_pvt, flags); - ASTOBJ_UNLOCK(iterator); - } while(0)); -} - -static void woomera_send_progress(private_object *tech_pvt) -{ - struct ast_channel *owner = tech_get_owner(tech_pvt); - - if (tech_pvt->profile->progress_enable && owner){ - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Sending Progress %s\n",tech_pvt->callid); - } - - ast_queue_control(owner, - AST_CONTROL_PROGRESS); - } -} - - -static uint32_t string_to_release(char *code) -{ - if (code) { - if (!strcasecmp(code, "CHANUNAVAIL")) { - return AST_CAUSE_REQUESTED_CHAN_UNAVAIL; - } - - if (!strcasecmp(code, "INVALID")) { - return AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - if (!strcasecmp(code, "ERROR")) { - return AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - if (!strcasecmp(code, "CONGESTION")) { - return AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - if (!strcasecmp(code, "BUSY")) { - return AST_CAUSE_USER_BUSY; - } - - if (!strcasecmp(code, "NOANSWER")) { - return AST_CAUSE_NO_ANSWER; - } - - if (!strcasecmp(code, "ANSWER")) { - return AST_CAUSE_NORMAL_CLEARING; - } - - if (!strcasecmp(code, "CANCEL")) { - return AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - - if (!strcasecmp(code, "UNKNOWN")) { - return AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; - } - } - return AST_CAUSE_NORMAL_CLEARING; -} - - -static void woomera_printf(woomera_profile *profile, int fd, char *fmt, ...) -{ - char *stuff; - int res = 0; - - if (fd < 0) { - if (globals.debug > 4) { - ast_log(LOG_ERROR, "Not gonna write to fd %d\n", fd); - } - return; - } - - va_list ap; - va_start(ap, fmt); -#ifdef SOLARIS - stuff = (char *)malloc(10240); - vsnprintf(stuff, 10240, fmt, ap); -#else - res = vasprintf(&stuff, fmt, ap); -#endif - va_end(ap); - if (res == -1) { - ast_log(LOG_ERROR, "Out of memory\n"); - } else { - if (profile && globals.debug) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "Send Message: {%s} [%s/%d]\n%s\n%s", profile->name, profile->woomera_host, profile->woomera_port, WOOMERA_DEBUG_LINE, stuff); - } - } - ast_carefulwrite(fd, stuff, strlen(stuff), 100); - free(stuff); - } - -} - -static char *woomera_message_header(woomera_message *wmsg, char *key) -{ - int x = 0; - char *value = NULL; - - -#if 0 - if (!strcasecmp(wmsg->command,"HANGUP")) { - ast_log(LOG_NOTICE, "Message Header for HANGUP\n"); - for (x = 0 ; x < wmsg->last ; x++) { - ast_log(LOG_NOTICE, "Name=%s Value=%s\n", - wmsg->names[x],wmsg->values[x]); - if (!strcasecmp(wmsg->names[x], key)) { - value = wmsg->values[x]; - break; - } - } - } -#endif - - for (x = 0 ; x < wmsg->last ; x++) { - if (!strcasecmp(wmsg->names[x], key)) { - value = wmsg->values[x]; - break; - } - } - - return value; -} - -static int woomera_enqueue_event(woomera_event_queue *event_queue, woomera_message *wmsg) -{ - woomera_message *new, *mptr; - - if ((new = malloc(sizeof(woomera_message)))) { - ast_mutex_lock(&event_queue->lock); - memcpy(new, wmsg, sizeof(woomera_message)); - new->next = NULL; - if (!event_queue->head) { - event_queue->head = new; - } else { - for (mptr = event_queue->head; mptr && mptr->next ; mptr = mptr->next); - mptr->next = new; - } - ast_mutex_unlock(&event_queue->lock); - return 1; - } else { - ast_log(LOG_ERROR, "Memory Allocation Error!\n"); - } - - return 0; -} - -static int woomera_dequeue_event(woomera_event_queue *event_queue, woomera_message *wmsg) -{ - woomera_message *mptr = NULL; - - ast_mutex_lock(&event_queue->lock); - if (event_queue->head) { - mptr = event_queue->head; - event_queue->head = mptr->next; - } - - if (mptr) { - memcpy(wmsg, mptr, sizeof(woomera_message)); - } - ast_mutex_unlock(&event_queue->lock); - - if (mptr){ - free(mptr); - return 1; - } else { - memset(wmsg, 0, sizeof(woomera_message)); - } - - return 0; -} - - - - -static int woomera_message_parse(int fd, woomera_message *wmsg, int timeout, - woomera_profile *profile, woomera_event_queue *event_queue) -{ - char *cur, *cr, *next = NULL, *eor = NULL; - char buf[2048]; - int res = 0, bytes = 0, sanity = 0; - struct timeval started, ended; - int elapsed, loops = 0; - int failto = 0; - - memset(wmsg, 0, sizeof(woomera_message)); - - if (fd < 0) { - return -1; - } - - gettimeofday(&started, NULL); - memset(buf, 0, sizeof(buf)); - - if (timeout < 0) { - timeout = abs(timeout); - failto = 1; - } else if(timeout == 0) { - timeout = -1; - } - - while (!(eor = strstr(buf, WOOMERA_RECORD_SEPARATOR))) { - - if (!profile->thread_running) { - return -1; - } - - if (globals.panic > 2) { - return -1; - } - /* Keep things moving. - Stupid Sockets -Homer Simpson */ - woomera_printf(NULL, fd, "%s", WOOMERA_RECORD_SEPARATOR); - - if((res = waitfor_socket(fd, (timeout > 0 ? timeout : 100)) > 0)) { - res = recv(fd, buf, sizeof(buf), MSG_PEEK); - if (res == 0) { - sanity++; - } else if (res < 0) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "{%s} error during packet retry #%d\n", profile->name, loops); - } - - return res; - } else if (loops && globals.debug) { - //ast_verbose(WOOMERA_DEBUG_PREFIX "{%s} Didnt get complete packet retry #%d\n", profile->name, loops); - woomera_printf(NULL, fd, "%s", WOOMERA_RECORD_SEPARATOR); - usleep(100); - } - - if (res > 0) { - sanity=0; - } - - } - - gettimeofday(&ended, NULL); - elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000)); - - if (res < 0) { - return res; - } - - if (sanity > 1000) { - if (globals.debug > 2) { - ast_log(LOG_ERROR, "{%s} Failed Sanity Check! [errors] chfd=%d\n", - profile->name,fd); - } - return -100; - } - - if (timeout > 0 && (elapsed > timeout)) { - return failto ? -1 : 0; - } - - loops++; - } - *eor = '\0'; - bytes = strlen(buf) + 4; - - memset(buf, 0, sizeof(buf)); - res = read(fd, buf, bytes); - next = buf; - - if (globals.debug) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "Receive Message: {%s} [%s/%d]\n%s\n%s", profile->name, profile->woomera_host, profile->woomera_port, WOOMERA_DEBUG_LINE, buf); - } - } - - while((cur = next)) { - if ((cr = strstr(cur, WOOMERA_LINE_SEPARATOR))) { - *cr = '\0'; - next = cr + (sizeof(WOOMERA_LINE_SEPARATOR) - 1); - if (!strcmp(next, WOOMERA_RECORD_SEPARATOR)) { - break; - } - } - - if (ast_strlen_zero(cur)) { - break; - } - - if (!wmsg->last) { - ast_set_flag(wmsg, WFLAG_EXISTS); - if (!strncasecmp(cur, "EVENT", 5)) { - cur += 6; - ast_set_flag(wmsg, WFLAG_EVENT); - - if (cur && (cr = strchr(cur, ' '))) { - char *id; - - *cr = '\0'; - cr++; - id = cr; - if (cr && (cr = strchr(cr, ' '))) { - *cr = '\0'; - cr++; - strncpy(wmsg->command_args, cr, WOOMERA_STRLEN); - } - if(id) { - ast_copy_string(wmsg->callid, id, sizeof(wmsg->callid)); - } - } - } else { - if (cur && (cur = strchr(cur, ' '))) { - *cur = '\0'; - cur++; - wmsg->mval = atoi(buf); - } else { - ast_log(LOG_NOTICE, "Malformed Message!\n"); - break; - } - } - if (cur) { - strncpy(wmsg->command, cur, WOOMERA_STRLEN); - } else { - ast_log(LOG_NOTICE, "Malformed Message!\n"); - break; - } - } else { - char *name, *val; - name = cur; - if ((val = strchr(name, ':'))) { - *val = '\0'; - val++; - while (*val == ' ') { - *val = '\0'; - val++; - } - strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN); - } - strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN); - if (name && val && !strcasecmp(name, "content-type")) { - ast_set_flag(wmsg, WFLAG_CONTENT); - bytes = atoi(val); - } - - if (name && val && !strcasecmp(name, "content-length")) { - ast_set_flag(wmsg, WFLAG_CONTENT); - bytes = atoi(val); - } - - - } - wmsg->last++; - } - - wmsg->last--; - - if (bytes && ast_test_flag(wmsg, WFLAG_CONTENT)) { - read(fd, wmsg->body, (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes); - if (globals.debug) { - if (option_verbose > 2) { - ast_verbose("%s\n", wmsg->body); - } - } - } - - if (event_queue && ast_test_flag(wmsg, WFLAG_EVENT)) { - if (globals.debug) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "Queue Event: {%s} [%s]\n", profile->name, wmsg->command); - } - } - /* we don't want events we want a reply so we will stash them for later */ - woomera_enqueue_event(event_queue, wmsg); - - /* call ourself recursively to find the reply. we'll keep doing this as long we get events. - * wmsg will be overwritten but it's ok we just queued it. - */ - return woomera_message_parse(fd, wmsg, timeout, profile, event_queue); - - } else if (wmsg->mval > 99 && wmsg->mval < 200) { - /* reply in the 100's are nice but we need to wait for another reply - call ourself recursively to find the reply > 199 and forget this reply. - */ - return woomera_message_parse(fd, wmsg, timeout, profile, event_queue); - } else { - return ast_test_flag(wmsg, WFLAG_EXISTS); - } -} - -static int woomera_message_parse_wait(private_object *tech_pvt, woomera_message *wmsg) -{ - int err=0; - - for (;;) { - - if (ast_test_flag(tech_pvt, TFLAG_ABORT)){ - return -1; - } - - err=woomera_message_parse(tech_pvt->command_channel, - wmsg, - 100, - tech_pvt->profile, - &tech_pvt->event_queue); - - if (err == 0) { - /* This is a timeout */ - continue; - } - - break; - } - - return err; -} - - - -static int tech_create_read_socket(private_object *tech_pvt) -{ - int retry=0; - -retry_udp: - - ast_mutex_lock(&globals.woomera_port_lock); - globals.next_woomera_port++; - if (globals.next_woomera_port >= WOOMERA_MAX_PORT) { - globals.next_woomera_port = WOOMERA_MIN_PORT; - } - tech_pvt->port = globals.next_woomera_port; - ast_mutex_unlock(&globals.woomera_port_lock); - - if ((tech_pvt->udp_socket = create_udp_socket(tech_pvt->profile->audio_ip, tech_pvt->port, &tech_pvt->udpread, 0)) > -1) { - struct ast_channel *owner = tech_get_owner(tech_pvt); - if (owner) { - owner->fds[0] = tech_pvt->udp_socket; - } else { - ast_log(LOG_ERROR, "Tech_pvt has no OWNER! %i\n",__LINE__); - } - - } else { - - retry++; - if (retry <= 1) { - goto retry_udp; - } - - - if (globals.debug > 2) { - ast_log(LOG_ERROR, - "Error CREATING READ udp socket %s/%i %s (%p) %s %s\n", - tech_pvt->profile->audio_ip,tech_pvt->port, strerror(errno),tech_pvt,tech_pvt->callid, - ast_test_flag(tech_pvt, TFLAG_OUTBOUND) ? "OUT":"IN"); - } - } - return tech_pvt->udp_socket; -} - -#define WOOMERA_MAX_CALLS 600 -static struct private_object *tech_pvt_idx[WOOMERA_MAX_CALLS]; -static ast_mutex_t tech_pvt_idx_lock[WOOMERA_MAX_CALLS]; - -static int tech_activate(private_object *tech_pvt) -{ - int retry_activate_call=0; - woomera_message wmsg; - char *callid; - int err=0; - memset(&wmsg,0,sizeof(wmsg)); - -retry_activate_again: - - if (!tech_pvt) { - ast_log(LOG_ERROR, "Critical Error: Where's my tech_pvt?\n"); - return -1; - } - - if((connect_woomera(&tech_pvt->command_channel, tech_pvt->profile, 0)) > -1) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, - "Connected to woomera! chfd=%i port=%i dir=%s callid=%s Count=%i tpvt=%p\n", - tech_pvt->command_channel, - tech_pvt->port, - ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"OUT":"IN", - ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"N/A" : - tech_pvt->callid, - tech_pvt->call_count, - tech_pvt); - } - } else { - - if (retry_activate_call <= 3) { - retry_activate_call++; - goto retry_activate_again; - } - - - if (globals.debug > 1 && option_verbose > 1) { - ast_log(LOG_ERROR, "Error: %s call connect to TCP/Woomera Server! tpvt=%p: %s\n", - ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"Out":"In", - tech_pvt,strerror(errno)); - } - goto tech_activate_failed; - } - - retry_activate_call=0; - - if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - - if (strlen(tech_pvt->proto) > 1) { - woomera_printf(tech_pvt->profile, - tech_pvt->command_channel, - "CALL %s:%s%s" - "Raw-Audio: %s:%d%s" - "Local-Name: %s!%s%s" - "Local-Number:%s%s" - "Presentation:%d%s" - "Screening:%d%s" - "RDNIS:%s%s", - tech_pvt->proto, - tech_pvt->dest, - WOOMERA_LINE_SEPARATOR, - tech_pvt->profile->audio_ip, - tech_pvt->port, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_name, - tech_pvt->cid_num, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_num, - WOOMERA_LINE_SEPARATOR, - (tech_pvt->cid_pres>>5)&0x7, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_pres&0xF, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_rdnis?tech_pvt->cid_rdnis:"", - WOOMERA_RECORD_SEPARATOR - ); - - } else { - woomera_printf(tech_pvt->profile, - tech_pvt->command_channel, - "CALL %s%s" - "Raw-Audio: %s:%d%s" - "Local-Name: %s!%s%s" - "Local-Number:%s%s" - "Presentation:%d%s" - "Screening:%d%s" - "RDNIS:%s%s", - tech_pvt->dest, - WOOMERA_LINE_SEPARATOR, - tech_pvt->profile->audio_ip, - tech_pvt->port, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_name, - tech_pvt->cid_num, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_num, - WOOMERA_LINE_SEPARATOR, - (tech_pvt->cid_pres>>5)&0x7, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_pres&0xF, - WOOMERA_LINE_SEPARATOR, - tech_pvt->cid_rdnis?tech_pvt->cid_rdnis:"", - WOOMERA_RECORD_SEPARATOR - ); - } - - err=woomera_message_parse_wait(tech_pvt,&wmsg); - if (err < 0 || woomera_message_reply_ok(&wmsg) != 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - } - - callid = woomera_message_header(&wmsg, "Unique-Call-Id"); - if (callid) { - ast_copy_string(tech_pvt->callid,callid,sizeof(wmsg.callid)); - } - - } else { - ast_set_flag(tech_pvt, TFLAG_PARSE_INCOMING); - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "%s:%d Incoming Call %s tpvt=%p\n", - __FUNCTION__,__LINE__, - tech_pvt->callid,tech_pvt); - } - - woomera_printf(tech_pvt->profile, - tech_pvt->command_channel, - "PROCEED %s%s" - "Unique-Call-Id: %s%s", - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - - err=woomera_message_parse_wait(tech_pvt,&wmsg); - if (err < 0 || woomera_message_reply_ok(&wmsg) != 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - /* Do not hangup on main because - * socket connection has been - * established */ - } - } - - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH ACTIVATE OK tech_pvt=%p\n",tech_pvt); - } - return 0; - -tech_activate_failed: - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH ACTIVATE FAILED tech_pvt=%p\n",tech_pvt); - } - - woomera_close_socket(&tech_pvt->command_channel); - ast_set_flag(tech_pvt, TFLAG_ABORT); - - /* At this point we cannot estabilsh a woomer - * socket to the smg. The SMG still doesnt know - * about the incoming call that is now pending. - * We must send a message to SMG to hangup the call */ - - - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Error: %s Call %s tpvt=%p Failed!\n", - ast_test_flag(tech_pvt, TFLAG_OUTBOUND) ? "OUT":"IN", - tech_pvt->callid,tech_pvt); - } - - return -1; - -} - -static int tech_init(private_object *tech_pvt, woomera_profile *profile, int flags) -{ - struct ast_channel *self = tech_get_owner(tech_pvt); - - gettimeofday(&tech_pvt->started, NULL); - - if (profile) { - tech_pvt->profile = profile; - } else { - ast_log(LOG_ERROR, "ERROR: No Tech profile on init!\n"); - ast_set_flag(tech_pvt, TFLAG_ABORT); - return -1; - } - - ast_set_flag(tech_pvt, flags); - - if (tech_pvt->udp_socket < 0) { - int rc; - rc=tech_create_read_socket(tech_pvt); - if (rc < 0){ - if (globals.debug > 2) { - ast_log(LOG_ERROR, "ERROR: Failed to create UDP Socket (%p)!\n", - tech_pvt); - } - ast_set_flag(tech_pvt, TFLAG_ABORT); - return -1; - } - } - - ast_set_flag(tech_pvt, flags); - - tech_pvt->coding = profile->coding; - self->nativeformats = tech_pvt->coding; - self->writeformat = self->rawwriteformat = self->readformat = tech_pvt->coding; - tech_pvt->frame.subclass = tech_pvt->coding; - ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); - ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); - ast_clear_flag(tech_pvt, TFLAG_ANSWER_RECEIVED); - - if (profile->dtmf_enable) { - - tech_pvt->dsp_features=0; - tech_pvt->dsp = ast_dsp_new(); - if (tech_pvt->dsp) { -#if 0 - i->dsp_features = features & ~DSP_PROGRESS_TALK; - - /* We cannot do progress detection until receives PROGRESS message */ - if (i->outgoing && (i->sig == SIG_PRI)) { - /* Remember requested DSP features, don't treat - talking as ANSWER */ - features = 0; - } -#endif - tech_pvt->dsp_features |= DSP_FEATURE_DTMF_DETECT; - //tech_pvt->dsp_features |= DSP_FEATURE_BUSY_DETECT; - //tech_pvt->dsp_features |= DSP_FEATURE_CALL_PROGRESS; - //tech_pvt->dsp_features |= DSP_FEATURE_FAX_DETECT; - ast_dsp_set_features(tech_pvt->dsp, tech_pvt->dsp_features); - ast_dsp_digitmode(tech_pvt->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); - tech_pvt->ast_dsp=1; - -#if 0 - if (!ast_strlen_zero(progzone)) - ast_dsp_set_call_progress_zone(tech_pvt->dsp, progzone); - if (i->busydetect && CANBUSYDETECT(i)) { - ast_dsp_set_busy_count(tech_pvt->dsp, i->busycount); - ast_dsp_set_busy_pattern(tech_pvt->dsp, i->busy_tonelength, ->busy_quietlength); - } -#endif - } - } - - if (profile && profile->faxdetect) { - tech_pvt->faxdetect=1; - } - - - if (profile->jb_enable) { -#ifdef AST_JB - /* Assign default jb conf to the new zt_pvt */ - memcpy(&tech_pvt->jbconf, &global_jbconf, sizeof(struct ast_jb_conf)); -<<<<<<< .mine - ast_jb_configure(self, &tech_pvt->jbconf); -======= - ast_jb_configure(self, &tech_pvt->jbconf); - - if (globals.debug > 1 && option_verbose > 10) { - ast_log(LOG_NOTICE, "%s: Cfg JitterBuffer (F=%i MS=%li Rs=%li Impl=%s)\n", - self->name, - tech_pvt->jbconf.flags, - tech_pvt->jbconf.max_size, - tech_pvt->jbconf.resync_threshold, - tech_pvt->jbconf.impl); - } ->>>>>>> .r41 -#else - ast_log(LOG_ERROR, "Asterisk Jitter Buffer Not Compiled!\n"); -#endif - } - - - /* Asterisk being asterisk and all allows approx 1 nanosecond - * to try and establish a connetion here before it starts crying. - * Now asterisk, being unsure of it's self will not enforce a lock while we work - * and after even a 1 second delay it will give up on the lock and mess everything up - * This stems from the fact that asterisk will scan it's list of channels constantly for - * silly reasons like tab completion and cli output. - * - * Anyway, since we've already spent that nanosecond with the previous line of code - * tech_create_read_socket(tech_pvt); to setup a read socket - * which, by the way, asterisk insists we have before going any furthur. - * So, in short, we are between a rock and a hard place and asterisk wants us to open a socket here - * but it too impaitent to wait for us to make sure it's ready so in the case of outgoing calls - * we will defer the rest of the socket establishment process to the monitor thread. This is, of course, common - * knowledge since asterisk abounds in documentation right?, sorry to bother you with all this! - */ - if (globals.more_threads) { - int err; - ast_set_flag(tech_pvt, TFLAG_ACTIVATE); - /* we're gonna try "wasting" a thread to do a better realtime monitoring */ - err=launch_tech_thread(tech_pvt); - if (err) { - ast_log(LOG_ERROR, "Error: Failed to lauch tech control thread\n"); - ast_clear_flag(tech_pvt, TFLAG_ACTIVATE); - ast_set_flag(tech_pvt, TFLAG_ABORT); - return -1; - } - - } else { - if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - ast_set_flag(tech_pvt, TFLAG_ACTIVATE); - } else { - tech_activate(tech_pvt); - } - } - - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH INIT tech_pvt=%p c=%p (use=%i)\n", - tech_pvt,tech_pvt->owner,usecount()); - } - - return 0; -} - - - -static void tech_destroy(private_object *tech_pvt, struct ast_channel *owner) -{ - - ASTOBJ_CONTAINER_UNLINK(&private_object_list, tech_pvt); - - ast_set_flag(tech_pvt, TFLAG_DESTROY); - ast_set_flag(tech_pvt, TFLAG_ABORT); - - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Tech Destroy callid=%s tpvt=%p %s/%d\n", - tech_pvt->callid, - tech_pvt, - tech_pvt->profile ? tech_pvt->profile->audio_ip : "NA", - tech_pvt->port); - } - - - if (tech_pvt->profile && tech_pvt->command_channel > -1) { - - if (globals.debug > 1 && option_verbose > 1) { - ast_log(LOG_NOTICE, "+++DESTROY sent HANGUP %s\n", - tech_pvt->callid); - } - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "hangup %s%scause: %s%sQ931-Cause-Code: %d%sUnique-Call-Id: %s%s", - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - tech_pvt->ds, - WOOMERA_LINE_SEPARATOR, - tech_pvt->pri_cause, - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "bye%s" - "Unique-Call-Id: %s%s", - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - woomera_close_socket(&tech_pvt->command_channel); - } - - woomera_close_socket(&tech_pvt->command_channel); - woomera_close_socket(&tech_pvt->udp_socket); - - if (owner) { - struct ast_channel *chan=owner; - - if (!ast_test_flag(tech_pvt, TFLAG_PBX) && - !chan->pbx && - !ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "DESTROY Destroying Owner %p: ast_hangup()\n", - tech_pvt); - } - chan->tech_pvt = NULL; - tech_pvt->owner=NULL; - ast_hangup(chan); - } else { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "DESTROY Destroying Owner %p: softhangup\n", - tech_pvt); - } - /* softhangup needs tech_pvt pointer */ - chan->tech_pvt = NULL; - my_ast_softhangup(chan, tech_pvt, AST_SOFTHANGUP_EXPLICIT); - } - tech_pvt->owner=NULL; - }else{ - tech_pvt->owner=NULL; - } - - /* Tech profile is allowed to be null in case the call - * is blocked from the call_count */ - -#if 0 - ast_log(LOG_NOTICE, "---- Call END %p %s ----------------------------\n", - tech_pvt,tech_pvt->callid); -#endif - - tech_count--; - if (tech_pvt->dsp){ - tech_pvt->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; - ast_dsp_set_features(tech_pvt->dsp, tech_pvt->dsp_features); - tech_pvt->ast_dsp=0; - - free(tech_pvt->dsp); - tech_pvt->dsp=NULL; - } - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "DESTROY Exit tech_pvt=%p (use=%i)\n", - tech_pvt,usecount()); - } - - ast_mutex_destroy(&tech_pvt->iolock); - ast_mutex_destroy(&tech_pvt->event_queue.lock); - - if (tech_pvt->cid_rdnis) { - free(tech_pvt->cid_rdnis); - tech_pvt->cid_rdnis=NULL; - } - - free(tech_pvt); - ast_mutex_lock(&usecnt_lock); - usecnt--; - if (usecnt < 0) { - usecnt = 0; - } - ast_mutex_unlock(&usecnt_lock); -} - -#if 0 - -static int waitfor_socket(int fd, int timeout) -{ - struct pollfd pfds[1]; - int res; - int errflags = (POLLERR | POLLHUP | POLLNVAL); - - if (fd < 0) { - return -1; - } - - memset(&pfds[0], 0, sizeof(pfds[0])); - pfds[0].fd = fd; - pfds[0].events = POLLIN | errflags; - res = poll(pfds, 1, timeout); - if (res > 0) { - if ((pfds[0].revents & errflags)) { - res = -1; - } else if ((pfds[0].revents & POLLIN)) { - res = 1; - } else { - ast_log(LOG_ERROR, "System Error: Poll Event Error no event!\n"); - res = -1; - } - } - - return res; -} - -#else - -static int waitfor_socket(int fd, int timeout) -{ - struct pollfd pfds[1]; - int res; - - if (fd < 0) { - return -1; - } - - memset(&pfds[0], 0, sizeof(pfds[0])); - pfds[0].fd = fd; - pfds[0].events = POLLIN | POLLERR; - res = poll(pfds, 1, timeout); - if (res > 0) { - if ((pfds[0].revents & POLLERR)) { - res = -1; - } else if((pfds[0].revents & POLLIN)) { - res = 1; - } else { - res = -1; - } - } - - return res; -} - -#endif - - -static void *tech_monitor_thread(void *obj) -{ - private_object *tech_pvt; - woomera_message wmsg; - char tcallid[WOOMERA_STRLEN]; - int aborted=0; - - int res = 0; - - tech_pvt = obj; - - if (ast_test_flag(tech_pvt, TFLAG_TECHHANGUP)) { - ast_log(LOG_NOTICE, "Tech Monitor: Call stopped before thread up!\n"); - return NULL; - } - - memset(tcallid,0,sizeof(tcallid)); - memset(&wmsg,0,sizeof(wmsg)); - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "IN THREAD %s rxgain=%f txtain=%f\n", - tech_pvt->callid, - tech_pvt->profile->rxgain_val, - tech_pvt->profile->txgain_val); - } - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - tech_pvt->profile->call_out++; - } else { - tech_pvt->profile->call_in++; - } - tech_pvt->profile->call_count++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - - for(;;) { - - if (globals.panic) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - } - - if (!tech_pvt->owner) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Thread lost Owner Chan %s %p\n", - tech_pvt->callid, - tech_pvt); - } - } - - - /* finish the deferred crap asterisk won't allow us to do live */ - if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { - int timeout_cnt=0; - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ABORT GOT HANGUP CmdCh=%i %s %s/%i\n", - tech_pvt->command_channel, tech_pvt->callid, - tech_pvt->profile ? tech_pvt->profile->audio_ip : "N/A", - tech_pvt->port); - } - - aborted|=1; - - /* Check for queued events, looking for HANGUP messages, - so we can return proper hangup cause */ - for (;;) { - if ((res = woomera_dequeue_event(&tech_pvt->event_queue, &wmsg))) { - woomera_check_event (tech_pvt, res, &wmsg); - } else { - break; - } - } - - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_count--; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - - if (tech_pvt->profile && tech_pvt->command_channel > -1) { - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ABORT sent HANGUP on %s %p\n", - tech_pvt->callid, - tech_pvt); - } - aborted|=2; - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "hangup %s%scause: %s%sQ931-Cause-Code: %d%sUnique-Call-Id: %s%s", - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - tech_pvt->ds, - WOOMERA_LINE_SEPARATOR, - tech_pvt->pri_cause, - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "bye%s" - "Unique-Call-Id: %s%s", - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - woomera_close_socket(&tech_pvt->command_channel); - } - - if (tech_pvt->udp_socket > -1) { - woomera_close_socket(&tech_pvt->udp_socket); - } - - - if (!ast_test_flag(tech_pvt, TFLAG_TECHHANGUP) && - ast_test_flag(tech_pvt, TFLAG_PBX)) { - struct ast_channel *owner = tech_get_owner(tech_pvt); - - if (owner) { - aborted|=4; - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ABORT calling hangup on %s t=%p c=%p UP=%d\n", - tech_pvt->callid, - tech_pvt, - owner, - ast_test_flag(tech_pvt, TFLAG_UP)); - } - - while(tech_pvt->owner && - ast_mutex_trylock(&tech_pvt->owner->lock)) { - usleep(1); - } - - if ((owner=tech_pvt->owner)) { - tech_pvt->owner=NULL; - /* Issue a softhangup */ - ast_softhangup(owner, AST_SOFTHANGUP_DEV); - ast_mutex_unlock(&owner->lock); - } - } - } - - - /* Wait for tech_hangup to set this, so there is on - * race condition with asterisk */ - //ast_set_flag(tech_pvt, TFLAG_DESTROY); - - if (ast_test_flag(tech_pvt, TFLAG_PBX)) { - //ast_log(LOG_NOTICE,"Waiting for PBX to hangup!\n"); - while (!ast_test_flag(tech_pvt, TFLAG_DESTROY)) { - timeout_cnt++; - if (timeout_cnt > 10000) { //10sec timeout - struct ast_channel *owner = tech_get_owner(tech_pvt); - if (owner) { - owner->tech_pvt=NULL; - } - /* Five second timeout */ - ast_log(LOG_ERROR, "ERROR: Wait on destroy timedout! %s tech_pvt=%p Dir=%s\n", - tech_pvt->callid, tech_pvt, - ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"OUT":"IN" ); - - - ast_set_flag(tech_pvt, TFLAG_DESTROY); - break; - } - usleep(5000); - sched_yield(); - } - //ast_log(LOG_NOTICE,"Got PBX hangup!\n"); - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_end++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - } else { - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_abort++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "NOTE: Skipping Wait on destroy timedout! %s tech_pvt=%p\n", - tech_pvt->callid, tech_pvt); - } - ast_set_flag(tech_pvt, TFLAG_DESTROY); - } - - aborted|=8; - tech_destroy(tech_pvt,tech_get_owner(tech_pvt)); - tech_pvt = NULL; - break; - } - - - if (ast_test_flag(tech_pvt, TFLAG_TECHHANGUP) || !tech_pvt->owner) { - ast_set_flag(tech_pvt, TFLAG_DESTROY); - ast_set_flag(tech_pvt, TFLAG_ABORT); - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Thread got HANGUP or no owner %s %p tpvt=%p\n", - tech_pvt->callid,tech_pvt,tech_pvt->owner); - } - goto tech_thread_continue; - } - - if (ast_test_flag(tech_pvt, TFLAG_ACTIVATE)) { - - struct ast_channel *owner; - int err; - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ACTIVATE %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - ast_clear_flag(tech_pvt, TFLAG_ACTIVATE); - err=tech_activate(tech_pvt); - if (err < 0 || ast_test_flag(tech_pvt, TFLAG_ABORT)) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ACTIVATE ABORT Ch=%d\n", - tech_pvt->command_channel); - } - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - } - - - owner = tech_get_owner(tech_pvt); - if (owner) { - owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; - } - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ACTIVATE DONE %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - } - - if (ast_test_flag(tech_pvt, TFLAG_PARSE_INCOMING)) { - int err; - - ast_clear_flag(tech_pvt, TFLAG_PARSE_INCOMING); - ast_set_flag(tech_pvt, TFLAG_INCOMING); - - err=woomera_event_incoming (tech_pvt); - - if (err != 0) { - - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "hangup %s%s" - "cause: INVALID_CALL_REFERENCE%s" - "Q931-Cause-Code: 81%s" - "Unique-Call-Id: %s%s", - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - WOOMERA_LINE_SEPARATOR, - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - - /* Wait for Ack */ - woomera_message_parse_wait(tech_pvt,&wmsg); - - woomera_close_socket(&tech_pvt->command_channel); - - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - - } else { - - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "%s %s%s" - "Raw-Audio: %s:%d%s" - "Request-Audio: Raw%s" - "Unique-Call-Id: %s%s", - MEDIA_ANSWER, - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - tech_pvt->profile->audio_ip, - tech_pvt->port, - WOOMERA_LINE_SEPARATOR, - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - - } - - /* Wait for Ack */ - if (woomera_message_parse_wait(tech_pvt,&wmsg) < 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - ast_log(LOG_NOTICE, "MEDIA ANSWER ABORT Ch=%d\n", - tech_pvt->command_channel); - ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=111; - goto tech_thread_continue; - } - - /* Confirm that the Ack is OK otherwise - * hangup */ - if (woomera_message_reply_ok(&wmsg) != 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - } - - /* It is possible for ACCEPT to have media info - * This is how Early Media is started */ - err=woomera_event_media (tech_pvt, &wmsg); - if (err < 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - } - } - - if (ast_test_flag(tech_pvt, TFLAG_ACCEPT) && - ast_test_flag(tech_pvt, TFLAG_INCOMING)) { - - ast_set_flag(tech_pvt,TFLAG_ACCEPTED); - ast_clear_flag(tech_pvt,TFLAG_ACCEPT); - - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "ACCEPT %s%s" - "Raw-Audio: %s:%d%s" - "Request-Audio: Raw%s" - "Unique-Call-Id: %s%s", - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - tech_pvt->profile->audio_ip, - tech_pvt->port, - WOOMERA_LINE_SEPARATOR, - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - - if(woomera_message_parse_wait(tech_pvt,&wmsg) < 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - ast_log(LOG_NOTICE, "ACCEPT ABORT Ch=%d\n", - tech_pvt->command_channel); - ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=111; - goto tech_thread_continue; - continue; - } - - } - - - if (ast_test_flag(tech_pvt, TFLAG_ANSWER)) { - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ANSWER %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - ast_clear_flag(tech_pvt, TFLAG_ANSWER); - - if (ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - ast_log(LOG_ERROR,"Error: ANSWER on OUTBOUND Call! (skipped) %s\n", - tech_pvt->callid); - } else { -#ifdef USE_ANSWER - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "ANSWER %s%s" - "Unique-Call-Id: %s%s", - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_RECORD_SEPARATOR); - - if(woomera_message_parse_wait(tech_pvt,&wmsg) < 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - ast_log(LOG_NOTICE, "ANSWER ABORT Ch=%d\n", - tech_pvt->command_channel); - ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=111; - goto tech_thread_continue; - continue; - } - - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_ok++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); -#endif - } - } - - if (ast_test_flag(tech_pvt, TFLAG_DTMF)) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "DTMF %s tpvt=%p %s\n", - tech_pvt->callid,tech_pvt,tech_pvt->dtmfbuf); - } - - //DIALECT - ast_mutex_lock(&tech_pvt->iolock); -#if 0 - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "DTMF %s %s%s", - tech_pvt->callid, - tech_pvt->dtmfbuf, - WOOMERA_LINE_SEPARATOR); -#else - woomera_printf(tech_pvt->profile, tech_pvt->command_channel, - "DTMF %sUnique-Call-Id:%s%sContent-Length:%d%s%s%s%s", - WOOMERA_LINE_SEPARATOR, - tech_pvt->callid, - WOOMERA_LINE_SEPARATOR, - strlen(tech_pvt->dtmfbuf), - WOOMERA_LINE_SEPARATOR, - WOOMERA_LINE_SEPARATOR, - tech_pvt->dtmfbuf, - WOOMERA_RECORD_SEPARATOR); -#endif - - ast_clear_flag(tech_pvt, TFLAG_DTMF); - memset(tech_pvt->dtmfbuf, 0, sizeof(tech_pvt->dtmfbuf)); - ast_mutex_unlock(&tech_pvt->iolock); - - if (woomera_message_parse_wait(tech_pvt,&wmsg) < 0) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - ast_log(LOG_NOTICE, "DTMF ABORT Ch=%d\n", - tech_pvt->command_channel); - ast_copy_string(tech_pvt->ds, "PROTOCOL_ERROR", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=111; - goto tech_thread_continue; - continue; - } - } - - if(tech_pvt->timeout) { - struct timeval now; - int elapsed; - gettimeofday(&now, NULL); - elapsed = (((now.tv_sec * 1000) + now.tv_usec / 1000) - - ((tech_pvt->started.tv_sec * 1000) + tech_pvt->started.tv_usec / 1000)); - if (elapsed > tech_pvt->timeout) { - /* call timed out! */ - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "CALL TIMED OUT %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - ast_set_flag(tech_pvt, TFLAG_ABORT); - ast_copy_string(tech_pvt->ds, "RECOVERY_ON_TIMER_EXPIRE", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=102; - } - } - - if (globals.debug > 2) { - if (tcallid[0] == 0) { - strncpy(tcallid,tech_pvt->callid,sizeof(tcallid)-1); - } - } - - if (tech_pvt->command_channel < 0) { - if (!globals.more_threads) { - goto tech_thread_continue; - continue; - } else { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "No Command Channel %s tpvt=%p\n", - tech_pvt->callid,tech_pvt); - } - ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=44; - ast_set_flag(tech_pvt, TFLAG_ABORT); - goto tech_thread_continue; - continue; - } - } - /* Check for events */ - if((res = woomera_dequeue_event(&tech_pvt->event_queue, &wmsg)) || - (res = woomera_message_parse(tech_pvt->command_channel, - &wmsg, - 100, - tech_pvt->profile, - NULL - ))) { - - woomera_check_event (tech_pvt, res, &wmsg); - if (ast_test_flag(tech_pvt, TFLAG_ABORT)) { - continue; - } - - } - if (globals.debug > 4) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "CHECK {%s} (%d) %s\n", - tech_pvt->profile->name, - res,tech_pvt->callid); - } - } - -tech_thread_continue: - - if (!globals.more_threads) { - ast_log(LOG_NOTICE, "EXITING THREAD on more threads %s\n", - tcallid); - break; - } - - } - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "OUT THREAD %s 0x%X\n",tcallid,aborted); - } - - return NULL; -} - -static int woomera_profile_thread_running(woomera_profile *profile, int set, int new) -{ - int running = 0; - - ast_mutex_lock(&profile->iolock); - if (set) { - profile->thread_running = new; - } - running = profile->thread_running; - ast_mutex_unlock(&profile->iolock); - return running; - -} - -static int woomera_locate_socket(woomera_profile *profile, int *woomera_socket) -{ - woomera_message wmsg; - - memset(&wmsg,0,sizeof(wmsg)); - - for (;;) { - - while (connect_woomera(woomera_socket, profile, 0) < 0) { - if(!woomera_profile_thread_running(profile, 0, 0)) { - break; - } - if (globals.panic > 2) { - break; - } - ast_log(LOG_NOTICE, - "Woomera {%s} Cannot Reconnect! retry in 5 seconds...\n", - profile->name); - - /* When we establish connection update smg version */ - smgversion_init=0; - sleep(5); - } - - if (*woomera_socket > -1) { - if (ast_test_flag(profile, PFLAG_INBOUND)) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Woomera Master Socket \n"); - } - woomera_printf(profile, *woomera_socket, "LISTEN MASTER%s", WOOMERA_RECORD_SEPARATOR); - if (woomera_message_parse(*woomera_socket, - &wmsg, - WOOMERA_HARD_TIMEOUT, - profile, - &profile->event_queue - ) < 0) { - ast_log(LOG_ERROR, "{%s} %s:%d HELP! Woomera is broken!\n", - profile->name,__FUNCTION__,__LINE__); - if (*woomera_socket > -1) { - woomera_close_socket(woomera_socket); - } - continue; - } - } - - } - usleep(100); - break; - } - return *woomera_socket; -} - -static void tech_monitor_in_one_thread(void) -{ - private_object *tech_pvt; - - ASTOBJ_CONTAINER_TRAVERSE(&private_object_list, 1, do { - ASTOBJ_RDLOCK(iterator); - tech_pvt = iterator; - tech_monitor_thread(tech_pvt); - ASTOBJ_UNLOCK(iterator); - } while(0)); -} - -static void *woomera_thread_run(void *obj) -{ - - int woomera_socket = -1, res = 0, res2=0; - woomera_message wmsg; - woomera_profile *profile; - - memset(&wmsg,0,sizeof(wmsg)); - - profile = obj; - ast_log(LOG_NOTICE, "Started Woomera Thread {%s}.\n", profile->name); - - profile->thread_running = 1; - - - while(woomera_profile_thread_running(profile, 0, 0)) { - /* listen on socket and handle events */ - - if (globals.panic > 2) { - break; - } - - if (globals.panic == 2) { - ast_log(LOG_NOTICE, "Woomera is disabled!\n"); - sleep(5); - continue; - } - - if (woomera_socket < 0) { - if (woomera_locate_socket(profile, &woomera_socket)) { - globals.panic = 0; - } - if (!woomera_profile_thread_running(profile, 0, 0)) { - break; - } - profile->woomera_socket=woomera_socket; - ast_log(LOG_NOTICE, "Woomera Thread Up {%s} %s/%d\n", - profile->name, profile->woomera_host, profile->woomera_port); - - } - - if (globals.panic) { - if (globals.panic != 2) { - ast_log(LOG_ERROR, "Help I'm in a state of panic!\n"); - } - if (woomera_socket > -1) { - woomera_close_socket(&woomera_socket); - } - continue; - } - if (!globals.more_threads) { - if (woomera_socket > -1) { - tech_monitor_in_one_thread(); - } - } - - if ((res = woomera_dequeue_event(&profile->event_queue, &wmsg) || - (res2 = woomera_message_parse(woomera_socket, - &wmsg, - /* if we are not stingy with threads we can block forever */ - globals.more_threads ? 0 : 500, - profile, - NULL - )))) { - - - if (res2 < 0) { - ast_log(LOG_ERROR, "{%s} HELP! I lost my connection to woomera!\n", profile->name); - if (woomera_socket > -1) { - woomera_close_socket(&woomera_socket); - } - global_set_flag(TFLAG_ABORT); - if (globals.panic > 2) { - break; - } - - continue; - - if (woomera_socket > -1) { - if (ast_test_flag(profile, PFLAG_INBOUND)) { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "%s:%d Incoming Call \n",__FUNCTION__,__LINE__); - } - -#if 0 -/* We only want a single listener */ - woomera_printf(profile, woomera_socket, "LISTEN%s", WOOMERA_RECORD_SEPARATOR); - if(woomera_message_parse(woomera_socket, - &wmsg, - WOOMERA_HARD_TIMEOUT, - profile, - &profile->event_queue - ) < 0) { - ast_log(LOG_ERROR, "{%s} %s:%d HELP! Woomera is broken!\n", profile->name,__FUNCTION__,__LINE__); - woomera_close_socket(&woomera_socket); - } -#endif - } - if (woomera_socket > -1) { - ast_log(LOG_NOTICE, "Woomera Thread Up {%s} %s/%d\n", profile->name, profile->woomera_host, profile->woomera_port); - } - } - continue; - } - - if (!strcasecmp(wmsg.command, "INCOMING")) { - - int err=1; - int cause = 0; - struct ast_channel *inchan; - char *name = "Woomera"; - - if (!(name = woomera_message_header(&wmsg, "Channel-Name"))) { - name = woomera_message_header(&wmsg,"Remote-Address"); - } - - if (!name) { - name=wmsg.callid; - } - - if (!name) { - name="smg"; - } - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "NEW INBOUND CALL %s!\n",wmsg.callid); - } - - if ((inchan = woomera_new(WOOMERA_CHAN_NAME, profile->coding, name, &cause, profile))) { - private_object *tech_pvt; - char *callid; - tech_pvt = inchan->tech_pvt; - - /* Save the call id */ - tech_pvt->call_info = wmsg; - memcpy(tech_pvt->callid,wmsg.callid,sizeof(tech_pvt->callid)); - - callid = woomera_message_header(&wmsg, "Unique-Call-Id"); - if (callid) { - ast_copy_string(tech_pvt->callid, - callid,sizeof(wmsg.callid)); - } - - err=tech_init(tech_pvt, profile, TFLAG_INBOUND); - if (err) { - if(globals.debug > 2) { - ast_log(LOG_ERROR, "Error: Inbound Call Failed %s %p\n", - wmsg.callid, - tech_pvt); - } - tech_destroy(tech_pvt,inchan); - } - } else { - ast_log(LOG_ERROR, "Cannot Create new Inbound Channel!\n"); - } - - /* It is the job of the server to timeout on this call - if the call is not started */ - } - } - if(globals.debug > 4) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "Main Thread {%s} Select Return %d\n", profile->name, res); - } - } - usleep(100); - } - - - if (woomera_socket > -1) { - woomera_printf(profile, woomera_socket, "BYE%s", WOOMERA_RECORD_SEPARATOR); - if(woomera_message_parse(woomera_socket, - &wmsg, - WOOMERA_HARD_TIMEOUT, - profile, - &profile->event_queue - ) < 0) { - } - woomera_close_socket(&woomera_socket); - } - - ast_set_flag(profile, PFLAG_DISABLED); - - ast_log(LOG_NOTICE, "Ended Woomera Thread {%s}.\n", profile->name); - woomera_profile_thread_running(profile, 1, -1); - return NULL; -} - -static void launch_woomera_thread(woomera_profile *profile) -{ - pthread_attr_t attr; - int result = 0; - - result = pthread_attr_init(&attr); - pthread_attr_setschedpolicy(&attr, SCHED_RR); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - result = ast_pthread_create(&profile->thread, &attr, woomera_thread_run, profile); - result = pthread_attr_destroy(&attr); -} - - -static int launch_tech_thread(private_object *tech_pvt) -{ - pthread_attr_t attr; - int result = 0; - - if (globals.debug > 2) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++LAUCN TECH THREAD\n"); - } - } - - if (ast_test_flag(tech_pvt, TFLAG_TECHHANGUP)) { - /* Sanity check should never happen */ - ast_log(LOG_NOTICE,"Tech Thread failed call already hangup!\n"); - return -1; - } - - result = pthread_attr_init(&attr); - pthread_attr_setschedpolicy(&attr, SCHED_RR); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - ast_set_flag(tech_pvt, TFLAG_INTHREAD); - result = ast_pthread_create(&tech_pvt->thread, &attr, tech_monitor_thread, tech_pvt); - if (result) { - ast_clear_flag(tech_pvt, TFLAG_INTHREAD); - ast_log(LOG_ERROR, "Error: Failed to launch tech thread %s\n", - strerror(errno)); - } - pthread_attr_destroy(&attr); - - return result; -} - -static void woomera_config_gain(woomera_profile *profile, float gain_val, int rx) -{ - int j; - int k; - float linear_gain = pow(10.0, gain_val / 20.0); - unsigned char *gain; - - if (profile->coding == AST_FORMAT_SLINEAR){ - ast_log(LOG_WARNING, "Coding not specified, %s value ignored\n", (rx)? "rxgain":"txgain"); - return; - } - - - if (gain_val == 0) { - goto woomera_config_gain_skip; - } - if (rx) { - gain = profile->rxgain; - } else { - gain = profile->txgain; - } - - switch (profile->coding) { - - case AST_FORMAT_ALAW: - for (j = 0; j < 256; j++) { - if (gain_val) { - k = (int) (((float) alaw_to_linear(j)) * linear_gain); - if (k > 32767) k = 32767; - if (k < -32767) k = -32767; - gain[j] = linear_to_alaw(k); - } else { - gain[j] = j; - } - } - break; - case AST_FORMAT_ULAW: - for (j = 0; j < 256; j++) { - if (gain_val) { - k = (int) (((float) ulaw_to_linear(j)) * linear_gain); - if (k > 32767) k = 32767; - if (k < -32767) k = -32767; - gain[j] = linear_to_ulaw(k); - } else { - gain[j] = j; - } - } - break; - } - -woomera_config_gain_skip: - - if (rx) { - profile->rxgain_val=gain_val; - } else { - profile->txgain_val=gain_val; - } - -} - -static void destroy_woomera_profile(woomera_profile *profile) -{ - int i; - if (profile && ast_test_flag(profile, PFLAG_DYNAMIC)) { - for ( i = 0; i <= WOOMERA_MAX_TRUNKGROUPS; i++){ - if(profile->tg_context[i] != NULL){ - free(profile->tg_context[i]); - } - if(profile->tg_language[i] != NULL){ - free(profile->tg_language[i]); - } - } - ast_mutex_destroy(&profile->iolock); - ast_mutex_destroy(&profile->call_count_lock); - ast_mutex_destroy(&profile->event_queue.lock); - free(profile); - } -} - -static woomera_profile *clone_woomera_profile(woomera_profile *new_profile, woomera_profile *default_profile) -{ - return memcpy(new_profile, default_profile, sizeof(woomera_profile)); -} - -static woomera_profile *create_woomera_profile(woomera_profile *default_profile) -{ - woomera_profile *profile; - - if((profile = malloc(sizeof(woomera_profile)))) { - clone_woomera_profile(profile, default_profile); - ast_mutex_init(&profile->iolock); - ast_mutex_init(&profile->call_count_lock); - ast_mutex_init(&profile->event_queue.lock); - ast_set_flag(profile, PFLAG_DYNAMIC); - } - return profile; -} - -static int config_woomera(void) -{ - struct ast_config *cfg; - char *entry; - struct ast_variable *v; - woomera_profile *profile; - int default_context_set = 0; - int count = 0; - - memset(&default_profile, 0, sizeof(default_profile)); -#ifdef AST_JB - memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); -#endif - - default_profile.coding=0; - - if ((cfg = ast_config_load(configfile))) { - for (entry = ast_category_browse(cfg, NULL); entry != NULL; entry = ast_category_browse(cfg, entry)) { - if (strcmp(entry, "settings") == 0) { - - for (v = ast_variable_browse(cfg, entry); v ; v = v->next) { - - if (!strcmp(v->name, "debug")) { - globals.debug = atoi(v->value); - } else if (!strcmp(v->name, "more_threads")) { - globals.more_threads = ast_true(v->value); - } -#ifdef AST_JB - if (ast_jb_read_conf(&global_jbconf, v->name, v->value) == 0) { - ast_log(LOG_NOTICE, "Woomera AST JB Opt %s = %s \n", - v->name,v->value); - continue; - } -#endif - } - - - - } else { - int new = 0; - float gain; - count++; - if (!strcmp(entry, "default")) { - profile = &default_profile; - } else { - if((profile = ASTOBJ_CONTAINER_FIND(&woomera_profile_list, entry))) { - clone_woomera_profile(profile, &default_profile); - } else { - if((profile = create_woomera_profile(&default_profile))) { - new = 1; - } else { - ast_log(LOG_ERROR, "Memory Error!\n"); - } - } - } - strncpy(profile->name, entry, sizeof(profile->name) - 1); - profile->coding=AST_FORMAT_SLINEAR; - - /*default is inbound and outbound enabled */ - ast_set_flag(profile, PFLAG_INBOUND | PFLAG_OUTBOUND); - for (v = ast_variable_browse(cfg, entry); v ; v = v->next) { - if (!strcmp(v->name, "audio_ip")) { - strncpy(profile->audio_ip, v->value, sizeof(profile->audio_ip) - 1); - } else if (!strcmp(v->name, "host")) { - strncpy(profile->woomera_host, v->value, sizeof(profile->woomera_host) - 1); - } else if (!strcmp(v->name, "max_calls")) { - int max = atoi(v->value); - if (max > 0) { - profile->max_calls = max; - } - } else if (!strcmp(v->name, "port")) { - profile->woomera_port = atoi(v->value); - } else if (!strcmp(v->name, "disabled")) { - ast_set2_flag(profile, ast_true(v->value), PFLAG_DISABLED); - } else if (!strcmp(v->name, "inbound")) { - if (ast_false(v->value)) { - ast_clear_flag(profile, PFLAG_INBOUND); - } - } else if (!strcmp(v->name, "outbound")) { - if (ast_false(v->value)) { - ast_clear_flag(profile, PFLAG_OUTBOUND); - } - } else if (!strcmp(v->name, "context")) { - if(!default_context_set){ - default_context_set=1; - strncpy(profile->default_context, v->value, sizeof(profile->default_context) - 1); - } - strncpy(profile->context, v->value, sizeof(profile->context) - 1); - } else if (!strcmp(v->name, "default_context")) { - default_context_set=1; - strncpy(profile->default_context, v->value, sizeof(profile->default_context) - 1); - } else if (!strcmp(v->name, "group")) { - int group_num = atoi(v->value); - if (group_num < 0) { - ast_log(LOG_ERROR, "Invalid group:%d (less than zero) - ignoring\n", group_num); - } else if (group_num > WOOMERA_MAX_TRUNKGROUPS){ - ast_log(LOG_ERROR, "Invalid trunkgroup:%d (exceeds max:%d) -ignoring\n", group_num, WOOMERA_MAX_TRUNKGROUPS); - } else { - if(profile->tg_context[group_num] != NULL){ - free(profile->tg_context[group_num]); - } - profile->tg_context[group_num] = strdup(profile->context); - - if(profile->tg_language[group_num] != NULL){ - free(profile->tg_language[group_num]); - } - if(strlen(profile->language)){ - profile->tg_language[group_num] = strdup(profile->language); - } - } - } else if (!strcmp(v->name, "language")) { - strncpy(profile->language, v->value, sizeof(profile->language) - 1); - } else if (!strcmp(v->name, "dtmf_enable")) { - profile->dtmf_enable = atoi(v->value); - - } else if (!strcmp(v->name, "jb_enable")) { - profile->jb_enable = atoi(v->value); - ast_log(LOG_NOTICE, "Profile {%s} Jitter Buffer %s %p \n", - entry,profile->jb_enable?"Enabled":"Disabled",profile); - - } else if (!strcmp(v->name, "jbenable")) { - profile->jb_enable = atoi(v->value); - ast_log(LOG_NOTICE, "Profile {%s} Jitter Buffer %s %p\n", - entry,profile->jb_enable?"Enabled":"Disabled",profile); - - } else if (!strcmp(v->name, "progress_enable")) { - profile->progress_enable = atoi(v->value); - - } else if (!strcmp(v->name, "coding")) { - if (strcmp(v->value, "alaw") == 0) { - profile->coding=AST_FORMAT_ALAW; - } - if (strcmp(v->value, "ulaw") == 0) { - profile->coding=AST_FORMAT_ULAW; - } - } else if (!strcmp(v->name, "rxgain") && profile->coding) { - if (sscanf(v->value, "%f", &gain) != 1) { - ast_log(LOG_NOTICE, "Invalid rxgain: %s\n", v->value); - } else { - woomera_config_gain(profile,gain,1); - } - } else if (!strcmp(v->name, "txgain") && profile->coding) { - if (sscanf(v->value, "%f", &gain) != 1) { - ast_log(LOG_NOTICE, "Invalid txgain: %s\n", v->value); - } else { - woomera_config_gain(profile,gain,0); - } - } - } - - ASTOBJ_CONTAINER_LINK(&woomera_profile_list, profile); - } - } - ast_config_destroy(cfg); - } else { - return 0; - } - - return count; - -} - -static int create_udp_socket(char *ip, int port, struct sockaddr_in *sockaddr, int client) -{ - int rc, sd = -1; - struct sockaddr_in servAddr, *addr, cliAddr; - struct hostent hps, *hp; - struct hostent *result; - char buf[512]; - int err=0; - - memset(&hps,0,sizeof(hps)); - hp=&hps; - - - if(sockaddr) { - addr = sockaddr; - } else { - addr = &servAddr; - } - - - if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) > -1) { - - gethostbyname_r(ip, hp, buf, sizeof(buf), &result, &err); - if (result) { - - addr->sin_family = hp->h_addrtype; - memcpy((char *) &addr->sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); - addr->sin_port = htons(port); - - if (globals.debug > 4) { - ast_log(LOG_NOTICE,"MEDIA UdpRead IP=%s/%d len=%i %d.%d.%d.%d\n", - ip,port, - hp->h_length, - hp->h_addr_list[0][0], - hp->h_addr_list[0][1], - hp->h_addr_list[0][2], - hp->h_addr_list[0][3]); - } - - if (client) { - cliAddr.sin_family = AF_INET; - cliAddr.sin_addr.s_addr = htonl(INADDR_ANY); - cliAddr.sin_port = htons(0); - rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr)); - } else { - rc = bind(sd, (struct sockaddr *) addr, sizeof(cliAddr)); - } - if (rc < 0) { - - if (globals.debug > 2) { - ast_log(LOG_ERROR, - "Error opening udp socket %s/%i %s\n", - ip,port, strerror(errno)); - } - - woomera_close_socket(&sd); - - } else if (globals.debug > 2) { - - ast_log(LOG_NOTICE, "Socket Binded %s to %s/%d\n", - client ? "client" : "server", ip, port); - } - - } else { - if (globals.debug > 2) { - ast_log(LOG_ERROR, - "Error opening udp: gethostbyname failed %s/%i %s\n", - ip,port, strerror(errno)); - } - - woomera_close_socket(&sd); - } - } - - return sd; -} - - -static int connect_woomera(int *new_socket, woomera_profile *profile, int flags) -{ - struct sockaddr_in localAddr, remoteAddr; - struct hostent *hp, *result; - struct hostent ahp; - int res = 0, err=0; - hp=&ahp; - char buf[512]; - - *new_socket=-1; - - gethostbyname_r(profile->woomera_host, hp, buf, sizeof(buf), &result, &err); - if (result) { - remoteAddr.sin_family = hp->h_addrtype; - memcpy((char *) &remoteAddr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); - remoteAddr.sin_port = htons(profile->woomera_port); - do { - /* create socket */ - *new_socket = socket(AF_INET, SOCK_STREAM, 0); - if (*new_socket < 0) { - ast_log(LOG_ERROR, "cannot open socket to %s/%d\n", profile->woomera_host, profile->woomera_port); - res = 0; - break; - } - - /* bind any port number */ - localAddr.sin_family = AF_INET; - localAddr.sin_addr.s_addr = htonl(INADDR_ANY); - localAddr.sin_port = htons(0); - - res = bind(*new_socket, (struct sockaddr *) &localAddr, sizeof(localAddr)); - if (res < 0) { - ast_log(LOG_ERROR, "cannot bind to %s/%d\n", profile->woomera_host, profile->woomera_port); - woomera_close_socket(new_socket); - res = 0; - break; - } - - /* connect to server */ - res = connect(*new_socket, (struct sockaddr *) &remoteAddr, sizeof(remoteAddr)); - if (res < 0) { - ast_log(LOG_ERROR, "cannot connect to {%s} %s/%d\n", profile->name, profile->woomera_host, profile->woomera_port); - res = 0; - woomera_close_socket(new_socket); - break; - } - res = 1; - } while(0); - - } else { - if (globals.debug > 2) { - ast_log(LOG_ERROR, "gethost failed connect to {%s} %s/%d\n", - profile->name, profile->woomera_host, profile->woomera_port); - } - res = 0; - } - if (res > 0) { - int flag = 1; - woomera_message wmsg; - memset(&wmsg,0,sizeof(wmsg)); - - /* disable nagle's algorythm */ - res = setsockopt(*new_socket, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); - - - if (!(flags & WCFLAG_NOWAIT)) { - /* kickstart the session waiting for a HELLO */ - woomera_printf(NULL, *new_socket, "%s", WOOMERA_RECORD_SEPARATOR); - - if ((res = woomera_message_parse(*new_socket, - &wmsg, - WOOMERA_HARD_TIMEOUT, - profile, - NULL - )) < 0) { - ast_log(LOG_ERROR, "{%s} Timed out waiting for a hello from woomera!\n", profile->name); - woomera_close_socket(new_socket); - } - - if (res > 0 && strcasecmp(wmsg.command, "HELLO")) { - ast_log(LOG_ERROR, "{%s} unexpected reply [%s] while waiting for a hello from woomera!\n", profile->name, wmsg.command); - woomera_close_socket(new_socket); - - }else{ - char *audio_format; - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Woomera Got HELLO on connect! %s SMG Version %s\n", profile->name,woomera_message_header(&wmsg, "Version")); - } - if (!smgversion_init && woomera_message_header(&wmsg, "Version")) { - smgversion_init=1; - strncpy(smgversion, - woomera_message_header(&wmsg, "Version"), - sizeof(smgversion)-1); - } - - audio_format = woomera_message_header(&wmsg, "Raw-Format"); - if (!audio_format) { - audio_format = woomera_message_header(&wmsg, "Raw-Audio-Format"); - } - if (audio_format) { - - profile->coding=AST_FORMAT_SLINEAR; - - if (strncasecmp(audio_format,"PCM-16",20) == 0){ - profile->coding=AST_FORMAT_SLINEAR; - } else if (strncasecmp(audio_format,"ULAW",15) == 0) { - profile->coding=AST_FORMAT_ULAW; - } else if (strncasecmp(audio_format,"ALAW",15) == 0) { - profile->coding=AST_FORMAT_ALAW; - } else { - ast_log(LOG_ERROR, "Error: Invalid Raw-Format %s\n", - audio_format); - } - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "Setting RAW Format to %s %i (p%i:u%i:a%i)\n", - audio_format, profile->coding, - AST_FORMAT_SLINEAR,AST_FORMAT_ULAW,AST_FORMAT_ALAW); - } - } - } - } - - } else { - if (globals.debug > 2) { - ast_log(LOG_ERROR, "Woomera {%s} connection failed: %s/%d\n", - profile->name, profile->woomera_host, profile->woomera_port); - ast_log(LOG_ERROR, "Woomera {%s} connection failed: %s\n", - profile->name, strerror(errno)); - } - woomera_close_socket(new_socket); - } - - return *new_socket; -} - -static int init_woomera(void) -{ - woomera_profile *profile; - ast_mutex_lock(&lock); - - if (!config_woomera()) { - ast_mutex_unlock(&lock); - return 0; - } - - ASTOBJ_CONTAINER_TRAVERSE(&woomera_profile_list, 1, do { - ASTOBJ_RDLOCK(iterator); - profile = iterator; - if (!ast_test_flag(profile, PFLAG_DISABLED)) { - launch_woomera_thread(profile); - } - ASTOBJ_UNLOCK(iterator); - } while(0)); - - ast_mutex_unlock(&lock); - return 1; -} - -static struct ast_channel *woomera_new(const char *type, int format, - void *data, int *cause, - woomera_profile *parent_profile) -{ - private_object *tech_pvt; - struct ast_channel *chan = NULL; - char name[100]; - - snprintf(name, sizeof(name), "%s/%s-%04x", type, (char *)data, rand() & 0xffff); - - if (!(tech_pvt = malloc(sizeof(private_object)))) { - ast_log(LOG_ERROR, "Memory Error!\n"); - return NULL; - } - memset(tech_pvt, 0, sizeof(private_object)); - -#ifdef AST14 - chan = ast_channel_alloc(0, AST_STATE_DOWN, "", "", "", "", "", 0, "%s", name); -#else - chan = ast_channel_alloc(1); -#endif - if (chan) { - chan->nativeformats = WFORMAT; -#ifndef AST14 - chan->type = type; - snprintf(chan->name, sizeof(chan->name), "%s/%s-%04x", chan->type, (char *)data, rand() & 0xffff); -#endif - - chan->writeformat = chan->rawwriteformat = chan->readformat = WFORMAT; - chan->_state = AST_STATE_DOWN; - chan->_softhangup = 0; - - tech_count++; - tech_pvt->coding=WFORMAT; - - ast_mutex_init(&tech_pvt->iolock); - ast_mutex_init(&tech_pvt->event_queue.lock); - tech_pvt->command_channel = -1; - chan->tech_pvt = tech_pvt; - chan->tech = &technology; - tech_pvt->udp_socket = -1; - - ast_clear_flag(chan, AST_FLAGS_ALL); - memset(&tech_pvt->frame, 0, sizeof(tech_pvt->frame)); - tech_pvt->frame.frametype = AST_FRAME_VOICE; - tech_pvt->frame.subclass = WFORMAT; - tech_pvt->frame.offset = AST_FRIENDLY_OFFSET; - - tech_pvt->owner = chan; - - chan->nativeformats = tech_pvt->coding; - chan->writeformat = chan->rawwriteformat = chan->readformat = tech_pvt->coding; - tech_pvt->frame.subclass = tech_pvt->coding; - - tech_pvt->pri_cause=AST_CAUSE_NORMAL_CLEARING; - - ast_copy_string(tech_pvt->mohinterpret,mohinterpret,sizeof(tech_pvt->mohinterpret)); - ast_copy_string(tech_pvt->mohsuggest,mohsuggest,sizeof(tech_pvt->mohsuggest)); - - ASTOBJ_CONTAINER_LINK(&private_object_list, tech_pvt); - - ast_mutex_lock(&usecnt_lock); - usecnt++; - ast_mutex_unlock(&usecnt_lock); - - } else { - if (option_verbose > 1) { - ast_log(LOG_ERROR, "Can't allocate a channel\n"); - } - } - - - return chan; -} - - - - -/********************CHANNEL METHOD LIBRARY******************** - * This is the actual functions described by the prototypes above. - * - */ - - -/*--- tech_requester: parse 'data' a url-like destination string, allocate a channel and a private structure - * and return the newly-setup channel. - */ -static struct ast_channel *tech_requester(const char *type, int format, void *data, int *cause) -{ - struct ast_channel *chan = NULL; - - - if (globals.panic) { - return NULL; - } - - if ((chan = woomera_new(type, format, data, cause, NULL))) { - private_object *tech_pvt; - - tech_pvt = chan->tech_pvt; - - if (tech_pvt->owner) { - tech_pvt->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING; - } - - ast_set_flag(tech_pvt, TFLAG_PBX); /* so we know we dont have to free the channel ourselves */ - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++REQ %s\n", chan->name); - } - } - - } else { - - if (option_verbose > 1) { - ast_log(LOG_ERROR, "Can't allocate a channel\n"); - } - } - - - return chan; -} - -#ifdef AST14 -static int tech_digit_end(struct ast_channel *ast, char digit, unsigned int duration) -{ - return 0; -} -#endif - -/*--- tech_senddigit: Send a DTMF character */ -static int tech_send_digit(struct ast_channel *self, char digit) -{ - private_object *tech_pvt = self->tech_pvt; - int res = 0; - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++DIGIT %s '%c'\n",self->name, digit); - } - } - - /* we don't have time to make sure the dtmf command is successful cos asterisk again - is much too impaitent... so we will cache the digits so the monitor thread can send - it for us when it has time to actually wait. - */ - ast_mutex_lock(&tech_pvt->iolock); - snprintf(tech_pvt->dtmfbuf + strlen(tech_pvt->dtmfbuf), sizeof(tech_pvt->dtmfbuf), "%c", digit); - ast_set_flag(tech_pvt, TFLAG_DTMF); - ast_mutex_unlock(&tech_pvt->iolock); - - return res; -} - -/*--- tech_call: Initiate a call on my channel - * 'dest' has been passed telling you where to call - * but you may already have that information from the requester method - * not sure why it sends it twice, maybe it changed since then *shrug* - * You also have timeout (in ms) so you can tell how long the caller - * is willing to wait for the call to be complete. - */ - -static int tech_call(struct ast_channel *self, char *dest, int timeout) -{ - private_object *tech_pvt = self->tech_pvt; - char *workspace; - char *p; - char *c; - - self->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; - - if (globals.panic) { - goto tech_call_failed; - } - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH CALL %s (%s <%s>) pres=0x%02X dest=%s\n", - self->name, self->cid.cid_name, - self->cid.cid_num, - self->cid.cid_pres, - dest); - } - - - - if (self->cid.cid_name) { - strncpy(tech_pvt->cid_name, self->cid.cid_name, sizeof(tech_pvt->cid_name)-1); - } - if (self->cid.cid_num) { - strncpy(tech_pvt->cid_num, self->cid.cid_num, sizeof(tech_pvt->cid_num)-1); - } - tech_pvt->cid_pres = self->cid.cid_pres; - - - if (self->cid.cid_rdnis) { - tech_pvt->cid_rdnis=strdup(self->cid.cid_rdnis); - } - - if ((workspace = ast_strdupa(dest))) { - char *addr, *profile_name, *proto=NULL; - woomera_profile *profile; - int err; - - -#if 0 - int isprofile = 0; - - - if ((addr = strchr(workspace, ':'))) { - char *tst; - proto = workspace; - if ((tst = strchr(proto, '/'))){ - proto=tst+1; - } - *addr = '\0'; - addr++; - } else { - proto = NULL; - addr = workspace; - } - - - - - if ((profile_name = strchr(addr, ':'))) { - *profile_name = '\0'; - profile_name++; - isprofile = 1; - } else { - profile_name = "default"; - } -#else - profile_name = "default"; - proto = NULL; - if ((addr = strchr(workspace, ':'))) { - profile_name = workspace; - proto=profile_name; - *addr = '\0'; - addr++; - } else { - addr = workspace; - } - -#endif - - if (! (profile = ASTOBJ_CONTAINER_FIND(&woomera_profile_list, profile_name))) { - profile = ASTOBJ_CONTAINER_FIND(&woomera_profile_list, "default"); - } - - if (!profile) { - ast_log(LOG_ERROR, "Unable to find profile! Call Aborted!\n"); - goto tech_call_failed; - } - - if (!ast_test_flag(profile, PFLAG_OUTBOUND)) { - ast_log(LOG_ERROR, "This profile is not allowed to make outbound calls! Call Aborted!\n"); - goto tech_call_failed; - } - - if (profile->max_calls) { - if (profile->call_count >= profile->max_calls) { - if (globals.debug > 1 && option_verbose > 1) { - ast_log(LOG_ERROR, "This profile is at call limit of %d\n", - profile->max_calls); - } - goto tech_call_failed; - } - } - - - - - snprintf(tech_pvt->dest, sizeof(tech_pvt->dest), "%s", addr ? addr : ""); - snprintf(tech_pvt->proto, sizeof(tech_pvt->proto), "%s", proto ? proto : ""); - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH CALL: proto=%s addr=%s profile=%s Coding=%i\n", - proto,addr,profile_name,profile->coding); - } - - tech_pvt->timeout = timeout; - err=tech_init(tech_pvt, profile, TFLAG_OUTBOUND); - if (err) { - if (globals.debug > 2) { - ast_log(LOG_ERROR, "Error: Outbound Call Failed \n"); - } - goto tech_call_failed; - } - -#if 1 - if ((p = strrchr(self->name, '/'))) { - c = p-1; - if(*c == 'c' || *c== 'C'){ - ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED); - ast_set_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); - } - } -#endif - - woomera_send_progress(tech_pvt); - } - self->hangupcause = AST_CAUSE_NORMAL_CLEARING; - - - return 0; - -tech_call_failed: - if (globals.debug > 1 && option_verbose > 1) { - ast_log(LOG_ERROR, "Error: Outbound Call Failed %p \n",tech_pvt); - } - self->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; - my_ast_softhangup(self, tech_pvt, AST_SOFTHANGUP_EXPLICIT); - return -1; -} - - -/*--- tech_hangup: end a call on my channel - * Now is your chance to tear down and free the private object - * from the channel it's about to be freed so you must do so now - * or the object is lost. Well I guess you could tag it for reuse - * or for destruction and let a monitor thread deal with it too. - * during the load_module routine you have every right to start up - * your own fancy schmancy bunch of threads or whatever else - * you want to do. - */ -static int tech_hangup(struct ast_channel *self) -{ - const char *ds; - private_object *tech_pvt = self->tech_pvt; - int res = 0; - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP [%s] tech_pvt=%p c=%p\n",self->name,tech_pvt,self); - } - - - if (tech_pvt) { - - ast_mutex_lock(&tech_pvt->iolock); - ast_set_flag(tech_pvt, TFLAG_TECHHANGUP); - tech_pvt->owner=NULL; - self->tech_pvt=NULL; - ast_mutex_unlock(&tech_pvt->iolock); - - - - - if (!self || - (!(ds = pbx_builtin_getvar_helper(self, "DIALSTATUS")) && - !(ds = ast_cause2str(self->hangupcause)))) { - ds = "NOEXIST"; - } - - ast_copy_string(tech_pvt->ds, ds, sizeof(tech_pvt->ds)); - - ds=pbx_builtin_getvar_helper(self, "PRI_CAUSE"); - if (ds && atoi(ds)) { - tech_pvt->pri_cause=atoi(ds); - } else if (self->hangupcause) { - tech_pvt->pri_cause=self->hangupcause; - } else { - tech_pvt->pri_cause=AST_CAUSE_NORMAL_CLEARING; - } - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP [%s] Cause=%i HangCause=%i ds=%s\n", - self->name,tech_pvt->pri_cause, self->hangupcause, ds?ds:"N/A"); - } - - if (tech_pvt->dsp) { - tech_pvt->dsp_features &= ~DSP_FEATURE_DTMF_DETECT; - ast_dsp_set_features(tech_pvt->dsp, tech_pvt->dsp_features); - tech_pvt->ast_dsp=0; - } - - - if (ast_test_flag(tech_pvt, TFLAG_INTHREAD)) { - ast_set_flag(tech_pvt, TFLAG_ABORT); - ast_set_flag(tech_pvt, TFLAG_DESTROY); - - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP IN THREAD! tpvt=%p\n", - tech_pvt); - } - } else { - if (globals.debug > 2) { - ast_log(LOG_ERROR, "TECH HANGUP: Destroying tech not in thread! Callid=%s tech_pvt=%p Dir=%s\n", - tech_pvt->callid, tech_pvt, - ast_test_flag(tech_pvt, TFLAG_OUTBOUND)?"OUT":"IN" ); - } - - if (!ast_test_flag(tech_pvt, TFLAG_DESTROY)) { - tech_destroy(tech_pvt,NULL); - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD!\n"); - } - }else{ - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "TECH HANGUP NOT IN THREAD ALREDAY HUNGUP! \n"); - } - } - } - } else { - if (globals.debug > 2) { - ast_log(LOG_NOTICE, "ERROR: NO TECH ON TECH HANGUP!\n"); - } - } - - self->tech_pvt = NULL; - - return res; -} - -/*--- tech_answer: answer a call on my channel - * if being 'answered' means anything special to your channel - * now is your chance to do it! - */ -static int tech_answer(struct ast_channel *self) -{ - private_object *tech_pvt; - int res = 0; - - tech_pvt = self->tech_pvt; - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++ANSWER %s\n",self->name); - } - } - - if (!ast_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - /* Only answer the inbound calls */ - ast_set_flag(tech_pvt, TFLAG_ANSWER); - } else { - ast_log(LOG_ERROR, "Warning: AST trying to Answer OUTBOUND Call!\n"); - } - - ast_set_flag(tech_pvt, TFLAG_UP); - ast_setstate(self, AST_STATE_UP); - - return res; -} - - -#if 0 -static int woomera_tx2ast_frm(private_object *tech_pvt, char * buf, int len ) -{ - struct ast_frame frame; - - frame.frametype = AST_FRAME_VOICE; - frame.subclass = tech_pvt->coding; - frame.datalen = len; - frame.samples = len; - frame.mallocd =0 ; - frame.offset= 0 ; - frame.src = NULL; - frame.data = buf ; - - if (tech_pvt->faxdetect || tech_pvt->ast_dsp) { - struct ast_frame *f; - struct ast_channel *owner = tech_get_owner(tech_pvt); - - - if (!owner) { - return 0; - } - - f = ast_dsp_process(owner, tech_pvt->dsp, &frame); - if (f && (f->frametype == AST_FRAME_DTMF)) { - - ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass); -#if 0 - if (f->subclass == 'f' && tech_pvt->faxdetect) { - /* Fax tone -- Handle and return NULL */ - struct ast_channel *ast = tech_pvt->owner; - if (!tech_pvt->faxhandled) { - tech_pvt->faxhandled++; - if (strcmp(ast->exten, "fax")) { - if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) { - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name); - /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */ - pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten); - if (ast_async_goto(ast, ast->context, "fax", 1)) - ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context); - } else - ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten); - } else - ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n"); - } else - ast_log(LOG_DEBUG, "Fax already handled\n"); - frame.frametype = AST_FRAME_NULL; - frame.subclass = 0; - f = &frame; - - } else -#endif - - if (tech_pvt->ast_dsp && owner) { - struct ast_frame fr; - memset(&fr, 0 , sizeof(fr)); - fr.frametype = AST_FRAME_DTMF; - fr.subclass = f->subclass ; - fr.src=NULL; - fr.data = NULL ; - fr.datalen = 0; - fr.samples = 0 ; - fr.mallocd =0 ; - fr.offset= 0 ; - - ast_log(LOG_EVENT, "Received DTMF Sending 2 AST %c\n", - fr.subclass); - ast_queue_frame(owner, &fr); - - } - - } - - } - - return 0; -} -#endif - -/*--- tech_read: Read an audio frame from my channel. - * You need to read data from your channel and convert/transfer the - * data into a newly allocated struct ast_frame object - */ -static struct ast_frame *tech_read(struct ast_channel *self) -{ - private_object *tech_pvt = self->tech_pvt; - int res = 0; - struct ast_frame *f; - - - if (!tech_pvt || globals.panic || ast_test_flag(tech_pvt, TFLAG_ABORT)) { - return NULL; - } - -tech_read_again: - - res = waitfor_socket(tech_pvt->udp_socket, 1000); - - if (res < 1) { - return NULL; - - }else if (res == 0) { - goto tech_read_again; - } - - res = read(tech_pvt->udp_socket, tech_pvt->fdata + AST_FRIENDLY_OFFSET, FRAME_LEN); - - if (res < 1) { - return NULL; - } - - tech_pvt->frame.frametype = AST_FRAME_VOICE; - tech_pvt->frame.subclass = tech_pvt->coding; - tech_pvt->frame.offset = AST_FRIENDLY_OFFSET; - tech_pvt->frame.datalen = res; - tech_pvt->frame.samples = res; - tech_pvt->frame.data = tech_pvt->fdata + AST_FRIENDLY_OFFSET; - - f=&tech_pvt->frame; - - if (tech_pvt->profile->rxgain_val) { - int i; - unsigned char *data=tech_pvt->frame.data; - for (i=0;iframe.datalen;i++) { - data[i]=tech_pvt->profile->rxgain[data[i]]; - } - } - - if (tech_pvt->owner && (tech_pvt->faxdetect || tech_pvt->ast_dsp)) { - f = ast_dsp_process(tech_pvt->owner, tech_pvt->dsp, &tech_pvt->frame); - if (f && f->frametype == AST_FRAME_DTMF){ - int answer = 0; - if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER_ENABLED)){ - ast_mutex_lock(&tech_pvt->iolock); - if(ast_test_flag(tech_pvt, TFLAG_CONFIRM_ANSWER)){ - ast_clear_flag(tech_pvt, TFLAG_CONFIRM_ANSWER); - if(ast_test_flag(tech_pvt, TFLAG_ANSWER_RECEIVED)){ - answer = 1; - } - } - ast_mutex_unlock(&tech_pvt->iolock); - if(answer){ - struct ast_frame answer_frame = {AST_FRAME_CONTROL, AST_CONTROL_ANSWER}; - struct ast_channel *owner = tech_get_owner(tech_pvt); - ast_log(LOG_DEBUG, "Confirm answer on %s!\n", self->name); - - if (owner) { - ast_setstate(owner, AST_STATE_UP); - ast_queue_frame(owner, &answer_frame); - ast_set_flag(tech_pvt, TFLAG_UP); - - ast_mutex_lock(&tech_pvt->profile->call_count_lock); - tech_pvt->profile->call_ok++; - ast_mutex_unlock(&tech_pvt->profile->call_count_lock); - } else { - ast_copy_string(tech_pvt->ds, "REQUESTED_CHAN_UNAVAIL", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=44; - ast_set_flag(tech_pvt, TFLAG_ABORT); - - } - } - } - if (answer == 0 && globals.debug > 2) { - ast_log(LOG_NOTICE, "%s: Detected inband DTMF digit: %c\n", - self->name, - f->subclass); - } - } - - - //woomera_tx2ast_frm(tech_pvt, tech_pvt->frame.data, tech_pvt->frame.datalen); - } - - - if (globals.debug > 4) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++READ %s %d coding %d\n",self->name, res, - tech_pvt->coding); - } - } - - - return f; -} - -/*--- tech_write: Write an audio frame to my channel - * Yep, this is the opposite of tech_read, you need to examine - * a frame and transfer the data to your technology's audio stream. - * You do not have any responsibility to destroy this frame and you should - * consider it to be read-only. - */ -static int tech_write(struct ast_channel *self, struct ast_frame *frame) -{ - private_object *tech_pvt = self->tech_pvt; - int res = 0, i = 0; - - if (!tech_pvt || globals.panic || ast_test_flag(tech_pvt, TFLAG_ABORT)) { - return 0; - } - - if(ast_test_flag(tech_pvt, TFLAG_MEDIA) && frame->datalen) { - if (frame->frametype == AST_FRAME_VOICE) { - - if (tech_pvt->profile->txgain_val) { - unsigned char *data=frame->data; - for (i=0;idatalen;i++) { - data[i]=tech_pvt->profile->txgain[data[i]]; - } - } - - i = sendto(tech_pvt->udp_socket, frame->data, frame->datalen, 0, - (struct sockaddr *) &tech_pvt->udpwrite, sizeof(tech_pvt->udpwrite)); - if (i < 0) { - return i; - } - if (globals.debug > 4) { - if (option_verbose > 4) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++WRITE %s %d\n",self->name, i); - } - } - - - } else { - ast_log(LOG_NOTICE, "Invalid frame type %d sent\n", frame->frametype); - } - } - - return res; -} - -/*--- tech_write_video: Write a video frame to my channel ---*/ -static int tech_write_video(struct ast_channel *self, struct ast_frame *frame) -{ - private_object *tech_pvt; - int res = 0; - - tech_pvt = self->tech_pvt; - return res; -} - -/*--- tech_exception: Read an exception audio frame from my channel ---*/ -static struct ast_frame *tech_exception(struct ast_channel *self) -{ - private_object *tech_pvt; - struct ast_frame *new_frame = NULL; - - tech_pvt = self->tech_pvt; - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++EXCEPT %s\n",self->name); - } - } - return new_frame; -} - -/*--- tech_indicate: Indicaate a condition to my channel ---*/ -#ifdef USE_TECH_INDICATE -#ifdef AST14 -static int tech_indicate(struct ast_channel *self, int condition, const void *data, size_t datalen) -#else -static int tech_indicate(struct ast_channel *self, int condition) -#endif -{ - private_object *tech_pvt; - int res = -1; - - tech_pvt = self->tech_pvt; - if (!tech_pvt) { - return res; - } - - switch(condition) { - - case AST_CONTROL_RINGING: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: Ringing\n"); - } - if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { - ast_set_flag(tech_pvt, TFLAG_ACCEPT); - } - break; - case AST_CONTROL_BUSY: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: Busy\n"); - } - ast_copy_string(tech_pvt->ds, "BUSY", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=17; - ast_set_flag(tech_pvt, TFLAG_ABORT); - break; - case AST_CONTROL_CONGESTION: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: Congestion\n"); - } - ast_copy_string(tech_pvt->ds, "BUSY", sizeof(tech_pvt->ds)); - tech_pvt->pri_cause=17; - ast_set_flag(tech_pvt, TFLAG_ABORT); - break; - case AST_CONTROL_PROCEEDING: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: Proceeding\n"); - } - if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { - ast_set_flag(tech_pvt, TFLAG_ACCEPT); - } - break; - case AST_CONTROL_PROGRESS: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: Progress\n"); - } - if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { - ast_set_flag(tech_pvt, TFLAG_ACCEPT); - } - break; - case AST_CONTROL_HOLD: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: Hold\n"); - } - if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { - ast_set_flag(tech_pvt, TFLAG_ACCEPT); - } -#ifdef AST14 - ast_mutex_lock(&self->lock); - ast_moh_start(self, data, tech_pvt->mohinterpret); - ast_mutex_unlock(&self->lock); -#endif - break; - case AST_CONTROL_UNHOLD: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: UnHold\n"); - } - if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { - ast_set_flag(tech_pvt, TFLAG_ACCEPT); - } -#ifdef AST14 - ast_mutex_lock(&self->lock); - ast_moh_stop(self); - ast_mutex_unlock(&self->lock); -#endif - break; - case AST_CONTROL_VIDUPDATE: - if (globals.debug > 3) { - ast_log(LOG_NOTICE, "TECH INDICATE: Vidupdate\n"); - } - if (!ast_test_flag(tech_pvt,TFLAG_ACCEPTED)) { - ast_set_flag(tech_pvt, TFLAG_ACCEPT); - } - break; - case -1: - res = -1; - break; - default: - ast_log(LOG_NOTICE, "Don't know how to indicate condition %d\n", condition); - res = -1; - break; - } - - return res; -} -#endif - -/*--- tech_fixup: add any finishing touches to my channel if it is masqueraded---*/ -static int tech_fixup(struct ast_channel *oldchan, struct ast_channel *newchan) -{ - int res = 0; - private_object *tech_pvt; - - if ((tech_pvt = oldchan->tech_pvt)) { - ast_mutex_lock(&tech_pvt->iolock); - tech_pvt->owner = newchan; - ast_mutex_unlock(&tech_pvt->iolock); - } - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++FIXUP %s\n",oldchan->name); - } - } - return res; -} - -/*--- tech_send_html: Send html data on my channel ---*/ -static int tech_send_html(struct ast_channel *self, int subclass, const char *data, int datalen) -{ - private_object *tech_pvt; - int res = 0; - - tech_pvt = self->tech_pvt; - - - return res; -} - -/*--- tech_send_text: Send plain text data on my channel ---*/ -static int tech_send_text(struct ast_channel *self, const char *text) -{ - int res = 0; - - return res; -} - -/*--- tech_send_image: Send image data on my channel ---*/ -static int tech_send_image(struct ast_channel *self, struct ast_frame *frame) -{ - int res = 0; - - return res; -} - - -/*--- tech_setoption: set options on my channel ---*/ -static int tech_setoption(struct ast_channel *self, int option, void *data, int datalen) -{ - int res = 0; - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++SETOPT %s\n",self->name); - } - } - return res; - -} - -/*--- tech_queryoption: get options from my channel ---*/ -static int tech_queryoption(struct ast_channel *self, int option, void *data, int *datalen) -{ - int res = 0; - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++GETOPT %s\n",self->name); - } - } - return res; -} - -/*--- tech_bridged_channel: return a pointer to a channel that may be bridged to our channel. ---*/ -#if 0 -static struct ast_channel *tech_bridged_channel(struct ast_channel *self, struct ast_channel *bridge) -{ - struct ast_channel *chan = NULL; - - if (globals.debug > 1 && option_verbose > 1) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++BRIDGED %s\n",self->name); - } - return chan; -} -#endif - - -/*--- tech_transfer: Technology-specific code executed to peform a transfer. ---*/ -static int tech_transfer(struct ast_channel *self, const char *newdest) -{ - int res = -1; - - if (globals.debug > 1 && option_verbose > 1) { - if (option_verbose > 2) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++TRANSFER %s\n",self->name); - } - } - return res; -} - -/*--- tech_bridge: Technology-specific code executed to natively bridge 2 of our channels ---*/ -#if 0 -static enum ast_bridge_result tech_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) -{ - int res = -1; - - if (globals.debug > 1) { - ast_verbose(WOOMERA_DEBUG_PREFIX "+++BRIDGE %s\n",c0->name); - } - return res; -} -#endif - - -static int woomera_cli(int fd, int argc, char *argv[]) -{ - struct woomera_profile *profile; - char *profile_name="default"; - - if (argc > 2) { - - profile_name=argv[1]; - profile = ASTOBJ_CONTAINER_FIND(&woomera_profile_list, profile_name); - if (!profile) { - - if (strcmp(profile_name,"version") == 0) { - ast_cli(fd, "Woomera version %s : SMG Version %s \n", - WOOMERA_VERSION,smgversion); - return 0; - } - - ast_cli(fd, "Woomera: Invalid profile name %s\n", profile_name); - return 0; - } - - if (!strcmp(argv[2], "debug")) { - if (argc > 3) { - globals.debug = atoi(argv[3]); - } - ast_cli(fd, "Woomera debug=%d\n", globals.debug); - - - } else if (!strcmp(argv[2], "coding")) { - - switch (profile->coding) { - case AST_FORMAT_ALAW: - ast_cli(fd, " Woomera {%s} coding=ALAW\n",profile_name); - break; - case AST_FORMAT_ULAW: - ast_cli(fd, " Woomera {%s} coding=ULAW\n",profile_name); - break; - case AST_FORMAT_SLINEAR: - ast_cli(fd, " Woomera {%s} coding=PMC-16\n",profile_name); - break; - default: - ast_cli(fd, " Woomera {%s} invalid coding=%d {internal error}", - profile_name,profile->coding); - break; - - } - - } else if (!strcmp(argv[2], "call_status")) { - - ast_cli(fd, "Woomera {%s} calls=%d tcalls=%d (out=%d in=%d ok=%d end=%d abort=%d)\n", - profile->name, - profile->call_count, - profile->call_out+profile->call_in, - profile->call_out, - profile->call_in, - profile->call_ok, - profile->call_end, - profile->call_abort); - - } else if (!strcmp(argv[2], "version")) { - - ast_cli(fd, "Woomera version %s : SMG Version %s \n", - WOOMERA_VERSION,smgversion); - - } else if (!strcmp(argv[2], "panic")) { - if (argc > 3) { - globals.panic = atoi(argv[3]); - } - ast_cli(fd, "Woomera panic=%d \n", globals.panic); - - } else if (!strcmp(argv[2], "rxgain")) { - float gain; - if (argc > 3) { - if (sscanf(argv[3], "%f", &gain) != 1) { - ast_cli(fd, "Woomera Invalid rxgain: %s\n",argv[3]); - } else { - woomera_config_gain(profile,gain,1); - } - } - ast_cli(fd, "Woomera {%s} rxgain: %f\n",profile_name,profile->rxgain_val); - - } else if (!strcmp(argv[2], "txgain")) { - float gain; - if (argc > 3) { - if (sscanf(argv[3], "%f", &gain) != 1) { - ast_cli(fd, "Woomera Invalid txgain: %s\n",argv[3]); - } else { - woomera_config_gain(profile,gain,0); - } - } - ast_cli(fd, "Woomera {%s} txgain: %f\n",profile_name,profile->txgain_val); - - } else if (!strcmp(argv[2], "threads")) { - ast_cli(fd, "chan_woomera is using %s threads!\n", - globals.more_threads ? "more" : "less"); - - } else if (!strcmp(argv[2], "smgdebug")) { - if (argc > 2) { - int smgdebug; - if (sscanf(argv[3], "%d", &smgdebug) != 1) { - ast_cli(fd, "Woomera Invalid smgdebug level: %s\n",argv[3]); - } else { - - woomera_printf(NULL, profile->woomera_socket , "debug %d%s", - smgdebug, - WOOMERA_RECORD_SEPARATOR); - } - } - } else if (!strcmp(argv[2], "abort")) { - global_set_flag(TFLAG_ABORT); - } - - } else { - ast_cli(fd, "Usage: woomera

*H^>6302?i?}p9v71H!oW$r|K^RlemWo9AOVn8b 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

KE7_}Mzn)&WA$ zDoZ2}F#;wfxwx$AY}onHN)W{OH>A0!#J@Id7KnlNy6gnp8Ew&A@0a7p`MCMrz9>y) zrIHv`>ofy>#xsGQz;lofLR

L6_iG}BKj3zkxv2p}hLp+E8yTh*N0xo#gE1%o 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

lZODYj1l^D>E2_$soQ)gdQ* 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%0A7Tmu=_`OdMBsDotOhQ?4n4syM@H{)ZF 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%0DG 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

rfD^xCC~pQxf_@Ybrx3s^)SVJtdAG!UN?ZVF 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

2fLVtyv3tg~bT0Qz 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 X$EF+6B##we5+L9D&79vG9k2ff7UmPx literal 0 HcmV?d00001 diff --git a/util/wan_aftup/A104dm_0100_V33.BIN b/util/wan_aftup/A104dm_0100_V33.BIN deleted file mode 100644 index 9ef73a1e0bc9dac1154d2d89380c2b7ecd4243c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 402936 zcmdqK4}2WebuWHqc6K$AN7`9=O$5m1N>=dVC&<_miJ&sN5(0@lCs_w8P(EqAP#({I zKiY0n^0U*>>Pi-%5C@h&@dw@~&09!l2#?01<<|!x4P#_LG)`>FRRA7P5bgd z#<))Sx4-YXGqbyrCI7?Z_eqa5bM8Io+;h+UGk5OXGk3OBDwT%rf8+*-3`IoKj!G~- z*HISmJKuIxOpW&$FE|uKoa|7p;E=^}3ggNllj>CJBTW1C2RkT2qw(uslz%fN7z|3X z`rk~O2o&hyu&4c-X{BGsf~?wTQ_-rn{1&>k7+*zarUGJiE{^!8glS>DbMrZoxVng3 zwj;u9cf~F$#*rV#QIw;~aU%NXOIOh!)YHkv7s{9Qa5=czSMn(Y83le#un6sp@UMy4 z3z}IeN7K5kM5;|_bK6Y+^C(m7{;{hh}5o3O(q?+(PPq$w`66Uj0*ORigYJ8&gu~7DPIYXD{ zD1L!2_mP5m6eA=|g#1FSma`)Hi7*~wGo)J)T~8=RTug;dBN&9P1sEyB0_@f(ZAX}o zB1?C!5%;vUN?5LVSe}|N9xInu*N+?Xf_e(+Zam<-ft}je*{4w7ymtC5+C+lUeBd(? z{8Po8{Ir2hLb9@X?9q9+WxkG{j+4(y=E?6w>70B%kW8Fsx)sUJ+gK43IO5O66^_!< z3-ha#z29JTtymOfN{pi*lt)G&cv_&MuM%R#QEV;8b1O@qPO~)+h$>bHv8l)r%Zgyz)xyF^|EQGZj zBqFSZ=Q$mdzl9SVqa^uIVT83jDkq9(s`;Sn_%ZZ_;_n-YP=m%fBK&_Kpvw!*#ZbGx z6CkW{R1Z)q${*DaM;8R7TL}Dx7@$Ws%qLO|bw*f*LVk#+kCA66a!N?DUL3P< zl_pKEiof4rq;FP!Rb>-l21U@gzI+^vIesjV$6#8=;4zCQ6%q$O*C-qe5=V8q>UcFB zVjn!9>=L6lc@b!v>4KT;0PjqwZ7x^lPK-U z;z(~XOejO_hdAPg(f5UBl?R$Q&iWZgur~};=NrjIGV|eT`D%W)Ixwyb1k)JD@xWA+@F~ zaFQXtYH^fJi=ghTKnuAI)Obv%XX3T*+3G>x6!|n>rhVV35mXl(Mo|b ztsSYfunLm2Te=2<2+D(QN96GlkvNif+%yy-rRRC%rkw_t92c^;YpFVCnXVZRIb=bx zv7*3?uy!~Y)m#u}A;2ttK>F36t1G%HccUtNtRP?Ns3D9K;YA-|RBRQ9s_=;fy|PeM zpD5El$iQs7KggUG);;g|xv=R zYBzNZ`K=Fjy!Gare_eV{K0->B{ve(ja!bk5%)V4|sK!M0bz+rCrQy=>5V8Kvn@b%} zJ@xd{90v46HXS}(nu)>@{%>Qk*p=Drl^x0Kl`B>N4_%p^o@q!v^!OLv-L!rCrndm` zj%-J%G&~%oIa%C+)H;pgA>GQk0_V`5eX_caD=(IjvUq6T7K~MhFANS9AREYYn&7}K zlm@9;1o37~9~8@Ue2~75HvYQFI67FaBG36&^hEj#ZOi851+^Mjb}m4l&X08kN02Y) zvkm!2{Q1(()wNJOOsl|`jwHb=062Y6AR6Dd=0VXYFt;h|8LXPLGq21zUI4bJaJXY_ zstwh=02JB+yIDWWMfpUSlSScbdlpc4;$%rhmB>cE%M(v`5|W!+H)Kyl{GDJNDJ6Hb zn)~*Z9w{YhCV6L`mc(~E$>DsdzJ92`qcrq#{IVhWFug;E4wYs~Pw(0D7t|r{yfazX z)3ayK+Zd+e@zR~8($Do+kV-+KR66{zc%6yy>X9K@w~n((QAdn2r9(lM^N%^H4(edL ze`NgFWVxk|vvm8W7j=C5rj!>q4%3y{&t}2uiO1sa=OUR^J=|Bs65LKk+~;O7PE$nb z{%o02pqm2_UtkW*Trzy&ujPOg(c>u6)H0pEiK`jU$U(itKtJf= zV+>V8sGsFC>s_*9z8Js0T3~kA(ihQ0t)*YRu0=k~k7+vyk0oSqT*Y*`ICxq>VG(T_ zBVtoiuy}P^l!i*6TU%`i4up2=QUvk2XJ07xOu?%=o5OT6Y$QX1Tm7!{ebVr1P6)| zr&o7{x=rAI5G>cnnL&t3T^c)~fVNVM5rc2UXfXx((B6PH*UIHAyBNnVZW6Uz>|!}3 z>3KY+8)h+R5vHAXsQ7MAw`!9o5Eh>Th|V(#v=j4 zD>=agQgCLl7S+uL=Wxsm22FRFXp07s^D+)?JpUHDSdAO^+A_VyRxLYe%ouMzH|Ab` z@3rW$52J0T>(aNayD4E!)5z;PJ=ssxX^7S0mRS4Bl#$0cwHg_vg}uxDHc16$^K%Q=AzwWV4o$mqG3AyiwMtG-`s3nN_vYumxw@!E>@%KzAU)c?5*Kau zT3Qrp4w9YnIg3$M_qkKnaO{Kv?SY}gXtT<4mzP6F1!QfJ=yD4^y=bMI$b~NigtkEp zGj`f?8&w+`qObK~vYs*Qz9u@$bqj4G?OGU9WFPv~h%#@<3Y%QjCeZQQdW~#9G+t}C zwmsq&6b6GcFw#hyUDZ|}a=c)th>#AjNdCmVOJ3&tUK>D#}SD=;st;^)A)9^ApVb}PcY_!J( z`g9^`eIM=O$tz>HWuRd8O>*VbPp=!{#JeOG3fL5%5*Sor7qz0(1g*69%hk5&5gjvt zW;<8NZZ+h$@BC+@`L-6bxmDG*-1d*SiESNh?sZqKy@zjTeqL55KBcg34U)J8QY_CJ zxV}y^@Tv%IrXl;jJpeTdHE#ht!|COI}~}y;R)JWc-)XWL|A_KXsiVbo}`vwT48u3(9W*wks)D=)Y&3^fxXoR@)6XF%vVC8i5Q~b8Hxl{3J70ej2NOt z7?{-w!KLv=1&KCg3P_SbK~0kcCq-O>g^8p30F2q7pDLgjjt$0DZ386Z2ZF=)Srqx5HVzUw+HQ$!{n zEt?>bXCI_4cup%qm~)ei$-77+J_%5vLu4si)I_1rapvF@KwUe1WPKLUjS z9{>Y~uAjLSWQUMp5*7mWS)gQ_Y-6 zVF4hIYt7}BWv?v|1De^z?Sg~jb6KVwY4q>HEF|W zL5^-)i}QnzPA8wJRrnjg@)>^fAfO=+5t8kJ9`Kv0k5Fh$H$Ac;psmKHpJ zm;-|2$Q>B}eEn#UoC4#S(Dnv2NMZ6E7OyR!;cOvCJWWZKgbD#7$3fS) z$YU)eIUYa-W7s_gMD;UE#FFUgvnXsefQ^Y@A_|l-h9sSren3}{HUoJb$22QSAI720 zN(G5A&n;_-`j3Pzbfz*`O7TlUIH8;h+7J>PVekSZ7!`FTs7hLkAZr8?Tt{R?kE$+b zg2XCf23SIRf(0$U=7W@|5f_!p@<&xNNH75M)sTaANUu}Cg4v(~MP(w}&&T}07VwdY z*rOa{(B=d|K8s551VT`9atXA~qsmgzp+n_p6qBen+;Itj@hAk=5*8vX18#T`Gq^qJ zdr+CgWz_=cV^yUFiDLn!ngfc6?t{SXmtE@mFXlA#?*#v1^eTX)0{#SX^r9DGK!y7h~N_+b0>F@TJ-YAuxD(x9AQ4Bo%?cYB< z%o^T(m-SY|-+$>}fA3#^@9)19(GD7Km}l43oxN#$Dz<6+a$}(Xrv8Ec#V-4Pw{J35 zrIP)yw`2E;(x?8BEr`mMocWP4lQh=df5Slk?ha!S)9=4wX>`wu#5Cr-DuiH*StWit zLsi*_K3~-q-QSPSN2T#N*9m^;FD`V#KZ`?8v3QzQKAHnL#F_s|b>kB_CMx`D*&xim z-hdzYj)QRE$DQckM(l59+xUp|MRE4~M!sfF$6@v%NBLFr0vcEhy3CM^aG9pLvrd7( zJ0$r>jT*CLPdOqQ%SqX9%EyU-!o{yTA&-Nh&>857e5_2X4(qteedkju_hfjWZH^C- z{%Xm{&bgRn*bf}}f(ys0vZ`|9iK<#X+Gb9CHn$SzWDF;>-InT^r*P3z>Q?fllti+DIWL@!LHVox46;)68v7^mm*+<*U-*=rtp zkuYwpyXGNdRmbju{%amuC74$Yk$g4n0|* zX|eXnPOZ;fq~q%$z`C?PDKHO&G8L0?#w z0L|Cnp@U>8w1ou|9d2D8c`5C?>Mg9y&4Oc)ID zT^yaK{3@WgGCFApd(ZLH@oZg#uBaknQ{?+h(I*bf2UClEtmM|vgDCQam zT6tl>bQKrcO!%hXzw1&g<_dN#k{KgWDW@OTmtjAY$9;5j3xQr_dTADc2o&@hF2@#g z@*>*=4=~P`(#`?@`5%JdE8_*4+<9p7hm)h6%hdXjpD3c`;`vx?)TZ_IH2F+ZHf|yj z%n%dM->=AR8YMj3FiHQ%X?g$h=P;)>YsfLq!>SvD5>tZ1E6RdNI7W#S5T8H==%;2=p9#{6<^vygxJH?iD~C>F zKycO1kW_{(l(vmeGYjQ#4l__Um<21FE7GRVFJ(d!Nd$_e4Af(V@NO)cl?e{r-lpWQKqj2I~v}|q08b0yMt2VsV}X*nXk1Qm1{R%yv`o$ z-UdI|Xl!Gxe89{JXrKh2f=*8Hdub^d?B{9ZnR9mIVb{HNr+3G|n=8}B7rdHhYct4m z)#cCrftUW)!A3i6+K+wt4RY>1n2P1!3K~Oeql?Kpm``ktV=1%+>k*r6%`_glczs}Nq$7X8EmJAk|T0((41BE@Y7D4p2rQ4TI$ziq2swCzmN z?>bLW*V=DBK;w%hJMZ0nS)*?Xr%qt^lofQ&1{MEH|1Z~VRPorjOP{vwnrWjY_NO*x zqFuDpN<%ZX;)um^(%oz2(E8mggEsNdnfMVSEpmLeiTD(*jRGv@)93rO~j502z(rCf#{&@*;l<+ zZ=yCzn}#JND3}nLSQln3M7N}B=~5Sq^o4#_MO&@DwCc}DB56*&lvW^NFo}s6#wN2r|* zk@x&$)g|=H{70HcXfBLLDYAb(Tp2SZk#&@r~`GV_cy#4ugMq}ZgHA{ZO53Y39 zGk&d7yP7we_9R-&?K(p!lx=Fkdf+4<7=&giodNfajEVX#ER-L38NxSp+Zm%7sh&Q4 zhQclU+eTM<1r4g}VjkUkvSgfy14&jy43^3{X1PJ4SHs1qq-f-Ndu_H+YJwo zMlL;n0PXlYdG)`HEx3|G*gJl6&_8N%iCN0b)GBc7IN357yYyP3tg)$G#UQF}!iBaD zCVu!A4gR(NzWL6dx{e(6micc#F^;>FL;vD#?}HD`U({tvcvqBpJEvo4tlyiVPd(t) zxK=yud8vTQ^89WRcL&^4J>#B<;sL7HMgwJJc#w}Qo zZ)tPWrs%Uo;~@15Sb*_D&%a2Jg$u(jG*Q2j@PELJLDQ8U#vW$<9t!_KGhH&s8uo0~d=i3U%YGNa?CjA}El*U7%)} zjt!waA4PhP&w#SLASy1!W=+&+Ju~ZTp}|Ft-Bg&MHMn{Z#o&`?FK(XrnSg37e$!cp zy?V*w_CzsAj)s6|7BcKg%&cifS1;lgL=$z6dp`1?0ROL|Re-2IYV~zmL?YP1FF^sp z=9_q2h0AbL?c=i9exkG9v+LYT61jV_~ zEZ^|BoGb$t-dFw{@tSP|HRP$_DO8tOpJxU-Bey)>3PRBt9Cu>ytK@ZA%g9s>nFgb9 z37O~If?nB%uZ)vuLIYy>5J-l`A)^3CY~U+YUe<6|-plfm+1A2%Fj4OyidO3~56N?EP7)SwJVUa$8%3(k}m^KB&Lsc1qQ3LHF0y$2}?NnV( zrUe;rpaMdGgJB7?6B$wi%}mlTYfJ%!hhYY-F$nTmQ{77Z1VW*-fN1c%8K$W&+H5s4 zi0Zc1J!&?)QsAOyl$&U_m?xvS(gDSNlR@Zn`BXqi;V5u(RP`&4F(^K1UWh}xm>e+m zod^-PsFf?>(ik%Xm|&z(lad1!kTMFJo(|zk1okilhJfe#*)*GbfZiR7609DMW^n^gXe0^}5{~w`LGT?`e>)Up+G<3MMp`+|E ziOd>G1-{&BKLNt8l}dWwE%y1oS9<3i?1W=DatJQkMad38i7H-^WKz3(OQqz74diwl z+L!7`Zmx-!_NCxod1&)f*uK{D)>~h}Hn~Hk4f|o!;bd&{=BJ(-+EB?`>o4stbtK_K z8QxGA#7pp~oPBnWw;~?JBfB}y;fVf&KMH)pdv?^&+4TC4RvB;q*Hp(63r5`;H-`Fe zxIg6$J@jt<*>&+)_oT6CvU{L^)Akju_uu~`gX?J_Xf2g?ckG_!`&~%%1nE3d1fxX( zzT3!eJIj|D`f_K{bebq_fHmI>e6)k=M)(eIeDYHhfBfYB$8mK2ae@89kuSJ{c|O8E zW26hy;tgMIM_^ar)73KC?_9}qqpw=!lxk((Am&ezuQw_<#~C7elmFHD>q@6n^&XqrzIG#lAs;<)Ma1y09wKIXHNY1K!RPgK?jvpqTt ztZid_0#Hs9$@)>?{p0aR>M@uMmla_U(&G^mqH$o;_T)@iK+}6L>hQSrPH9i9baS+`Rc?tnbPzuZ;1iI5fn*VjdeGc?4;Y z_dskW$&jo%&*sfNGs%>G?xak&-`4i zfVP%>xt5-zV#=*oHCZpGGiVPflQ0L6~l3M0%0a8%}~peE7ERzKd7yjJCV)VgbWSjA$%Or7`ht z5(X9JuVXl|@76VJihQx_v|VEcW83IIP?pnnMloO!gm;GYUY!o(7?TaXr%2;eAVz^+ zqIFykfV=cP>RW*?3c8p1! zfNFd@_Mq}7B|S^i(+74T~4jB@j4?>I zuokivPFSSJ!mBh`js$YEB(6zY%3jMb4J>rP!Hg9)t=n)-w4=1*#TLD#2od-K7%Wwk zWXdrMW(w$F8g#Kv#*u!G0fY(H@7zU!fOQIIE;NrQ8U|JV30fxeh?wm-IlRILb5zhc zSdKF=vd)++jD$HQ$a2)q9LH(u0qOV$w_ss#s!t;Re2gEMA5YU8Cfx$*IvmPS;FxFJ zcP%~o@m6cwa-n3y-oDTM8Fgp5o5`N4L2!+rR{Eq_Q>FPVPKZb%>{8kYBq z1`BPLMc5C_-AV4SELS$JhG9>5bs+fA7XaVl7*_IPriv@OooZ+9u=9^P=l$}PbxVHt z(ashB+?9|b;jTEiB|C16JG)v2of@mX#hQ6T(ls59wKJEwCq5_=2R*H6z7sO(`|;cJ zaZZ6If;6}?8AOe4A8zoj3{Geh)G-3+w3#B;seWaaC2;^o6&C)`Eyv>6)nN}po@Bz7 zEd!`P$&I;)4D$8WAYQh7@_ojRM+cbvca0fN6_t$0(?APZfF zKK%^745**#WiZ;9=s!QJlW`w>!_6-7S2wu-K#AL?k&p2>X0BaR;OLKaFh*Q=AYM!k z;x}cW3HwwoUUJ(3?t5MIT-H7JS!1=C$aac7Q+$3HcV zPa<9#Xjtg{{41<40vQEP5o0h3QpU&o(lvRc?&g9o_I3J>jg)9hUP;#Pq}&^>JP9|JB_R~F^kG=C3C@slL)fw_a*3Msstq0f8@i^f*)?FC~g z2e4(*B~w}SAdRe+GH-#M!W!vxi^RBQG+VY0xq8@hyO&YuYvYvBqZ=na3OtGl)d-hH z1)^*#loJm5T(Kx>kiZy(Z8iPnu?+oAKFnhV=Z1O-0$w0YDBY+U5s0nW_CJk!)}&r} zjA;5^$F?U_VlT?s(AAvVYwNL_rWMKm=s;(uYOlkv{_vlVj@QsPTI@HMPwy;z=eg%- zMN^L2G2gQ@)6jaU4W}=zME46#lz3EH0@qn0gA=jC4^GH8$x_suwIso(^;xp>FtuBk zN3nngPsibI)Rlx0j`kWVW^cXn_RF*NegAE;i)wb>3?Be}ciD7~#`ieRy6H3BvD+|~ zUfHbJo9DbTn8+M>ENIkF>m0=G?F>A#Y7Y4nqZW@(IT@v{$zpn*WjvcK(7g0{3PgVwA>I?3teMap6mt_z_i5$A8$;^gL&J2 z=5kE?X>pTzx4P`^E83IzZiQ8_egCD@xt#WIU&0kMKX4|-3S8?IC{}{=gj~>EsMEs? zuaaVPVH%Us)itD2Da=TC(>31s#go^%CNxIDcJFIvy7=8x%dM1c6&{=o z<3iakZUYcD$n*?s!%fxN*FgJPDY3fS((9%g-9ckjTY+R-%DtQ1)o@eU{k3bey|#CC zlU)$*YDG=GmWw*;he7BCt{yyXYLi(uP8OOeg)-Z=)k2aQrD1=WeV_2;)(UDruT7=d z_Hn)o_Tw;}wXP`y%(QiSu=+(tW`xABXtZT0vvy2a$`Vpws$^NhmYLCvrP}SbZ6r_> z>TeOE4U5Rs)g>%jj9a$d4~IO!w)KW0fgm3Ys7u>K{%B965KKA>cvR!9zv!_1yjqWP z)>3mfW0V*U+q^|xE^0iBL75!80O#j~>!l$@?q}hq<(%E_i7nLheQzTx$$uA{{;AW> zdRQdq8^7Jen()^wYMnLQv<{mgn0xWWqg`w2ZD#@m_i@)d4)H(x}pjrDaNbfs5% zwRi>F{;czPfgMNf)!sS$IqWg1BW zB5;8t)nFLtQy^d-QXz+Twt$eblVx7YKxZ@>92I;M=jLlxL)@k3%7wEJ~_rl4A(gb##5fCME_)cL>*i4hmI zStS;67sA249v*yTHpuA&#tN+U;L4PO;|x(^Q+J2+h@?X35F#$C zgHouCw4lrlnhFL0;u?B&K3oa~2^-B=4WJ7Z5X!#pipFZmN;tFuSqoXAa)_g4bAo^Z zDF7W0(?+z}xSVu0xe`-h&?w_5#QCZ)Z>1ZW%NuZ`R6(5t7g#H6(2Nm%`ACj4=;qex zin^y*Ol(2-OxbslKyBe*JIkHHD__e6kXfnH6(KkR3*wa;(TOai4rYF+}Q$ z^#XlbG&rfg%5Tz?Tah%a;&6-KcV zJn7I4Hw-<}0k7r#_uuo}Z@=){F9iE#fAB}uzJ>t+D<1xXJ$lk#;lU-st_#5MZ*(L} z18Q%Nb4_=t^(o+@1^ryp7AY2U-}Z;9zWG4CCCP~Z;PyqN@c)e+JH4j$T& z?D%N1BY91amIY};X*juvdGMiZ)|gNDL~3c+_b)76SSIQ0*p1^PSCo!`4@h

  • N{l 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

    K04}B}teL>ig@MB*BhH?!lO^=HD!uW|yZ{vR z6v`}N&^M)CEbz%vTHkgt4AK5QBSzo{0HN&(Ua^efUHlj(c&?#f0fJeOo5gwmjHap; zyPN;>t9jgVn6yOdyFt9~V2-%F3fhuS{Hy`( zGuF9wuB-N|9WST+*ovKJy)|y!mcxnCZ}ort=l$8y3$N#rHPRHB@@T(ZCx&YMl+~^- z#WE8XJ;`5*pk#_}8eQP7Z%T|c(-c2hdO}W8^C7g)SC3+K?vT+eZFl2>&EAF` z59W}fn-_)wFrjy9;8TK{=H@K}S8F9EG4q`@)s?>k=kMf+k)Farw@bn`;F%|=I~;C(j42kQe5^wI=}k&B8QU!jpnZsFl$Q-huF(pCa$m*<_G!g}~v z=!379p?zCom#Ar8;}x(Qgol8{x00=DfoVnPO;f!wo{yy%#@?x3yU`SQs)U-L>eYJv zgwOD{cnnSc3>GP6HcrDeXtUw8T-Rf$q$Ir2l7mixXD80U%0APR$EBnf(|%hL4I9HC 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

    (V7jeGvSu>!L^}QGqlcfv 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 literal 0 HcmV?d00001 diff --git a/util/wan_aftup/A108dm_0100_V33.BIN b/util/wan_aftup/A108dm_0100_V33.BIN deleted file mode 100644 index 10fb6bf98a0d6399927a64b56ab2a3d35a07e9a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 402936 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 z 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∋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%0Aly%X7L3}eKs#E-_tBjZ$NAjj7>+hW);aoW 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 I-SP4IUvDRX1ONa4 diff --git a/util/wan_aftup/A140_0100_V02.BIN b/util/wan_aftup/A140_0100_V02.BIN new file mode 100644 index 0000000000000000000000000000000000000000..0b719538a72286ec6cf908be98276c9d02c0fd46 GIT binary patch literal 402936 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 KVtk`h#{UQU!44t- literal 0 HcmV?d00001 diff --git a/util/wan_aftup/A140_0100_V03.BIN b/util/wan_aftup/A140_0100_V03.BIN new file mode 100644 index 0000000000000000000000000000000000000000..7dd6cd86b205276b94bc53556cb31a834e4e16d3 GIT binary patch literal 402936 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

    ?oQ?8Qn-YqO_-KTR!WD#JSz9?) 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᲌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 diff --git a/util/wan_aftup/A301_0040_V07.BIN b/util/wan_aftup/A301_0040_V07.BIN new file mode 100644 index 0000000000000000000000000000000000000000..058c70264b2a35198a98e5366b5a032ccef7a93d GIT binary patch literal 212392 zcmd444V)asbuW6lr)Rcj=-us=Hp(JaqIOuLfhUs|EAS#Ks8%f2n#lGju(9liy0X|2!RMQ*i+#Vw=#{3y!YS@YGC9%4Ke6|~7&bN^dRnth% zJc?3Grc3e-eN*n!}=H{T~;KDC-#i$Cbq7+$cxi{Gv>@h+_V9aS!*yrNN2D ztkWm7a*V0R@MJAvBQ95@@61H{v3w~Un{Ud;i=`UZ%M?jt{!DR`@ixptZQ@Uw#){+H zB-NrbEmxc_w%e3X*wQ8>Vl|Uz#5<>ro6NLf#G>}&1WrsWfLqH&r&-R}Y*RjAEY&zy zn#>dvl9)ezd?;b1Et!!J-?l4tp}~hQ+@X1ci9&E3Z)vnOrUor9ygDXzNr%Zgsj`(z>ZwH)wveMM_#$qD0D5JSJze&GC znS4w-MYhihll}swB|09JFVaiRM(O>i9#OmrQl4 zi810V63L`il1V0w=t;5!lZt}`sEDp7kBC-2R;$YsHtM9^Vm{_i7t6ZEwuFkLX>-$P zr){f>2C=85vXkYrWTe;*A#Ezsp5n6&K2B?cX0RfRSSuM%Qt9|8ka4=CFrxP|j?IA7 zJa7pI%k`K;dd)*5a4^K_iiSPyP>*P&DsalN2rt7*oURn<#<(2u+8)ZS<-kpRq*F(U zde>zUAzB43@-P_>J0h|rSq{1y@q+nffMk6f8iR~+oV1mXA)`qMOKK@AwSJSRAM>6H>h6j zIKCXon^0?cEjhn0`FyvelF8yMjC2K=E2TwJEBT78S_)F%lm@(2zvWt?l_08HiPBlz zi?&*=AXq$C>jAchKe7_`SfJTiRUqzc)GyA`(}qG8=1DK=9EPJRg2qfFk&4 z4Mqr2VE7UhbM#vrqai?;bIH?bJX!_T%8}2kx6*SZPLx6bm#@onEt`ZogPYU0^d=LZ zC0!op>KC7j8o?Q4DbWUak{OT=dcK!i&D?5G;yNSjb9sHRTJ`Ed)5WFnita{eW&9Gk zK9?uRZSXiVzxc22T5WKc%>Z0opr}V1(IO!_CW9#wh=@OJtgW;LrfIa)mW%`%Fv5(; z(qTOiEqpzqPRKfCh*rKH9oM5SXeOd_(kzU*D6(FdSow5uY_AE|twvIzNPtwp8d~Ec zv59OOiWX@rUyqK6_np^gG}AA3weHrhI67Q^IcE)^wl9^^>4Vxk&hOby z-9wKKy;wUovuD&>bE3yvvu)d7TJ**nRD0nabmQH3-)Qn$xV#J1qapW7zQ8OW`9m9W z^k)at9}b2XC*vEmhiR}MEbGQ;4%lO2tr#OuG-QYuYa_jWZF7w7%@f^gGmekg4io_g z>&|a*o(`+>CXV9C%MPQKD;xq5MP98Oss$ozj;pgDcQx%`+%pjLsNBs;W#e_SK!18SbN;U?}Kz zAAR)UhieyKTpOx&*AA*7v9gCIe)`iFYHrT!j*af=c=TY89)%{|PiwVPY-6Zr&&#+) zKQ;c+Yj1q{g%3^Cwr>bhsflN9`b2FH$Jbu2JzA@!Qa}A^?cr;wHsMiiUv1o{6DMjf zyz=Tx8y=>E#_EajJ>3A#kCQQe<&|{ZZ^-;|fZLpXb(53+)$Q~{L4V6~MRei(cn2qk zFRqTQ$U&cFeo*sLI0}493eo^3#z?^W9uEd96zcCH{4d<$kl%KrsY8o%wq3^#h4bZx z+`&)bqvx3X_y(AHp`)YxV7GFtp?`Xm!lErK!1dNwUnJBGC;`$UM*#uP11tyt!c5PW zsH^k{mMeEeDByz6Vbac|<`wFX7)v?^yS^IGdfdnwB-(@9{0;$R2|j%q4zb))QGSAc zq z#d1GrK&X?<(h($k7gf1l^f)kgJj-}xR+1}L{&%7d>PV&LI?yjT680Y_l}37iNWoco zB&8(hpC9G)lv?>Ln6m&@x}6bo&P>=Y9x}-{x`NylRYi_AA_WQ$5SGv_#k6S-SE1^# zW~0`MXqsa%+(M^9YD!USjz7wmT4Ojp%*{5u(SiQ&~&vtV1vdn&nC;z{nySA`Y<@uXYWlKSnK@XAY%b*0QY#_I@@b>5X z=xU_9_3;umMxX+=pP>>IpBRNS0bsz?9FW4(qZc!FL@?0k^1JnJ#6{$-8vO z8eU7`utn8tGD;|U_g6|feTea}O>pB%@HU;Y#w?nnkraK}M(*^lBf;k}Yto1;m!>YT zsn^0Cldv%yx?Hi9g9Wtqe~|LI z|6@#eJFiYrsNNR1Pg-L1-6XBsiG<6`T5c^N9HJ`H(>-Xt3b|wKq`1N9v+hD0J#f$4 zw>oh4PxF9L_J~yopqYTX67*@1i}aJ_SXnVTht6yTG>WnPeWJB8r=?R+!L&&#LTMf@TUGyU98TrJwAeu3X;v zd^k>Ob+{`}m0`LV{fH;E%P}8KRfxX+SG^q_eHL}B>V4N7imY-a)!~=v2bRAwRV13p zvI8XnB0(>k49M4KvNeHmw=_)37KNw{eMvpS!fYs4^!Yn3mM9m_BK(ii8M$L5$onJk z*jczP1n|D$AX!9fFxdW`MYs?#ID#U{io|Toivs)y=poR79#66|5F{l0W0ip(cobJm ziUAU1w1J=qt)dkEDCH~M));QSxgUZV#9`Di2tK4lmsFq_U=e@DuVf@GVL%>tZ$1*> zM_05?uTx7usKYL=E6aDF^l5Un+%+z=40ZPPvuo?}veu(3J(7Nz8&(EyXA#Qp`$4Hf zejv&`B~&&Eh~3T-1-J;)hyI`oaYXNRp;>~~UX;2bk%=$U$P$h-`lT|Z0}85CeTY_| zcVvRV)CI=x@~uD&J6=V& z{j;0pm6&FZBPLg-ORfxPkTze8`q6bbM!3TuFAk!90t3jKC0Yv19^;q>+X|{7kPR|P zMV3*-dB9_$Nhp}pfet0JeD+P-GlpDhjPC4EAQ4;AIS7P^351RXg*u@kIx%Qrvn0yR zVp`YPM!e7r<7z}Lfa038Mz_jUtHL~97Y5R}bO{A`PG&VLBB6>fkz!KdP^JxRrorG} zm|NJWIUynep|VhA#pzgL%z~)k04U`cEEsX8h#-nLToc10q2;~~+Xq2Hj1p)l#4=R< z-7y{Ec#2sJ3+NV1-a_k5S$Y=?g#(C@af6Dec*e4+ABK-Et?$AJ{^tSDA?N&Y9@675e$*Mj#(xWa^{!nYg(r@VBf@+q1w>+)!kc|9(oi$#_plIZ?Ze} z(m2aseRaq9mfFvLHng(4!;N;aD|j|q?J=LvpQv4J?dYl9v~M5toStzK_PlIS?L#Z6 zHuKCxXRY>3ZRSt@1pDkUjlTLP@MeCG)1+yo+UHUpW~2E|DM7H1ckggUe*f)tq|SoQ!($vJ-Hd z7-fwkpJA(yu>u_}i{eki{IXQpehfTXVxIkwZyLhWw_tjvcDvVVFa62Guc8BYyWMWw zUvs%{ezW$@S8ESnQ0so?nc6cG6X(}nfBl3`#<|6Man3RSXl}f=WlK%p^~P~Y{K-#_ zkJlzXc{9s4Y$?@#_7 z$HxLG%;cvU^IROIG2|CA0X@lB>FX?0%@7K@6B6VnacF&noR8303JHwmm7pJL;@>Hl z6vzlZ$wNW`7jPd2oS4c(Ehl$G%Q58(L<1BDx+Y9CKrzX3!9;Zb4f~o)1WJH`+~fzE zd0c2rK9WY*=Lnx?q!(Xfw9;E1gvg;I#QNSQm3mw^hniH%to1@VB1sW_ z(#GwjdKcdqrzpiq8P_|I;Z0H+RihM2W}t`vd9dyNye)sgjUxX05u#D;Z)EqSRzGqW zl+yGZ!hctAI5!_&5C=Ely*g`^QfMG1Ep%u;gE(aa4jv^7S?V|}SM1{eC^$M8$Dr6z zq9qQ}3+{5z)2gwG#$ighG%f5gf?g{q2&y<3&rb^BvZ1tW&1S`3sz%!|enNH%PDS-k zW|_fiB^(*DB+j?W{A{e6FA)7ORW{2hU1-)yK#A$yUH1Ql1n1}qNtU#NEYd13>u9xhu90kP|{&jQ07wH+&y&|dI8!FUc09Fi0QDY|N9SJing_=GJ@_ngLDEv z|0wRBW28#;+L$$QJ0owEjDJ%QFphdxHlh5VgX{3FMrM!XNS>?6Uw?^|$|Y++ko**{ zk0tB0>Gv!q%kRD2rl-Yv&9w`9pS1h~&Kxg_;5;&}VvuR)9Q?K+(03k(+`yaZC$Wvw z!@RD?3iXlHMhZjnAIy^6Z`B*c{XF``Ef#*jkHEcsD4+t&sr&5yFP4b*AL0#2T&{Q{QaclGp{%T6{2usRQKk#* zE`{oTKh5RQAVPHE@Bi5D<0&Nk#w305Bebz&>nV1^ECPPl6FbQND%x`a=yGl*I&v;t z3ng?p>jtCd_IU>|a%6TDngoq>ys|*@H!s$+gFuKbuYm>31El0(fInM0g&Bcu1kNO! zYVgwt>2H-gD9`KMqV3F#ZM`_S*tZ1=?Mxv(pGdzKCIDzSFdRV6UVIoI#Zcq1;ug9 z`F^onrVqh>7OI__*8C|k$^Jq5RUE}xHx2)$J4k6!dIa9OY}vnp^MEJQMZsp_wB@~m zn~=NLpX|gMa2^r>wLo`&1)*k8QZLYRi?^8uAQfHb!Ti%d} z^f=GDJyGNlm9x;SfC1_VMmiLJ0ure9BqZz6@2tS00n`z8(IP&H9ttk|89Gf7{$n4q zB6lP1b#8GE<5=50Q%aX_@O8f!;oWwy0` zZL*A05luD7)1kzC<$5-^w!|&b2cwqqk%|uk0?4FeDgyj67?V-MH`vpp#A)iEk^1+r zeXBOH{pd?CbyH1kr+u}w)%{GT?!N5eI3uG`qB#8#-mmpsZGy!ttL@qI{x@T{Iqm#j z+#G-UTm}BYN-y`;_~2X4=(bb)Do@{LBSkz4;Q!QqNREL_`ym@zZ;Fy< z3dmeRnK*q=oFw6sltN3`*T^^aXKfPDRynWJfRGo%{I>wu&mKM}ykIU~%;AQUy@aFM z;kaO;1#C5o!w?S7hG=C+uhEpz75XYHzt3p^NUIE#XeT%$edUO5K z$7&*JK?p~YhA1<``~rrz??R!vsO0@7?k>AeIr8d{5Z!hEp|e+1eG3=)#9_61ADRSv zT7H2ca842(cIZzD`xmXb=fyXDQYu?Idqtizrg+Toy@dKPh~e0&VdCCgDBoQ2`Kb%H zhG}_DZ$^YOHl7H@3U<<>`$){!Jbg(ta?md@r?OXE;!qfva7N-dTaX-}XT@e0SO2b& z;Sc}*Z({x{O6!r25QUk&XT^BK2)k4y`^hPsgH-NrME&AXuH##D+ckbys!VF_kLSF@ z=;WCdk$dfIl()i0_*@qB^02De6&#)=s4i(oMjFBrpj;(w0r!_A3#(IXzY$ara5hRf zeQXu2!Ehc5a;5u!zYzx>*L$zYsgnt^!5!{Qc3NIx&z@nE*cfrv|>$&!D-p-oqG`9T#w0{v= z2JVG-l&MO@pBX}rf zQ)dH(GBIc!bUyfTQDQiAJq4{U7IQnAlc_b&G*HVPawcvu-yTnWUq(ONthvot9txV?7ZQ zi(}JcLJK{WQwV`JW}@EIOt2t^I3mWed~uBaWFT%{5eqn{22+=w9#K6#^}6<+b=~~5 z&A%(Wj;)l*4Bx2zKO?o;8@1;~zuWtUwI|QMl%erQ`A$v)_LOzsc=wk+8uQD?_?6^L z;B5N(mYILU*BB*;_C0DjX#HGvvRqO8GR-&CWW6IcWJ^$$C6ZL?SBoVKopy9QR-%Nw zr!wAG8PToJUY~XroIss^s+H)Yi>0c)R(m-aANvQBvNNG;doFl5nXdN67J9Yzl_8eB zmg*jVDQ(72taIbtZ!B8QSnup$er8%MVhVe2#2v_aRK{H`x>>Ia)|^B*l8ADK+m2Gw>4zHN#VOlk@fjeImZnzQ}5VnHDQ_*%&+-?EO1kID_-& z)7+xIa{Vjl()(Ucx1@9*?h>VJBrAOt0_(>lH%`H?^y6}Xa-lkvreT8vK0 z-kJsbiFG6n zb4Dx|KVQ*Binq|QyDvbD67UlWM@jex(U%>PD+ai2JVkyEzQWN-cndAhp0ZFc547t_ z*mMh)oy7=X%fRe)=6b_uM2sLtD$7?2R~JM~^Y9S3z|dBq&>-YYS<-d}$ik0mtYPP| z#TH7!l-1li8XqLImj@y0v!tdjC$#h&fughj(WC1FM^N#~?50^`09Tq>ZU^jN&5{e3 zn)}^O?U;lx+d0-b3kM}!k#KoIx*m#-@Iz}LRv+o80bPkZey=%Z-!|elaDZT(yq+l~z!t>mI{(Tg!<()#ZbFhywyBn`{ zbYU}kc_cTHhN32hp$u2&R_vz?ut}Y(<|6O|g&n47iLyJ4_g`>c=wr~pPhUCCLcbJ) zw9vq+s=9-&i5He1hal4reHZBnPu)aeA; zR+zM?Q(tvDHs)2G6N|;~3J~22ZOk-@4AV$hk8JJZY#3@$d?NwNmj&E~)x0*DpY+&Y zvIhi?yzcSwAv{`bFt!^WeR-VlCdYJo^X7x&M~99M9UTAYM~@EGYB%0}>{#s>r%75H z8b9y6q3%8Tr0m*j_l(|n_gB7>)MYxK-;`9-boUp}Ij1(U;iWj@*M9A?%U*RRimcDT za?YFSV=3cH!F%zve+Jnd4Q1UOAX3PK!f7W3Ar@$ztTo zG|MAwlusj+EoE$zbTMC|YMn1t>1*#%^4mDR(ZKqb$2TG9 z@2zxfGxkj;%`8QSODPcT86VPaqT0Sw!4P$C8=`&ueDyv~$^8_(H1v&kr&33ceiZP* z4<2m$?DL~NL;8J;tk1ydxu0Kq?YebFLUiMeH{MNn<3Y^FxVGo&W3`Eg57c?2ef8CS z{N{pZK-Tq{ekqL?DD1<_CtsbIi1n9?8?C-@iYe@4RODVr=VDnQpl9&+an-}VLn&KR zD%{&C+*0yvC&j|ourlrspqIieY)a|(H%69Bx;8~)-{M33e#i(M?5}jUSI#xQ$5@&Y ztmoYSql*|1{(dZ9F0L#?@ebCpdTmu;OeYPtPs)Pgn2>`cC}u3mM|XoEv+W?{mSdlx z#-L;1eA>Vvp|pM+b%y|D!S~4JfSp+WBh43lgB$WVeklxVOGD_V!c@q2EywlxThbgj zw8oK@e?dna%9P|*bPGVd2L!A1`7nE!uUt0&(P0V4EdjHoCwrc(UA0S<%X!pWI$;~ zr?`a-s2z{Ci*`U9nglmQS9P3!(?^x5EOTeJl4xX2F$rM$>=meE~PI}3Mrs<4|~ad z*Xl#HES4%rEm!0bH%Y7bJGXcvp;>wAGPaB$2SNqiI-sG^^Ayf;svzr93p-!IjnoAZ zk^a)RNZz@NTi!q)@65p?>EQVEpdHvAKsz-AHl*Ty&YjVs(+m8i)b+%P60T6lIm55y zjDUMPr;cVZd?i>%blN3Moe!dcT40Rl)9PG{6noM-$h>6O#PB;$gN$fV!)BwI646uE z-g?9r4&%Pb9bOMXuP%e&D20PdHOzsPs{R(xSqJU&>vPDO!)XvSYzF@EVMV2YAHwiW zo0Rmk*4P_-3;hJY&Y@qo!touDIKR{omzea|E7)Ci1c3p4_r8j5i1`?2@Te|zgj`hv zl1oy(6XBTR0b~G5{D3;$$@7U%#~b>w#?rVtPenFM?5!A_oQu6;(q_LSMyliP$VsP{ z94ab%php#yk_sBrwy$V<09BWkQ;Dxe1GYQj&j@%3M{M4!hpPpe*c}+i(x|1d5pIyj z0O3~$yo6VvnM^%kMv^5g2?;wb`8gL$jJN{6NOc{jaA>RR4h*8ZTw_TeFU)jN0ysqR z#Ts94v7VGPjlpbL4vc89;H8YnH;GDIq)Nb6`Y4McdvGpR1TGqYtUt>WC*D$tFbFz% z?|XR`4_Nbb*jZ-jUhKImm+>y(GU~_5&~@>B6qv09#Q@EMIos!p5Nc}PmB~ubR#|p1 z!h;7NUy*B*T|eu0RjxxC_DKE~xocMW*m_AWZm%(cvvGlg=wrwTFMtGBfy=E()~pt{ z2`X)5Eh3*Meho#=7P}99Vd1jo(J*RxoCLpYvLD_+H#d`6Ev#W|YsBj)PnDy5Hr@^utLwvlBku139m2O|N5ZzD{78z2~#HxMUBb!EL%6Qx+){ zA@>N{kDD-nVA`XuOtClT`Ro7L&j_)>S11cMIpQk{6?ivYZ(WYx5AR*UKVi81czn+R z3(vWC6)+P!E^md@0N13eTN9kFT_j%=!QI&$&*t>0WjQyNjtAijqlm66zz51_hZJmWM0r;b4>6b|t$^Nr9# z=h7CK8}So@=ms8YEygRs^kZ2pkODf6ffBa%lzrtwr05 zGDUo39`k7<&sdmD&hagfD4D4d$470GP;KN@j}A?nG%E>awX%q6uO%#vK*YonxL&a8 z5{evcSv}Uo`{)_=OB_4eDA<>2VkI1nM|*m{sISHx&#;uqQ%4V;s=nmCHu~JjlTSZA zbK>czfAW*+OIzsCo{8LI>9z65zM;?WspW!CekaJ|!yC^%_x$rgEnf?2cz<2@`8`{r zm+Hl-7ti>WsJd*+)jMy57)wedI3 zZ=t6j`0RuK_`qi$X*!&b-N6Gh>4R)dsqG^V2Cb()_Oo)~?fjncJzw`m z-*@!HYpSjqSzw zM+L=pv{jZb1d;xo(AMckO^SuoWBX2IpP$XAX)P;(Kh?3IVep&`S{6gbofb1Ip9JZ z?I9)Rwz-tbYtKLkoy^L2{Q!PX!U_ia{N^X>un*gOMO^vpU!+o8E?b5Ok%bJIknl+1 zeU)}NS7i1yf%lq7B7r}&2C@gE1iS&$`d-D{WIz&=*3-zE2-NXfH*STsC~?iy0JsDO>Hpa=Z7CrPy`qrum~)0+%0j1YL)=$$2GQ!6Kajni#x< zs~(ninHe;sBP?v=qESI|@NGl`*HrnYq=b{ms=6TslMoDY3klcqJ)81^y)rx>ESxc- z=YhK$qN=<^zaO_c>?zg|uye;@yYUz~Uw?g%+iG;K^Zk z27++mgzG66wFtW}@D8^Q!H&?~u0jjRi~atqOWaty{f_^{Mt1uO3#pV~dM^j95S4Y| zj@gbWO+`};Uk57I=t19H6croWEQ?{qY9GZB=m)^y( zRyZuF1Y-6ZLIG{#hH4K!ns2vg#Ce2o&M4avpT7ZZ^WW5auR(e4vO`baPc-wDz=m#@ zaUleWWW&b7af3VN4BN5%cV|io&z%&KwxYkGf7zqly2FFA06!TzteSMTlJaHG00k(K zrFINB&cNt2dbDr`Y)e?QVseBEmgDsH!XIEyPQuP$URg@g_5hX#(ThbPZ}o6%vT;Xk zP(s-X*6@V&3h7Y3M+rgBqy@KPaUd^5o&;X~I72yXlFp0KDd7oA(Bzm9zNAqaAlq_^ zlL7{N{F!OLZ>u7Q>=9H22^lPuPy2jGLN(GJG@%{;zx`KqJ3apGRdz=A$^ZISv%&BI{3fGpp8UMahp!AS z-@Up6pN#ibU5`t~W`3)re0p=IGeQGi;ZBII-0$PJ3g@~4ezx5_>^pzB*Qeo%x|}xA zBbh$Be)|^!{UDFq9XyojTEk231M3fXsuWe09ZZ443}-nH5ZeGHXfp}sjaV@WP#i!6 zEYKMBhE|t?kvO+Nz>Wf9kR0&(oMF-+4w2S}3H)J1qLZ^kjB*S^#X;mk5QtI9nxZmY zH9C$kI1YtmDq#B>Mp?jv*syk7sRlL?jj*XL>SBo+$cXdmlokj}BNfFqkgf=e`2a{= zFf%(aZ)P)nN>Dt-MOG*{4uIz?n@5EP+n_ka?-4PHB#I|ZOve6(sO2pDtinyqpm0bW zh}R(pTwWY1!cIM6J|P>T$Y4XzC0xi*A)`QQ(> z|G(axp>@8sHRUrO(*<-g2nF1u_?kkm8#7~he8Vd(k%KNO#T{DWif z*oW_w-$7Y_KP0DE1Z1O5ty*I({YaVHYUFLVs%pNH7;CXVk?}%4!FfiO@*!@tQ7?Rd z75T7TO+&_@;yC7)urn{;RzV1XXcZd%4ZI5gzHanONpIBfm1zLSFy1G5;vzbq_OORS z!xqo%k7R~*YD1T4zu);2|Ms8%@qhid|NPz0@WB-0?|x=z{6xcQ$ zpX#0%eP8}pjvhN&I|^U?i!Xlt>#rR2YVUZ*`%^Xj{iTT_bR(F^ty{-roZp_j8H;SE zR{SA6`mddO4)EfOx!MnZ=+(aSor&)A&qsw4P}?_uU!)%<6k14?=j9CDsjkrYHXGlk zHY)9(x!(VF$AqqwS$vyA|`o6X!D2(kbgez*H z7?gJaaTYlWHi2E^2k50cI0@v8l5mFrhf+$eDW>?pDFB0yA+qCh83DXR({>`voQ6ox ziS*o9zC&LL*V7Jt`4GVOAu6;&&d;I?epCSOyXh$XEs(NY@7EMW2eiHE`bCRl+k%Rv zQ4fe&gHNJSQ-YqdpM0FQ36|kRp%@xTCYvtUp|4W;lNd`!tRq~`3!bumaLC3+94yH= zkcWw5Z8`~N4o4UrKqL_%5p2b8&d(w?%tH_o{aEh<0-YhX@`BU_T!Q^L@Njjg_zCM2 zw|lsf{`|A`})kK#oiV!4Bva@dIA1Fw~`2O!4? zi0Xm7v}eqLqKFf7W0J(5sVk6B2#^p-VTE7(j@Q3~8L@4Ai-4sva*McN&I;`8?VF_Q z<|MYo65al@UHCNvWyL+GV)K4LS0ShHf6^RFR^h;{1DSn{aFe z3cl(>K^gTUDh$)EsjK)LV&CG&5V2Z(lBxmM89#)oP7yIAqpk1jYX`g0t2!(S~ddIWiel8tk#65 zlnWo>US9jroSa2nkqJ)S18l3R6wU%}r9X~9!zDClq4c{H>mff8z4^D(N!er_kr{GBSh@^9EbZi7_}3V6ZyH-Z~%Ika`v)rm9Bn7pM!BXk}?5;&~pz zKb0!{@pSAliQ!5Rcr}`yZF(_zV4%RKgzlxDwN-{bZdWZNZ0H-!**JL;%OsPe{j9)s zN4Pz^ZiQi7Bs6e^dFSQ1*xSOF6kU29Gf6@>1$u|zl~@TcHtm^$4`UV!nyG$ltzicb zZqMPnB-&*wg!UjR$PNK31i|AI+j124F*rO^p|dc7lS`I6iq$9beG&&iSds)Xc>rn+ z2)HY!RD7x9)jb1xkL9`wxyx!^OH5z`$pl{~QK0tF*IB{mkDOp86=J~5l~iove?}5t z^wSuybWkt@Haaw@K7FE!_}(?D$faAgAHhoD+9jJ-bj{Kw;Q$@#ppRWLgZ+*?13&&Y z1lT*MZbE$v)GyF-pz!T?mRtQ#;!5YsNpvq>^bxJW&NrWWFG+<{@{V)}2}?EfBArM4 z(BK>j(n0;!PVz(aU#FVW{r&d)V$}#sF7vWMq)@SItj*fip}$Wn9zzN}azErMw}SSg z065jLL7p#hC#}E-+&o?i=gkgk4Yy-X3`SP7g8eBHP2cS2l+Z`*nUrFSE*2TSD8Zqxi_pJw!8Qm?#Mpyk$I zgoJ>%r+rIEB1u)Ug{Fpu+IObYt}E1 z>Gy&0WHpP{R+OFnz-+%?E_(FGyDoxNCp&x32VCz<_?XSTSFZo$J}7wg)! z*Si;r{sWso`srZP6|>$g{lDzdmj1W<>vvl2xxspW05it0R|+;~{vLPsANvp{bb)hN zy#8`bD?VlV0&n*;f9jjODsHoIb zj789}#R^9#N1|(Tf5P+WIMBm2&w4n=j991*26>po_+wByL^4UmlE836y<+f5VP4_6 zijyfOeYRRfG7MAZ1rBKrlSh2t!W=h93`yD~jbj+=+vB9bsMn;U{pfI=*>IE(8 zA3<{-7Ku1QW69C_aGLGL@+NH}ag`9s-eaP$N@k6Fr=m`}01zWy`vCCwlhe zyR|=^<=ybn_h8?#rcdE{>IHz)Gwc~XmfE)Mg;cD@zQp&v?}xb`=3YC+e*4#63$VBG zl~d0@fByOJNY_#(6@P4--+gfS@Wl2Z+H&!P7N1W)pJ6*aJ!(%9-ESS}LRCMp!P z9T!uS_d&$64-%jCivT{slp@ubT_IPP<5hv!he?s|QSZHDp65Z0jjxerugE!}P*$bT zYlY%SU604P!mX(GB?@{#;r_iOXbNj(UN+{wiH$3YL=KNv*|3M3DDdvlY%a)IN~ouh z6YQyf0bU-2%Tr@5l#8!k(f6w*O|sAu2n_s)Tfpj1$2>UJ&v2Un>pCum5A%K;%cUO` z1{|_fq>u5$=|4xSBD_LlpYBo+3mhh2X-_hPeVB((4uRuPK_Q*=&>n18UzDJ+Bovp_ zXi>6=-gB}Rs$-|88ZJ~*KimoCSq-a|Re`9L@ zvqx;Y`mgEa%24H>O<7O=SZzx`o~JOiRX%P@PLx8BqES$X^<4%h$I@DbDRlv&q|Wuo z-{CQAU9zW+&?sW3(4~RjGDt}&*f@M45?%~)n9(5pY2f&DsE7hzb){YhO*?%9(7^6P zsrMN=R>4BopfO9}eqPF)ptOQ@Vfj<=76?3kBG`rI4-BXtiDft6-1t~jG8Le%@ok7T z%Q-Z^MQeluzCI^39pZhWY{% zN6>}11cDhpab%Bv89Q|!|0Eg{5zm+D90KOzVxJM&H&dzv8sO~ZuPc;=gWlU$9h2Pf zs$-5AX2xy2FNzxhGK;*7zzy&n5af{#zCg(A4p#gb{0)22ct6Lwtb%qsS!OAzrdL^O z(L#Y(D58zLvx)`@pU9O`B&8%*Jn#{luA1A8GiE^VF$_0~IaHN*?*O^l23KF7BZvmueE806Fvn~yU!Xnx0gEv`{ zo>{M%!elEt=5capqeLsC2lPTBu=eQb${h&9NIvkRkohO zdFtr9lTRnt6kl6LVDGvlM12d#<2uo$+gJf}%G-d{<4}Q~%J4h@u%+%}DtmPeP1N)}`3DQ>BjIgh#prD-L%3C}fAK(;sK83y~kX*GW|= zp&{sO7{h{OkDQvs-J0wb!K4tF+_!J#cm-a`U|?p7 zoYez8LW)7l67B|D4Q6>hLOb#a>p|JADceCAaT-vGMEw;+46GS}ii!D{M~NO8eV8nB zo|Tn&VIzN6#=W=mSG|q2J17rV63L2qu_K?Y;1T-TuvJb0@9o?+Wm}b8N6&kNuJOj7^Z+kb(W6KNwaU0$Sy-J}}~US=X=b zKexxHptNDt<_fla4sTx5ze5B;_R1|iLGX5QFa7;)Z`V5me|Y8uex@&rey?-wUMp~m zR$1}&&pR;e;f17J1C*6<1gNQQqPj@xnIO?^V$HgS5pWYR=+UD`6(lyNi(`0H!I^4f z<0ao{Vc@%BC%UP?7vu4GIsS07#vRw47KpYbw2_);PGbYHaJI`51%it$h$Q2Fn~Q8K zc)QX6p<7WE#3C8a64H9kEJEl4FeH#8%Gg{XD=|`7&E(gtqvgmB5bCfs4TLQzq}GF2 z5ls=-2LJpCDfayVK)8HUDzkrt@g~8KV2vTUWe-5g*u&%^`5yFAFsK!h0Bo+828Gij zV2`V7PqBSqT$%@&z?NUkr)VR8wkV3Q$TAI=av}o?4s%c_BY*s;0j8=A-q?<$asG^v zT{BFv88uJbP)bZpGRhJ~5Ly956b&9dl*^`ny~X@u-eL+qC?Fl;eU4;^KMSb^VUOc; ztl;=WF*L99L64U=KqCUP0a6_4i3PBSd?zhY7equ$r*Ddmm1Eo#xm<=F6G`1|+sq!S zW2uMrzN){WaY80AKBo7h1o5zeV<>*oREaa=3*Cv}f*6)(w~ zy^0An`1Q0b!rJf0KF5gH`w;ovkJ|qi_1Hx6I=PJfjjXHvnLN`(Q0L?PqrBsI9&yG; z*^n$qO`;b|-N_eJX^miiUMpysfFF{N1jOn0zFG5xYdwAW$?6)5pA2R;^eb}x1r>|G*V~h0| zwst~+DZJ0SNDI{VYob*QDXMF}^Us+}C+nlkCR4<@GtC-b_$iE@b&w>lTtn-tux`NB$ z{ji<@Qv{SR#P$r>No?Y&E1WqY<6;z=ZTu*Y9Ib*siAs@0juINXhlJAdKQAzrw@K#t zlFeakOVcJW_N6tVQK5eos zl|Vt&tERm!kw_p=WOx)9l%5uGeokQqDUYGTWk_vSnGd`Qu>*zQ;PK$H`}@3oQh-iz zqtdL-KtKQOV~^!r)GVj??wPs<@UDActAa&d@jUoOzY>6rfMd{z6$`}@k?iav(*Tj( zDf85lfI9NVD3hyDQZt6pO>h8qxO>mB47W*5O#M*VEol-DH8!i3QH!ubz4dy0~`CMu|58uu;UFlgzpgj!ou_XBtcLW z8s(zu&1nvTHc;R;9HtJ86@XxS(m@OFMltz284<`5*yER)^=fEw2U4q|=rBuNa*k-- zj}k>h@(?fG!vWyJEC9&gfQX3&F`II5;vC&GB~FKRn>R*C=+GqY2L=!?H$W<}HWs#$ z7%6#waMTufCRFsz*rL}j4Csfd1r;4JC3^Xt0RsE}tZ6x-MwKnyQKd*^vyKQXu^v|t z*HyC5c{dFRykG!!`&`#ANM}Z1ySms4H^jRox3fvFqko6RkMwTE z3ohPW*lN${AB4md2^i7sVPiSupoorRJH%CM1=w9C6nWPb&m6o#4L-9nkB~CWW-*Dl zofiq5i>`aFK)#*WTm@we;#nwkVNYZy9FktKA1=2YZ!hCA-PyUONPCM}{|ZH2#cy}6 z?d(A}px^y0zCMFDLlkl@Qow8XJL`Qn>uvQu?5*)S``t$_FWfu(NV(Iw8-2ms`G~tF z`|UO4Z|dxKD%no&w>!VSzH4)@w~4NN?7OqM&W~Z5@tu2yskk=HQ)|x4Wr_c)TnUto zp{m1q0c*4cR15%Xs5RySugmqYsk|#t;D$Zl^3m2eY`zi~5}c?Cwi|k>o0JMr{27YdKG|H|f`8S+*S9)8tXyIDNe8K|1s(*%2bb)*ev7;^U`77fYV&~WJXeJDBU0xqm2+e0QYkm*8|_70Oy@B@Z<)k zE}l;`YFR&7sBBc7xLVE0CgU`V*=M6I@R;+bdgmbdR6v{UEI%%oDa z)Ia>g!AB21T)gQh_EH@^@!Zi$x7rum5N1G7DCljVTAf6}l`p+fois6!YJ)w-lTaqyYi_a3EDJcWJYZ^l<@ z9p0U|#XHf%JABbyhgirxmhqnac>USt_fsmxvWX&pJL$%|Uwo~*K2~bt{SzD)r(=4Y zYTEzLbP`^E^(E|Ito^im&(H+)$7>J2u%q_9;!)N)Ri>x_Nu79M4L3~~B3fS7K@ zMzf*Y)ZVSiF^`!!6!b&B2!&$(-2#}`_>OnvqSdP=gXzcW`p^~B1M?Hs|Om@rTxTi$?VI;j>tp~Da& zGoFmzO7(+K8InV+V~)V7&C3&-RS7X{!gsmZU z0U~V2NwCp!AM$2^F?}+Hgb7E-G4ID(4hgpHU<@%v-w;Zx2}Gz^s|`jRM_U2`QAvkO z1p9SwDrffZEnt0KUe8a%_t_;kC3yD$QFVammJIsC-i_dPnW1|MpC?DW#CDzzA8UEE zf{&8Plcg@FiXu2A!j@JF@8?ouf!Kg98$L=uUZo}E9iYE@?ws!(1A(i^Ha2d5{}2w^1u?!#dehKs1z`{v&1FPAUL!%xm4hXtg(01ei-@d z2e9RGj^C#kP(Ec-$5*_}?^!ne@Au(^l{kB8{3XaXrBDEP&Qds&cc*>P0sV|iC6!3b{ur?9OrHD_RYQ7epYY z0ai&!L8>7zl!N_`R28UquijHLcq`m-AB34+ZY+skZut5kq{aIUpoYxN&3_OODF}GK zB`9`!XfT<=D4}s-;B-L!6SSYETh4jbme$;ED_62*hI-ds{mX1+x8nCyWUy(8DiVCj zEKdZ+4mg$i);~H*$7jrWlo(0O57WcX5{37bq16n2$%blEGqHla-@<+7A-aTV)a1Qi z1%JySFq{#?N$z1|EBcUugSZ$vZUPnlj5-yzIa?*|2PE62Zein93}`Tbbarcu{#G=^ z;-USbj=yl_F5JlWrMtM=7os@w<2XnEH|hP1nd8{|TgH52DbwOrbQkE8?RW86sAe~c z4n*h1N?wOTTiHbKae%-2NyK7fYyzB80j?iY)`Zw+dfn4-MgT5G$+rPd-iPXP{X@!d z#H!;Jv}Zv7$uz09TSS}4L#wEx1O@!oLA{(m+RaD5M&ows=IEtd0dY{(VY@&zgeX3Z z%}9(BN4fWqXHRn_1YaIdD{F*ziJ`Yo+cYSr?!Xo@nwp+=CP!6n)N(g&wd{*~l~h|t zof-ZL%yrhlhP*R~X#k!U-zxTO?v*SjNuGlm>?!m|zY_!(`q zK)oZJElOiUGUiIfPiAk=^V>5Vdqk2unjdrMV(CrJNPLfbGHc>S>T!m1uu zk`!`^6qYI4lx|^IW8ixt2d#_P(|`&FrHAo)9sH`ZRSK?~4ZO!-Y}PAZ-~ZuzyS_W? z=Yq#7xyouEu;7Tq#lMA_xJWi$RtogPjTCQ-cV(MMrt%atN7b$B~4x-aDLC05y;NOTx4?p5Qc*Vsoo=@-VbGN(B7HgIJM`%oZg?c!=@2tiOnjj74_P`N#dt`8f*u`|!N?ZM!Vb zgO{>=?l7vqd4)6V`&kKBugtDW3yeegwEpQbBaTARbmBl}BmcA^csctOG-I8YpD zCmA=P0RhD0gn=>lQU>E+6q@FyN1VhT*>V6fT;P&m`G%VU5{SiqUM-M1)OUP%pMqx4 zzKa2};bO9q)Mep$$-uNOzaYmLYLq~tw*X374bOh_J1ziGer(3kQBe>j6q+?5NTpd5 zNFZ%8!f|UEKdGW=t)`&k2#gBgQAiXH&MeB;sc<85F%)_@$FV{T2Ut{$AkQ{KCG^ZI30u;GfqJ<`&eeW7# z%uL9^Vt{OA4`v2k04_umh=_|Zv`{1b&w~P_+Df}fX#fALy$yU^)pakr_L-y6nemZy zBnwwIve}ZAWXx5PV`LK92)rc^prlSZ4yZOfJ02*d&ij#OfaGV>I$=vzh(dgm0o**& zpOfE&(AU(>1wpy*nU5p~+X1C@gDJPYd9P3g$i1(9w+~!ClKd#S^Zsk^b7n@e{6X3! zo&B-)+H0@EsBAsEF>>iiQ&Qp<51W678f zwgqkCC%!Y=6Jnxci2fRfK0f#$>l`-j?BF|l>u{VkAE`WajE5f2{}%7>JoI?B_Rh(- z57mfujS1lp*s%LGoP&4ORd1vwc3}5s{{w#i2Y>PtKB?}cxiRMLw+pq6LwsjUBGoTy zxIOz<{0IB?+AnImVaD**{W$aP#Sg;=4GZqi_#pT_UwAWr@{N-?{qF5UZy$Q+9o9AO zoM`Aq6TYX~NoP4VnHF3{d2neCD9GqjtZV<)eR<+aQgEf z)-Ccg4}Z@5629~8AX>DY&L>*nYu;CF)+3%}Pc%n2bg^#G=mZlz;R4>L^Ol>$Y<8QG zL)lmh^_PrIbdX8dnbuEQE{GE)u5-6vSVV(d@*<9({2}9NxAz}<&2*cM z8-G>1{dTY$dIMbeYr3W?=}k(s)_}=&4L+mBXJcD z)ALREHwcxijk$q+G*KXqsC}$M!ANmcftbj?GKi#BDZ^!n+2AZ+}Gc&`q@F zebSnXU=&;K$kWVC;%{+KTydOcpmX!*am<2aHsExk8SWaC4zx7beP@3YWdz9(Mn+Dt za9mi1pR%lZ-IDreGI_7U(jH zYnb`jAUqpEQ+VWR_U&5DU#aOT^>t$pYlQVKK=+a)@BV+p=L9Ou1!7+&Xdff&_Y5Hu z>%nZH1g>$?pi*W8B!wo2Gubc%{){-Rifp-6&K7@ea$$f0aA=9kcn#%I>;ls-p>0&s8*sa{vcGfoKKjF92xsfHXeXf%YRTLBZ?5 za6sSZ*2MAvL(~NViFiU;JPRu4SKoI4`|qdc$oA* z0TpS;p@}MZIKu#lj}n9(arNU+>qtNch;^|NyjswxNSk0kA+*DI2`qh+s# z28oWjyKcN6?9s8(l|O_{d%-tH5z2e|B@j?ixkbifz%8Qi(A`?AJn)4Ec?Lr<+j9kO zi{uu~SqUwk)8RndhU{=ge;Xn1)kVtPv7$5mo+5ODnUFqO!btpyfbu^JF)lm=5)!5` z;80u8$hZno7R*<->@tlGt81yX1g2^HCQwBHmnaJvVQE;=G_m05c_`1>vPoMXC8@!S z!R4|?aVWfH)Y|LOSAY~~eMQ(=ty?t8M7Z#r5l|zQGZH{r&NED$?MR#TsVy%vM8f3%sP`|X2qm~5N}kw%SW{c(26_9z@;xEq`w?_g!I9H?@aX$ zAQPBT`5FENLSUC=S+2u^M=pj=34b@?P=wA;2zO=*ryZN#If{wl)k=hYg>kL@Amfbb zav#JKAEjJ>2Jb?0Gz9kC-bwtDAzUq{1U}}=C|HqQ!zJS69Ur#q@?uVIwTKP01=e$( z9g;nmdqE1NiGN$x)7*b=KweNrkNLD6*E@T3sptETZO0m-?Ci)MDsRZ#Tkzya#rxwx z_LMIDW3SNWxsU!?Y1q4qW_KWiegYWo7|WEV&QdBN>KTys zIz8#*HCphy`_Q1V>vuHV6AoWe^oGJszTf$=uYUTvy(@a>jz6*eGJoa&wd&r>X!w#D zf8-K3b;Moet-FM1z3;E^z+)Gh41M3sm(re#_ z%WHgJ_$V|iQ4H}wN0gng+l1K=#j7j#k68n!8E+GQZaXhU#yrdir;{% zNfKIvq!tMg477tnBlpI09=IEK3wv1(AJ;TVqZ*p)DORGVZkyIdzkF&MDa7=7RqcxCd7*x}cS=3vwEbf|>+0nX-`)iM?`Q(TBp zQsd3b*)0PNN)hl6;vrQg)Bg!=Tr+M44}!mHB7STwTUI)QfLlWXyR8(MShlzb>$D+B zLmslJo8!Z8b#^9vo{{jfNSE^flqnOB>(T(QOc#4cW2}j4gE$%>sB^;^Fsy>)w|E_5 zB39gEB4W{O8Rvb!n?|DuhPX!3AnHligV`ZtUt&`wM*LeW z)=zMJSVk8)vEzcy9sUD;_7Z=`p~v5T`<-{*ew)`k;u_rv+)Ul^M(Qf;fUd`>bxbtw zfMNXYwc0N(8JeJ9)Nr8Vi_kGL{7H`YDcwU)`AYSu9>_OLFK@m2@3`IIQpDVTFc)M}~J1)Xmn>c`oO{U2nV^<->-fUTTE{>9 zVeQ2SAH+$mx3hcaPQJkgN3xy7zKMOw(}ew<@oIuL&87y zPOfpCNV@m&luYBzbdk|Pb_)+ST8Fm`!L27c04@PI=SYT`R^Er^#uG1TT z0HovqBR|u{AB>pD5R!1mUN%8k=UBH*`bGx{R6SnWcwpSc;bP!!4GR;cwADd&3%2p{ z;}qsWVV>{ZdZ3uVf7L`ok#h}3coZrleSMtQW31(ZUd%D|i%?4w+YO`%G0~Yp)p#X% zjU~b@^tFurxaEhNk{gFJKa znL|xJa+Kz(qlmb7oPgB+>RX^cL9^aBiHXOLg7&F32+z&>V}z~2Vr|#`xL>CrF({{K zFdcD?B@M(j4o5P(l46~ZLZwy&^lK{cRu^%7h;)`Y&{GIWR~(pxnwrE1=qpZdgg8ym znDH27$Yxr%;KQ(D5Y%d|x*dD}t(GLNZ;wlZJWivCN8y9$D4|7u>}qVG(wLjL-Oe(s z^~&eB1(H67ga%l|7;f>NA{;R6>~ODI#pf#nD{{6y6n3r?4M| z#R^;KUP$ynjn)mvX~ES!kg_{sl|Emmie?Df#I8p(iPwF^Joz0eFDt!MA4cksu!8aVrk(AR_L3#r9{~udP{oOxt%*8>Q-QHMF3;GVZIE}^r+e;;a zKmbp%5jg!7*pqnK{clC+rqfDof(+_O`o?{ekiAO%mqRCbh1l$W$7IEfCnAkp@$Uer z!8)`S(T399#Gji{%MFf(pEb{VbQca|6w^G-!x54!9fkx? z2^55OpgKgEi%~Q|ysT7)HtT?tcEiDP7D_iqPQpJ0eP-_#_W-`UwG>^Qj*?jQs0I#b zvA>&~&3WqWbNLz(ZE}We<(fApH&N2SEegpvC1Xd11;)BU=nSD{JV-a; z6j#>Q_29xEZ#dhY`F`7-=~aLH2jR87mt8o#;)ymWzpi;Cc$B^nV(lMqvPK3=6yT_a zSuBMN>9gOQ-SNqizhgMOdczMk9HQF_5EYuUHk$oGX0unG-3!D;%UJJ%A4`x_;Rof+ zvi5^LnL%%Z|Jhl+cGvozVVo0bM0OWtytgYefgSp@7r2Fa0kSk zBHHhjvU_kr&Nm5TK3?Hvyaq^>5r{3`F!1D2N)?^V5`kCVOv3ePIC|$NW zTezS%-1KPI*vJ#PaC;bD`pceRa}f59l)c`O-b?B5j5nVBw7+d+?Y7~|w*?RN`VXz& z_B`o(x6K~b*kOHHPq=G%InH+6PQq&&_OV>ifI036YcfM(EmjsKL^{O2hOFl6!9F?& z|Ms=d)BP7v$NMh3hJp|Mv?HKxl76G3edK0|jn&@!3!3^u=yLsy%X}{rVp*h%UtPBM z4q|Df58W@{sfDK0-tISk{z|GJd&*HL)Ck}lH-jPM^I7IY((w};p@E@D$`Bq7lV&Ki zKV)hAQkWA8xBj^S*s?AO1e&yB4>AhaPukeV08zpY3M5n~9+RMiBgsKb!n_z%9LLIC z*9@-Z=3qd_DWS0^s0Fsgs|DDFUZ@@xpf<<;x@1k^Nm?AHt%xRTT&~!ghM)5I4T65l z#tgphBwowx#*}YuQu-LCT^tT!Ql2C|$@)dmnR4X!w={(VgvE%Y^lZ(b?2KfrhgVEA zn`VY+DDv(hQ|sP|xO&M^M$FnOPFq1}3B*sngDP)FshI_W6Nl@+G=FEX|?|I`cK? z7f*(tI|Sw6tH%q_j6lZ-{O)*NSA%-xN_!q7^JXlzTMu=1PMH0i?0*sK8aMiuhR<`X z-TtpNtY&ny^RRO4_Kjhs!u(#W)sA1DFPCde zw;JBNcjLE00P}4CcD(|IhB~lu6<6PMOyJTRny-tTe1Oxci2mbzdkmT^&#+zs|Zx%-6Bzv-s#~o`-mUGwb`3z1YS-V0&is-sie* z5&|Xq!RGLJZZpz?4*jAW_l=+44;|wD&>`|Ou!s&Z&M5QYhtuFE(LvVBVSz(O^E=;y z;6=TUKi=87bt~%}Up@YSZ`L_JcJi%%{^#ePuVIaE4R=>xc_p{ejp0>SZ47r7Hiq_Y zYG!uv#m#rf%-5}RILBd|VR!0s!S-u4+PeAp^Y37#C6-!pcY;R$om!Rqz{Et2hHxxo zN5>(og{&Qa;K9ddIL`m9ZN#&aY8^|#bExBD0LNvpw{HK#A2J>KKjc z#tJ~Sge2Y=l3yBGk_Aa+8_v@?4#(`=HI2@m-^imj>&mRY41CNuiue(a$nZN`j2r{s zDf1mPG?0Sc5+B?2RDAbMo)$v15OH=t^9-7Fj004dc73*gI(dt!BDtZ#meRJQ5z^7AHJAuEx z3f&{f7J!*OEWn-B>v{o}R6!^-ef*sQjB*tAmMWQXgBDD(FyKb`!oUZdrwMu2=GRI@ zRwx)M!_=s16tC4rN@PmnRe}??%zTEw^-Xddmx)}q2zzw}+Y%TqlZc`zAQ@!=%1r`A z&XMl8?t~59a2Fv-$qmqv$_>z97J^=gI7dHAh?D!7`bL_@)`?ssD%DQNjKKz1d+Ib6 zT2&lcnUyR+c#zk9!9n^y7zx|}hgb(ARE#op)(=OHedtN3v9G3YXjgE5^!idwg zF_`?_!Ah(d{(ycGk)(p|2hzQNUHdf3Bwfh{EaPUb3Eaez%CVMBtuy(>9UmvY2Z4B< zB*O{liOh^%@l3-s36;BpoeYI;?chL!qMTWS`MX3$tDKL(Te1sBt@e$nR27_oF%hdp zi3KUN1sT?_0H<#8B3S-Ox(rs^l34czw<-LmM~w?~rPvW$5wpbqy8|rZ!bgh4hT;Q= z+$AMPce(;it1*R7p_vz;Y@;OxZ=1X{7Rt#{WT2nT0lEU+-mw^%tfLQER%uYY&QUv# z93Tui&Us_P1zKQOhMI-?_;VQuCGya)AOH)7K7rv^26vLmgNhtw`dh$G5-b2>NR3gs z=nCC0jbR^5GKZNbd^JBLNY8lJ6i&SG4~nu+S5z>sx_WYd^@rin@~-Cnqq- zxG!3zB0J3#%&D@IrPani^CGjIB`TV73bIA;r=QV-Xin`%yeTi*2VJJ;&;2)SZWb38 zm@0~r3=Ch9;`UMb1JbN`v(><5_@PQYliy`odNqvJUxqemxaUE^@-w=>c>!nkXtOd^ zII4(ziiZydCDh-M+1B#S5M?yop3=LpJ{INTK$&`iSlu^>0#ZlN1yJ$xm@5pQ5Kb|2 zdJBx|EXss^SO;0e9&5MQt0yp?Y(iIreiutn2LJkV7^L$^bQ-0}%3fx1qPzcwX}X&R z&~>?)P#4#oZjFc&gch5TGkC|5l#H)vb_2No#=v}tB>%%$0Q2Rxfm*rb@<8F`@tRPI zrpLxzklYRdqzSAyC=s});^`*13_dOLJDbhYZ8*}f z%}L`bvoB*^qMv>kbKJtk7?{0vfp-8uA>G82+|5CGlENRj4`Y!h+6uNcANmlLDYFe{ zNAA71^u3E$YE)QT+g|iskG_2am2dJP`ZtXDnP4y5stw%{UDMz=)JH32JApKsCjavd zS~1ie*s9DrI~pmd9_+xTwWIz>IQ|#-I#?3)%&9_;H?qHH>IcHVq<5cK^5ve}GwXeU zAAYiwde{>gI`M(ct(ko@w9;F#()U*S%l+V+mlif>hSy{_ZCKxhvlv6HOI*&0k3dJr zg@%uW5z74+9H~M6+HrODNVag%rGr@D?`KlT?7AIJfUW4>iZs-gp_k5KVdI5v_<>>M zuqVvsyg_e!xW5z<)<5F7%0V0wi7T^r`Dht~P($v|xV^s5YCjiS$?XvO0nXF|@Y^m_T3m#2O|`YlBe}BLx&p9coU^%qH`qFiP0*0=X`-YP2IRmKC zra;?dL=%RcdVwF~Dq|fDLKJ8sR$M^N@Tjs8>U?5<36xzZag$Gwlr3j@z{8;pT)KAj z!?cUzLl!vhM^ai;%qw(%0f|i_l2Z|`b`707&9o?6{7ZH)1lF2mOR;(gL%RZhM<^4f zZ8)1TX#+vhxN`|+%1vCSwQb!qouy55c})=zVER~$O6aJErV!f*VeB5s6hVM(7HqS} zyb;)9H$DXhX<&c`*bfYr%7e&dV))|p$z?Z#d6`?MF;zh}`A+9Nl?E7{P-~mr#Cs;& zC?U>Zd=0xrdC#+1_xRx3Zy$f=?YH^%n3HeRCbr^y#fe(H{hIeqGrR~rV+<=-?#^@C zwUckXwUM4Vo=QFQjPWBJ)W=yz^5TnICT@q1@sFSX!b&WN?D%tPq1tPo`Aluc7Und> zVQ*dBVe~Dv+J{>%$@)89?|(C2s9_Bz_JO~1{N!6d$>I*13wGm0&*$mIdL2^^zG7UX zaE$NF2F4|$Ph_29tXE{6o^i9@?<_h=?ih(Kk>ezOcC+r$g4II?JO%<1I@77RW0?mX z(9pvVoutt{E(kL^$Fs`ADcE#OIYcfa-aT+*$CK=7P8ihvNm#6dO!R(62RPuEcytyW zX2O&0W<90x$6_12v@`2**(EuQAxY1;z3yWKgs5Q%ZJwg_190<9(ds7TW`MEf!>GvWSW5ECtj!?O<#Nb zam)3^;~n&if4#kS-o~Xb{<5}pDbv{yW7dB^U@a(PZ1~Qd3BQGQF!}D=iOP{EO7-nq z*0^cxg&;kgWnEq{yPTk7j50&`{gyCs9y9iSjP^W7oWa|*JH^xMn=@HgWBE9%6(j`G zcp+(`e(uV88{G+19U?6GDMMc(`PI?@!@rUuSDQxfI+zP1BQ7|ZjSmRN`)Q@?MACcY zO0!C3fNn5yuq5X zbE8pu3aUbE8cadg7cCW3cw>f_m_%BBq zdDx`?K2e`BxvJ2dgS7)oBMtr>{tB&r8kv1MI!4DLS}Nu=VXt*`GG5`6=ho-UKzdd#1U*dLG3;#q^!b{ys>(P{SGkzF5`VCL7JQs>!twibC#uE3 zeOjl$2ZvnYlRd`Ot#aLU?hX}m9`3er;+K0ooop@cfF6@F5kKJ%26Xc2Z!D3h+4z2jO!l zB7LPS^|qvP*q5n*)28_N>^kW>p7d2J}3ZH{3t2o~Pim28i%0jF~tHtDzHMJ2Zg0@jF zd3ZIRcLjwwHtTi_d_1-X*=`Lkfg0u{`MVT*?{3w@#8dX8=b`QYldCbx!bkq^!Dy+{ z;L{N4|ISca6-iPBH`V?O0hK9gMfM`JEr2PRR!&uP?{6y(YI1ZtRo5T_KDH0wN3hX= zp6;Z<%kEzfBCJ70@wOsknq!ta(O!zwS}fq)NlmR);I6>$Nk!NURW>jTAU#0Um~{h; z76DHsNR%n*nM_DLfRR|^syveI=i$A3d{jt9eXf%E&M6lMJz@j)U8AD2-_KKKEPM4` zgwyq8w$GcCp4*2HTrsu9&9CeKNVo9vTc*~^@jjdo+?~q?=x$1E#^5K=`6R9rDeO0e z2shR->bx`Mjg8UNL6H-Ea>H6NNxte6lL6_`3ukoSXrFTWM!i0F^6q?IOy*UeKb>>K zX%~lWxcQG9__84MQj(lmZ5oG0X1MQi(F-(jMxO$%X6H4>e`bA3bIa z9VFD;H|_PFAnzk>ZSVi&@a%erR$Tpm%=G#X2jwRorGtAZytL3hC~or#yIfITMUP=C z@z>uw`=7cC*lt}c1YZar+xBQ-C3=_N^YKGCkTLYbkM(k&DfKQJ_V*%<&wG0X(xRJg zETRFHS-Jczy2W3c`Fd$vxxD~IUivwrVKH(l$)&NReVg>x zt_$dohwWjP>qjpMZ-y4|v2cq!<9~F-Tji}^xy{S@BeeZeueWE+yXe{#sEp-7X*#!u zioYE0@kd(1o;}aE4-b#@1|NWO(1(&x;4&CKdO3vh3MGfuvNpiEn3y21rd^kX_^~xt z81ULh*7+gSpWr`O@`7Q%m-LFBV8e=$k&(6AWlwgc*VEI}yJsL5^mqf8`84u541eB8 z&)`AGFoJQ7t2!`QjWvVD?c*n1{xMn^-vT3y{fP}P8U?5ctp$zDN5MGUOu$#dVsJG7 zTfmzHfWV-v&A~c6t79J0+%e+>$TI&%jEPs107y-8ig+q!-5ZlAjtBrVG;0L)!y!$h z<+K%ipdxp`b)n_f>;;FwE%MJPVTpaV0OBZ&XaZ!$g0xm-twl^7;}RQQE)W2CAPMw( z;sPbeq}T#LBq*(o)BM82VYU@2WGHU~w0S||d=mTeD)X2@Lfb%?iK}cPu30kkm@76^y%rk;fi47%c=zyyv)WgpxP&rVrb$j4x51Xp_yi(`<-{rH;TlK;WMe^PKu4b zy)&0}6?~t@%9Ss4?#^R9quQGKmrj32__^?NI296q$7^})BmK!w_-wnaTVKGcuSCDW z>mL`UMaQ>p-2she_7c7en{}H7+=~5^?3?+W6FadQlJCjBBwM((|AWsL3gCVS+87@x z{3OeF%Gf(Nm_NhN#QWaY%ztCpSW||EQ%u6f!&S2RvG_ALEWU?^^?R%XO!S6q8$Bde zxh8lMb`~9=i3eT`hTaO$FwYYIY&uV)A7veBEN_D`yBhfnBEOo1jqBof<28Z2H~FCi ze>PiVw!?b8v*{9K-p*T{DAFbSt& zZsbulek{J2BkUdGj^GJ6n1c1>=@#;zIG2b&L%j-d$9S0f$^GID z^z5AldrkstLNC7f{PRzj2G+-_BuwXsB1xNL`|1RLI$L9S)0o6R*VCPfaz*@N3Q9>4 z&)lV?zti}Fh;sCE=7(qVEoP7N9Kja&WW!84fK39?j2*1Ux<{$@8NMD#ge?F=&+{tK z2Lh@`yiEo%bn=?VIZht7MmX>c2Bv+EFiQ`X`XW}0Kg3AWN85{UbT!L6pV|9Q=-hHTxlGs2$tfNGhBSp6~FW3 zUt(tQ_v|$=hkW2mb#9J*S5+f}L{nQ7(zLWl*V`1(E+|E-*=Z@tpYY2gm=Al{-NbscR;T;!BNUn_&AX|0!=eWcyxj&B@Rcz^%bY;3;=b9_+|VVq?7Q| z*d98tgI_a*u7G0M5p*8Nry+_K!iO$tunZNUe(EN2N=q=IT&J<7!b~jH8br8AwWopt z9OEn!l(ujh_{YSN*osvgYYM}qJc)?KQB+DqsS*kmWs;&j zdKoaAAWyc+Y{q>~lC}vP81`9qH9@@`!X~8n65#O z_ZV<7)XS)VR1zeJ5d#C$x`KnHR4C|1P@QI;Lo&UsbJCv7!&k{si^A^C@48gc@VjWM z-Q$kYI|}M1X;x4>7>grvP?m~jvOcn>B7b$@^!PaibQ?Jro&ag8Nar=a z4Z2SutRpnLVC+V@&~Q6f1XWUBLRNES^qY#n9Yk0IdjjI7<$Ah6E9kwHZmnW@H!B#Q zgoF{!vFFO)!&m_MRf@XV zJ}c~E3Y0`)5}&vy^)!1GwSN)T*MCfoS`9}cZxez%ub^iV)zVDlD zy+Ff(2_5nn>}ikk+Rc08Dz7F7#em9deWB=9pUAu9jE{2CgN`l?h#>Fwpij<>Kw~oL z4NQ~pClw-gYY#?71q1j^%*_Wmhf~y?FoaNW=BS+4qf#quoD{fVW&nD`y!3TOOwQ=Z zX`%c24+tvAQBm;qXny~Q8)l%hnVeK3+tiwH)ZZYT1EMR_C*A!RP+Z{*kcN1!H;A-& zUPrFv7H`9H-?fx2W6%g8NQo*?LyE#G1g&>x zFVB3h_xsWhSB0Pa)HV*kv^3KDjoI~ISpUT5AA0oO+k(RE_JCHnEuM^9sz~5oOP5IA8N^dSOEmoadk0{)pf`iLY{9!Gr}fxv_!n(MyRkR^xzuG zU4R|UYiKy^?1ct#WVyfP`3)gob2HMmHeBOphi@x{+x@`Xwgju~FMXnYyFU`N441qx z+k+*dVf#ub9{1x)p6#4i#Uw4oDk_D+C^oL+KI?Xr5DrR|>-IXmy&=|;`}=9b$nds{ zdPZ7MK3zTj3a}4GdbVe`QTW(MZ)Yy}*6?M$`$snTSmC&>7i%AJ;HHO* znXiG1dxoV&YC3UQJIMlk2thQMr-3A7cCm28L>V^$x@E}BRg80!FjF{5N{k&vX)@*A zrpPcb#+1suXWsipu+ZY@+ibt|z0od}uZ*cPq#H>+39oCld;5D@iKei+uI`kkk7#W+xI;vpNM_5#NiAU-*lXehytD-Xxgvm{C8f zlU-zVk!QLeyH08xiLOy&?uPVEFcOp8JipYU933MGgv9KM?E>-vIkcpoJ;ZyhrTZ5c zC(uwZhh=;`D#LBwa^Uk6Vp*6>9I$i7J%ezT{*I=QGdc}DGMqph-|8?iH@CV#oh ztRiI|EKedp5$<`Qq5g4lKsgG=nL#5Mvu+`A@Y4pk4Mfx)3Hu!dzhskPuQ}UxX{fXVDjJ<+Bv}Q)vp_KSG&sEPyiK55{?RLotar27|B6c1HQM zkYP$0CBg`5)1hdTYZaG#6;Bi1if@Oa2E7!MLACVvTevWKa?Nc0HKj6mlA zL?{dDQW1VE807iMIIoLj$V)c8e#8Wzx!9qN?FML6Gm?xOi)}JM1hHB}!Hv?5jWN=A z4Qpf;tAo4LKmh^ZE2l6i!eCw)lT+?y9t!h>-Qk*~(pL}U2Dtf^bst_$-6 zbEhRT!=KD8T55aF_6#DK&;X z*6S0ripWMA#^g2}z8K81iX}W{0QyEea%a(<;q<&9gBH+EE856!TVKw$9rTtTrt5@~JU4BjBTZQ(+J9r3b z2HI4x&G733a)mgp;|VNVWRM>H8LZEb2xt#7{)p##C5JxkO@5(3g32YjZ5w@mPo}Np z(_#O%wmYxsu6(Yrtys>@W=ean>0M4DgVFf_3jQ1P-E66F8#GRB$gY73a*j7rrGjL+ zJWx+W{5oBN%<(El06sur;z7na?;%D{_oK{@87Gk19bo+q~cr z+*n(tZ1Ew~lqxU)*OhD$DRdZErpF>AFpQ!Qrc#gGP8W=oJa>n&Z#Bk zV*|Aj#kduh8*1GEPcSW%F<>xgHcm~9u`ysV!qc4+?OeIa3pgk)7waGw|R?JV0$v8kpB6iiKPW)$2o9~g}lMt=_n=f%pRz2*@ z*8XY(PsMH{X-Kq?}EyVLb&$Bj!}oVQ@W4Co6l#YaJoLD~qj2lit+mvA zy$W+M=}ofP=m6u*Izqas%%RENXrrqO?RrMWGZ-Bows0kGtKS1Y*7GHLJwpJ)==b=% z#^!YNO*kWQ-t$mGe<6)OH_NjWs zS^TU-<)o=HQ4ERRu-Vq!n~GiaUZ**piX;3xScX6NXsl`EbWPf)%G`V=r77#WjI4)b zd72-14e0r0a@AEoG#!&qQRK4}?Y%7Ar;Z=@2+M5XI>-n7*ZW^R1Qq1tA@*_ie=z*q?unff zwV{ra_8eA2y1OHumKfPse{X)X;Pir|z~L^LH%7#00~*7kW@VkV-B7xzNS2?CgU#rx zCHYgHYbSxyOrU1nB_Oel+k{v{SvJD@_>~8M-iK{y2C=>o zF42v=TF@85#z*K~Bn_f7XYBHp9KT~!xf4l|J9Q-CtJ&XT*@EELhKN}};}LOX!M1z9 zr#WBdRTkT(y*DRfx6vJU9w!(HsrcFQj4j2E)zy8Jd#qJKj{1zRv*FV zHug~0;Yeg(#Sjnb0B5xW8}H^;XU6s1x}_1x-xn1x(%q)JzUUlnpy%?EFh97PS7V^!zm>bW^=1OG>$bsS`E*ZNK= zOwY*fk|z~YC@vC}=@FbGg+i;(J>aD7=~$y6u_KP~4F|3Yc>bO64aoT^jiRC;qvmR~QZOY8UI$%w8OI)? zBZLSj0jHP*X%j)bWTvmvtSoB)h6o18W&!d5O58?(mGnIC&E)le4AZR7s^H$)Jpww& zyvpW)G%?@@hZK4|xf;e!w41yPb&hQFr`ps{5k4+BY@4P*fAY+$~uRnP}j zqi=I-$k{lr?lKO`l&9cC#bQ^^QLVB;!5Ufm?k&m%uEf)F*eb4}$Q{v4si0Un2jKRd z#yhxs+z{tj$N2$DVRIj{h(^Lcig{nz2WdmE?T=vL&V*%7nOiH)zI)k2I;5ABunC%I z=Fdw4vxXQV4#IykaBAf6V+=T?(A?nQh0^Ld}ZAM+~Gj< z9&$C44VZ$5mfesE~9L9EmC{HSfd6iha^36Nv^~Ee;}g15jAKhZLG7 zXjtKM1^FEVSZ2rBvl%tEW-q{enJ_yGk*PCH^n2__VklqE?ENOkZ*qqGO-DGa4qQKg zTs)PFd7UuB4+kirjKzk9C{({ugx(ivEvaH_I0#n4uVH6dPDjx>!heSj8t(wkn^|mR z?i?aSk5Y6HBDYVMz*c%+?Z2MrsVC{Z=OHjc`*hyGE3tr;Ws3pSM$PE9UGT{+GB)B% zhzg7{oi$r(*SzA~G#_9s#BI(={Go9a_MnW4#+fZ}SkAbuaXq<3NbGpjR^+nKl&W%} zYicdPbhITqqiMx{4#QAP#te8_>BZU5X*0-zw`P!N<{6i1#2^l(BH;i_>_#+w9X zrcg3{pq+y12nsO#b(cqb6pi5>fH?RU5;dbnyHFC)VRe=Vq#nkk&c9coOcZzkP~670 zCY%_{l*ubNGL4#)zKcTi9K~|nwPsw;41{`o(7_>(N)3(@cg zq!FaL+8?6zP;-iJejfK(p+%QSZ1+n@r#}8; zWPo%=)%RtOtr_l_ZQcgg`;?pRg4pRy=Fz*uLGPP5y5buD!nWRak1tkfyK~rIlkHjY z=ry=wJ1E_D&6YK@*L=J*yW_V@|9RzDA@gSwB~Ekp8gNH`%qmJgilYd(LDW?-7&Uqg z=FX3jtI1nS8=O@<;qbnS9`FG~_NZOsy&OPq>P;damtm4^esCFqti|?pwm?{++AiBM z*tmn5)|CYHZPSJD3BCoWgnO$gSUXFz!h!ZN^e&qXSqQM*uZ&$EjPU-lUt_3Oi~`|s z2>mPhrR}SrCl$DCCyR@H)`nQqI1mQ2;qs9sAzJFN9MRaMy%yOJbPyNdgaywXUWF@X zyy11orhgfyf+ARlg_fLczS#!(Yk)Ey)bi=UOlT4cJLN~kB?z!X>*Cl0J*EYslq^6e z#ud!)Av}^D^~CvSsdelJIX;uv1wf%fz81S&(2Sf2)>dA{A4>ob7#qeevzRh4H4726 z2~EPuj7$wN5g2n|*F2E(d}`8on@ee4I6NUsYQ(i6kdgt}jfbra>!2vf0X`edXzT?Skd1%_Kg5!{5m0yW z4J?WN1j>@yY7#9&Ewxv%zw`Fm#A_WdywFOozWU*odIUIFC&7NBn`jugs@I<1*c^8I zt+kXmPwES)TEtWjlNEY^(71AC{2K~4PP zZ;k!Sq2slULu=W6)m0t!HCoC28-@mkO_j}4@423*gVZ<8j>}atx$_0|90xUSUg&i; z$y&o^9pFN`hK|q1XFt=|@!-ksI#Z;>ev^K3u49Z#;&B>Dd>gmnPr@|TII=#}gwK<^ zL2Kj2DMxl>Z^+SbmDfSnh-coNF4M(XLs99<)$e&p?t5vrUGw5@Zsy#c?ZXT(HPm@) z&%-MYYy#DAmj@i{NpNg~Pd$DSJTY0U`{6Whwi%Q$=NpVmo+RW9Wr8k*whv|g8$)k& zJlOGIZRTrVYi+f<#K#|>*irL_F6sEKi5)|?PV8X21K@Uk}h+{2A;2p1>CYCgk*9yVqF~-zlR#MS-!8i-*_4pZlJ`=NZ%0^`6XG z=djAc=niT1+6=Ep9M}}&H4lvu!ka94RKJD511@MBS!VXyEm zltAc)os(EBpfE;i&?$ky1T?ZWW%1A%l7=o)9YY}FkB})3-rd&>_-v8z;~i%i4S<;G z=|08rT_j`t&dZPw{@jy^A2z`0M|tsYg)eKSJ4N?-_H~bj4I8eY=$@y4yf5|luh5TD zFV8)B6z4Vynp<62jZme*9@0c}`*Z|G|fSZ*A{{kKx17auS(Ex^I5E*2WUJJMJC{o6-Tj~>)D1<9W0N!*Eovv zz1C;4;i!HNbSvVH{Boi{af+IND5pxmg7tkxS%KwYEnOr?_ekiuI7B+UfAs4;l9Lbd z6!92X>XyvfJZdRG=!=T9NkCB0jdcMZAjizQ0qq)o{W`9N1}k;Vy~X`5)};L=@jfbi z3ep|Fb2A;Jlhi&2ohGIR`>|x~AkxfD9e}>AO6gRQL=QyNSkG1d*LA#B2(KkDv7oW; zQ7I%b5a3|JYK$e8XmP+^T3$>+R29p3>+Z2?F=*i|zJ%J{hsK&Nu0mQQsg zUJBCpPeKk6lz7BRqYb5A#%~0QejhqckE+fGQ&q(|_MCkvYt+jU=vyJ;ejvT0Yn1|X zcpC+ul7^0^?`qOLCaEv55s{&78ge=~KVr=n1yyE>GQGl4-(Drj%_DT6C^dHEJ2~n^ z2QJWY8bAx?@wO8wZW;pkgPr(RsbTzjVKzA2x#W?6+7-7Nnx~Px? zqWec^0iK(|Dlz?uoQa}fdg4=J95GuIFE7)SLDv9Ux(84OkR*gABq|6Lf)G9TIw(aM z=PXIV+E&4?=OY*Qeb&Joky`O9G3p*Y_9CNmi9|1b_kVDvwfTs{;@D-CB}_@YYPmNZ zK{bwcBP73t6*YnFTek6#{x&!N!N!cSicA92R3^dKknocgAOT8_`z=+-GrEUKHY10= zehG0-gucd5DNGww2!b4lhkvtI5v5SZdA>e93GQVM{{Q*_h&A_qjn2-^iJ1Ki{_=;-O25oe9!c*-ou<>0Eh z8jn?a3A8_r3`Oq|^jo~Hk;c^jhmmyEv&-5+AW$a2@xXGJ`RJY#T%a~0qRVx#4EduN>~#h@Iwd{d#U5(qEB6yL z+7JB)+KEfDA9}|F(m_KFWtupL zAJn7B9^#^IsneBRf*U_c2_rBPnehejFf=NmXo@mZ1^foBl@!_hxYzGHJz}l*k$&n6 z@={TnVVK<{M~Naa}t?PA6+lQWBMC2=@s8}<6IGbQ@n_K#$}TQcoW;5LzV zy0qL5k3!|m*48L%%DP@@_FR0LA7 z13${+Bw5YQqLu_@8>I5QC-$~OQI_fPyzldD+5IH#@NV&zzo$oi(@SF&bz2*6JpRvL zUgcloZKh9WmQy=@tFRubRZ#$|QWjj$#lpR8LFJ12VTUHlv2Du=&DWF}+69-MixrSA zbc??4a_4t-aPT?^=ynrwufaBh1*Uk}4fm||1CmPu5EXiYUVMjQQK{GQQ-AG>a0xj2 z%Q3B{)P|2!r_4m5UFH0*6VJ|^@jPVK$FEji9rh^dUyuXrfM8Zw;^k1Noq+W;&4gmCY zPPY!a?y5UXDb#%pM~LD;3xu?6o(f=G2T!w8Lt@mssbE2}-WWNI#bpY!EMHB7V*vgY z!nlA~5@s`KE0km$_@PwUfL0bB*84%-X=O4p0%yYwE;OXZkf$(igq_aikUCwEm7ha3 z#as4cQf@;Gu^2IyEh|kKE}ofcj46x3LFG%PWF6(lVJ1W;=>xmx{RcmE?TtTu-%}sDcI4WT8vWq&KluF5KlAg??97_Gc3*w%wHh8= zQt?jho!4Ib)vs#rJX3qC_D1c6+B0~DSW~z_56Ie+TJ6RgU)X3IvB3gdGC^0f_raFO zF`}NLvow^9Z-y6Mn3>^#-K~vuPL^J*rzz-PaZVlIW6if%^F7wQ{)}*+w$*bs^I|tx z)#EbXMtGyp#IrAz7dy_jgeaW!29*u8V-Zq{ycJgiLK$$H3NY^_b~-u;WMZ$YQX_-5F+@vY+< zH?|z#_`{t`-}gRquIdo(o!N|QpKjl|6Tc}8{owOI{9#S~?L!_*oCN?(p ziDqt`rqS{9S+D#XLOng43p$_hG(O$X(fxNO(Kx>`wy%!u8!)0l2dPEKc1}N8GIqql zg!tAr|_4Cry6`C8=thLYBpKN>017t#zzi78k6P8mow0bdS&tO5bHkg z_1?Ic?Ss$o`w-!OV=3pGNY{?5@%l#-8qKFke9hy!wn$e?I510#Z7;TCyb~ysjWGwd z#(eLHwVnGA3xF>L0)d4#I)V_QL=_ z<6*upM?gqu-=6J*>2_zH#Vg8lmt~0SVcO^z;aCW#>K=77iK#KS34?Dd2+EmZ=$xUW z^bJ9FmFMn@=t-8VHKM;HQdJ|1p-BzNnKlyOmrXY3TtF2RCz3;XQwYV>sngWHViu}Pw zOPmrPhlN9r)|pwD&Xn4@?sfVGEVzI~aHoodUo5D7s*h$+M!6OVMd4EN$0S|71bF^} zYnL~-PhCd`1B@zW@3TT4i}XA=kSl3r`$;$!fP?SquiS@HxF2(7gpYOdI?7Q8x~hXc zRTL4R{eO4N-s?4?<5l3l^E;$bC_F!12wbULVEAr^Qm9%F4(l$cLca7$F!*#EbveHb z&ijZ%@89?1GA)(2dZ`HOH-~MrS2S*-XtOAlov3<1L^x-0hI-Xz=(Bgx!L)J|bb=Q{ z2kH&5WBf6AfODzRL>Fvq%fK^GJ`s{2ALXNpV~fo_0P z7G4z}$orW7a=M~x7ieV9mEHRsTz^1*3rM}p4HR96&%8d=6WUDccOj2l{3Aw|Q5KNz zK53VI#3>aJEq2oIhyHYwyroVB+T6fZlw0FWD!FXzWjEDFA167`I|m&kRD8~zLX(h= z9OHB+GXoHfMkU|e%H>n&9v3}ub(;;R3d0>b%na_4Q78*fAqsby@)+huBB{LqFNY&^ zh4J?z=C}Z(1yJth0dtW;8tGM4_^-|rT1zVb))n;2#aE--Xlosi(q2r z_&nUr2TmdwMe~FMy{tLVR5K%-`(L3ydPR=6Z~cvs+{??(pT2T4rJszh=yr2z6VlUI zAln*Y_J@MJ@)&9PIyMqVMMonHg=IkVzI@g!a5{i=6^9p@7?ehJQ7c|B`e_7IhL^#E zH?eJZOlv^l#RhyjGQMVG5IRnVJ2W`wAx8z7A&CZT^Xtr{9I8GE9XTMa$kVV>5e$H4 z+WC;wM|wUwSD_5QD5Dk>7%&@fFNQ)H@DCnFo>3uzh7ODdqn89Ni!PVCj4LkC zC=A%Lrq%)?0ifqKc9Y>VpVku;{wY|lN(-s3M`)p&BrKtv{(pujJx2upwnG1Hi<7GW zpElcJQ6`XUF}OpR=nH}>@Oz{*>K%`o=~ZZ&ZeFR;QM^~YzGuTQ>RWrwi99oA_3(Z}Ez3`50jKLfl6YkR$9f2rS2m;fcc% z3>4s0(G!UroN>6#;;E{Le>;Bls^Ti3(SyG)EQzOH`yfd`UdOlg5(|4$Q(DxShOfzEtBqCc;sJuP>=pY2X7g+=t0(!O(9H zzi!C>&U>qM592(-4GEdvp#C+v0v8xi530)z-ZSX0SyTtAf-i*XHJptsPtwxRzXmrd zy?LmF>6@j#2s>jB%GL6Q5B$j;Lr9+;dUNTEe26H`zfRr-MwPQX;jAn{D>RZrYoPOJ zH)c_&3cPidD5_Q}_=b7kbhWgmvT*kJF#K1WzbsYrP52~l7@|K!FhxCr{-}f>e(1uq zhK?`H05yBGBPujZQGF-d?TBnHVa3LP=QyT*SAzAFsbE55fP8Y~4I31(>$7D|-~>~{^3 z5_hZ7XDga?5EY`vh(Z;5?1(Fc8mTg}T9Bw~(FtZVMlv8W3Io;w_c&9t4Rl!MIj}#n zI1rSPiql$Jvm8Lu3L}6%4pd@0+vL|_{1&(-%6-}iWuuYH z>fw~k^rQqL4z6y{ol8mA(ShyVxon&y%C-6?!4U>{Q0q{m<3x4g@w_FO6N3&zJ-I|J zO?88RVz78+GKq+p%iAtx+U4V`Q(-D8QtwR3(Jz1bP4E8Jx475D^M#w24Zr z%2VPcZ>N5Px^pm@AIZGSfj*Jt^S~&V>0F*C;b{6EhRf$YW_gn#&tacGTB+?=;up-; zUUa;689qI={Dmz&7>;^v%hGb1kSFg4%%!LCyui*n$f!s1%q#8T@UR+ANv!dK;;T#AQ{ZK1ZgbyvJ3}NUU*3fI1cP zEXY4f8u45{R+$4DwgomRPTSjgqsa@Va(D=Lc$6@nLlJ`Y6*Ue}$FfSpGT`%-HU;OS zWq5*{Qr4|#X9A9qma6hG$vhcTXd*i|5$t6-6nW2n#}1!eLC|gofBzCoqPqo zF0L-dS%1_8)mZ9A7fC$WCYgPG?YQA|o!>ymnx2FOybp=#v&v#HR+tcjE(RL&o4q{; zKkH&~4)iiup)U@_ndD^M)@c(!y^kRvixa99cHsxDRANqP^wmn>#4?Ezn7knYzPX+t z>0v_Fz9fz5Ex?8Hmf)vEQSOmw_1>$zu(O$r29QEc=U>w2 z_({HqfiBCUq&DqVG6o~xLSsL?1<42Qon32=`EuFJIcp7lI%TxH9kgHj7i+Z1SxAcT zsWZ+RUr&ogxqf;q#G-lj_ABz0bokaX75CwdspPsFfM$3da}?-&$Z@Ctk&%EBBK~=`v#L#dNld#yr1T1VqSXV<42ln~3t5NV`G#=FPrj~UoveqGU zftn2nVUa<^fDV^sz@}In$EbfBbf@KjIxR4iju|9|QKXKrM$EGe^WaEq7rW0zV<9$X z!Fr1F;nJP}jVT32{4lUVfOaHJfwUj#hrw`G1wh3(Ivk82OyOP=?4t?J@qLRYI3pAK zWRZGAA_op3u>r9P@TAj1TuGUN@(FwtF+?nSg(E~9Q$t(weWNK*f*&Ok+#pW$RFDOt zVd4iz9*ehfi$=5d$jL}1p^o5Z<0V%0WTD&vJ%&m}I`P6+Z4S!=@XyWG?yfFad)K?( zKV)sK8dgL1c9|WxX4pe29y?8VmO(sgN|B8$ZxWy z)$$wbzz4md5SyH!*t4(6M(eq1pIK}h0|gL@QvWhZf=g>Xpi>ktk}u!tifIuS;v$8edY_=4!+#wIOQ;5%19ss5oUIxA8>)=6N}&jC8K!_=3Q#< z(brchZF;AF6ua=iD+uult_5%t;-GpMhLT=|Jr2ecLjY5ma#SyU&gIk+71%|dZyDFU}51|g?Tn5vSqnwf2-kFkO}v8MRaT1O$5=Ott&!Gt;X z-O0eDmBd&}q+dUm>OjmYXxmaP81V__QU)uV6rV7(CP3Fy7cX=vnCuBGVcjFKl9nBZJ03TQ(t=>{MGi4JI9P%_1O>RMt2t+A#8b zev4@2qC7J*Zft2xYMcg5r9TAHz>XYQHmduT&tQ@xAmgnRtI#O~n%~i^t%16dPF=ro z;k@#H{Np!1*gWpI>5GXx^SA5B{Cr8A_!o&MYe%kB%Bk>M<>YmrEGK18fGtbNqzull$Qt=PJ_Md-?vyB^{curnyj3ko*Qeo;?Dc|Yx8=r6dySMGwqCUw-dT?)wjNw$guf!i*+OHOUBZoL7juv^CKwT)|GLSrc*EYsC@!CzqDIk8+0c zTAw7=?4X#k51gaUh{jJ#9%YC)*Cbmy&q7y2q0{JR`+v&%1kgX-o>W zX30i=c(Basd;~SE|M2A#n6LB?t%8}}1?HyltvBD53pGs7T$264EWT%3QaU^fgJ|Zx zQUyPQN``cco#^-eFbd{^#M9PC-@E=L_htvT)Pzm5B!;%Fj=Sblc&heHp|)x*<{egM zEqsF~EGJcT(g^2r0yVnya1Sy5nkkd8P7wN&|IG_MBlGYvo;zaTfLQX@fTjqE-k z7rZlRqZF!Wc7}JxdvMCx0dfa?oC;<5C$2(kLn&Vw;OCr{c$sL69>lvcPn{Z^&G7LV z;@JqLSo(F+%;o8-vrR2znaUc$CyJrsE9~aax9&POy`s-u> zk>WPtTw;qV@vC-~!H|RMpA~PFnaA&?Hveolo5}n*;u6+-lneKtRFz+Y2u_)^X%Ji=eXVPi zpKXiNBm}Tc;=Ez3UQtCf&{2c69+j}$_~D%$ys+dCREKk( zH%N0h0LF7H90(s_@GFNmsdw+3N5o~E(oV3qO?J&&66JuT^$Xx^x7}0SPgZ&5*QMxD-U!pXDWzCG`cl= z@f)d37&ss|S2$%+`!3uZq!MY7s4?b3Rx#fXmB$3c5+%uvm`kBx@j1lYMw z{f!xCrMSv@i~Nx_@iCPuRr-1%9hAJyPQ=jL$W7W&Ymk5lZb==Ul@jh!s9iEthm#43 z;~(J{&${0dP2HOA=$JQwW;HWLD>guFLUM!|rBGgzOEdwtQB7u3Ml-5pDw-T3I^f$l z8CUf;Q@YDFlYhL3O*^@3jnkqWVnduiXs}-io}Rks6@t+)4dxkd%yVeT4xxPV|3Exz z?T@KQ3?y14g9wIb(kA1wKMi}onUtjxH{n>AG z78gb7|G40S2m0_qGe3fZ-y!*Cns^>42YB_CEjzc9Pa>awB0MjvUq!#z_-LksX*)-L zaVO&pGF_l`?&a<+uicWRolczT!6{vB;oY%ca5p`OV}YsJJ~DdIQgL3PmP6(n%;XY! zxm-6+GAA-gna6sNTKHJ<_bF8gUF#mhlFKY(J;Nhr8)$U>j@l zcR$>CsayKVc=_@u+yCPJ{f)~Te~TvZ;*)~w7=EBnDPN)( z?hQkX-%#VZ3LkNZah9B>&#?6kIN43e%0;XVgZ$%6JV88{Pgg~;h9?ZHIHdbt%-EB) zdEt(x=aM>of}M0uv;(yU474at`FLOitxsGI58}rXw(85#sW6}Q7247>xs%12l9R{S zD#pPWSn$yu(lL|I66c8w?}M8Ga~>1&vmLKgnb3+cR*GCL&*QcFKgprhPw~274^3*f z3+Fmfw?Jo|Q67|^XJAQ0@fY%#u}YQ0LwdQ6Bog6kg98D zPqa75c7%`rV%mA9PN7J=O*$xOsxU6ijx<6VB}6Wah@;+t7&Rsxu?ErsnqZKGgL4eT zg9_?E+=N;aTN!ck)(Wml6kV@Ueiacl)nFpL6)pq%He)2CBzIY@^8sv`cozoe3by5Q zmthUSvUlHkOX&Dnr1^Lg$7@8}uSfXi+hHL2Odphed&hO|Uh$S|#SI&|4L--QppNlZ zlU3&}$*sY-7h_#YAM}0Wi;{uK8z^IT#(s>!7dQdvGrRvXFL5W;+U80yUBP^k!xME| zL@+&%*S3Tv@ASZLipS65+vqZOm|cXa7IjY1wPQ}>rVM&$Jv>+z>1)t!CU9~VKH$Ck z4?f^=e&bo6`;NB;BlqL4{B>_5`fL@_#WQm28N1+%l+%Nft>6~0hM5eG`sPWZfNj)N zC)N(MNQ~ER{G?%TQ1e9X0w<$PD!@1pu4Gm(%g>{JrU%yvYrD;N80w*Xx@g6>toAm!#iL8c$#n=%I`1)4pT&O6F=;_s8paPCtAq8> zR)cCfDu^fGSSFzU*QlUPJR%9_v_l=2U&Z+#Q+VryI-+W2EdESwq*EwnNZKXpCmfCw zcM;Y_R^b3co9CBUDb|w=tMW=R9Vdyc+<@yzp$4%s4)HJl4z3f0Pp9U98=@Q3A@eIZ z)}H1NQC*c(V-h=zd;6y3JSoPB9njZQ?2-!)FcHIG3{9sW(Zbn9day35YUIHNq$L(( z5Sa7rxKk5-P=J!;n11| z7znwUZ?N_bgx2D_@zfIv5>QT}R+w~lLIaP6D<0~Id4wgar#CtRbG$1MNW7(RNdgBw zOV+S>r3$+C%gD(G?0o_+EtMs8S6e7eo&wsakY0E=?XpO}Vem0NI}DbCSd$}$kh$9d zgEG|@v24g@0N-f#t!(v;csMagKxr60+!IG_>;_dHVweL7UpI?t0#p;)E12+B2yK&} zbYzpvA*wE4Oq!;ptz4Gc%H;GUXP6bXhC?4%_uOeSC`Cw24@5PRlNa#GXr_?(5g{#( zDsiY;maA8eMb7{NY8tqq>_lCvduGda+Bafe;ls zbvVg5QAPP4rE{|lOlt_V_}!}DO|;V0s(JD>@y5vRPc(Mye&+A~?!^~gYBauo=8m`R z*tz;e^-=tw(ZEYt0`zU*TT%6okVBgAKx4aLFJIjsCgHS)X?E=Y%iV15zdxUsk{O-F zSfj3Q_wJp8_a9z*n&}&MT+p}Uu4i^uvJ!V4$_(5G5aQ4zuV5f!$zFd zFDs96C!Xg~KBG?-vwQ`c#-|f?<{_QuWprl@F+yaphYj|pCO8cK>`+D;aQ|ur$ST;@ zc}4kVdA19l@v^lazxBR9edf`c-hwq>mfjgdRRXR4#@PCLWA{R%&)dD>rI$wfc8u=E zeBkGFOh5mn2A>X330`U({^kQCJAY>93%kC~vy7QWKCyGPH1G$2>+0ZzcmIX^FO1{H(gryGj~r{*aU+6{&kB8gr0}ef!l}%A z%w*eQ)9fi_yY$=TOa}Bc@r<9v(187`%jHC>PFI zLgvfNe2ki{tvuBWdmwgL_whI~wWW8VshCD@gE1YUJYDN}!Yg2J7e0&B+hjlloeZUs zmz@?NKDvmSN1vsyP&I0RhD!lT-|db+Rq%N(Ivjkt#(vcZks7mUUVKQYX-%hZPdnGQ z&<{n>3@q015xD(~4d(~|9FD#^f&d3p9ePY|fzpG8r`CRj9DOb05Q7^RJOI*+B3YoqD#Xu6378xVn;7;qA9gfrZ#X% zD$gfmu7YwB#F#Tii)ibi-e9#Eg9mn@O`L-eULJhM7hv!R0f@*_2LZimF*yYjBRmwU zEaVGCU#UrZ+LrW5$fW{pk#iFwzxdrsIJsWr^Dknp%o-*!J_|nqVp)1$ChU?r&bH{X zH%KD5nYG>MrpsPDyabaP`F-3z-F0PeSeCenM+!8>A`ZMFLa{5%dSjTBOoC8!sOxYY zeOChoJwFSdqD9QtI`>&HXMy7`TQIUmzT*`ieLMG@2}+p1cpobQpX7Z5OBmi&Pj2;R z9ej-HQn;=LACwWlP?I~x>QXD+A>TYJ_9&mdTvKlz{9A7EQP(;1zdDiI4peG;W3lqL z-{lOjHh@$cpzYeAWR_M`nk!4#kG!jlAMy-AI(<pHR4iR#J#o`vx;Om)mB~RH>u&ONM1uPci2vEk@ERQ!LYao8!oa~r#`O;2nZ-e< zaQRRvv-uM!2`8xRhYw8+uX-@NEfV)ukS5j&K3$K@m9X6m&LnGCI49P;X%5oCYP4^_ z54m&C*eJ@e!gVDXNA3}vSiX%=oP$394&+1s1Y_14$57>HrSB09RyPL7473^~iia4! z;)YWHELP&MoBZ%NZ0T*|#Y#V1WO56@?*P;lPEQ$kxb^pc8|^`HY(AUDeN$3s7MM7? zZ+5}_ru^E25p-}+xy$E~qYe)U^2eWp8wuo5si3)=#T}4gT(0FHTIL*B=H~O_ew1s( zcN{m1{JN9HR$dK06reJQP?=X*(8Z%r4GQa&UPSH+VEz_$3HD$5N46?r4ve1vtKY#I z3tPve_I4y#+sdZbf#&(&KJb zG!$U6;}mx03W(cauY}HrZ*maglQ4_#&j{!U`U32xC%k#sJESs04m4e93^*>5JwBEp zo|G9X*P?9N8CW5f%?g}c&H4gx-9>Kf#wB7&gAHLukOXkTDr4VD)ds$GND)Ffg{lAz z90F@`GXrx)SkRP8nx4einEKpGX&n1TW94H^BE*w`<$4-+9@80zXK|g^%VRno=7%{e z@ykQ9ec@bO$=1yJ*py~|mKq1}X)-bca9$89j$5SQE=&mUGX}tmLZ|NQH94&^GdXip6@CfXxXdH54TIo=(1{PAtHGM- zjm(4YJBt295ztZJ0RW7Y}k2^mAVeK?%M z<0rwh%rdWd*I-XqZj(u6KL#*ebzs1q99o^*8Z@v|Bxa?&9ac0-b8z!aYl3NFCqZcP z9|h{U%z0l%H+;j$^1Z3^ahxqr=(z5HGqKY^utSHl;1 zAAON+d&KO$X@N5IL1y|y-w;|f`IO1h^KqN5Y~LBi(3_Xb<1L%yFbllPu`RBBKK+jR zPZ2M4%D5Sv>^L%*zaFEv2LB@CoWABa+dR7r(o)F#A~POi$9=Z>WN2|7S#o&pra0*N z>-BX&)8=Pd{6rR_ncos<8(2`?j;2uSlx=L;4L|s`hMfgFMVml;Y!pvJo-i5$pyQ>>|DL& z%w7Fk+P>Llp6BpK9Xod1b=Sz!!GmD!p2X?~au{1U?QRqrFK#%z<6gnasBiPPRG!D~ zHRq1*n%r90zFTHrdTGng{oxkmizFUNk_&i!8F58s9SBTIPAM!Z8th6fuDZy9M| z4;n1U`kc5O9_C{HKpgLCaMTn=_4$~2_}%q}{4%g{%O;e~`Q{!^>9#m7%dIJ&QR-X7 zx{c*=rwk3~>kDuP44AIK_>X+ZU2`b<$~vZ7ts9=G;^WD_*k7j%j=$o*)QGp!Cn@gk zR1d{Ln?P?el+z~|6IeWdK%eYoL5QuxGaczY8(4lg=Pp%x#$Bv&)}FakUh4t*{iGG* zG)^Ly`VhOv>v${hk3p2_)Twe2Qy9Z_3e}3myV$UZF-&riMQRpXD5wF;4+s* z_(YlXbbxvx#_O!cemHLp3K;VeJ(I_#4CTr^fgH;JfJ~Y^(B}#&YcT2?P1D zW4!7}Ajce^1ebq%{Sk0AAL8y1AstXK^;r7q9||B}9})wWt3QFI`D80lT>APLrSR11 zzMyaj536Fq@#R1v-m~_WLSgX#QM(U9^3^ z7Y6($32LDcYswjndxxP(!h;&aT?belu=*ecc^D9tt&Uo;5M!NCP!u?vP9Zk^FkTc$ zUo>D?oCF5x_$MG|3$Pbzi;!9lmwwC(M3p}_cQa~$yWDNF5}s$}iowr`y3p(^P+=^N z4>>t!3EwK;44Fra_qVM(g)@8tMr>@d*%NQ{*s*k?rSlF26Ctn!uO*+ ztIoAhC3TUH7p?~aIEFVd1G-o%ni}Hgd7Bl_9hYCigos}lrwk0{eFuYt`(-bQd~U6` zW@2en_P!UBcVcmOyxd!JPTk}F+3=&$u!4QEXZu;!M_yuqiQYoG-XnaH=dup>TnpDZ z6B96rq!OloQHC+bD|3t5IhETMWn-ZZAC`fB>&ty*DILXvQMWxScSBD0E(#_rssDyo zY7SZ(f6+#LUj-k4eEb&h)-!(HJ9ogaiVG-u9`UAdkv&%PQeOyI^hM$yL8b2zU$!mU z2*gEN571tLij1d zN9W`IQVuIOyMkQpt*^gz0{-Q2d{fjHI0yX}>#DLGtY6~lQavzsmV|u)7RbQZ#LKa~ zbp|I@8MEIp)bu2IGx+7O&s+{_+nxY(9PxSdItliO%mJ5kkPd)+a-m0SwZ3Gw1DdaJ zzD1|N4@_UT4J<;nJ7Pc)+3Vm728>V+5CcW6{k}y+^?_Ar8i6*H!cpP3+qR!Vjul$K zF<)|UZ^9)9-)5+L#$bOF>0gA%XDjxO5BYZfv5I5Gi*e$U0A7I;)fE=Th7B4}FyhNA zk-oSMLj!OKc^N~H<>T_B6WsP50PhU3w>^t(j)2~^NBwq39FT2rbWboBBnZ$8#9+)gP^6j5Q(ROoK{2Ba zGDG9o-&zK+1|aPWsJsa@GF2?^1Y8%fg70w`N)eWIptb3HtDu*nntZ1C`mk2Apa=co ze^H!;LFF9-^HQl@EpLQqav8;r)`C}+V2YQx8vZyj4*)^jQlvCH8{zpj{D8ct7+See zO9huA^@Ykn4d*X3gqThkp}z2OLV?JuAW*^iLQ)6w=Avbt2ZN#?fcefLD63)5Y@Fm+ z50b;Z&I=F%0M>idxXv)(cuwF9wG(`dFu}USXa-)y;V{5w)YycECM%uCt;C|RkFuUY zTS~Y>M(fcmyuyx4d15`5Tn@j0eWll97=-g7o)8A15Y9vT4>wh?u%)S%V$`B64qs%4 z8{w72{8CuKV7cZ&xi|=Te|keHS|6g~C1j~oHhH=&4BUomXaF1@AJu_5)&aIvvz{U7 zdz1!P4}-;CsOA{S`eKFSSJLVOC^pYn`6n8 z=AJm*%Uug8ni}$~9|IVE=wlVrZALbW-V%M(w?|c5m_|dC&jKcE>zhmFlt-GFI zviUIzzx>vvN>#71dH$uBKG63--&@|o^W=rTojc$1mYq9a=z~x6g~pNR3%hnDwQUdo zKK;gN}pu~kItkWYMNHYtrosNJP+aJ1vyH1`Gs#W{6fD|-(T=osqb$)p2R$B zVoSZau0`%_L`L>6l?C%4FKu8VK(SmIke>z>=8O8Un3Ll$y)=}W%_P`(hOuP_L_Vy^c%9Ssj-gvHJ;&o~fZQPFrK2flcHvZ~3X^*~6FJeB8SiHqd7BJ26 zP@)N90Pm4_b%6+WNbmC;5SJCz=JP~CJxc(tz^}dW!DHQ!`mC~0n|SNN$w{Fyc zB280$hAC}OZBl%57c>e=_mRmrD)I16P}S)!Fkcj4@<0OMXW(1Be8hN|vwg~q1EVuu z{18`LZ~|=bh++f0);Y<+Jl^dLjHTrO$*Stj882jK`Cu8nv9umy)DH^2HV&0Fz|*QK zrhz3VJ^k=Xg!j-1h|Xa=rZ#~TN+9SUKw>r+l$oXhFVwIX^Adj4zXQI)I_9L+WEFgj zXCV${Q8r!o0a-J=p-HU$_(DC@UDLk#!(erb@nBbt_~Ll z{B@XLg+=#KehLolHfE#4YZ7)lRpv&9A3?sepz5|+x%<3D-{IS7JfV5R^eLV%SK!@- zQV|2df;dKa`+F3!)%uO{NXw1N3$pH(T=?#)A4Dk+3jEdufDGP z_bm^vU3eoJ?VFv)D8c1-mJ`uj!N>%gQE0XWwK^=N0keS7E~A!j#0eD9v$FW?>!p7Y z^Cu04u9M$~^tG!)w9i=hYETO(&7e-C?&Fn`zS{*NtI~HpJV;raV{?UMgL(3o}@~4g$cxiHr#@L6RepiQCXp^uLE&+>3C0N<&%NP1D_hc*5@4ycg zJfFvo%@%8_XA>Wi+#P?p5udu2?}QCB7X#>%@#-dAci>4W1{ptM69()fiA{{M9iDAU zb^zta55k8@-n=HThBabV3nNx?w_{%8llt=uX?2cXepMikT;;ht4mSBrL%*iBJ(`e7 zSZ@*@E92wi7C(?_q86{3c(4!`%9YzEoR}GJdJ3EgUuHnA@@72TV)sm&=}GkG#3~El zc;K#@dfi@`S?87H72|F%U3Q)sT@|h47&QhrFINq!nD00?XKY2ph<8bZy9o*(mkEQb zk-simO|&}7Ob~(4Uh4u>Dg~Ry{PNl}kiigj2nZf>kYzZC(G0(eAe>_fIM^}~i@T9S zjNAx$bOO2r|2SKVVu#>!q#L>l``2;#li)XC20(}#43#KULz$28O*T%e5<~&@4_1EP zx7K2V=}ilLzv(1+5Asc8R$6gZqSruTIGOiYkun=PTS3J(v(m#Ai8z@4t)XwSBpBWA z!jwiS4n$FL=)&0=1dFH(-2d<4*)|MWh?TS|QSz%0S@h1a9qL3!XgM2_K1&0B4VP|Y z)T$z6ynv$xkjqqQbAM4y#hH!pGM+(Ko!%4&P2$0d(79{M=rgmuGCs_aBc-z|S8fa8 zx{boojTf$2hZ*E&hq#=VN|iEJg~ZB`(6ULQ%_T3e*cBUTY|42^k~fa>JLk>8X55SL z6B@r+2cR)vM(23aw>dly7gSWzu$8!cpfTS9!##GEOraFguBFZ3>&FC!F9;BoZj5Lf> zCahzSq!1ft(5#~pX<+ljinv)Z1qGs_XfbQtUSVaNT9DKFwi0Ti!}+>Hy!OF5$YY=QO39rf0gE;)-{?SBV7BYWQKb*&? zZ@!)BB|a5R2Rtde^3k087}x&v7ab1Fe{A~k@Pz81hQ3D5Q*<~KQXiyCo+Dw85oU)XodbLTgLp}_7N7OS2<8N$)nvx$~vfJ1!+n*fse;AN`C8g#xR)E$flddHkW#3oal{NYb}# z`QG>L!`TOT`V$W{9@_nI(z&f{DeyoO9ZSw@U`iUo~bc>5%237#xF#52dC#DPAR(Cd#QlR}bD ztETPM04Z()0Uj7VoNkDnRp~)kO7%D;QLn4C{0qr%1K3mZyA~IEvi5dZq9vnmR&^w! zv4jtyFW?&jRbU-iJI}>T!701{u|iy!^w*+(NISSX_6tWRSKEU4aSUIyTwxE!hbAFg zSd0$_fx|q{dGzy zv52q`gN3TBeoWw-L=EX8!NLP|%wDSdviecyp}xzYA8)yRG+11KI&Gusfna@^aE`$_ zBHDHu!y=2rAM_yLW4OZ!L(4=?`ry&?t?UJ5@e0=`E}rszDR`mVixAgXlVk@v zsIrpF!Azh9Jgc)#Z^k*NO@C2GFK@{8}XUV&>H?qq1hiltOp5Cm-Gq;Tm5r zmqF29C1d9=xh#S0R6VzNQVy18GrnPQDZG1i&94^fzWLl9-Fw?yXHfQ%{PL=`K3r_# z`HOh($IBk(ZLSgYAqERCfm_*AkIGF~2Qm8|+ZGihtkwMr*zhgQiaQR}TS8+>aH*rE zvYD^JMF+bkZkT=a1;PcZ`w1gT0Fq-WqvZd~Fk*n|sEkZs&8?Xdx%N|kNwQY+o!oua zvp{D@vtLe`kimqV$E&}AMU(SJ0*8-s(Qjuc3)phNW~;~(!?(>3^_;xP^YKC6I&>IX z;$!F|fps!Ie3BfT9I+^35Z6ps7dNRB#=sw^^9(QdA=MX^k5`i?}-y^yjhL@zjp%Xp8gh>Wt*m_lrm^Iczx8R(`7v6ma`wOF7 z0|siK!o+f5<@_M3Ac~6dRjlq=E=C#d4DqeNsr@&%%gfLt zha#)2tYO(zoqQootMo19N>cr+S* zE6V+=XW8?(z%2(}PwqxN+fu>>)C09?=TgKba?=vnV4J`>hATTx3UCdFD<%)ZsTg`@ zK=#>5JHTfIOS2D7O$1XH&KTK;udM?gH=>!zDeJAXdvJGh6Ei`8PjmP9{4EXh4q32u zd+jGfx>T=$QXpgN&X&+|j1Vkjg2)0Jut3NHRB(ij7-G2YE0&H#$HBiU+7{v?+C4bc zEP5~4H=3S)5KXh=+0j{x%it>H4b!_5YGbKR0R(H*0@p&hzGGA6Ft8d{;yT z;@?!8^#|q4@TL{R^WHbR5I9_QuZLu5LF&4sBI?kmq302EBg$FgC+l$YvNTksYZ7qsyR4hKo4Qv$W^#HhM(6&>{`u^ zLjDM)M6gL%`k%4S?X&KchXmt*)QOn=^naZr*uoc0o}F&j}@dQ&EbvKr#SBx2j2+G1G{ccE}*BPDW>O zVkgsToy^8$^Ohz$uuNLkkd`hRXu8jMHSW zEtRyA72?g59}nVGjcco!ZK|GbV%i}lBhw0j^b9USDH~jyq7?^(Qu7JJ&VMXH)CMj| zOE`Q8=mL;A5jdNqE+BFVnhQ-1KULJ)Qlp&*&^RO_PALymcmJB5s2`oyYOq z)IOy79F>Q-buHwr)#TGsoR2l91)1OBbmMxkdiB)Uoi{%BwL;-z!9jWM51#vjMkDzy zlNHGHWq4L8`W`c$hp#$`4-O{Me}f5NBftAhwl96xIYE~%ArzauwZmMYIthP^GV~FpGoC$Vr*+(9(j^1KT$GYA`-iTYjusL zD{WTEHiH*Xg6%lE@hC$;K9jXY{ z!`#M^=NqNQ3%lW>i%evG`?uvIT*G8!X`r~_@T!R&cVYDHd#Ul<{X_B$zGr^1G1Pz) zBRKLGm&;okFX8-2#yyM4<63M-(3wuUvEk)sY#H0EV>;Q7n!ZAK=Xc|5*up(y62Bo; zohd&vvH|S={x}{Ly654bf8bqz$oOlAw~T!MdoRAI-++Vmq_O*5?`o9py?3B^e7tefH|TiYxw0wFZDNdB86kavv4_W2 zh_0u&!on-SFUQ**E|EBx*aVB03Dm-K1}~dA03U#hs7o;BC9oU?lSCPv#k_{zuJbPU zt@{$^PnLsw3iLRcb@TK3ZTHMaXSF_*OsaCp+1j2&A;KtbqC{NF7nk|u{9~hhuWS0~ z{A2L#DV_57-(EIQ4{JaH0ep?KAZ9!8IOP&XQW4@tk2q%BCq6=j*f`HkVP!3|%5&Q? zYv?mM%Vpmn#*x%FrCa=?s<ABVL`(Z9;EZ*_O>mZJLcLz;?J!pJ`gESp=Qz`8n5WHu& z>=D%m!$1K4rrc)>v5zeL@Fr^oTA+dEdEy_`i6bd(${=--M)+O)^3HS~T7@(Z#Jc(w*esFw^;zQUhfm5ux36kx49a zf5y@QDb&P2XHn!W*W$`=yt&|=vZh%7$0B?MY#_^AGa>tAunIrTLco#F61%i{@P1)MZ4kf-7q-DT160%qc^!W*3)-W-K?^0?$^Ib9KG&a*H zob%EOHPvT7buIWtCmva`wF+dn;Ygtt6=JbZEV48Q_fW{Whf<2Mw&p?D`A}4;9LLw4 zv|=O!Fw%T_#pf+95?2}tuf+ATfZ^4IW;J~W zZ3Xz*Vq_}T@w7sK*0@hCp(Mu7`WSX5xB(qk#Rvb|b0haz`NpDei{T9y{Q>kGd{RZS zAbSdG8z-8`7DP6aOJmH(l^SuYy_=SoCKg!Fku;sWI&~aH*Q4H2zX6T2f-LYlp?>(> z`u_tl1v5vn@Ai0h-+cqJ{lFuz)}O<8_Wi|A#A0v#>?UMh4k*iEEzzPw5}mKs2eK$d z)?qO6+1HM1B#`d6qVpq-@yoZ|jvqXN_pB*gk9^;nmxD~_1hy8ePf^=qr5M{WyD3SB zt42W`98T@{k#l@8DVs4GJYwI6y{Hzxt=wWAl_Cb4Fz%C2!i*JqeK@}40@-xY6SsR` zkm=E4p?b5#1BWhw>wM3x1;19q1^W z7$D3y<5^E;BHR@)f!zxrQgNd*V>Sq;VFcr5WWr6X3+B8@WJM?8>W`Z;7GFgwRD!^m zi*Qi49$+S5LklTihpYx7cQ6;hGB2v=qYQX*r$AM$wbL9zzElxf+y(*qGYX&oFa;CW z;lT4C`e_t-iA+yVMpw(2ftoOw;XX<0xX$DrW}D`&)F^D4L?>v!fVqIB6K4_QK;2Q5 zc}n_l@9{=@?(~39S09)ImFqTtK}YKEyj=zts_^Pr`!9+&LHefJJEbyIeSei%|3tlA zSma~YlS{}@g>)+t7Pt{r;tVvTqh>lOD>a?3NSuI68Rnw{;YZ=uEXdiF;i30chEP4c zc9>f6PlOqymgv@tdQ_BOuxd~Yvn#^|q^C_qJtzz}EwFl8D=-vL4~|Lv7-gjLMzkEg zsWSqN;darOI|F)6h>L1z7)fDxQK^JYfh2nKD@rE3hT>Aee&3b#8)f4F>^@ZTE@H`p zVJT#e4q%;dyb%$!IDDBvIv57UcUVID(#*D0l-`bN0r-uFM8>SgrZ!$le?eC}szO!- zzaoU2aPE}wop=?wIfpaEk6T!%1UROum&9<$;^M6**f<@}NGc=sWS}+437H(8M_1yf zGVN+WMXk(0+mdaTlr&!{Yci(BZSv$K2G1$w*y8Z67)0%0VE=>z?9{ZCKl z96yI~~%Xy2FBN@^dn&@mgt3p%WmN zbx)%%(~;CkcO;*LMDDbLi6H1@Kwe9TmTFNg%cbn5tw4*t+AvZuY221M<1LTtDJ$9& zHhqNjIh+pM`;Hs2_{5Ev0CEPu*=%?hKk&fls5kn+Lk~SL)VO&09ICX;`{94NcWLuG z4sO2p9m$L^?n0C7sj+M3*tzf7{P?>MZ@BZ`^Pauy9V3SiZ}|B?K6uw%haZ2<=tJMQ zVBgb?#_Jxx>pi7TyCwJOd?z_o&^q@Sy;mF84?j4&NS(+Mq z&s}3vH{O}}9;0MPS*_xp<^H{HzP)Zd^*!p^jeH`*fQD}`d5Y)Y)&Z_XbO!V{&X27T zt|R%4KmMK1Kl8^}k8$jS^D2iQj3UgdjM6xh(-?U)FY;wHb#N}D^5JW2&6mX42R@GPe1+Q z)6Zbnm>ch$SasKXZj^i9F;Kks-Wz4K(m2eR<8H&@sj<7>GqH;J2;MY~{6*j4U6VVO zGTq(ccZ|I9|Gx9Cmwmg@=)-r~1$p~t4vrMQ_u$sw`^?+_&CbE8ssC0zc<}L0?Ht^P z#V0rH7+Ko98KrH0{8M)xyle9}zLA_8H{STVyYIiZ(KzqfyI+(24$xUv<9=)*wc+po zKI1nY#(vk;7k02c2YJ@tIZ(Xw&LUn^5{UMcT!u4tt#7TB4H}PG^v$iiC5d^NOMG>! zG&VDdPY-ex%-k^&e^lo;uKy2ty({3pm1u^qO?rDd+wkdPrlt>y90(Z5ZtQXlLh$iG z%JCPH#{E|Zio^R^1e*L$&p`kX+H}3h>k}G7dn4<$?smQJ8*vNz?X{TW87X2!RZjMw>g9pjR3D`UrFBY2J%(375<89Tnm zOh@i&a|!zq^`KD|-fIkKD|nvQ`o)N7*C!?nX?ZrOFPRy*3}GBY$U__&QsNjq7E64H zh(pR+@#=9w9u;pbzMhQvxIc4TVmDdXUvS9&?nk`{a}mv2UY+X56yxX)hvGx-(SwD8 zA8$2rKPH47J8l=BdJOe6V(!5nF^9G~xdn5a4i>OV@3w+>ha* zjBn}3t32wr6-6DC#k9N`Sww0Aam?x;KO~cj$~bfj-jDV?wfeDm=Fp6VUGJH(P9F9B zR36dM7MfgkD=kLgfEz=H2*5W8U>Fl1wm49E#*r5}IPe0z!J)vT;LE|94QQXzE_AMYd{-s%AwxQ=}V>x)N*rrF6uY3=9Sp<81n(|#+T=%xwVNO z>x`PL;%f+OQaY!ObGRm}i%a77&q~2yzi9gb6#QNIZP@B{*lE~nl&kkydiSG;z(5Alc3aCkok ze^JKoMY?_VGawQ_9_L*O)MenXnQJjtif^OZwI7+BDze;M09iLD8;h|N=Pvd_CKPITjarn-{);^$xJ|CT4%5gMrS`I8@B`GPa&Iiw!ztc} z%!~1=iGTb5pp5@x(>qt!e2k$QvUG)UNA`k~K19~e;sbG!N2jD;$3H%p^J9@2Ya?x* zhn|F-_t{yRN^ET949K%jE#fDpvfFb&X5M#&*FKphGX?V@bYW;_&6}U_@ZuYqGisjg zKeU)6*Hft^3dZ<`=%h4-k>~A|Dt5}nd>UM?FY_!G&h#)}EF3WCQ|rZe7Q?(O^lK=4 zuo_v68M2!8FGK^C3;V13KcO5z zlhTG4WyENTaQ`C-rlKOteGM)uJpcRaJPA|OdkzZ-Vh-}XZya%m`_rCtPtH-Zi$D9IR@#6-SFN{dIVK?y<^1eX zMU%IWMO?a``b=>vzQO*`*T;q(lHOSTqzWW~%|+Ha7{fa9aACH%gpc$~A~{HjK%gDD;5qchaf0zSP>F0s z@INk7rdmNcko9a8YgQP$&I+U^ZB#K4RhSAG$OG^hL>>Z140p+C=mnHn8)e(aV4#ANq9`s^?Oam$09Eyy^)VRkCFUbn?x{6S}PihG*vjNT@8Q`GG zoObx2hy?F1g!D0f0ObIN84Ou0UqS=`#YPcgRy>2MY4?z6P`^mmr$q02rQu2?I;SF2 zo?IvsulYGMLRq{QExznE;d-2Pa5*YKli(8UNi-xSgPyK`PE=luk=AcBGogp3U0JW~csj}!|qsX@zxL<(6ZsFE@&g%p-U zRX|zYW=thGS-Jw{)8g9FO&bNmCBv?httnlYr^CY2Tz5ddSA@hw+TNy&X<{cw?8+hw zO!7L@9Zb*yLsX5|;^nZFQy|oAmdWKvP@8e)mzAHTbc+*XaQqNh|7HaoIVqS7=@PTN zxU*0@ok^MuSur+pa+!2YcG1zy+eC6gDX&|SN;M6d%QKhQ#FWXiS~rtRZlYb8OnoE~ zah*0v*e4C?t0XLoQ+?5?>P_`D3*>$8bl_y=r24Y@WHBCOPf*H<(oT?VPntIRxunZ7 zI;~@~>=US9QZ(w?B|6CV#4glHZIb56ty_-=%W3xm3+FIiXCT#J{kT9wQ)Z}-h9^4Jn@sm9gB`+@`tT~=Km=^8Beuc+Kv+l zn-iq{b4_wToei@;*=p6Z;!k#+KUsRF=SPkG(^T-^v0f&vN*2dy-S|jNFdF{%4^Fq7 z)0ID!7Pth3CZ8qB=DA7?#JsS2k%elw-WXMfndsScCr`U%I29p!g> zBkK_9N_OU(?J9K=<_T=tsXx=?GUSJjlTjC0D#%s9kOl-RdSH_D6+%mX{(84k10Y6O ztLelDMneX6`4f)S3{7W5cGg%(cNWq~Q)3r^M-Wv_{etvBy^}%%Np9*-%9u@J>~&qb zIceMMECo|%n|y%;pqfN0h6D5n!g<-OF6ad+S%6m7g6RPM#z8Ng$`f5+faJ8M1DWeE zsV`Ens}<+VHoJ^9p%P?hc5MYT;E$RNaUe4*GN~IhyHc|czXUGSW6Q4G6c9c3EE9qZ6|WL|u447M8z!s8a9gmKVA1wLuTr zZYi1mEL-!(m=)x^>G<*UOseu^{eQ|ObAY-|X=u-y-8At%TI`BSM|Q>IhCOL>%S%AcUREtwP4?^Ke^sR%*lROL=l z-6@M@<#xuIf|dB4=^35HsSASZ9TRf#<9(P9RrTa?T*VQWxc+b%zxXVVRSx|2{Gi(O zCA3$%RrTb{quz|p%FF1^nB`}BQ7#-iTF+)o`K+Fr4*5*3vmElZR=uESfu03=7U)@^ zXMvstdKTzepl5-e1$q|fS)gZuo&|aq=vkm=fu03=7U)@^XMvstdKTzepl5-e1$q|f zS)gZuo&|aq=vkm=fu03=7U)@^XMvstdKTzepl5-e1$q|fS)gZuo&|aq=vkm=fu03= z7U)@^XMvstdKTzepl5-e1$q|fS)gZuo&|aq=vkm=fu03=7U)@^XMvstdKTzepl5-e z1$q|fS)gZuo&|aq=vkm=fu03=7U)@^XMvstdKTzepl5-e1$q|fS)gZuo&|aq=vkm= zfu03=7U)@^XMvstdKTzepl5-e1$q|fS)gZuo&|aq=vkm=fu03=7U)@^XMvstdKTze zpl5-e1$q|fS)gZuo&|aq=vkm=fu03=7U)@^XMvstdKTzepl5-e1$q|fS)gZuo&|aq z=vkm=fu03=7U)@^XMvstdKTzepl5-e1$q|fS)gZuo&|aq=vkm=fqzC8IR2fRH=p;3 zC$i|`k2TTugp@k%^q(G6m43*ojER&_ly%if(vf%DiSqv>(}JI5;k~l|r?5caTO;wx zP1SU_a=HlepD_JId4C$yJfpRWHS7|2MwzjOT>{UL8N>|#8A2eFY}IvFYui>$7n3$# zeMJ(#Z#s!Zrezz`BEPuJCvPx~r;9(e7u>Asrx=?Kxlr3FQcd|TN|Dh_a9@gqA|6m@ zMSzOS_-XP#wP!LfL)XFh8K?$@yv0 zKh0we{i(vF59Z^%fGzf12Ud z=~JH5F7{-`u;n}x5(q9zW1sQ=-=6ie#&rbo+2^P5bbhC-gD{6sU=b=DBf@&VKalAtnWK0pekb(N2h-*0xG?j+?T+YsbC zd8FIfot@pCnVtPN&xm!Y%(Q^tL|sTF%s@&>Kk73#%V5`=YwZsG?9_z!NII1W%git==cSJgwa5JcHtOenLA7ev*3+o%RTJxRf50i})DPfcI$_2e_@Tf0{` zP~m~B8sd88d#d1f0>F^$rkvS?toWaRBe;pa$5VlvI&dj2W3qAWBpBl{XKDfUlIv$obqP+>*G{gQ z_}A|2RT|LrVS>?cRsc?RQm#Bq^(E*~-efFo8C2Gs{}~z#G{tBA2X;J*kR8FbvX_U+ zA&6DeKX$0Lrz!Z_wQw!Nl#bt&+y)(IKel+C1>V%M%h$vfUm^B* zooF{!pS=0ThJQEkEwDgY1Scoc71jFb)pJ;5oGNvq>3<}~k%)cg7DB+KVt2aUE>-EF zJDqF3YIxl$a2dU7v(9#zFU2Rd*+>OnGgi>ygAG1_EM6YC=l-<&K`fAeS@uSxy^QH@ z`g3YEpK1HR4(~(1kaUC*{to`fCER;NE|7hoKS>=N7&TNwto~5DgWN zSy==ef|QXj(;&r2)E20_YFXu`vyJ-s?Rk1XJ!Ox#pifYpU>=d@9|y%-HP;e6W`o$x zvzti&Lu!h^Pl51|EXi`gP!Pi%5q=@npol=y*(^?JhvEm{e3{*7Jf*XF8MPs(0B=2 zqR%x;DTrA!2B~39(knU6&)gdI(CiVURA{lrI?rN~ZD(M?CPA?tCw8eTBX=3ytU=Wc z#QM7)CoVo@4fxSY>~_yvkD#M`vc0f8zqhIqM{ i2vwVmPq?+c`<=Hzw#}%P1=@npI%nt)Uk!wjc{z5?WR!d+p(m%-RRC1L5W^ zx%l3(jlIMVLrJ>^nQZLA;c>B#{m$T!1g~w7W8Yj1j_GAFUWYyWiQ^NW6E+A)Zv66c zuxudYVB&educ~XNXEc&_F*yFDuCKm7_0?C^)z#f!SNGKG_4@SZ_Wf=^jv}IkK;;-0 z0_7=1Z~R%HGD^*6z8_GA`F^5T4aj4f5?Tf1Ql4IB)~^9vY<#%%*T9uu8y9}f`b1KB zj!694bkBdFBSqA`;HDk;B;8ueZlL4)4YOqFH-)Kb$J$F{buNW$*J7@>Sr65+D988H%`)Fxvm&>sqrrG~-sYt4}_&?4QQ*+ag!KJRuw6QFGw78$g;p*V|M#mcz zI%6^Q8=4#=UpBRVCHfww0S%VF8n%X8>Ip1YZ?@&~; z-mG7?oVD9hPu$igB&?dLGoihs#w}(#5Mo99wt#0d%iwmu?8%~?zZ`ANw$u|_uEzQD zOsez8hqf?OEhgTQ4EUZj>gL+w_iJxl-sZUR^D!nkJMjl zH(y?+o~OH^G81CTH(=?Ahw)6cYd(>OhR#$qUCmnB=!Myci$mX7StfNTrzN(&nQBgH zyP?@-irkPDW~$2=ATs_`J);+9693$)v19#njelX*@T-Zu>0eS$$6krK_CXSi7-CL9 zzgf)1mj$1MWMK#Ux=h%RYqC=kGqXeaBjs~(2FXc>(+#r?D4S`cEq`TfJKN$mV{K%j z<&5%u#9dqVlQF^Xo zv2dj$6gh5Is+P;h6@5jyaV|}yl+>6sEzt&RrRk3`#WZx4QE#Lx)T58xlw8v=Ur7oV z6I@QP=36{0|>TV7*mG%#yJUc<&%LkhoadPkgQ<+UQIcXbN%fgQw%G&m_-U(nr2=* z&Aios`%#aN1h@Onat5K(BTsBOTjJ>?6DPQq;MI_|WA!bLlY%0_wKh5-8{^c{7FRfv z+D~>2>v;mAQlexX{e=Eb*0C5_O^y4nk_vR^v-JR=3l0$gVtez>0+X8#=Dxs)cTKs20q z?MM==)^tQuL^8pxNc)yzh1C>+!NGFy5^kwF54x17_(`tRloQ>+8llz*qeQU{wX@5j zY&5!)dXk=PE2hbkPK|{c5&QwCn)vh}E^s0DDFibOmbBQ)+G)+t>)XJP0*&*`D@8~& z9pn+U1w2i3GRr|z#6IAPIfy6?VC8#lo}c;pY! z5Ux&3o3z(d@Eud9kXqtwK3Q%zXOIB%|U799gQzx3Q5v1MT;!4(#mYn zFhomj*f}ko32$$o$Ql!~Q(Ff}X4;2di&n&8czwe=k?*GNvA1M?v$MpI2=SH>ej(p$fQ}5j}`P6$a zDg9)!zPb0Mvo>FG#b`82^&gH-N7K`zg}%}0{=S99-oF0+`fJzSb=P%VKhV-O1cWOA8!_PUYrcl@TSDcg7ZdaFOCi~y)kAPX7Qvb zFv?9)Ag1UG7$9G88QZN{j@4W37}*f`Y>Q=PGj>o9?S(yKziEecjbFw$kSjqPND_SX zB3T7gazHlJ#2U1p^hU_H!xV*LN~{qr{FI)Rg*e>XC;#@k)CignV4Ky3A0aWH%eI%- z%1K>pt2(mOKdsX#iK(V?B^#^jq|xB<*lQ5T)L(x2XLdYpruV+LUiWF&uKHIF*MCA< z_Zy?4zU|O+^_S`|*>XGT^+y~B$JVhw{pmq^oqkA*lo`#8_K)^&_&E+ehKB)+8)bHA zvi`{C`i?F)(^cPBKm3(rpfl>4dNTD}s9Zn%!yo=j{gi%MTQA+RYZs2K`r)q3j{2+9 zY^y#B))4~tZ{>JQCo|!e)r)v;Ec|UvJuefBxoa`XGT8L&C567^a-@(m8O=A^${^j?2el?>|A{#3E+nWgDNx_d6D_r zzTqyPDk5_O<)BMfhd8FVsdX@82qnSWkItaNBvv>;MbTPwgg@rcI&&ckmD^_Es?&uW z(E*)OZ5^<9v=C>XK*puoT6Zl=d^(tAEc6A76CY%PhILKkPhwo6CWY?*(E;cZ_&?AZ zH5UjqWUx7~{TRs1!I&~o#wei$q(=;nc40Mj53^cIM+meLO>wYeVs3zkamxQl0G{4o zU~UXt zDyh2m9+j1!=F?4>n{>a6r{P}i8oCsZh`J}YVyRbhc{&>H0;#D>Mj_L;;+WlQQNI!<6Q$91J zW+`@d4*$V!m*U~_MgQYRkpI6jQa{yCk0PG><1M<01B&a#9j8uLPD&_6K@25tWkn-x zd912uExv6I9i@j^fPJAtRW@VJm7a9yo2oc+ZkZc+5q0VggNo_y$fq-5oZ(f=W(|s*WQ<3 z<1JD!=S-2}{Z?~nD+Wuh_Is*tfu?`(N|_FpX()`R9)}pmT;(ht9g{Sc96MvZY`sKN z;RLz#HzNG1U&bzcdgu1c!Z`M5IlOlPCoB1zeh=bP85#A`HJDiAf#dixEq9+w_u+wM zGETr*6|g5UpOjbC>!g6O&sP~$+QR$cX>!!*j(@AW0f#-QZVErW1(W~n_h9T-NIsdB zd_K^7YT*td@pR~KT}%G$?zR1V{Hwp7Sf4Ge|Fl9!x+S#Puj1;H3&fc3Ji5mX)hzTL zy6A4Y4cs3)1AYAPWNU8Q`WXD%{wi9p`bmAhaE_zO2;#-={isiEy)WsHAF-_?g(#&M zcFyZzAdO7$pyo~xygNaG7l>T|4R6+_Fa-3*9lmh%nA%*#>P?(artPnFSQZrSTW|atqQ0#@m?v+)P7Wzg* zp&mzk3Pp!u#UT=W(q?2ZXPTfzO)|*^c;Yl4@zrHAJHsvgk4b<_<3XiH1RjL);L~wBHLNz-7qzEy$itCr? zrZDhGOi zLAjH^*rTV7ecd0YN&w$`XdcDM@75=X;N~7~PEbXnf&EXqDdAYMbWFlf=u-S+_v-zs z80!agA!7&bAoFj?M{N2`-SM30D;1f?Nn=8A`CfmP{ODpoFI+beeh6>T2+8GSC^1I_ z-w}Eeb+dau519iEgbhz6?0Aqks}lNvR3t(|ftdSgQgTgEh*<|CWux#*o5Y6Sj-oIR z;hFyX6hfg<6(?x81`g`qL>qXH;ydLHY_x&6A#DR=KB&op-hUTV{ zM!AI7PAko~Mw? zv_d2dFsn;V+8qc9D*_Bw7-E`SDTz`-C&?Er4^3?}CgE9n1*}IpgFn9)WDmVdOW1N=^H2rJPiNush>=<6H zAv*fZI|ws!V$>&Vs=Y*%d7Rn z^&aZsDNe%!5A>OMh-EB;>#slXz>Xd7dY2W~KjYBo=F!oA|M%yftJmsR{k(q8dAkZ% zUG-4?Gq+FDb5F953|4=29F$hqSx&>o8C&Jmfq<$yMhW?djZN}&)Z920$vP%pY0G!E zXQfSS?O0ASi(30hJk$Vf@Nylt)hA~ViW5N(KlSm90;mIRqecXx>HPZB|j9$ z7=?*5a^1TAgkGs!i!5%TIub`W?hum%JU5Nl{3C0r{?UK0*Y_UdEIwVoh53D-Ass{i z39>)@;lo;&`L^P8Uh_tqaZ9Vyj=4;I^H)auGxg2&k9N`TjBXC<^+bIYA#L&c~n=IV0j z4`Asr$q;LOljl@w&6ZO_Q<%y*!VpFuCN+)NB-@9T8PK7l`waA32AND}Q*lT36T35U zCgVO4$C=t=k7dwU66$*bHju-AhP1tq*5WShAk+NMdl*8{P3X|$EOa^XIMJ|mYwYfx zBw9P;#Ez0A#lmEElGgs{8??|Bix*$a#EIrxiInzYsl_mLrO}Xvs-|$;r~GO-g*!gJ zR=_0-;s&}g3KO5JT*{G9%G7v@ojE9d7m0bzK0C!Uw zO3Unt%(bjF)ll8z&`^AgcmIX3|LLDq+;ymb=K1o2rvWRc%zA;SF*+g;%j}6GDhwr_ z$(F#L7jYCgl?YSoPb3=RQ%#RGTWC zldR{^>_`Rik`XnG7^sroKj0=5`(pU)h!8bky zs5FtvcP*fFbBa)1SmLzkjElMdj>%eHKgd0ngROxw(XIQVU)_}n>Rk>bUzX%9q8Ner z+q$-#tU{uNf1IL6F=42E=Slff!U^L0>$^(Q>FRDa&O=|usZkCq>Dz9mG`JO;(^!2E z9jo@!;A78&emblXOvcBXZu`^y3%XB^Bw*iSHATRERDcnUJsHA3gbf=~u(5+U(IZ|G zc8Gg76fFqi$dEfO3!%JR$pJa;Ovp(RDCCKPq`A@zj_i`45h+U}1c4AVC5g<5BrKwK zm&UC*o+JPmbQ+XSLxeL0Jd{%SVhT=%<1{|0V5vl70=~lrhc2N+Ro|7|5dGE#W8N$z zd1dJ|HcZ^0Y9-w#5W^JTs3Tg4h$A-Y9@LSN?)eb$Nt}cE$I^YSTp#aXX3f^Zs^ zU|#xE(|2~%9dvi|E%cYWyRl3V)ytkrPzhk+{Oie!dd@CaHuem4U-h2u6JSNpbu%Vf z7b*yO1L+gaF1p{)UhGr>&gPO6h=H;*xM9OhPB93=^|`ZApeHQyuKNP{u|Oy;n(yC) zC9b?~QsD6rDsoVL0n-3N?ra<|ftiPWGTw}1M<8&GZScS_N`?YaP#(#2da37|(PAiu zVHT0$5cs9Wj_Bjtl~JM5bbo zTufqXZKO(EQ=WpXU8-4ai7*il=3lY|v9cs{r=O@-Vx+ zXc>uMzD_vP1iNcRleJvVsxBjkIAz52ZgUu#!lJ`aY8hTDkNlMVWt=!l_U7q6`w*n1 zD~x>KMv2)o+=m*I&%R;K-d`q=B z{`hu-i7mF*f_mAfCGp30y%lI_C!!T}RuGxk;tC4?5h9K?9&Nla?Wal;CePzOn(xbnwgcNz66keAf=(GQZHyf6M8jw%AzTsF;L5`vr1NQD0nw z_LzM%pgJhW6yqO%tHa+xMXytAQN^uZOh^)lfq8q&p=-g`66@LyB=xLwq+am|rqDHm z{3QV^1SCe}>V~vNhk=5lN#7SFey~Odtwj3EAz_NUk}fOtuPLFK~x&J^|=pRg1E`+II_!3s-vG#(iV?4zu+P;a?R3G;#ad{ zxKCt<+LiChzkPm@+{g&wO8t~N)?jv=*A??cO7ZQwu71bb53+}L7y?l!~-#JdyTO{(MFM@xyfj^Oo% zM0YGTSZ3DzQvO@aLAcl6%%?2}^8KW`CJ^}K-R*?L$Jo(9&8jO*M+gdOnA54yBTyiZ zO(loJ3}Ww+d03$9dV8>^MCb}gNevE$YET6uZs1RK_XL4|69QfpER^)2xt``jk3tWD${rdT>^Z+X7^B`|B>e8) zZmfF7Vsz92)99My{cY|fK;z7k&?J}}_Rx(wk|@q6;Zucorrx2xmlIfHOJy*w$HpD4 z1BJT7PXHb1n2c@|s2XmXtE|=uc>O#>2^&_@<4@CSLq&(fLY?wb=l(E?98z#02#Qq0 za!o%J=rDnTf}&vT95if<9o)N9yX|c6_Z5XWZw97;20 zqf5{xT>w~NgrJSQ@z`Z($4w4|C9QHqiK(NZ$~~k(CAb|KeW}@rQ|&5D3r<>XTaQ`t zW_!#!OIpjz0nZ2k*$2uAUow6!sRoyL_$nMCWc;c=C(`h*8oXvLpHQ4Pjk%l12)PM0> z{V6&`^&N+w{`t>uxuw2i%Tp|>?>Oe+m-_qkyQ1x7j+{R7b&o&#=FMMz?wdD%OK%%* zuIf5$oUbhgX=9HzKB#molAFGy`5k$yy&GM{dP?4S%C}hi!z;<*%WCC~?lP%t*}cms zb!MkWaP{b~pIeQ##R{jA3A0tHonjACUZiXs)jQVhX5)6o>NLjnEqKcrqjrw4Mpr+g zKFrI1e+hWFzi%{M{19E4COhW&cp3c$9+>tXqIFnmdCM(3PO*yl9Unf;=HE_?Z}C!$ zca{@8i;E%LYvJVwTqVY$`edVST!VnG2Ouy$7T%;AI;|O;OJwtWV#>E_q$phGu>Dg> zudh6~jYaV5a^sIbqHt*i`j1mZ-nOhN!n8xT8|=O?!!;oy8w=1kg*uY@*6ky+v?|e50@PH&Qr<@FqVb(K1rABTu5~*cihW( zN-B!gtfz1oBgYrk3hO^`;~_d1T%B89U1h0;L=$=!saN8uKS|6NHQfDt1*eL3xRDu{ zZlJ|USA|oZaHauw!k+qBgQS{+vzRW{j_e|6L!yIx&pc_?$-@@K&Ij zkSsKy*dKI*Vse5L4Z+huu0+xbs+Ht}Zsi7X57Rx_xq=hd)(G-%MW=2eBwVaUUY1;O zO}o)w0sUhNsEm91g)#c<44S_`wg18IH28T&(IOT%LHXFvVccZs`>d6wAFWz;#VqQ7 z{>HAk|C3`2n{Wl|QWs*LY)|b^*?ZfwrtMt|=dS0FYlPKNd$5P-uTn9{GCQ%66M)hw zCw#~&cWGmPhuh$?5d)G@jgw_y5A)097BNRNC_aqcHx`BfmCcxf1m_mM&U0;!P0 zUuU3iYli~AQt{|P8vM9V-M>HW^T!Yo61$Jit-AB{7YGBc_s{o( z9=}_RVX3761BK_IG>=7lK=`By*AeM#l2jPa(_f}}I9{@vcIldreNmP~NWX95S~*^- zS;CgwZd6-}m0GA2fhK8C*qupsMWj0xeUeA>F1QkF3&(q}bn^NFMBu{~&HCyBEhw>^R%`EU#q2+RevDH@9KRg7=z??39GF(TEt-{-DHd{pRn z6A9}^nc?wE8n*c@ZB7jyJ2tEw)vO3cF7yE7Sg;0ena(h+gwEPTaRv#xfFVJK;Gw2H zWH0Rug#ElMC^jV$F=L4Y)2;SH@}UO*G=}WWfm~Wlfz^Sn6`8MW&U6lrY|Vf-4BRst zbdIe^&S^bi3%13`xrg+$p}0K;^sY|w?MSp8RZ9EQqndj2I&1b&lWTI;<#xWM9nQo$ zwJgRLris<^JjR4T(mL3 z$*{|6NuMlLKI5Mcef7{ks7DTc^^AX3&u!kUH4fud&9nC1-bbS+W-@)JF>jPU)73|} z$Wd$vs?;|DeivXZ)}K41Y@YEi>eDBkc;e=0*W}i%CN??R_i+E={vD;m{g+*KxW8V1 zSN7r2S0;n2?!W&~{SaQ=F5q3zQvIQa>e+W?H=7UKJyL&!%ifZ#v*bM6w)iJMf&7-u zo9q8x*YO#=PTCTuVcn(Bd61>`5Ocim@4tETgL)gdKDiEQzE^Fh5`)kV6N@yUih#|lUIfJw?)3>)uN*MDo7?dwa+pjvIGiM36x*Vb)u!>JCLxOLQb z&}guxQsYwLJhLR;sN|Rbvy$K1X0~QuG%U1cesu4L@B90EKm1_J=9QB^Z`EZ=ZN&8u zZ^9Ccom(T8R9VaLt*lZsC+ts&vW%Su`V^?D}r3k*ED<(6Amz+)3%B*1qR z9lFKG`zO;sulM(V-~)WD92(_x-*k(C4#eWVLyOTHa}U4p!s4OmjTc@({&3-?V~^b& zyqaA^4edpAok_wn&N4pSziZO4ugLW62(Bu9q=X~wjW_PUzf|A%z~p;hI+V@sn!e%+ z*2S909gJ6kmf2|;MUJb*0`WBydlV>xS%^z|t`tW;&e*&Z=3K=2v#~yrap?0pMYim$*u!0!=QEcl`w~kYyD|$RxmWXW zb&<(R#7JUzCSg;8wFC+X1vQzo^y2=t5-TUa8$Z5wcZLpp<3POjpfC#HQ(3yXYYfTh zx+ngKGHRV2Ozyfkeyp&Np|0ouzvt;2cpcT1?xT`5Db^`vg~pRoBlOo>2E0U~IE+yz z@W4KGDdI-1Y*Z4~F#F-$j^U}V7mmPzSrRetSSdsN1drnl)39pT)8#!uqQQY8UW!$^ z$C>F-%>!ZshSxvtj`u4T;dpWx8&HW6hkH{c%wHCjVd_QIHCrM2%=iX-dEUE)Z!v#b z$qCrM^Izc?T)h35%B8wGi1?FK$?XlZB)h2-rtr$E9OSsiHM9l9nFYta5ccWOson`J z5>c*FR0ei7>Ql3Fx2diQ-;`rSg0CN;+^c^>0pE!;2L#I;;rNV?tD)wrN#)~@xwqX2 zJ7D1z#96 z5P0G3aBPhdRqO`Rej+moC(&+Rl*Hlu8o3Qy!;PHIh?_jzE{>0dA;Jl36b)p2d<}!< z&_j-54MF(qt6SqN>;TI9@qomkcM>Xa{{ReNnpmLf8sKh$ge&7ts6rCbJ=)S#up9k2 z3BSi7f%Vk^jadb{7I?o9&8|b6?HC}bdIa-#_951%y1qo=+&?;WK<<2p3)d7PMr}_^ z6}KS9W?}Y41eqMVU=B8896oan@Im9W!ZVXD#hPWs4VB(bWIwK_?hM|n1c8HNEkuL( z;*frv)C*M9IRx8aGNc1=SI$roT8|^tAi3E5^+7%Ek0jK5~2Df|&jX0Hp zGr+lRofE_}_+G$2;%)NZA^Q7qTz)h(O@`YRXPeB0)6uMKxi?1F;CqoL$J~&6*93Vq z|GUWzo^p3eQ)Cjs{UXNA0=d^>->|&QQ_XxpVSwvuMFOTVj|4J95>rwTmM|>h5BnFE zfxRlpOQ7&Hcg$)~Ybs#IFnbBCMux`%070-z$)QOHhVea0np_i}?aQizXU2*==^+p~ z5$1j2NC5_5%Aw=A7sP-wJbMY;TT>K!^#q_)-a&{`D#YhiI3txiBILltb`OU5m1|dB z>=dw;&Ht1{1Ty?=D12ua(MV5;2+v2nafCfLhEp0uj9#3!Focf|FfZ|Kmi8yKB|*|Gdtx_$BB4V&~ob9bHVj;raexmNs2k6*}Hgi_Z6Y*L*b};7xH%9_Vmf z>Umf#>P_HYQpYa+G6uJ<*0D}g*-@sF^>KKx zMas)OmU)urujeL(SR$Gqz{DQ}9*GHmL*UTt5MuJ--s;(6?c&oa^QD8mUN_E5Yl2{) zIKvH(EyfC=srl5F?5q}(hY^xGV20i)3towXVC1 z^%yMI;_L3ZPXDeJVrWs}&TjU_U+d85mE#5*UdWaDAu4oW>esC{7=UK6ZLeSS?#p7+TgDeJ3LaowB1G- z%RCYsABmFD`9&SS8uM`dmcxf1e)yDAMl(CsUO_+kNuT%HYg@8*>@v0%4UfmQ8ULDo zt^Qiy^x=N1!hB0$dX-Trx3c2J=)F^fSJx5hZ+Y7^W2; zT)0&S#&r^LjPY7n&`_Z~MsMs``t8Ky>;W$3_A|yA)zAu0h?$n~!+;qK;3Z&aVaW!* zgIWBo9JCb>D#m;{-UfFtA3dezj9HErC)i8MHTv?B)c#=Aw-4Z|T)UQj`~!AozdQ37 zeplwQLyyscEcVIT*!dpDOad_-Xx&Q(GLKoA{y`LT_4XKXkxAT+T<8|Gd?8+-jLA0j z5nFjY&d}Bj6enINT!cc+s?7cNBrRzDvc!Ot8HHeq6Q?b_9eLdQ0VE0T5NFmO#-}dP zNjyB!C4}cJj>m)nfmkBOcN6vuYt_cZMk0|?aL#jTj^vEOXyAgd+_I~2qd86jA8{Jb zNPW!uiq&<6JUTSR9P$J@mLK>a%NVL4VEY~3&!18?gN_67^a^1{m8@>W6vpL7~w?kCYRNyw5yDI zw4cyh9)z>JtX(qv=!?8l7BzptsR(xg4N)kWcgC$UCJ^iq_ze5sq+l z7=fG|Om%yLWR19JPQUVpHwOU$2UA^@L(?S9?DfdqD>2ZziL26|*K>TFf8d6q-vBef zeUnU%Kb!_*IPuoPVD>Zca3MT7n?arTeE2y3QBt=}@5JFRaq_`2Kw}uJ4N!mfJ7;4D zFC6l!%&V%~p5I9Fo9Fu37(*PfKm$9mo)q+r?FEdH>HLR zd~CkT=pS#x(j=nY<0P>@mUl)VK8(>3-$%HV~pf)P_xjNU!rnPh(&!_-BC~o z>62Lnd>ju9I$<7f-4Y2bai!}2Mprn}kI_{a9-MF`V!@$P^1^Y^JcsT@&<2oS1D{Y& z5xvN4>0()6^WszI$=ua(_mFNjOv$f{zn4 zvquW)sbM_&l00nJ&qX4Scwb>0O5)D$J5*t2&DkvaL0OZSLz<-&g%%Og$sQRUP@g@A8}N?o8v%b z`X=5q&yC=BTs~YJ{5pMr-%k@<7gUt_d)EIzWdV?Qq#2ecAYK5{jtc{$C z=uf=k?~HD*DkEi_z6VFdcp2Pegc6p1yX&&BxREUoML1YrUVkvd909 ze{;3}FK?d559E9;|5dELoaZAEP{Z$HmpHRL6w{)d?Kq1e%+m*uIwh>_bVQKD&#y&) zflua6(!lXbU>;L^$`cr!Snv7{3Wc`;55&C<>b&j0Ikc}I3mj#DC5ri}3yQ(Uv!avy zXh>}uyOR7r49=`XH`4JJEcD+vhFIy;_Thm|LmS5YEC1kIx#%xW#WLFewduG&=pEYj zUujzoD<)4K9t`l?+U0lBB7T$U%wP_4tsl+5LoE0r976Q7Tnd7PQY6anJ83Yu9>Ivq zd-1z3_&nzr8W7-@uodquUQHQd?=mFF5H^*Ttu#j!@E$qm3NQks_(X{QQOpAS%l8bm+gHLdU?=Os*Vz=IW7Gr?FqMGUoG zvNyN~T0wN)QBVrStdrX1 z<}$q5_@ph{ikt0e@Z;4F5LzWB$hKCD@o{`I0jsA5EN6MlYaBJKQopu|I`}>7Mj2}s zhn=m{vMg3;I&VuL21hL6wlWr{>6B9@5#f7jA65|p7GLG49|G-&3D*0kvAUNbU1)Ur zfvlx>>^N=I=2>rg^r=j{zLjqd%(23>)!~@rM?Ml<^-y%^sn-E79YXzB82QFxz2B}K zekya?X*)^}=oqNAWo=kHY5q#GrL$Li$rWf6mO`IPG0DWuiKeZH^7XsfJc~jH53S7l z!-kf^%%=Dn88J{ONN&ylXA4wR#b*B2-a6 znPJoTO10%TG2c+#-6WG-HD1Cxaz;_B;yPcgSmq9vqBo2lerc8U9oc0IfwET?mZdSr z8U^jyt3V0OF^OV?8-@huo+%=SnCCOadw_j?t;#Af_+k%r_ZvT%)dJ(%?*Vw$3d)kn zp=-%@JdvFITfJi~bhTo9u;skqG0Va_WO!SPFlEBa5PvGtKx{MZ_| zUZOQEw0VzfS5}6+p<*wsna{_R)ES+qX4WOw^SLZ)_s3KF6BX#k$}aKjtpo|A68FTy zZw&_U5*O@7!Mi9`9+ZK0Pc45{To78tDM*ez(qG{MQr~j-Ze`zG$|cv1T8k5w>xf2! zLs)|rgJKU!pGCC}Qz_VkQ6$fvN^!WcQm_5X*LckfK)8Ml2y;x4ZHO9I23Y(UGLdLK zP7o`ABGwKfF1Ns1tsq*-qo7=cW}->G2!@eEvY>EE@oTPo8@#{=43Nr|%n24cI_4xf zTgG0Cbnh@_KtDX@MXhCFS&W%oaTO{>jc0;T*a1C?UkQtGFk$X=1OcEYcJi264`(b$ zPe>H3By`#GQ`k-A(^;7&I^_}J(<4u+35cY@tVQc{IhE`~J7x1vvyP71c z_$+DD*F)a_D;F9&StkMZEpidUMJaQ?o+F3*Bk-_cyc*|uh#*pd9*`-!ihHE$l*wEt za7gp51Ieap_&*kNohS#f16-rtN7*|BP1+|91vcxaK%GF`F!q}YJgUl^YlHY|BKb^e zAMHUX3GGs4#3XBrs0R?cISB+y-SERlBai=1+kj1R4x>0WtflXcu)DF5T zubm58z!AfC(c7kCW||4nNZ{CrPZJ4YjubgU{-tXKiOEo`!LQxmX=XSXMz}GaC5#Gz z4htqjr(bw8lYtP@1s4;Z9LDcj7raUG-c2Otz_>$rG%S3nCWiyi!dHr>Ca1*I#*qmG zZbznu=bYiWq7-gHjFf~YW{RFb3HC;W#R&wdr#^@LjOXFpp;@KQso5ZH{t+*@cw3OG)onrLgSf2> zqA%ooHu>I=_xtnI`~L4#=6lA18@q3K|GluMx^>8Y{yh}*aBo2U%Sh(&l#buZUIEZn zp~d`cAV)dHhvad{0ZLkcG%ES!lINf=0P;QD$<@!{X?9Q8d&ZrmUWD_azzOJ^Wqi{$ ze_zS({qqP{7XHT48^Ou`rorHp`N%)!%KVj%+7M=M>>ud3;wg3ODClB1zuXH=$O*dMw++H@{{l>AKMWsd9fUgT`zRj$7N2BjY;9|8Ubh(@lN!Ejv# z1iB%mfl{pMB zG9e*|G-VPTEP#kp92&?mg{>XhhI}H{m9?vaR&=lfx0R)A>kM0)YSw~dQ-eyhs)p=s z`WAw-2Q^&+oW;RsOXvv_Jl0G$EyAkgq`M>}1{BIkaP_)I%S>vN8=4G<5A7v@-IyE< zX_58A@YsV+U~Y>#Nm_Y!4>Jy1Md`YYD77e&^#wMC4WN71WDRNUf=bNlh_+S{I+YWQ zt)9W!j2?bmNX)dhRTpEv%`Af(@>)vaf$T@O>?%AG?#O?1%ZVp`WL-+s$UcA{kzs;k z66c)Lmwk0Z{o%_l>zjT#v#YRm>jT-#ECU6c4=B(j?$ zBz>R@P@Eo}-jRPb`*8n>C+;ZiD!iIK@x;?kyX>-a&e>Jik!QSF*Y$Gdvdj2OlcS^4 z({=NMq)8;`YhDe~ z)NO5Xy*log#4~jsa?95=bdDI}rY4WczP>s>g39=$7n+jJxzXuc=#2cRu;bL=>+Z^A zUVi!E{#S7gKs4QV(n)sQ;wRxpkIiN>ue>o@=i{s2>35FBkJV_sed)Eqy#BFp*0ZHU zhjpwGvCdL`vi`~|{GEbRPI(HzHh18Mtk+Z>hx4yynX1O6Q!zd4^ZB=V;)3 z=T>y!$`sG6H{7O*xPsQ-PfW>DSzHQ{;*+2L-eMeFhINmzDE=`nWZhVdd^VBei6Y^0 z7P{v$A3N@NLTr#}ZJ!p;Wg0JRj2c>JN1cQmIRd;1kU~L-#<> zNA}2|F~J)3%w$q*Qm=XKY$F3UZxn~SV<(d#MVTk~)=u&-yu=WO2e9N(YY5yEXAZd6 zP$6@G;wP|Ta-mEIp2pkTFJcg7e&FKAQ-Ql;zITrCm$|5m4#-C*-Auvx?tZnEa0tJ^ zM)6WgF0d;r!?J+rmC~2-GKV{Po+djwslk;zX$C6;=kc`%0bI3 z7$0EB8|XH4>OEkoOK5-=Z-Dn8T>9*9F|K_GYp;O+b#TxXr>o=K3jNX5D7QGM^*Ao} z8z9v`9pqS}Qln>64c(UGb$}>#s_p~6)uA<@_wqO^bB~2M$Qaj93bJ91a2Ae9xd=Yq z1D}o%L`qM7X#rGx4c#eVAm&isiZFE=-p|x)FBi}ii2rph;CG5W-Iqg+l46WP$Z_>9 zydMMkzMy}=5@BAWwJ7O#G2~+I6ZD0KS?=SC@3~B76S?F@S-(f zUYH8{OtcyQWBLI`4bui>rq_^xEjYxx1Fwr>yuAtVMkL0!`&kT1ls+40mv)dX43!&q z=xW4ELQ)WTbo^epR7N|nRwf2k5|*a2BqW9bJt`QN$(t%nk&3B0GcYSC#=(MLY{hyk z1ny$e5J*0PDN~3^Dk%||huv__6=*V?n=y?pn#O8Ex+GEb7;Inzj0#Vzpi#PCcZ?P- zpFn#FbS=<;LOfu06k~pMSl@Lb9H$GFSt);`?n>;NP1d$v$B4zC>{yKPEHL2rJU0l2hD*6Y}Hg zSg5J)8S1J)J*%X;1B=<@dA(g|$H2kg<8N&aprO4IdfEFhN8qsI9RPFh6W{?5^VRc7 zFV_cQbcSYwUvs~drHH=6{k009x)zX3DLn#_;XOUU90sUrZA|_;<9Q0})j}tj9Z-0E z@DdL%zhkVrB!>7}qd%B%mFHmYFNi!|>J4Yd2lhB(=<@E*-9a-G178?{R&{3Ra#fg{ zb)3S8%#R5vHr*-TA8Z$XNvi4>0y$e9K3#-sCX3Fc5r1=fHX0H5iEFhzlq4gZ#!9Z^ z7JUCa0RnDy_fO7+!cimic^?Ov7#VQ!2#mb-&Ia0}*nih^@t~TO0gfk`$CN>>scI#$ zD@UsM9-!qWA)s#Too@d9nQC`1A0UPv`ImQ}E6{y-^H={)Ob=BMi3}rg!*$_2Rfax+ z86vnKh&EiBgW7wd_16!c;a{a_Onop{iMoeQP`^j>zUsm6@Ps|p*|F$TL;ip-hkE9Z z6W>M;fAISEjGRNoJJ(009?$PSFDReCuR`ej-kVRw54lj!&V2VbgJ}8;ocoF75WX>q zh~n|3A@5_QY6YXk`*=@pHN5H!e5*2-%l4d5t!$@KmP0jFXtFXVm^N#STcF4$QCEqz zFF;oP6Yev+(8)B*6qf=xu79Ib3d()>8Sb@DQ;_KiHU`!6$T@w_`w&d60&6 zD)2Wx8~Oe*rQY*Z5Dn*PZ0P#2oyXDX_+gq$eEg8iCVZh0p}^vq8*{!B3~V}U?!5D& zcVfxsSP-39>K9Qo7=&XXe&DFfAFB2o9|k8=|0X&=Dou<<;Y27gG@Q8$u*MVnAPO(& zD_j=;NJU>XNh%rAn59c!f+rdy@aWjwmy{MayyWTl=B6&2zM;!odPl1Gm z6v!kmd5{5Ijd6vA9jAwx&}^IV2#lDJIu)GNr(usz1pYO8H@JR*Tr8(1Ptq_R47dtf zFt-N%&44Ut%Dhj;F-+|cT|;sT!q7!IKnM}zh|xA=SWjXDU$;S*b75WZ35vC}DJ)La zx?r_{?u>S3i$+2SVED*u6g0+}5{==dd8ifwM?%PX11^M$vk{Qs4DkesAGIP!=njED z2o9SPIECy*VQ&CTICC%BDSTiHi zgBw!seU%85LLK;T2d$2du_i2T(VOLhGO^s02xJ?bVAyDr24N&XdM}EQxl9=a{34b9 zwi2&}iRcghY}6K4-zjp)OELG^-XmZY_Bf7%)z;T@=wE^uCX| zum<_2;TXRq5pDpos9p89^S7$x+5Z)Ypb;mT; zW^t5Kf0K?^d~xiA%ixvLml-o~J&$;s1Ag}u?_BG5w-LLX+#H!TVl1ETGx40wQS16i zW1*RbGu*wpYc+F9U4P$u)b$T0+t-_#&0KoD;uHmf%j@-q{H`_PkBv2kHg7T4!|};P z-{!UDRo;=-YZsGPXVc%N-@4AkcEbmzle$^XHW)0{M5km1BP(v&W|gUE4Pvrp>r^Do ztMU;dFjJ10<4t4G4W5+&bNr8i%T%Fn%V=hjFwgQ;av`mG$ajoU+QLaax-8evz&PPE zY3*`;HBfP@2EyW(;rju7hx=bMb3&`Qg~A6)pX)oTOOIU^@EE=9veQm`3Nd`nr|@L| zCH))vMscisre6Ps*5vh%TeqeSav26|%VNWA#t!TC*0suq`_znB^foFQn@j)$d3v_`rTtok}uSpIwAKao?mqLkLpo zGMtarp&q=Vav5Tc5c1Q|=otYGtUuh(d1 zvmN7*T33_pB12aInIot!izBii|a7NV#N6hNDnI3LFET&VIBJM@0`Mmj*F=C zL4GFAI}qX;{IbDD8K{fzxaW-bG|KtmS) zhD7z{K%G7Y|H=*iGMRV$)*{KRS{PYR!}uO_hhV!{QlhZ%8-qyg$5@GRt66dAJqr>- zwqN0cNkdklPdt*i!2vGQnuyDnX>AArz@;0|w+Zlm(_pc^INyk)5TBrkJ<@WQ!y*`P<);RCSWIdMaVhPJDJpYQoQ$mTD1iV& z7e~b;qO$OB&d2D8`%%U(u7`~K1>tR|R-uar(A*>it|K8~$dQM%hRsz-*dl=*MsAZV@zzKe?nH^I4J{vsS@%K#Q5Q#yO0YGh6egXp&30OVv;J^uPO_@ zlBWo9we?lVxm?WS02mQCP7DY}Q}kmTtnt@(;$=OwdplmSgwo?i11Z{BW+LKbC4gcR zK8dWFaDz{x{yl%)E~*JUOt&p&?0^OMF3i za?eKBL6LBTJoy2~QO?W+9L5jEDHx0-(Xd`7Iz=M__ECXQMc$!ma*q0a?hk!$?RL)% zquvQYt}nYu!7r%eqJ+0aztfJ;hUXI4Q*8T;(Ll@B4-XY8>L9y==ih6sZV&IFLhHzxjP5c&m-z6b_x@Ns1 z`T%-$2;bL@qDv{N&a2R&>ZZuStL?@CU~m2;I7k97w~H$sfsUOIqhn|cuUY?Q@0F#o zF%i+fToR2%dl6fFc5LvsL#%bgx=S8~Xi&Zv;YV2OQH)oBImq<5YSD4iRA5I_EA}J? zBA)N@i4>rP($pq&4-ey!FiS!YG;*FI1ExMD9UNyoh;owod?lixq_vUd>zFXviJ1Mh zP@q~@>a1=UxNyOM#)@bpq4`kZ%QRD;^*#|Y!bn&Ga=*UFU8=2ERW~T&#xRABHnuHx z1n1N&j%tV_%!>k*^fQHa@Ck)fvOknA?%=i%xda>`lCeo%#5|pFrpyV$Bz&%xIEOKl z3|+qL!5jK%kWzc5xMoG6a)1pu9vWfCgvC|}ESt5qnoM+NxMysu6CRMz&FLsgl+43a z=xJTSsY%cx4SZHifbAm!X-VuUOehJ>>b8hcfS$gnXG+X+s`xb*TfA`^(BVoJGdSj) zz*)<;1(??kB4JpJDmuff*+&}Qar|Nwza%s5m^D$h1oJmXN$ldX>=vdiSe@5ireIXZ zH0*cjtVS~)Vs)*A>BIddwqkjGyZUx9-_nekW=Qjp$6Kj32KugS|0&Owo-O5nGt$4H z@y4M;PrdQRLlOUaM!nyZHtFW*;eN$EH^X#u-J_A3l-EC6y0Lx{gD@R?wCfRV?2oZt zhsbfr1njy zJc`euUU5YU?>fJreg^)HL$AED@AYS&-Ld0c*?RvWnx=a8*=M8rOZ%QJvAlq_ zicdcI$}6Mz4&xOWe2*a7QR>sr1JYx^wU(t6bQ{kQIM3VYj?o=fb9BecmsuUGhTOqx zk3j>lezNdn{-G%P=u7)vfBlU&-dOzE&)zr`T(x<0^XLk{IU}v*CRW`%m8E7|%q&uX zW%zDG6LefOda8uEZP0TOd%T;^A6g%Zu#;nZF`tnfj!8=2tapr;#2zvC@+Y%SZP>@| z67WO&Bk<*J0FHSN?(nMXgg@I1;rTzhZT2imSWQ279=S} zSodgX{Xrm015>gS1xv`{kMZO&Fi6|@H(oABjBUN*Uz`@`jWQH!*Qgk`s`Mo% z2R`K%k#Lm1GhC_JH?|7hl3A=E%7#BX3|cgL!A1P#_7fn2e~2;i1tMY*9`U_37T3NtGZt?+3> zyz7jc8rRLlXTuoY0WMOm26677Tfh!hgodD8bkSES`a^{5X#<;6g41Pz8$o+mj5boi zda25qmVf;l?nVTVEI8hRJJdy3w5BZ5i!i#n?+DZ+INt&EIN=eS2LI9HJro(FehJK8(;kGhs@(95M0{fcqlo{f6xfhv zb?Iv_@;&6jEQ!5f2&uWcxX!gETrLgzVsl`D52%aKYKIRCUTB%t+dVLVI|QkVaeRKn zdamZd8+R_=jgs(hM&BAbZmbj@FIXjAjNOqsw``(Zbh+vErVck6^VhwU)4ZCCcn)$h z3d=6;F=9Vd9^xE0wwQ~kL=YqHhQ*$z-UnmOL9-%a=BK)J^Ga8fZAqEwYdJ}-W;u)7 z{R9?tkGhuRjO4M9fZ}^nIJxZ~t_CN@k4gBhl$Q=o{LMdL-;@UQm3wO5N{a1-5ZM|> zb~=Ebq@p&#-M3x{UydU;RFI%f2cc%HGkml+o}qzkJj1>n>n}K`N}?in+`=cJSHt{+ zz7fC}E<7s(ZqzB~+Tb0A){Sn8;A@w?YhFMzAs|9^G& z)zybF**#L%$Ej1NzN@RxJyq4pqwcI9Esr5-Q1AU}Oif84@|-bGO^snL#7O{3>CV!m zF36dkUdN~|`Wt<3INy8s6n=wpFa<*+GV(h$_G}cVpsC33)e>HlUUygILH?I7h%*JE z32~}kaSG|)<3h41tda8tQxkIL~xE@_=OSlI^6%}520*4^B z`DfjXE!lFe)G9Lam(|OI^;fSgH4k^MyGZgMzIi0+uJWZTLyR?SI6xM#`#SJ_zb(i= z60|~4(%$wc#D-tjK^X$LJUZLD;KQv<_9|oxb9z2(Wv|LtVIX#U4VPyVS`|y!Dl=`k zX_~*uVc$0IzOKr^*#H~#{E&a-TL3o$jH%~+II{GBmQ>Zzy1W| zQAM(S#@`{3Ob)*bnME332f8(4XTmZMX?z3Dufkrt$3Zf3E zPWA-tXJV6e5QQ^1pSD}h3&Rlg2hFg^pec`@6a}RqY=^(Q(zT}>d~s(_DOACZDB8HG zJ8D8q`~ViTkF-b7cie6e3zAV5%~l_BX=jqGcc7+{YGv6Q!S*VPur);@U&(^HTd#dt z>JW9)g|K4A2l4QJ2F8Np!EaIz9G;>Zh1Ql%qvL1E8-`r$(Ii2g2a^!Z)`MAv8-2YF zCUr4F0ue2pxKj&By(6&gPfC4U@)=SvQ4C;DWf6<0j3lbju>0VpO{nMD*x{bEfxr_v zG;KeHlVb(xJ0VdiblCjcpB+qwtJ?aY5u&Frh9nEn8q^uyI)JWcVv#eWYP1s`z%Xs2 z@W9R>&K!$v)!;=+3yHBvA)d6Q3zklkb2<@O#3CalO_NPnsYMj@^e@7wq|Ypzk3^c5l2 zz_l*+3_H>_LdJ{tz+`UPuVRPxDX09!s*aAAOXr;Uj1100CGxGoB#pP`pCk?VJa^Sq z^Z)YXJd`qDgSOb*;QSkJDej$rt5Mcsk%QYdZ>G*A_kZJ7n^mNL zd&maE+fy+#+tYkJnI7enRt8BM&jK{MiKU+pR`AqQtoz}#?##~UmfBf3!jEM`JaMd`74e1>Y6{e4wEB$yt1`Zf&+nFnEcv&!tKdobCi82bmG*WY zgM%^eY|v%V*%>qUGr4DS>(=pp_dz+QsWiVJbKL(>X+Dp;+y^<91~d9&*&8;@KZy?i z0K;*pBu+$lt)50>9Nu*!?i(0D5I??!&EanYgG;6P4f%eXXf`M`$D>#X$4{4zR-9E6 z!1Z&OjcideRAS@HBv$gHbZ_ySO(Hh7+3*Jw;R>kvA$K`2`OHn7#1xtJ&Lu{2^^iZ97>$Y7dr+c@NyFaT39K$i8 z5a6gP%>N}YjK!u>bVyZ;v5p@zzv1*RU5R-K&?X1qT{}}FR5Q3@Mf(wC6s9J6z)er4IiMk`X)yxD4m86#EXw@%O*mVw~L5#oSL1lP=4@C0=gW#FwMrDMqD)#x4iq zMg65aPML=p)v>uM@pP<=OoC)|8QDU7n+)pOj$O?kKo@`#P~ex9D8kv)=ryB0z8FbO z+2^sr96RW3LmFN?(eLGukLLSv;Cw}(gz4t+frL%bUi&OEfDa6=I{&hf8}qD_vRQPl zM8DS5eErbINc0}~yLTzs!(R=+ASsEsWzv~x4UGAYLmXf=V@~d zg?FVjckC46q`wCSr4!tyY8RdwIw~9izI+=6M*!gDkfv6AM}G0UdB3JmwBOgsB$8AN z!iVs%!hr`}0-@cFL4C;B8MmmoUSAo_GP`7XEJGg$p%|`wZNwN|&Q-_21^412OGbLD z%>ubCyQxO{Y5g$*mC6A?J&c5Jm6|MuALhYYkJGH zxUVhnvguE_R_%#H$ zmRSt6nB1>pe?i(&I+iqW85rhC<4w#isga#jk1`8i(bkQ5UXfxEa=?}w!ZJYhfm#`5 z`u;bWdolks)OpFQ$VJ{Y@Yy}9ZMN#frQZVU#5AQISS|O!@G8yh>!%+@`=WUI@75^Z za@0-ng9TJ=h+jxzCTLJfJ%ZWge0D%=&y@xtsX}XfaGf2Wjzq?RiI`AXh zEi>Tl0E9J!x|~2a1LkrlFgs>B4LQQ{ilfaq%Xw?(y@gA1-&)8Ffd;jCQqB zTBcO@#rHsh?mK;Mw^IsBBE6l)L-fv0G^C>^?0McYp~U0bdkPs;Zh%*Y(fG9k2Xd$o zLPzn&pz@&XhX0Aa(V`9~4btz297y*YQA1O{@syj_QL9xB?!35f%$(^Ldi$^oyQo{c zah&(4xB+O8glA;*&H?N)nGPnvya<_SuQ;v;DI^OfE*>~oWNW}ycnGL$3LKI3);1^t z5&!O>yUL)Fv{qXo#A}miA41v`6#8%{GlUkcQeF2I=p_1brL1Z7E3GQn^kKj1f7maL zTq$a#t!?JKwwce~TRC@K+XMNwpfZDVQL0zndsT!bF$1_$qU+>3;OaG2n_AefORY5Qz#AABjaff^MA`63YQeI8^KvyYjqg%#-0;Py`nt7Io!c{B<~H6jNs76 zaOgb0Dd-8O@ms=h6%tMV-}#(ZLwN*Rmpy(MKvd=T{HzsHV9yVRd8au$0UqnXOhXqz zTXT_Nsp=TkPzIW9NN^Gx{tQ^0I;7k+`z2pM?1zvC7`jlo8h-n;n8L`~$ojURQkzLA z_Eg&xuneB`_onnazMg&H12;l1a5bC&cxd9mc6V_>A90W}CuzALIzJAW)`!iNQ=c}n_{<-{+QvE;jBL5w*fX-? zSSp)#N*^x7v##_7x&#Za<%S;2HKfg}H4q&EWWwdYQm6`8_+f?){Cn^KLqKID$O%VT z{br>Qrj!k|Mps(rNsRuT=r4ZgyifAQI8JDfNc=t<>r=QL6Fh;!tMufKi-vXWr_#TVZ^LLIF)EPbP#g>J$# z&pi7q1LybRILPN9XMAbZ{2TN0uTyu@MuNdRuiu)7h~&vc_K5H!^Zzpc9565KF2?cv zOY_^_nt$k_=jJP#aiAc!NRBf9(nCA{+e_2?UwieLix{3kk^@M34z5~Jp0j!L%Q?g5 zvj%?=N?_as58!zudA2;9V3Sd3^%rdqg#S2uq#3U+r=+{C=a`P@j8AH3I*p8H-E}!6 zF^tpj)WaHikuHI839w)YR1zn{rg^aEL1yt5!V*`i_h?)uwlckbtmEy%839pp-Xdw(S^sxsk~Tj2Ki4ozfjILvVRd@wJ}w3B+vZap zS{}BDHeOsO7s#rQerEhL1pILG_f8(G%iSv8oPC2-D(r$a`M zQL|U06MtqH<>AD=8 zuek7=K>-t82?56fM8r&(+*@ro>*PJVdP@0c(dKaUkFf$I=3`O5Q<5Y<@UR?s65#q= z@hz>qoL2pJIhOC@zL3#cTQB&^V(4)$wsz6kZ0!MO!eaZ~Y%g}QH(K!(2k7UK%E+LH zLK`BSA5$jjXj@-IQ09j*#Tjg6VE7d1U@1JKilj;$n2ivV0(-iXe89Z~5_-JRlYG=e z4P98MY%S1LoJjJW4SWVJh9w;c?O;gogIiBEXp8#}9?l(Z%6<1x9H07hj+GO0-SEQd zxU3N#OYRVJ4;cLp!c7%{iZI++m_^fpjKEgW2 zVlsuqp)#-SI`u${g<>&nC1Nxku<j~3ExHfKOy zHVM(l7w#{=2e~r>eVqFp2&wMJ5uexs_=T@wyB|N`S1K0x;(Mx(YF~f#+hW3Zk$H*Y zrzZ?)r;&lJUoZ2i%t8B$v(ly2_}EiN#XqEn0+!cN<&#i8^o8rfsWR+Q5QalA%2Mk+ zQ{uCRv^R^o7#(9xNVQ3yuW;#hZdQEQ;?&&t0DZNi-1e`bfVw7u!H90=q=5i~dLmTN zrA5&bmF~v`^KZZL5i2)zyogl{Y8cpHCs6(ypTIT4CofD1I?dFiba88SP0VMIO_N@gux|=ub>b|th zMhHOZpU*=O)g^7YJl>sUgIob-1H+Hl7y=j63GS$IFblLbqtMDl{1_j2z?-d+@#hfk z3>$p4v%hpo84jGdHtsp{J$uJ3{p0tZfOyRZe5>ag7l-A669(|PILyFC!1;y_j`S*{ zC%DkMZw#^>1ZBA%$QZ-ew$%bbnNHuZVU~b-`eWD*{Ga31o!7}dYyXpkx*{f={p329 z^>lf}{T3ZR zEcu%<9L?8DQwcWev!TE3DK?*YNmSlJpm+c&U8%SZ8mj#hY}B6dDx0DdZO&O=Hyed7*NPUf`Ob zRpSGs%TfK(?_KODZ`AaA4*n>6#2OAIS*W6z)sceRDa|e_q2R*)`@6%c?t=P!^)&R; zE~$}ddlx2_az3*9i6wvE4ljVpxZg8_9ohaZxCX_`Pdl5io%hlFmdn2~9K0LyFKpvp zf90c<_7b;U_u%xkwO$m;o(RI;D?eTeDOs@+_AnSJLAF@M#oLgAwqrAR^AopV(ryYm zS|Q1V*sm@4YS0$6wKrAUMPL14uNhSAoQMVop#EhwbUA#6dXEviNF*OFx&MYYL;pC; z_xL*aIwms^G}q9850{3*pdvDdp5b^?!KO_)9jyLltoO4kM zzuRx~Pk#_ISA3z%25mg_3zZsI&Kz5*V zzzVg@-cn<~X#o3GL%)lYp&D(t75xb~uInp|@yu^~+eTF4B4!BH7<(i__lAdc&wlUF z7h*Ef$%_#_fUmrowmd^mC@oXUfto%%01yMTV%8mI#nYPdOn5>JNVY4^;KiuG&naRz zIz$k)8W12vi~$4J!)OQeA}QJg%bO0g0n7v+6R`kJt?o9dYsPX$@e>4I&R~@n$J7^# z#9)djIx^HyOTzbzvUx&*Ld5T+mrktraQ~LayLk8@zhu!d4)qofS(|XwM6I_;?i0^x z3(e#N7h#C6B}AekcZx>ek0Qk5_ZG6la&sKG1{pYs9*|>hv-JVD4aeKe7UIsNB#cZB zHVh7i0=&dZO-rQG$^wP&8-}oQN3{*~+3t;zShpD)1s9&nV5Oik2kRlEN8uZRMBt$m zO`LQAFAxY;lBdFl2W-pU8svZ_m4>whRJ~WS z2{KTb12*uCE{V7e_MSg@eqADe{PKrJKAOlLEkSBfY_Zf&+yZpq?%WsmzqtRw2VW^3 zncqL(_ueApgb=WB-{=*jWBkl+bQ8CE^Rpf6)-9aJ`1AP>+T`ANWBvlc1rj%I!~FtJ z&OtN@82rvH)=mwclt<#nPksnz*6rL0bRuW5;aB8tjDo9!t6wPw$kh=@N(0DCUn$Oa zVE<@cPtqnfK{FY2bV260g6xqYDPZw+gnXLdlJ1#yg}@_jtOmD=J^g}rS&vXCt;lQl{)U7IF6&|*myRh-CKPe`eP+o zZO9tk2J1d+^My&!4G;Y(n1*;nSy`!-JK}6g*cO-C*0aPg@e%~QyZbJ??Bjp*@jqG~ zl3)@&$Jh7sL{sjqe*N|RkN^DVbJ$@BTu&MN^2ZL9N5d`fo z?%z)tQ`UwxcG5ljPYm$@l$}-xk&ooWPVep*)?zs9|7m=;$z})}iwX7n%Nn1gHtr#0)Bg1iVx1W6 zi;s+uIZ?^7$H0kCM57ppq}N$rhK7z zrt~;-XW3OV1Y25@!yMug6QMQAMvOB)e$d&2>sbuy9`cvNju~Up`Fabn3;-vhnSonI z8u*`_l|QWh@FN*|sqNRuE5bsXWvjUX%AI#&S8n|yS6GhKnBdA-NqWc&im|HJo0Eg_ zQ&PjE3i=+zv!5&~kN66>MBl{5%{f(zfbkU<^0ly)6t0N+t>PJpcm432l8Z^A%Nq;s zG?q8|+w`gm%MTv7DT$egT^12_hki0w05+80zZQ3wG=cPw@ojk^lBVlG_tY4S28cz2 zWdp)N>-v5X@$@2m0|`ed>tss!#e>-$GGP}Q5L3WmNo^n^1P=d0Sg>Q(LC*%E{?#El zQDa?*&g>f0yko>ej4?a}R2`OOWf(4979xyHZQo6kV#==WHg81DpzZ0P@U$Fv<<-HoosVkoL*g#GfFc4 z(OdDA_Pyl0s)4xfwEJw4K3ly5^BqeO<`mX{m_T#!kj|m`jRRG?S;m1L;~$I6sxn24 z$T4aZF<2pGjH_HstX-wrw#|vL2pH?T(cV9X@>w?tO2fh7oFfMhz=!r0RF?uD@Jqoz zjf16G#`T4>D3%7hmV|Gv%Bq>gHIznj50r&xuxfVnInX$0pgMqIoKz-?VxgtvbO~DV z8zq@;f~ao=uq$!RfRY5Tt4-pv{J(+-ATYDUS5R2kK8@?Rcqr6vz}d;a^x8G%2%NP* z9_lny4dMZ;fgnId%-Uo&rLX-|826Lg#7l@ebj$kQFLJ@1eBTvJoaVnodIbJ z)Kyy*g(}^FJ|pPRaOK5A$t@K4X^ao%g7G>_uBUxdGIw=AD{RcU=T7ZwZ6drHikF}3 z>+z{x@y8>ram~!IXY`bk(xjf$oxR5C)RUg;+>P;ofj2NFoeF0*irZ>J-Qo6oN+Vl3 z9K$H_oW3rt`zI$nEu9lnM(*zOd^G@3$(?$K>O-db`zJIS8*)b+-zkoF@jzd{=(|y- z$x%-`Yl>t2+VS=k*R1hcNA*+@S2hiZGl}UA0u{&}(I%8X!c2RNcBF=>+V(NXi6DDw z^|3kFy;&aX*@r#IQR!xxc?72_qT(rb!AXd1dxC0fL4pCC=7^o!ZC8$9c;DORpSiEJ zZynfv=gRe0hTS(~j`#CB{BZwcxQ%A`mPhVrt=tmcRhcMZ3pTa_e+TzpcYMBerd7&_ zlWctZ6TIB>(M<4Yl2%k|ZVewrC&!7B=!Q2pg{G}?6LJw$x8uObpc0_VVgK~U(7ys1 z#%~9I{q45an*-dJJtOCTU7?zgYe9UR1UVuDBkd5tNoj5A>?dYWn3+;j6``dWksGB+ zDkUgRS}5Dv2z>`yQITIL{RPZ?@Gd0QF8&O}q7ldfNO6MZ(g~Te#zL}2v+GrRe*(e%b2f}cDw1JYo_pKj3cPt#)AkmiLTU&$b zNN{~HBHNKye`H7_brnK3h$`{@v#@4#@+U{_yfw!6djh#&sC&fUfEMVF+B;NJJLiHs zN7i?rAIUFpmCeZcsGZNZcMbVB=XbREBf}%5bE9`nzkl6`A8z+YzTO>P9t`*FKwCc% z4o87Z4~T!>`t_cNUwzRFFn(AIsHP0;*vve%7lINjYsErBnR;CeCJ)t1z)Fo)NS7UB z8ig4n%0e2fMdPM!Vl)l6$4Yp{C=g0OHCmikflz!6z(~VHexJ?~0+#~HmrmcPv0mgO zGR#%vMwSuD)1o4a=_ny`0aWVL6AL&8wSkev0Y*CuFqtE<7xLrcV^0GKyAHNW;KS;y zj-wBNwoNk?YWgQ&YLvK255ZV7wMOBoO;HuyNDW3Bh@X=(m!;O$qyf35b=!0`oF+{2 z^-YVWK|dBo9!QF5rZuBts=pr6%QD`mt5U+ttog5^}rVj^63=2#*_}eZ-q|FNabk;%DU6uu+W(ea$ zcWUkkz2CXzx1Zp1`soifJ%oFwU(UVSRD5xFA5NTmj^TUvS_wp5?vVJF%ONuSPqv-X z@u^bjQ+@A!rTF6hH{XmP|9kL3oFO+iKX^`)l@nT0@@|CraFvyXY;zzinSblq`8Vcf zYy02WpYg>O?Y*m-9!mVrfhk~bW$%`HI2^lopD28Y`^9IN*1ybeefgQs(Lado-K%i* zHg6_|q%|oI>H*V-w)rqLld0r`=K4qRJe>H6YkaUK;a=)gX2@6uvi3%KB5{OwD*LO` zCD9s8@U8EoPV)f0$GW@``J$|m=`)Ya1N~WelBb2R#&R(1XWz!X+26+f+kA#TTeS%r zm@)cS3gbqg2bw+l;qk>X!x_^B!pMFFW>Ku2=|L_+rk+gh$Np^Pezpt4O*JdbR28=rcZ7;Hs$Su)BKi znN8}w@6D|uep|qw~FM9rwS>fz_wx zpwtM6t(g(VkYXfmXEiTP%|J1cA22ce8|p(^sKJZ{2pAW_4Tz;>7FO>6b#h;{Dg(^5 zv_Q(K?r)I`pN29d&Wl{lWzON%ysRV_dyv|7#8%((`J9efs0GjqPWx&%e2t@@5wtaJ zdnCF0_eJo<=?PWv>{mCk%1sp zLo)nRLV>lvf;*J)QA02B1SO-sG0eXOyQ)UesONO+9QSm%2n0ZV0Us$Soh>Fl1@WsX z(zjUtIBF~WD)^-G6!S8fX3?!1#_(9?T4LMR zi-$LacB|4-j$rqE0C@)(e0rmHJY-s^?LbHilX%=+w3QXN$QNG2J=zMfPQ&-J68HRB z2-*<*q2Iu$;32;~Tag}RSyDJj15**)vweqr7sW9D(`jjwanMz^P>}PLr?3iPC4m2O zsAi~kgKxT%zKi=VVqaF*Hi&0LzULs@eaJiN^!Hu#(ta3#coD0Tt#BK#*uZBXsx$r& zWE$6j!$!RO%Og3I!NxC>ZzC-7q2##xv=`B0kGxu86q9?D>U+LxaVV*nrMjs%qS@dpsNEK%UDkd{PfmP zo+^M-*jaX3@u3Ipt#U$ImSHp_ljkx>CCJp=g}kf;$r7R~G@v(lKj2%PRT_!ugT*qY zP{1kQ@_XLqOr>m z9yfK#?YR-)StwgANi1vDl^7aubQ)HlX;M|RSy{X?d=3svD{D=slyNhW%{-D>0Up8J zfqpvXT@RV!f$QXFEl4}oXeLXn$8sY7*+wN|oDBwtu5&{DIr2Za-8keJp7xEEQTI-^ z*gI$(0~vVpEbA?W##~e^?!q?d6u-}PZ@;ud{_2H)BSqj%&d5PTqujCuWO0X`D;pSP z3|F#;R|BhCW)Z1*9EwC^&~G$>cipgD0uJma#xaaIK*N?RanKBI1j~YrVRFdJtKvj&pQrlO9mU?h-lFvP>J1}Gsfo*r&PGh^s-GLM z`=^k+^m)j)P@@@u6HWz%P9g9s73r0!8_YZrTvTd@3gO1#X1sBl z)qCS(j;1aht{+-I+#RSAc2bXUWJ41+8ouG*Z#lmQheJk% z;SK0^YkGX|r0e*- zwwdaBYktcHi>d{r2JptT1A&am4FhW!z!l?DzPi)kV$K;YHHvk2>LG!p$d zVumpA8$%Xmc>7C25*C8O)w+QWc-(J|hE{#BUDQ8%sU5QT!N({r3k{ZN)&_o(;}Aeb zS$cFwjHK}pY#=1U#`>&*R~YOFtpgQ&?Q7d05OUf`p!de2AdQb40o;r`Mq@oC1^|>b zS2UOnb|LgxI44-J1VuEE33GZp>twZ(Hpw#aDcI^Z)41B&x^`e9#ptQ}Yt3(;rkBy;V6K33G4z8CWD~my3niA;< zWSlV{wHO*&gMC8DxY<*58Mu^1>c^a!F|t&t5n~?Gb|i$*09Xj&qyoRPn9NRs6I|kk z*`M?iog|J`7Q(NshuYjVB#gxnIAa}S;X;_0)fV$-NLD45YOz87X};2cZL9XrZ5!Nw zWZSB%MryBavwDLJ`o(8{`-xwC<`@S@x?lRwsFk2dr6himJ?`~rL7No02->Alx8HY~C`jZ(Ta8YZ|z{+IeQ z>p1#`+%ck4OXeT+cEsLZe(R^Andn#Mynjszq#LLz(InO|o=SIIZjSP`axpHEP+1DRJYRbEc3!=;T@_BSmh91Ume z%Dzrw9Tg>z`7NJjOLjgp&L^QZkFO0UJ0CK!r=?m58SjsvhlsVJC!e%?w|6;_eT!-5 zG8+%R6madKYjFBa=FjYk)r*YfCQJV-=+|)%_ybT4qRi5FuC;#8`IPndI~Ba+G!A+< z1$?R~DW>*h#!uq93u`07!nC}#*TCO3k;ok1gEcSwb{8Vh4GUw>(usT<3nb7 zAN0M+F~`3<*~7hj?{*SToQ&^XbnthtC7{zxkJ@wu>5wK!Wu?31 z2J7D?i43&pXyzB3SQq{ZvPTD)oEjbNa@R7IxrtWkE!aI$oP#QQm6vc9ECw$dSqlG$|66$3M;J6U81eJR6 zoo2uYz)`0Vo!nr<2itYAf`D_XNlA^8LS+(8v1Ur}H3C&%(%*oA?rjJ%makSs89eyL zLn0_X()EzO2a|XYxnKy#GC=uQW}>vJ)!G)97?ryF`J2e4yk+bf$J}#2(U)*9jLAVk zMclb97ou0H;o05oH3)AXg3{JSm@a0`!&s%8igZNOUAQe9n7)r~&Rnnnk@` zK7@d2X;OFroeJ^Do=EO>5?Ny}inIg_dpz6b&-cLk+lyta;+WfhU6ugxJY2bAN=OE_ zm6xLWTgu?u3z;SIW4~3Tg4dHc8f;FA5k_`%coK**2W|Ixcx&ardjb0iYsA=K(_|jT zG&Zh=xT#f*G2k6R?kMtx`aA*Do8^_0a*zqdo;eCGNmpg_YGgk?7fl=L--G;SR-qFs zEgzMs@B|@cW8Fh~K#ZbUmdQKt^1jb2yK`LL>X7kvAwBQ9^F?ADIcByXJ&oPmq0Gkk zBvzM8Ood3)2cB*;wm7N+CtxnM?I)SGC>kT^TBV-%k2N>pQ{&@I-ViNrJc)kJ>^gcY z^1U3wv$B<{n zn@F$#NkT?M%P5Zmknnpr762-Hy7hCAzAM~V1)M=le?o?g0$(U~U5;wF!^nn`fLq8q z5md)ScMF31eYuy@L2>zi8k8Zt*C$SbOv?Go98E^;*xI2b!9-tWbi*#7(H`1x~Au7NyHYoue4BYD3!3z7^F z7ttVV1`O#7zlg|jct`GY{LGvELM}{h>46xWm1Zax#Oq$#W=F6%h1^~6vTNRT8Uk4g z*TA6M9{Fel8<-(%1;XPNa5u|$(Z({wmA)4IqGobcxA-Zj+H}rfd;z-%3e;s>2DuU| zrd!+!6jc6GFrQ8!;*$Vf{WmoGP!X+eC94jL&WIfQ;D z^eM}7*$v=--*n65R@ketXZrF`&cxis`>?fhjc~WJG=)^Z6mu^0nZ2*0aAoj{fRuKy zH!ZV}ITCbgTLFFzl?hz->8f-Q{?KXlO@|jikrDa*Gn8b$dJMzM%O zWDfEPM~g-&4BFV&1sNUleFc3*Px`fXi*C`=q3%b!;B^)n^gX^*Mcg{S#8`Tr;NDc!77OH`U|y_Y0J_*Q$Qc3%bNn;(A4-B~wVmCIz=5LKMH~ zaZ|K3L;Tr%_r}xQlbS33_4wAtK4bN5zs>9ZK($={SXtUygI%bT9t?<2L$t-bw^iE6 zvaRwk@5jb}unF@VE{J&|?=<@m8s?)bKPRpEu=}s z)(n;0a6s^qdk{K?G80v;;4iGOx!OjmNX1#JZpKJ#bK9VdM?@7@GfVy|>H*f|0l!H~ zn{JjbuiFcXaMW?*}%Fxsuc;VI;>7T|D5NIRq9U|(BL&^>^S*TIm&7@BiKVxR)MKVW-3pE*d6*0ImJZ&`7MXkslPO;#^*W(~OM2L&>f%q(@Q3O! zi>SxQN`spAI|Z8$vjR2cjNiHC6Tf8;1O`aVVRqDmVTD+ENz>9gTChS zbbv8<;$_VuOZ6RBjN5>utj`WZ4Wvq!{&c5MmnU|yj`7J=L_kKD(pVmFXY#@ny~wii z$zAE#)(FZTI4w{3&8NX1`7xl&(zP;4rVD(Ad%JX^1Iz1#vTSP8@);bQn?sUs3+$lJ zU9o%j-W%t)J(EjhiWoIJvq&eOyt7m+b}Tw4@~pEGI@0W&mv-`?JG1Ft3JgnO+cu2O zEF4$Q>?MBpZfHR^0A-zTU{m#3XJz+ZBUkyI_T5IZEdEkEJYc7lrRcqi)F54L-GAq#PgGEXxQGOVN2XEfMTl50h{@-O)!?|e~Gxq&i3<#8soFw-p# z^cA16@qNRu=oMju%6oAk{wV{Iw#_)wnZ!JbJA@72g_NBYvB%mo1*09Ni?`kCVb6&R z|Mg&0SnDWNoT%8hq^YOBEU^R2Few6k4K92H_R*FGn_hykCVtN?C@hZMd@RODlRhK` z1WdVBuMqL%u0k*Nd71o=3y5*sKyEAPJbDs{>2&1J5nmKOR5JWhdn;cv;`SwYYlDyb zytX+R>w^t{{sl`nmEU-mAYDhfKQ7z{zVi7WQ`UKp@e}&w^H$zDfQ4ZPu^YHP^eqQ=V^e{_!c<>>M_7 z7=*`$+vV_g<6kab2;2s8SAGUTDNfXJei+Mr65sanVZjNW62}Umx!i>>Oi16M)et-$ zJlJ;#`&#X}lq;m8SHPtxMH`DIgYvLx_^_mg<|1IX1w!$&4hsm^b}j`!aR3b=8eS%z z8kK4IN=;J+5pvR@90n)gX&rVMV31rQG|57i*a%myUW~-5T?}&(A)6YuPL^2AkD5mM zSWxx)IVJ~DXD@OA(AHdTB$+BN4-hfeppH*1f*$~*6riOUreY+6rw-b>_CN&eIq0sa=m;85k&Z=>E5qx~f-j{) zpi(qlldD+PlLG$~xVWm+V;O~!HmDtq?8YyXR(F9!kfNB2U?d6Cu@a~ikoQ~VLLXmu z$tpslpLfMblf4xD>Bt~}L%Y8UdtxnN3-Z}K3lV^VSc;uXK?o)C9z0Ppl;8poDRBi4 z9gqizKHK(1dKdF2!kkcHRy6o&O#1-k2BI)3=A00|<|YL_N7O;5a+4pf4DJ(l2*JJ3(NX68gpl3OIGCVGr8T4-D)|h#W1`Eto+C|VQ7r^2nQVDCQldfB3+|d-M zT0iM6F&dXcMilViDbCmgs$c@e1TtBuqx%3fC`h#gIET-0!bA}PuCc!#fKO7rC2$SD zg}v~wZ9nS6v2e3V56`g-q8Jw`I9_N~&&lO?gr+$(VN;c{m%zY54h3^c{%aM$~dnTDO(EgHlcORGE!aMWl=O-)H zOtPOK67wG&q~<%FoQIlg;|cu(2rDB$p#M5L#gFded#qElxhM;ixGeHtVas%c$d@{F z+P8RYU5y5+9C_IV6eA-lh?@mzCQ!qNw)q^oHtRF_G^p_WNZSp+#y zO2#YEy&RaYM$l-4qz6L`lAmTN!%MeXr8kfjlk9kDu53hPaEjT~+H|AjQ{DaE1`J*g z^LuHU9mpN-==WSPdVATmR< zx3{O;gSZlT==XY2A7E-=DHP@&%q6DK>+9l}=_ebraU7S_bZQm$j?1)}>S}eyAVX5h zDHbDdU~+A~*WG|TVUPEex)TWo-b6=N5&Y0;IIvJAWD+&k00>R0A2v?<<1H-#?y$k- zE_U{_qh|dKBcOIKhLur!lr&P-xJKiuWd0I1gZ;WFtLz9N#eH|Ry#O`6U`@5TaIV}O zwShUrr_r8A)=B##8zsL6nyniAhCc=_I=p&&YiXt=o5E7-Ej>MdE&Hi*2nh%V&2Z%w z&>{b=5oDLpu|yvH2V{N8kJ_I&7Xq{Pb!}G`t`AzTm%nQbN`G3C?SJo=g1b~(Q0m#Y zy|wTiBwlXi$%)V?l&f%gHibA(fO%eSDIw1l`_DuyfR1%UVc-Vqa)Krkd8~mUjBS)0 zO@uK(u+>qo(NcRik-g@8#=}k4*hLMRjU^|9RMp@JMVzhJYR)|u^)|9Tz!vQfp}q&s z$C9E0a?lXrJ^uD+yFVmX4Oa`iAEsM+?v!rDHXIIj7~ByvB5^b)5NeLDjgZTpXp5&J zZ0SC4O}GymCZuEJe8{hZC~`Jos*Q&C1bz?VhmcqdtL-?Jb9_y($q(CF{Qv?=--q4f z<5WmUS}7JnhLB~H%eK9pv}>`IexWGKAVPC2hn0|NCE40b=NlxM)MlN7t5RpUxSB;& z4dV?~8owUHI#3S`vSHfxD~l0Dd;$ðS~~8<|2uTU6SNl@h|)5C!<9V3s24e$yDS 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 diff --git a/util/wan_aftup/A301_V05_prod.BIN b/util/wan_aftup/A301_V05_prod.BIN deleted file mode 100644 index 7c29bc1ff4286e801bf1fb8bd24560d08a985e1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 524288 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∨?^OEDbaao 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%0DD4{Tq_48elQPDIy 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 diff --git a/util/wan_aftup/A400_0040_V09.BIN b/util/wan_aftup/A400_0040_V09.BIN new file mode 100644 index 0000000000000000000000000000000000000000..0eae50677ce328fb78228fb7f11fc4a748f771dd GIT binary patch literal 212392 zcmd444|E*GnJ@ZvPtT|&x1^RV`wm7nrLh77Ye*Xz5RO14A!5PxCSyRs$uaQ&$*#%e z?HzK-nruj1k_8CjYz9I&B#+IRkllo^*`WM+`y61`ZES**>y6FX&2HX#ajZagv-{3F zM8RQsmxRpwebwDFJ)@B<+0LI&>iX*YQ(yh*s_N>mt9#1ja(V1CPyUfZh9aUFN2M5N z9AyFj>PwDFC^eDzjzbC1WQTf1hb*Qkq?JP^wa^J>{T_fFl%ezYpeVmLMHv14Y7?8p z?@iPEjti1S{&_22hEd)%KPdN7>Bz25N7)=#`vML^kWu8fghiN7gnvufE+U)sT%GYcRzxoqcW^&EIauN3 zYNdr%jxcouG#Mwc5tS>{x28h1MYFsH($c^Yz#Wlto5c9Q(8u0_t)5MK%^v?54E;azo?!f(PC=9;Vx` z%dM>48ZWlIkzMFV(ONvsLu$O3invDuI_UIR%~~%J&~Ak;26~pu2F8oHbSwY{ z1^JA-f!?^AQi0uouP7DRap!H7*+4(c&ut3JWd^uXuBhB0zi5W_sC136yp?*#OYJj} zCc%io=K%DnVop9UU{xep*ucI{<5uLFY!vv+Y>>_+*!zN;Z`UQpe&^G{P!09^sITCy7{9EbGK31<4nSqx7a2-pFQctmR)>BZ8A>L*3nP$S3K?#g_+rC2g1COfTL{n57lHO1{yaulPc@L$r;o40 zSihdG*N>ab#R%QkKv&wEWoYv_Uqtc{18G=FyK{m_KgwTdD^-3-)*vp22sxz~j+Za8 z>q8##S(WKH_;Df@kH&Sx%7>9ci0kPb^U+2cV;+h0wubtPMUj4l7n@G!3uT=z^54M; zW95kCnjh1P%E{^sZh&H;f|VK&l#!Y-N#U?C_0`)|nj5a7&=!1_T*Eaq-UXWg( zkQ_IIjB3^)iZ%HT=HxIPsN~|BMSVqJ4vL09+kip0Fd!(*XpQO{7Z zbe^sgGh7^{pi?sGcpOscQH>~u5Q9ti9#zzOlbHW@g*k+2(DJJaXIoC0ne-%DV!?G4zKnHq}CU%Hla|Pc;2#Rm~G? z!elIWsMx!PM(ME((PJj#=m_S#Kqs&h#Y3#^aGdi94o<6j+hA`G?42e^NAk$D<_yo% zwA&!LiUtVFL??}kPQlS)j6X_zhDggsp;gi84VqX1$MuW7{OHi-BvfNxb51evsiac5 z$X9oYMi!Th`*x(+(NTW#SZlfOFzqZqQ14ck z^{J$vFO3wn5~WuQmMMkfLt^+s{R?`h=?mxI0&H*2xtf0i%W>9$7?XiAYV2t&5obHP zcQ7AdnTqX;iha#J)u4!Vpr3^YB3*GdoT{m6I-#T7+!_>zD7_(oN!e%*)LvTS0;D0_ z0E3@Zprs{sd)QQqWk^SMgd50ZaCyM}g@JmoeGX3t6j5;Fl?j{tbc{u5{oo`=B;y1J z68{;WZ%Gqm8~~n?UsyXL%v&&kGdSDw>dfO;DIzRn5i-~UF+)x-*OWohPjd9_IG*F> zs}c!XPKhR4t~Dr;7@?9@JX68YnKFdR;ja$#$rCuoTw53Y+`vc>=DU2y_&?l*2%pH1I3?{t?5l0?7w z0goAXG%r^yLwQ8Yz2bkikhMQATyz$lB+uu~rN0tHR~_`sL>~R5$IhD*CLJ))@mP&J z&}oAoSg=mpP|N^#hT#~EiU4?-r8tt}fQsVNrpU|P9pguFp4VcZ!#%FZ(RH}v#-d{_ z9T-NZn##J86Cc13Y9;|kh)HL`{8XoDZ7>Y^wXAW^WHDuY*8Du$kx&br727`@P{`Le;Kp+R5Ki+FUp_7jg-tc+kb3~TCc4ie%z++Z$o7BJUVTp>^#xP2;D#I z!|`Ou9$OJf8Z~SW%_{qONYTnC%(j2{DcQ<^vd{GZ^Rxl;N#V4OG%(=K;WeR`_!uCl zBEYn-?f^sPQ}7)clRw^@`b3VzmpW54drmg8Vrusm zgGA;*g9--S`}q4zA9`O(N?3yqx@aMW6 zLrB^|@}c`ZLyUTEhD?du04aqhActqsgMu!<&J#ogGKz#)gcy2NeZ-=4GL&oNHbc_< z8N@vdOQNo3s5N`oImsQem0Zvcd9CX}0~bI$MR>$OH@5;0uzs84?A7{@!kXtHsynks z(;j;UgBF}7x`ri~Jy0-57soO4bSZf&A1kl~vyIIQkYe+wM^d<6z$EVp+DxOaCrkO; zk!&TB|IJ6Y3C`pz%{kzly()>q0B*8N)a+0)hoVE(b{tqPq8$qS?44}fkaEok5Ah3# z*~m>p4x!ymtYu7|axcLk&T`!iwk+GtK3S_$R|r@<=bDm5v0NM7+h|X;#v`Z!y~S zIx1wua9A+S5!}rIAQTRPDB%vCLj>y7^JNPG=yMtobvPUKcJOuYkI5st5f(B1M)H`M zInjFkISOD19FZQ!1CFa>VW8)Djz@ZoStCx@%OhHFB!oy`lck7z3b?&}Yz%G-3b1x5 z`i;yq@@p{fvda*hc&o-^7_7=JEx`&?2~fk>6wo5iE`=xEBDbcY9H+D>l@s)o%3dSqcSXw=j4{AU)BD>H$V2} z-)k@?3 z%eEOoE=wVBFOn`vyt*b1`RTaJ~tFL#`C&ROpEx#X8`;xY6l zM$S1Mp4(2l${8x}N+!1-Zy#(Q9Bh9rUWDISTxGFL7c{~%8Zh6f%m;=PGA3hR;kpzq znF(J^{gee#gcoG3#d5nBa$KIdgE0mPP~p>F=mS_!M+|-S21jAl2=qGxZWA)-r2v~R z%~ud96pJcz`#4j$t9z08Mz5lgSx>9u2CH%18VRgM{IwfFRtG4Dopbj!uwnoO(ODG8OAs_DkGe z7`XkzpyKqXvGz(zeN!PVi|-5!I3_0{wP2r%r5E+w-z5HQ3_NL=recZ2fzft`=Gi=~ zogT~v$t$BcYMWZCaX*{BT4KY4V3js=)?6%F{QL$|yG+2!tqf8Isp zoiy4r!G-sCtjynH(1SzaE*h|Ymym8k?zZh=zYdw`x(vP!>jM#IjDz4dQVy+^3CddM zf^e+tx_^R+B<}RO%&REXg9jDgHK?n9B6t4g1byD^%{gd;J#a5gOY)U@zv#sf8@Bhm zW(fu=Q#j(kYw)WDXs<>Wis`YUJ3N}EiTdf_ACtT{X<*YFX#X~>Y)wk}JJwC2Kb&pM zoOb|S>0K6`cL;Ou{+vORI2U-aXM7UVaw3;MPv-et>{uwz-?B`*J9OO^nX#TvJfc>! zz$uF4j~n#u{ZqEe8)W+rwfzHpiMhQ$H+^^#ZPQI10R5N4>C_*ipV+({!j${S7sx@A zsWoTiQ~KKTPw^>hktI2a8oO|Kcm@G3uS!n=ArmvZtTj;6RYfGzX@Zeqxe8pKEJ82^ z2}FxH1THFul*1C6)<%Y>s8?o?fyf}G@CHT%^rS5(X&9AP64w*iqb8A#q@oVd?-sLU zD4N8DE7(_V+u0x|u0>R`2y?ong3@ELVk^mAn|H{;_%sfjRqe~WsTm|FcHCJs?X>E7 zvifdXZ4sQdM|E>}&<>%5o*su*yP3_~1;?c}aYe3;R#BlvdIR|sSJ3`@-k68W6K%eH zV{@TUVCCH15T)1j+j~)r=IO7(-)2+(Y1+2;ZWOzj95@@Jf}r3iaIjMlW^%fFqLJqV zJ)}7S4m+j$Mm`r<;|B=r4t5=$K{+Ep%Dq=tQEP^MiTS}hCi*g>JDCH2AfOd`&2V_> zN#jq!;QX+4lWDdiwzk-#VtwzWIkHv{crUKIw5UjU(+cAC{b|oTio{|AU4rs?f{tR7 zBV4;iZp*6me`b3w4SELFH~rfj7a|QLA|LRAu;Lxk@~TorCs&Du34r*j0gyVJ zH<&B-8rav#^#GcyKiBk}lU9?68!v>RD1zoxIxealj?J-DD{e@64Y>g`%v&s=0#U4l zp`y~Au{M=tQWtQpeyt``l}4RHU74W+jxZE4m*@!J|EVahU|2*Fmh%A+I^;lBVhcy6 z7ZU69x{$)WGBK}YX#y)=rzq+C#^*}1u{Md)pA65naCjLAMxer2%y z>o?wf^BdnNV-;IIcH+eGOQ-z9JW5e~`ILGom6a%#p^xPmI4#Jtk`7Hjhee2*@C zj=_jfp$&dE%hObpCfM^>oA!)Qa;}y7ei)~>mj`uUotvu4*|LRGl*=o|Mri%|efz4C z2C;q5EMr}kw3o-eui#T$Pkr7yk8ClXq>c2ZgA4(EC)!)aMy|e^Z4d5hqB8zUrE>ci ze2*;Ox%1eu2G&oB#qEBk0XB{BdI0x`+8^0hSn8-?k*istu^N@o#l=Es7W*)f9Ig=| zH3NJfv>Ev-7411Mp!qSjW%?p}LrC`q7EV7bp1z4W79`i4Y;F(64PO9)xeAoFQ1P9B3(>Pa}|~V z-$@z?^AL94BoM^FkHzUbhH(fkN$`}f7tOe-Be#irk6Qa!Rd>0kDBCaBAlAlzQjx9 zP$xJ7_(iRm*K3L<0aGK$-fc|sCu#ou3LJcDNpwqT!LFVEo?gV(%~5k7BDx9GR7eR!jCf=$Jr6}ZL*&_f{7Eawl-D*SKW#L zBZcz7Y{-4`5`1c~Jy0nNUJS_f1TDe*Z9suD zsp)L5W^0S4+HBiwou+2?v0dmnbS2S% zKzzWq(`3U*$UFUV-m@24>9>5d^8CyrRu{7g--Ay5gJY zd<9DW$!(sgH^DwUeH|v{X7TA9eH!U6cqdEk?G7AfBP7Y15(Vehur_D;e2V5Q>j^`L^9kqc(OF12m zXOZKo!n0}Y0ku_D6>=_RJ-7c_*UPO#pYULXQuo>&yrTaeKwYt%3LwB(Tm__LjCPDb=ms~#EHSxQL^%`G3{T(j!3v!IEMgO z&ap(|SHFsMPY1iY{dq&fd~j-`u;Mdh-=p?F*4t;hI9LYXBOaz_-=S{bTX%ddp0?^| z41A7(4>KrVCBOP?PJuSKL&<6fJOvYTlZejnooI9q#G|Q|_c+cAtQQ@uq|?=EtFV~b z-x$dwT&sHelstVCaSPbwyP|J7jg7t5Zaxmr{fZSw^g0!u!8hW1@pyar^`^e^_Op*2 zJI*gNQ6Ff=W2=uOKG`&=I|Gjodznw=H?VJb`_3Dav|`2BG5Gp_{{f@X$6+O;_{xin zeX-}K1%25dJyL6`fOoxpLG(YM$9%j&s;^y%5EEn)ho`SVdLcZ-J&>GSaBwDptBnQdI2?rc?N2H==$59cTy^bgX@FC1haBsepn=I zQP0l<+2;~`mFDhNK!+ik`d<(hIHpn@tPGaNie`xAqPn{ESm_La8LUwnTT;69_0qbr zLPM@ZS%qmNO0M|C&G>TezoJ6AcJ0-z8Rp?4TavxGp`k1UNo-HJV^q7f}dfKLu!aLiD!C5qOCdFUa9eh>}^_x?jrTX__LZqLzH zn!)B+e?67Z!J765U4#b|m4jW8{)7^{d%*QK~j62n@sE6TMbe=ZQg@M=q!7#`IrRLwM)KSG_hE8(3?(}d+o%2>)8w=hS@7GZRd5R=jnZpNH=5JSd*zskUs z2J5ydJ~^AQGn6{v3%mjD(5OUcTa+y-o-WnW0~JdGgAs{sh}H{*kej=l}Do2Q$- z!t}KLUYc$$QM0uF4>aC1JK=(p&;C8{b|eyT&3WiNw-Mb<-k*Bpe4QT4wc_(0c(J;z zO;~RydPil*A;D?FQFxcRuo^rLJ?tygpxHLHwBX5-uB!q&kK?^K7!(d}5Erggq>)%R zZuAasy-i#3%|?gPZSa?^vgv6mq;0g9hZo)Z9qPjN(~Wj3 z79O5JtEb5uz-ZZ%GH_x(XYV9|lM!|X%R=`wJT8HTe6_1btfk|sIb@6ey>tsm5e%0w zse@voz6`(VEdW=i2z`~{YtYIfBo>F}t?$Cgv16*Q zy?u7Jk=BXC&P+X@eH_d?yiFay;Qvvtt9={}4zBH6-uKJ$lN(t+Mq^2XcI|B6RNlTz z3_8a;Hf<^!>~nnbNh-hRJp%)W`=0mx=YRE;U+o>cWUT$k6V-i<x*Nvvxv>It-0x9owi;GpWr*y?bG#aO*il>f_{@EU&wjJ4t4vNk zeoq|lh-=&RkBHcY?wAW0n@7aoT|8B2QhC%r|FuebPv1mPjsLMCtc{$`UPm=&pw`;1 zP<|!0q)6jF7nm>!UVDs^a{J%~Q&Z)`PWzkX8xt5Y_EX87H?H8N?h~&Z`_V^s+2x&| zY%1@B_SiR;kF}Q%?^|)?$jTmV$~Ahbp*h<$~M&O-MS^w0SHGRFVLw?T?KzZc4D5;0++ z)Adp&^g)K#rRe&kwH2O{BDvuU^;2fRE>>!b1BEGA;ci1+Zoy|sn-z9;15YTl3NTiF zwNR`j8&Gq{h|f6~4OFw5=PSne`csG>f;Q787Vr$d4r4)wj$5>e?E(~M3H!fp6y_LmSJ%mRGerK7Y%sKI>ebYgapm_IP*;- zu{C{f57rcij+9;8ng49!nW~{$DQX@$UpY z2xpkTXz*FnPxvE@C0m<8#6(Ur^Nt}X%m;k78o*Ek9^1)1=&a0=eGwIsj>IpiZEADz5|)I0idJDbO>Ak0tQ^HEZx zU$id1N}zm3hx2}vSDnyrB2dfh*QUO3mO%Xm~m z^}2CdyNu(EC_a#wF;r7h+RycZB|P)K1Kbtz#PeF}sBLB^P^O+{a|%A_BeN@93AGpg z#&jl|NzNFw^&9^IpJi?XDvmCNc|~^^LFZ24L`ZlyP91bzFM?T8KQ?v4a^6dVnR&Fc z%%A_MxP|6=;YBJpZA{_14eM4Uj!SNe5ajDKex@F~M zW4=Z(1YI=ebtr`)1P!B=9xxuVkpq08 z%{aJpyz*%PwM@YprVcpA1A^B)?>+}k0y+vG0Y4fZNdD`0{ z(|?lxnAl=Sc0P&%T-Z`1Khwr9T|ewe?aMD(shkHl}&R; zxac4cO>Wx~jw;A%6q#sH2o3z@QRVsuZDSz{gyI5Hv}Q9tVnS_q*i({Z8aJBnwNiP< z!IOW->)z_E>-IJjyK@5tOmf|6$L?)$TTs=b)Z!Jo$mri&a0|)l?l<|Bg_YfI|2w*E z*G*dw??A2Ln@l@bqSwPEE7~q3t1W8}@DI;mw4H=OrDM?v4A_DZYga*^ z@Q|#pVx$$EeNZ*MPE_fTZ}Sk*5Ms@To(9JHVT67R5S%onCA9(9S3(@ibr`gwxlmW& zV3TCEkhMvw{EFqd78lK_*sf_|$tQvV%Sw&Wd1MfYu;xoBFi0H39D%o+$E?!zHklS2 zFbJG7{KNyfDry7BZT=>$NUuilPh%g@E#$?FV=&Cr; zATFxBSTxqDm@9FFz%3P&UW6PGcAbeHEeY6BjY6FY3Zy!$3|^+H51K&KfT*Dw5P<@g z_f^?AqA@ZMlmfKqaO}x)d3)}uodx`jwH%o?py!*<3H1WlD~S-ZI7JTvi`Nf3y{g+mJ@J)@Hg@_#0&jvg(N4NO$9$@%F#SzH0Odxk*Pjm|}yW#40T#P=zls!viarWm}>v3{>(J-x{C zFQ_ILlr|Ld*ogWs<6|8=M*?2NXI$;eyKIaHwR&|~^|kMk_~j+I&m+Tc{_1<*Yd`Nq zg6%Mm_c@MrjFgWZ+kVc~$A9^>)-%dS;K@9Wk3;t1>#2iLTE=f;4>9B09y!opie|}g z7%*)roGDC;@BvD@557WQ96o}#)=Xcl`{#n@2fo3mBtCqP9G3#~uh3XA9f86Z$`Loh zgY^_sKI_K-wEcBE*hd-qG&kcy15Fjv`t3(`?)Y?`FA&2s)fY8Z_IMU$srm+|qLL}0 z`416e?7||}vZs^mr!*r3_?+W{2#`2J^ zhwoDc8*sp#K|PlHq!Rwikq-7PYHdkP;8N3Y0uA8%CCx;SVJs|7l}IjMo}`QfHG-9U z>VUk;PHGVcR~^_i)8v!slN?#A;5it1ff6$iC>#t{fPOb24;!wI(B)Aozz8)TpB)s~ z@yL`0VOqF<5rnD>5sDRUB@;OTBEogkB&v#47E^RThmfd+kJ`z_(Vmdf%-u@$J05ynb0I{rHfJak?%NK%*LLRmvR2cTn{UB$3OEPpOf z9jGJNy+7D$Qr8G>TU=9`t|+=5L4w&9ZG=Hl;^+(-jQz0+MDK(ll{+-bzk`9+v(W8S zo@DlrZOUS>0RU(>z!41DDw1Yl=6zBWJf!0s`G0AUVE%CG* z-+iS1zr`+4O8H*f)XPXOM%g;b!8QUY?FK%Y52@cel01RHrB2^7bg}SF0k_Qsz2>MZ znsBu>tga!Z?|m+iOM8kAY(Y7nb1#}+35~ryE4+$KNGj}lG zZQuQVqHFz^S}|p*B<`M9WHCPedBUCqRzbdqp-s?)+~d^ajCEUaYNGaCfKd7CRxbu9iUPtYcog-wkX ziv~_;%-q`8Q~2+MKq(oPuNQa@Q3p{ES!2 z`77+w-(`1P{*EF1BFv7zNQu3FS8C2<+vtbAD<7pR@?TBjz3mcqUQWYtxe;f@rmNlN zw3B_pyVlNa<2RKhdB|PCJWAm;OGK)V4M8w?0fJL5fC5j1^8pvQ0@+GTw{FnHnunf^ zAKgK7OU1vlZC?lO0A90q2FckbavPm1bCj~*W3QUV_D*jl^}oZ!mPhQ>H1G1dRyu9n zZ7t%?jcM9^QSSvekXT=!)cxBwT3y~6dlUABc0VxSUSxagTC&(Uxel*eJMcd4UGKTB zlg{!WlV^!)^iNrN3 z%tjIJ695&pD(6#4thifP>(poZW0yVDMoZI zDoo5+mnzIV_>hSVrKkmJg2H*w!?jWZ0hDec9o>V?RU9crtz0tJfpi|^5MWwLw_}ky zb>dFg;vAW&Sb=(UdchR_bvpr9Kue*maac$QgZ7NHWDp4vML6K1d80^(>uJrF!*yB< zkXCpWgb0+Z5R2%%^#_}-LlYuU7uisa*=W~Z{4)m!C|yBNTn?cLmJQ)RR|4B0Jf6bb zik{&k9zwjIh={pZJW;i?*d#UIP%Lln`waUy;&38y-g)eMWP{A#g}*4y^ph9N9)1ll zc1hqL=^Hz7qWzO&H;sM2J@(c#YX-n+zp?y8Vrt~|@>Hq3d<&INoO8}I%XXE2iFc}} zXUl`w_o$v>wF=z!Nc(Js2qSFm?6ZUSP3vWgqcK6v1B(5O5%9i6_W6OQkI>(!{fp2E ze1UTm<#!GSE=i2Q(s8&Hk7F#B zpTcp@@v^%+N#(({PsM$Voc^igdFRFRkK)JhOo8L96Y&;{Yg@i96?}?P^cKT?i!Glz zi+z9O?LMDzK3%}I&lmoYP@alXNBaxiewMpGRV+~CFct>sUW7RAVn*O&3_2C;j(~-Z zqiM{3!9||a7`hzmjzl#l~2EGw`A|k37pRR_zPkBfRCLc?J;sV+oSr%GKF*3+} zF^ib7E)if$`GRS(5i-`5;pq4dO^3f*O$QWes&M&GE=wtBJ8V9{3rk4X`;zA3H*12z zcVQ?gW*I?@Zb&=UIl2Xhrp zhhy=1(FQn+M28KRMKfkUQ%FN_?M<*z^vbE=6|3ai6TIG}u%2^;;>9K}R}6mf$v0He zh6X_K{RvtI3Y>;?w-9J8uC`?`AJL>VMu`L^1v+BMf;?zUVh}+h9ghdX2v&e`-WiYQ z*rGmbl1f|_C8B+UD(FTM3Q8pq&f?%JCx6X8Z_rl_qI+R-Y4O_qj$1(aWih$?nDx}i!hIVKlMfzbkxI^=#^b5eLCuBr$FfATDs$5Onw zRlOvr7kyo!2ME;CQU*B9$@Eo*N5a9opUwacjYAcqi*KXIl(<1u7(KGn$o5h*28?NR zKZG%I!nI2|(D=M;6?D?6DjmiYU%!ykse^9Rd6IiE{$1E6KG22fi)*lwN~YolgRhZw zblaVWqR0}crmQx4ozT8$$!k2nL~9P+iuQS)I^UWh_rZU)=}SAvJ$f+ziT`F|ti9L) zM;q^9!}J4d_kL~1V^eVY?rt`1ldb!T9wn3f{k&H%gaaK!KhRl69F6rnmz&G4Q95P9 z3>u}#2GAS^&{6honVY$%H(`8}rG+e^O+24Gr=vZHWv)7ZJ#B(_ZZ}wd(n!s`pS50c zc4rMmFB){;4#QREE$1G%hc2Y&G2C31yAD6-d%>7>n*I{=&J*qv!#}}U7ah)ln^{HY z$BHEKXzY?sr0FQo^NBZ?AIVRS1yo?W0=j+qS|L#tHAI-h1@rI>#x;b%;>sB5w575p zB_;`bL=IVonDT@YVthn(^o~3@Y&MG#s~gk5csP?0>7JgJ-V4Na%F1>+8Ou};iVn78 zOn4jI$?Oey$O+>k7+bDX6W0i1WE3B`G@7N9hA<}0$yJh?$1O=CI#p;R2u*kkyN9_SI?cqKHH`|3oxV&SfuN-bs z<5RzQCzz&l>|H~eR+_$?n$uLUrUk8=o=#$-^Zq9NF4~&1ix)lgXWLx+z1Pu&>5r~X zy#p@0KU-zGPd_Fedq*)}%-@uEXrMXwQJXG&`mUT?9DCMmre<+2Hu3g|0^f`ealZsEIBw8Hx6Gk-p;auq(C>9)87m}=a;R=;fxz$J_Ak6d>9F@!iLJPYxO0SEhx*fq)Y{D8AK zFHD7!i$m;2wjvBZ``WnS1ncMq)Ls+mT3PP*8lKgmCh&OEF(Bz?ErTX81Hp}pvB8NI z2nIL-*peQ$ct8Y2$st3Y&pmvv{N+$HD-411W2&`+oOB9S3tB+yBF=SGI5_FN5UbO? zIuINR>lC$(YM`u}0Z*nRa+Uh2#<av z7UJ?hNc!;|>Y(rqE#zS7mf`dPVCG@YgbMZsW_qzaWe7qY)y*Rj#WAfp)eJ+j7U=}F ztobQf71?1l!jS|gUIVY(Lr_G5qrf2u#%K?XBMTs0UgQO*aNHmv4eDi0fY7z9m}C~; z1~3H7du68*(3>$dlY_vp0JjQNqQ+KLp+1IkG=x$^Zk0J${_b~~Vn4(sm$dgq`?gLb z2EE%J`K!NTe(<%$@~^MPo1$geVFbJ&>{#zjbL{MA&VHuv8`vW`d*Z~{_b<6*?EBAP zZ9#aK^hDwt%a0_Eb-*?@XKmW_v!9(v;CFlXm4BK{UUEq;7y4h0m-R>CBio#of$1Pd zbl!Pfz5p({Wami4UpiiR-(#@f5FH`%HDVH*6W0?P?~GtsbzdUu@o&RKn1_Gliwvg% z6qiRh4(%%p;}NfdxmGL-%AtbY7!_JaIEe3w{0;dYD|v;H$k!L)8hPXcRC&BpuHUKV z_o^%JR!2TcerLM=z3DmjBEKQuGy#ej3sL%j6NGcpF`LukXrv!c+c+K!CU1XZX(KN8 z%GImSJCE@Z`0OK{@)*8CaIDWb=bT+-^!e5wedIs?`+xrTAARIUANl)_{{2UP^pQ8; z{N*n>%{P|!jkO;;_Tp2Y7(3GbNqjoslRHQFn~p3ykqCT+Y!jp8`x=9<@$vF;*5Nq5 zm8!>3Bp>u*>9E&w&^zzEzA@gnTpd%ayC_IWt%hsBf}n7>9{Lsq+!_ffgll^2dz5y_ z=QR(kKoj5#dR$?G1l~+S;~NOCf%-y8JZ8n39#Jf&eU4ucE|;(OQxShDSQ|6uPoY=@pJRw=i{O}~!1t)^ zh%dRMc*Lm$kUsnbbIQwY%RklXI_S;kdLW8BJ&;N1p6uvEI%~P7Qz35=_A76>;L_1oCFSl$(FQzpEHGd|IqSr zFhL4-!*K+8!VYUzK(as~Ny1lnD}2e2SzL->od8|i)a6l}Cpte0iioZVyBR(YZy#*h4c(+%4vuw@{uYpeF>i-2-gT?pUX8Mrv^h?P2`ttJI`tH)-Ni zV|1_iKHOuW;_O?=;i(9kMnWwFeMv&TM%>3Z3E{&hpszohRnuHiy2W6D;>{0vmSRS$ zzy|V%nBc|20G}-nrCO=`Ili7%G-#XTufL!#w9U{;U(k>xJfayga6iA5*Y^8AZ+2fi zfdMcB3Z2i&&IGq8=V419RF#o;(Cg6kJ!;~t;HF`JQV8optcxv~@HvRV^XQiv3NhxH zj-nzV;LCzEgZ&kBzS0~Qp+Jqq{TNA7dU!;Wqimi>P)`5!h!0%>4ZlYkbRaX?3-VxZ z#@&K_vW7iGpt*HRe0@Q;XAqPhb_K~N5WCz51MWt4X4!OSFsAb0MSzn6K?Lr8#FfoO zGHL{o!WqG^PU!Oy;KvwHcKoZ0!RqH~J18z~QYeLQcRzY7=F!%Rn`INdE9IlDCdj1O zPoD>66IEL?1t;UfZ;_p!MgK^ZY=`&srNj=p9t!NoL+$yrKa0J6@C&86A2M92zw?NG zGs8EJQuBgmF3ctH{+%xL*^HN)AmE%Y^RAJcX-oU#X)wsmdnyJh+WXjA1#`^I|Z%A$#A8`#KZg}uI zcha32YR;J%WBtejBRvlfjbnvVXw>Sx*0dfoI-0vCut66t6(eh4PJ+Jz`}`%!jvm5*!k-qX`qUO% z#9@CTG%f-S=Pqh)HL=I_Ti0PnqJ4M4hM<}EIu^E3dXH0hcdqb+=XI@KVLyA;`ORW) zYOk|ql{f7QCpBPBUv955y2q|?yEkA<<8<>z zvLAKYtTL>D3+%K#(A-JZvvz;mHalrMPS(Ls z@$lxz0mpJ|I3L?4=`L&wwGA|$?RfZ1B+A^6K%Mqn5=~Pu84OiS-GG3NuFOjWTsHBC zzQbK85Gh0ipOYKVh575JX?lVcX`N|bcR4(ZPUmQ$6Ev^(+zEUx2zva0VN@uCE@|0A z<}}VGUw5<@a=HA&3CBBk-`pGALifQ4txMGJ@C7>+5 ztZU05%>Fh$Ak96DPq|CN$AfiuG8I_jked~=BV~04;AjTdC2wI9F+i{a0(^ET$MLM} zL8yUsMGy@_5HT8A0)o7Bl!Jh&Nu|Ru2=k4zP7=o_<;L3EFVQ|oR)wDsADBCFV&`SM z`V89H#J-B1Hx8bYz;>;{%kZ~i`||DQY`?KwHt=Od{=OoAWw8&yb~wfyrm8aLvW$7{ zfHFP#^G)#fnzw zCye}v+P4_)Z`9v*gw04cTKSeEf6sAA$26BM_+4w#{!7k>kH}A1jaNz*$U$mZmA&|w ztH_m$X%qYyo!2Sih9lpe-Uo>;$(Rqqw;Nf;N4=jhPDk+wvuz!Rt;lvfzj$2BBmW}s znFi&b+#-*i?YX{=xF+|}NL+Xy;jhSx>acEQaCZ^1x2*;{nJSvT;3N=q9)*8WeamLEm>()EWv^#%By550^o;QNV#Y~TOKwZ3TqAAH&8 zW!rPO(I#}h5MGuv!&3M@Ie%&Ret4f4Y4~9z!V&*Bfv0MXqF@SbD#=np3GAGaYAAt` zVWLI`342HqQuLrTFy?F}DF6vtN@d}`4G}z3HWas*)yYd+bXrR&QVKDw%$Q>qI~D)R zj7cm8Tj*CwA?5tB`x5#!AcKK~lTgDx^Mq0cXW>;W<2O(+cCh)xBAR*}_;FsIe}l zqtrzJX5uWoeLPwMBLHOqqq!c!?Ye#w{a!HOKZ*fcJateyDO#q|IP=?D3z3gwdEr&DDXyFMtp1FF5E25_7e!Fl(lK zGU+FV-&Fb|?l*Ms^WGYTED}d;I!8C-N}4)h(7$lwg#9FM!n8!QFiYUz@hmZ5e+MAa zczP#?t2w*qnk}lWR}p=;;~`QvCpu}yyJk~?jQh+yn)zb9J8hYgaN2wNr-0R}gNDO( zZjl?aGZ-_E957pb(BJ(UWfk-U?x!JFN4Lo6LbH72gG8S@fO>}j{mq1?BykrMY4RPfG~Nwbw%}2vAr1Q)$_RP!gSpJZ zLuyK`dbC%Ks~aqQ?eV%HVY$5{ljeiNF$RecJ z3i)=yKB86-UHu=tb0f9be|BO1%IQB$x!uDG!I!>z5!YYHEG>f_H_aFR!}EgMKsp1$IrYx}vjid6(_=Uw)Q6H?MeH-%akj3gi}A z-;>7|Wo;@JybA@sKcW&L(%0|r7N&7eK8F}U7vX>*)s z^>-gpdwachd7-EpT!i`*YD(#_aS)||G*_dcYN(hs&BxZm5YFXZsewDHr7*wY04Oqg zZ)fw}Sbo`3px4;>OBL_3wa~RN2!%%@dj;;P2T?=!k^dCj1Sd1Hu@7 z!HH`Hz>){MCv`Lktj$3YFrm0yh`21K76_mehe|!-%z5H+Uc)*;)zmNw0{0oXCbBcv z%MN@?fJ^2XG>ozu*vCj|Lm(y$@pdw%_=N>D4H-}5aUx7>y%luei@#aI?1Zn~Po-c1 z#v~=>W;D(ee~x^DGLkgF9u1=aMo4>56|l*i=+$$_>^#z4V%Feg~?_;n` zu#CYD?)D%S+*aBO%UMRD4paoJX%;W>&j1Ks1vdiKh#B(62*1Yy_uyFH^<%HRVfNvh zi-Rm;zXb#LczlF$1!IHYZ^Yk+yurSwpU(Y{S2Kr?I5)MtZT7?~hw+KXv2!}kIS1Yj z?WY`T$M4Gku#+p;r#Q$v9s#dE^;CQL$Pr0{gZs+6_I>iHc4z8vUt(AJM0xwzjfppA zy$@yH`m4j4xBf8q>Z{&|UVZhl%XW@!AB)Nq7WQT#N&EEz-(J*7t9Swb;@7xCNB+VZ9PxFBuiD}%h4)c%x`pkcOtHO?^Va7i0#`u+ zZGsO)&#$Q{`-e)RE&)XETG#sqN72vg_Buv;9xMAEPbTLaioNxt-qk$LZ=v+{ z>PXI?bkN(o>C<0?yS@Db?=E+^!EYL60^i`ze_q}mjGdiL#}6+re{$-^8)sj8H8b+g z%v-k$FMOL76lNqrJ&Y%nGL;(FJQme}+TUZ~o)4 zLu7ZlQ+W4!_D)_8qXc>K`?BQYeh~YzXqhBuc?P$pe`Q`b`5}Y$qdTF;c^sZLaGQvQ zIwVQSnOLqILY35T4r^=0T?Pe0QH$u{KuJl>omt3Rdfg46w`ASC+YGxxw%Fq&*P|yG zA0X9fS|;vTTnw&z(XIHdpO@;Uk5Bf&QJKjF3<`msY3NHXd*?`}dzkl0oX(h>&! zJN7XubPTvA@gouB9{Mi^eVbM^ne8TxNOY1ZG~j+u?G{KdoOUK&he3bZHu1TPKR3od zF#@}`4L3Y;Q|X z@6^Ng*3m~NEqueVSy+=;eW=MEcU;J!N8uD1pBx{WGFs3rhSX$kgE!Lo@O8?-VCM0QRN51XACWyvn<{!FjTjCTri-N@wd4YJpEkjlkA z9&dv12Kf4iJj*gV+z!haA&bzp$h0%u4MCX*(P)bWRZ;ZAW~eagBRHoHoj=VvV7P&z zr|*In$hp?O%h|iyqGl(1r@hVj3w+Hc*WY&Mo!%dMj&QqM9v0&R&weZSDBJ{lFSj?A zyy?&6&hp&p{(%8%-dmt|(7FsUH2O&Rb(dxY}ee25G^3(Rp z!lMO~K8=BO_g2b%%>BEuIsiRfy<45JxmA75KXXU<*zx&Gd-Gfi3*L>LQzT%42mtXqBZNJ`8 z99Yx6#<{e+^{fj&>s)TPINqLtL#zIry6trOef|CEE%d{-%lo(5R}5@B>oL@AV59Rk zY;jC?yXk@ERqsv@^rtthbn^DEIyV1l&i=v1D^fpfw+7a&x!u8cI&H^Jx7aOQc>X1A zr7>>8$>JzODnNB%E=HsBAxta2c+`MymXK3bG%*qK^?-XMKw{*h_Yz$ULP$O4Omtq! z)22`Z;0_ov31kdel!r5pFRIdUH{`h8k>?*OJV>)7YuKWT{g!-2Ad`ZvgD@3la74UG z3|-DofvPF3U_K?e_s$1$KEaasDyAKeGuzUYM?_%Ex%_Y(E>)5lt_%A}RXzp2^oCLR zI|#eV16858*wYy6au_|@=8t3!cvCRv(G)gS)7Kr0|16$!O3XZpFRz9wT7v!WWXZSS z5h>c5__MPi$goQ@S=S^eN(@}2I|;-SD1k~qe;m!f5R9`>>V6Wa*+OH4IBP*1SZF

    ^Z5V4~Vj zK)4bL;fD%1ra^=_LiKdSCo_!ID1cB#MWrUfK8r!`uK)Uh_m7PoNo;xj5B@-vJ~H}| z(M=zJ1zV~Zwl5#tIk=r;gM-`8+1V6)tByU9M~>Y{|Bx&vpM2(fEl+zb@Rzi_4c?L? zCVt!E#>Dpa#Iint_e+n%zgYg+KOFxadog$Q4PqDN;ALD0?57<2kateU$UA>Al6mVJ zv#(~@@A9j|uN+SP|FpdgfKItqEyc`I1u6vN)mKUzJ_QPiNP`J?nNcZ;YYy)6*rr^`EK+& z>h9j`-TjnkT<_;<`aW-+?wOupz@KE_nLbtZ)?2@)s!pBfyj2z601R?NWq@I>ZV187 z_-8rQY4>VeM-}K3ImWcSVpx49HS`_3isw#q3;pF2^Y;FCoLgOvJ8C;{N%k-2pA9Pv zbQw8a2Y4p%O_;1F8R$x4h79}J!jDah)73w{KPBSTyHJc@u43`dYJ4oc$6^c`do0R}d;ncNHdHbDxk5yd`y#DQY;r;jL&tD!Y z%zFB0k=y`XV{Br5CA!n5`4eU#RM0hR``SSU|BIi#S-dmEhGfZ3}I5wT3WFNscW%-y}F03%* zmAl#A8=MpUPyCvO5z`IX79N)gy=VY#$wMH_lVih`+!!Pcwj)i1mnUaxJ;xKqDZLh3 zRq_)8;e9Uc%aI#wc$QR!E9|9R%@wI;zn5J1wkY4kip^ zJp#5`f=Gu?u= z>32#M^3g3xTJfPuI)wKmcL8ILVCC=|OFj@S<~_$3Bh;_}$0)oWG7c>dEtnR<`nMEv zGsJ#>KtcuZawb3ph8xP6K?Vd_Qeb*u2$&L+C~4+mja}$If{SV)5MN*@W1!f~Bv@cG zDUx`x=4%)%QwbvmT_4Qb6h);}c0FRw2}z)w%!d#u+912eAy)!iLDahI^Bb#dG%TJr zBZNTSM^YUp@R?ca%wEByMc@g!0(wUO=q_R;d&|s55*ZXN6q$(Wc0KRb&iKiB&ze|j zV^Cs`TaSUDO3?lEMvUmHD$}_eV9}S~rHaqM{NAK4JB9FVL$p7K5v9UgOW%S?ug{#J z)*${jDx!UeZ|m!Z9-zpS)PQnhW*1)|NM++z^l%IU{?%REVC*_f6`^jAF4Pt06`#B_ zVPcr!a2|etKmsPnbn_KHH31iB37y2*-9PN1bB5}%k6w2T3EV@haeW@ChZ1BeAMJc^ z)XDGQJWKkT0>~)6KfU*hMAGkUKMErhGb;yABAnsXJQT$lAu;LRoy7+}dZH%(Ws(@% zGWUgvo=sr!4vMu@w#mCQ2q@Nu_MlrGY5w7&Z@o)M%A-E?58pR&ZzMK{Q-seC7vaLD zS)A#@{C!BC9++bk_`?Fx&PW0$)|(`dgWNzT^q6hD-PHRbiiubib!PDZxHm%-kJvkK zf23&v-hirX6Un>?8+0Xf@S5@f(n5_Pg&XV%=|oIJJ|b)CK5)(KDM6b(8IoJ$!WK|6 zeFP`RTYqjSkq{I!0lvkS(n@J}E<#^+3G-C@hd^)4?YHfTs{0n;SsrDnsi*Q1^6`Hd;pB2#`{ ze?QtsU4AF^qUI`gx0#!tCwWDh?y1Tk*I03S4)FgYdD(P#j+|P5f{D#{QC#nP3ip4@ zLaGTv?%2>EHS~En4MSdPW=yFbR~4Hp5sx1||CohCH!vn~7YP{<#?Z&n}X48W8q$VDoSmEzBoQZNs zT!Atwv(?O?ZtT4?7hi#D-}VyKADaMp)@Vz7W*wl!a1|ZP0)xy~nd$2=6-nQ3A2Ud8 zyV_V#oxxo4k_q&8(;=`Vb4_12zCtc(yT(V~s>&<-ZsafjELv}(8)wd+LRPA3gR&n$ zRY`JBVJtj(rU5#TJj=Bkv6s9REH?E9&JIQWQl`-;(26bFN|9*p#Z#inwYo06P$~LI&RFM6(~8F_R-ZN`-kglOI?BdT|0KvZ5e@OZ4el?yN+ei-|A)IA+d+8L zG6{Vhx$yWMK|^4&t8KS>RaJ#OHFALN{U&zpciQkMinO#iQK$L_+g_Tqy*Up)Sl3F?^)=~il)R(^#l+;JiHE1GcP2mjC*dDWS?@h!^<1)Y zVfCF~x$};jH#X6obzg3u?XDjfbe*Ygbx+c}9t$iVyyG^{_3}S*jC{}aJ?X*dqZ1D7 zT^X&ZI`HrWd+)-q^FUZC*?FB&WZn>CzdshiYz(PE3Af&bm3L z60Uu4YRkIzL^Qg$?SuC7+P~Kxozhg5oX|YErM=y9s*~+i?M|KJ8Gx#)?UOiy2K^R4 ze%;pX0836WwlKRyu;bq?IboLU#Y$0SUV#-jAPBVsLRi>>AYQS9ioi>1f6U&fcRek+cJ`6_Q2Y! z4b~0j95Em!HK!w}cT;t-Q<)0aypY(MCZje(1~~;Odfd`|4n=yH@uXA?`KdOhIWm28SxKnWio!5z04{&QL;)Le3sJ=>{YK*LE|~h zIWDy~6Y~6l*%f+C0c3lF1||>%YaI*B{2|{ca8?()c8k~b7AHc8MjIX&LYf6IS6C4@ z@JMSoZN4v^ETT#3E6cD2CT9W(_~+@oART6LdfGhWrFYn0$1yCIAGVEe3DZ74VY=|% zdxduy9b}wvbwhynF$Q>>cUkz&6V58u$BJKEb@_=GPrY-huweu6liCfJ@w#gO8JGVA z*vR|||Nfh|o?pE>;Jx?uzyIddm;e1YA3p!q^H^`%z;SOX6ixv*S^oa}&<}gB@ZS6h zuT&3XB;nEA6HuXXk|Lu1Qb%nast2vD_+VtZ)dB?ne`_od1fXVRM*46BW zsd1IDW=WP5*XvpI9<|^IrdV1>%?-4KGoB42WO{~8(vRha<1XTuoJI+w zig$5|eCDGfHy7LUS2jl*ed6y4yLPu%>-t54kgr2e(tJV1l>iD7q%UozQ$ zm@tNe&bHqpmN&msc#LMfQv_27j@scD~j_WGsaDCAc;KSgr)jad?C} zQ@}o8lfJO>!~P-MPj(1Aj0BdoY3%V|4K*FjRnW7Z#vuLkS)@deOBdx;i8t2#@A~{} zhw8BgTZ#v>9Xj4dBfvI!{Irnrb|Wy47u|b{X8&+>Jd~)b;DqEy5$XdXGJ8dW&D_=< zxB|V=Ph7U1i2|%Lx2@!_*n$;fMQpG?z#c6_B{ct=KGzuUcUB^yEvSBNmbLMcKwuu? zd>Kn?7wY^q9tzfSPt@2ZmKGTu`cAYI&0Nt;Y15{b;Tk|J`eSAg>)EdhDovSPJ4AH6 z;aFb?73t%DnhZhN!N|spk-=qbH2xb4o(+X!Wo%0~61?70cqmSrj~+i__|pK645j$I z0JA~4hP2EpJA}utwkh`++*=W-jh|iZI#3&fDyUnJ=0u@Gr(@oH2z_$!Ui$E#V7owQ`D!Wtuo9#;~YSg~?Rf zXS_=edW%M6*arb5DoBDMG}E*(*HN&t?q^JqkDYi7gL-Amq%2!+DFsY#o;@ z1SEwSij_B|C1MC*0wA;{-Y^wBFntjaFc1^FVN%g7`GW(J`ii-B(Hzf6ztA_W7j2`x!@9x2Q+dgEpb_1JTK)$*amr8|3`dWy+hN-(~8*73cumsoI z8OT-w@C;YF#}cv@Yo_VhyiL>0MB_=H{^T2*4eIf$LgoL#&_{b6!Ivf*1$huUt=kgo;|vywr}VfI@Ih{kdR0xI-LMkRf>$j zy#V%9VdrlG+orYFdSFp4nJbRng7nb$Hw$#Tqlk;T;<$h~qZlcDqM@NKW>5f+fmJMM zCHrgsXj3y$)Q_NMwVtr?zF14=-7n+dJ;8k10O?F7mF_17O6j=G0KL0Z)*tEv%^f~~JW@oh{ z1x>>Tpd{{;T12v`lW20xQh+bJY} z*zd{}glOPK2L_5q2HYXInLo;eNI;@wIkVYB_rX&()l;8opzfW|naFV7MAx<*=^GWV z;(lijwK)q|?$9^R-;B1mWg!-rtbuu6*WC(lHxk)?=A_XZ5#;>2VH#IS+>3XN3$5eQ zjvqGMXQg!Bcn$5PtIeqz;-}K7N`-rmGda@VoyHhslF)Z3L>cqp*HB19Rv-Jnh_cVD zsh|we8+lx)yI3a&VAsk#XcxD#T@%-uTeP3eFzF-PNlnndTocRmpxUxl?|1p^lS%cA zL6ZK-Jim7xsa@fWu7ku+Tbr7@@w)K6*Q@&yNEv5!quolXH@|=Xt1eMWpLct z!$U2f%cAS~U$!gJDi$8*!I%3C(}gH{Qt@2ge+f5;=_GCn4E2(B!Cm5yG1=SIGDG@0 ze31%Pg_7j7i7ygYE7g^YDXR(V-RWe4IjXD-S1TH8AoyXjPK zvUxhKXlz;B)`l-w)3*w-G8b!UUeXquIeXECogFIGYvk(q@xK!bo9h-EMrSnc<{VXz z>12de^BY^OD$7EvM$<^)MH{6kBRnli<<_Ps^MjS2PE0;m!MJ2I9A}eLU2RqLtmrOiXJbo9>{@I&$8Fm}DQckWJ%%!4+KrbUEr4+tf0S3;%ub_X zjUsLH4wAv-2OKh*D!?F03lk4C9vUQmE^RNi za05w##Mrye%wQ-HkRC%~cm&cOVvP5=P8D!bexnZKpGz@<3N^SKe+HgN1tXp$Q_-O0 zjN%I}?v(`6xJW-~357Q-95dwZ^I&bo2rE626OJOtD`-}GN+uei^&HJeduCor8bno) zp_;S1b9oh3y-3SLygMw#$w?2NN7_5VV5TD2n2TXUnPAAEYG4C*gxE{La}1R;IJ(ow zK+(q~%aX{YCc*jT@dZf>Hj%P6X45y(QwZ9()qVIVq{DA_4aqNGHaULY_fl6uT%+QVPyk z?2Pw$KC@mcfJSwgh4t!m3q^A?`^W*d+*==^nwdE-LeTYG1hQoEE0N;Ktb4K zToO81=dvDF;lo$q0!E2_?B03zT^ pbP&d^vQoUU@tIG7giey8PvIyl~=`4?d^` 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 literal 0 HcmV?d00001 diff --git a/util/wan_aftup/A400_0040_V11.BIN b/util/wan_aftup/A400_0040_V11.BIN deleted file mode 100644 index fd3081dc9b1e676402afbbebbba029865df2708b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212392 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

    7X%}4e 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

    V{QEzd7K} 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%0DtEBSTlCAzvp3l{AMCx!`h;tH?h?mMC2vmOC*DmH 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 literal 0 HcmV?d00001 diff --git a/util/wan_aftup/ChangeLog.a101dm b/util/wan_aftup/ChangeLog.a101dm index b96f2e8..9b16770 100644 --- a/util/wan_aftup/ChangeLog.a101dm +++ b/util/wan_aftup/ChangeLog.a101dm @@ -1,20 +1,6 @@ AFT A101dm Firmware Change Log ============================= -Release V33 ------------ -Sep 27 2007 -Type: Recommended A101dm Firmware for echo cancel cards - Fixes issue with hardware echo canceller chip - security. - Supports DTMF detection without hardware echo - cancellation operation. - -Changes: Firmware bug fix for echo canceller - This bug can shut down the driver. - - Note: This bug only afected new Maxim AFT cards with HWEC. - DTMF detection only applies AFT cards with HWEC. Release V31 ----------- diff --git a/util/wan_aftup/ChangeLog.a102dm b/util/wan_aftup/ChangeLog.a102dm index e6c6f88..a3ccd0e 100644 --- a/util/wan_aftup/ChangeLog.a102dm +++ b/util/wan_aftup/ChangeLog.a102dm @@ -1,20 +1,5 @@ AFT A102dm Firmware Change Log ============================= -Release V33 ------------ -Sep 27 2007 - -Type: Recommended A102dm Firmware for echo cancel cards - Fixes issue with hardware echo canceller chip - security. - Supports DTMF detection without hardware echo - cancellation operation. - -Changes: Firmware bug fix for echo canceller - This bug can shut down the driver. - - Note: This bug only afected new Maxim AFT cards with HWEC. - DTMF detection only applies AFT cards with HWEC. Release V31 diff --git a/util/wan_aftup/ChangeLog.a104d b/util/wan_aftup/ChangeLog.a104d index b920f96..40fec19 100644 --- a/util/wan_aftup/ChangeLog.a104d +++ b/util/wan_aftup/ChangeLog.a104d @@ -1,14 +1,5 @@ AFT A104d Firmware Change Log ============================= -Release V26 ------------ -Sep 27 2007 - -Type: Recommended Firmware for PCI/PCI-Express Cards - Fixes chip security issue. - -Changes: Firmware bug fix for PCI/PCI-Express Cards - This bug can shut down the driver. Release V25 ------------ diff --git a/util/wan_aftup/ChangeLog.a104dm b/util/wan_aftup/ChangeLog.a104dm index 35a2767..8673c57 100644 --- a/util/wan_aftup/ChangeLog.a104dm +++ b/util/wan_aftup/ChangeLog.a104dm @@ -1,21 +1,5 @@ AFT A104dm Firmware Change Log ============================= -Release V33 ------------ -Sep 27 2007 - -Type: Recommended A104dm Firmware for echo cancel cards - Fixes issue with hardware echo canceller chip - security. - Supports DTMF detection without hardware echo - cancellation operation. - -Changes: Firmware bug fix for echo canceller - This bug can shut down the driver. - - Note: This bug only afected new Maxim AFT cards with HWEC. - DTMF detection only applies AFT cards with. - Release V31 ----------- diff --git a/util/wan_aftup/ChangeLog.a108dm b/util/wan_aftup/ChangeLog.a108dm index 75d5759..d4ba6c6 100644 --- a/util/wan_aftup/ChangeLog.a108dm +++ b/util/wan_aftup/ChangeLog.a108dm @@ -1,22 +1,6 @@ AFT A108dm Firmware Change Log =============================== -Release V33 ------------ -Sep 27 2007 - -Type: Recommended A108dm Firmware for echo cancel cards - Fixes issue with hardware echo canceller chip - security. - Supports DTMF detection without hardware echo - cancellation operation. - -Changes: Firmware bug fix for echo canceller - This bug can shut down the driver. - - Note: This bug only afected new Maxim AFT cards with HWEC. - DTMF detection only applies AFT cards with HWEC. - Release V31 ----------- Jul 10 2007 diff --git a/util/wan_aftup/ChangeLog.a200 b/util/wan_aftup/ChangeLog.a200 index b3171d7..5111b66 100644 --- a/util/wan_aftup/ChangeLog.a200 +++ b/util/wan_aftup/ChangeLog.a200 @@ -1,21 +1,6 @@ AFT A200 Firmware Change Log ============================ -Release V11 ------------ -Sep 27 2007 - -Type Recommended update for A200d cards - Fixes bug with echo canceller chip security. - Supports DTMF detection without hardware echo cancellation - operation. - -Changes: Firmware bug fixes for A200d cards - Card fail to load due to echo canceller chip secutiry. - Note: This bug only affects A200 with HWEC - DTMF detecion support only applies to AFT card with - HWEC. - Release V10 ----------- Jun 10 2007 diff --git a/util/wan_aftup/ChangeLog.a400 b/util/wan_aftup/ChangeLog.a400 index 698a14a..aa283fe 100644 --- a/util/wan_aftup/ChangeLog.a400 +++ b/util/wan_aftup/ChangeLog.a400 @@ -1,21 +1,6 @@ AFT A400 Firmware Change Log ============================= -Release V11 ------------ -Sep 27 2007 - -Type Recommended update for A400d cards - Fixes bug with echo canceller chip security. - Supports DTMF detection without hardware echo cancellation - operation. - -Changes: Firmware bug fixes for A400d cards - Card fail to load due to echo canceller chip secutiry. - Note: This bug only affects A400 with HWEC - DTMF detecion support only applies to AFT card with - HWEC. - Release V10 ----------- Jun 10 2007 diff --git a/util/wan_aftup/Makefile b/util/wan_aftup/Makefile index 7c2fac8..0f6a654 100644 --- a/util/wan_aftup/Makefile +++ b/util/wan_aftup/Makefile @@ -28,14 +28,12 @@ ifeq "$(SYSINC)" "" # Project file paths. SYSINC=/lib/modules/$(shell uname -r)/build/include endif -SRCINC=../../patches/kdrivers/include -WANINC=/usr/include/wanpipe WAN_VIRTUAL= # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -I$(SYSINC) -I$(SRCINC) -I$(WANINC) -D_DEBUG_=$(DEBUG) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -I$(SYSINC) -D_DEBUG_=$(DEBUG) ####### RULES ################################################################ diff --git a/util/wan_aftup/update_aft_firm.sh b/util/wan_aftup/update_aft_firm.sh index 207e57e..1bc8d4e 100755 --- a/util/wan_aftup/update_aft_firm.sh +++ b/util/wan_aftup/update_aft_firm.sh @@ -2,10 +2,8 @@ cmd=$1; -if [ ! -e wan_aftup ]; then - eval "make clean > /dev/null" - eval "make > /dev/null" -fi +eval "make clean > /dev/null" +eval "make > /dev/null" if [ -e /proc/net/wanrouter ]; then diff --git a/util/wan_aftup/wan_aft_flash_shark.c b/util/wan_aftup/wan_aft_flash_shark.c index b502b0c..a145414 100644 --- a/util/wan_aftup/wan_aft_flash_shark.c +++ b/util/wan_aftup/wan_aft_flash_shark.c @@ -139,6 +139,10 @@ static unsigned short get_cpld_off(int adptr_type, unsigned short cpld_off) cpld_off &= ~AFT_BIT_DEV_ADDR_CLEAR; cpld_off |= AFT_BIT_DEV_ADDR_CPLD; break; + case AFT_ADPTR_56K: + cpld_off &= ~AFT8_BIT_DEV_ADDR_CLEAR; + cpld_off |= AFT8_BIT_DEV_ADDR_CPLD; + break; default: cpld_off |= AFT4_BIT_DEV_ADDR_CPLD; break; diff --git a/util/wan_aftup/wan_aft_prg.c b/util/wan_aftup/wan_aft_prg.c index 4dd1779..9469b7d 100644 --- a/util/wan_aftup/wan_aft_prg.c +++ b/util/wan_aftup/wan_aft_prg.c @@ -601,7 +601,21 @@ int board_reset(wan_aft_cpld_t *cpld, int clear) if (clear) data &= ~0x60; else data |= 0x60; break; + case AFT_56K_SHARK_SUBSYS_VENDOR: + if (clear) data &= ~0x04; + else data |= 0x04; + break; + case AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR: + if (clear) data &= ~0x06; + else data |= 0x06; + break; + case AFT_2SERIAL_RS232_SUBSYS_VENDOR: + case AFT_4SERIAL_RS232_SUBSYS_VENDOR: + if (clear) data &= ~0x06; + else data |= 0x06; + break; default: + printf("Unsupported card type (board_id=%X)!\n", cpld->core_info->board_id); return -EINVAL; } diff --git a/util/wan_aftup/wan_aftup.c b/util/wan_aftup/wan_aftup.c index 0bfb5d3..a988cb4 100644 --- a/util/wan_aftup/wan_aftup.c +++ b/util/wan_aftup/wan_aftup.c @@ -72,6 +72,8 @@ #define WAN_AFTUP_FORCE_FIRM 0x02 #define WAN_AFTUP_PCIEXPRESS 0x04 +#define DYDBG printf("DYDBG:(%s,%d)\n",__FUNCTION__,__LINE__); + /*********************************************************************** ** G L O B A L V A R I A B L E S ***********************************************************************/ @@ -127,8 +129,21 @@ aft_core_info_t aft_core_table[] = { "A200_0100_V", "A200_0100_V*.BIN", AFT_CORE_X1000_SIZE }, { A300_UTE3_SHARK_SUBSYS_VENDOR, AFT_CHIP_X400, AFT_HDLC_CORE_ID, 0x00, 0x00, "A301_0040_V", "A301_0040_V*.BIN", AFT_CORE_X400_SIZE }, + { A300_UTE3_SUBSYS_VENDOR, AFT_CHIP_OLD_X300, AFT_HDLC_CORE_ID, 0x00, 0x00, + "A301_V", "A301_V*.BIN", AFT_CORE_SIZE }, { A300_UTE3_SUBSYS_VENDOR, AFT_CHIP_X400, AFT_HDLC_CORE_ID, 0x00, 0x00, "A301_V", "A301_V*.BIN", AFT_CORE_SIZE }, + { AFT_56K_SHARK_SUBSYS_VENDOR, AFT_CHIP_X400, AFT_HDLC_CORE_ID, 0x01, 0x4F, + "A056_0040_V", "A056_0040_V*.BIN", AFT_CORE_X400_SIZE }, + { AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR, AFT_CHIP_X400, AFT_HDLC_CORE_ID, 0x01, 0x4F, + "A500_0040_V", "A500_0040_V*.BIN", AFT_CORE_X400_SIZE }, +#if 1 + { AFT_2SERIAL_RS232_SUBSYS_VENDOR, AFT_CHIP_X1000, AFT_HDLC_CORE_ID, 0x01, 0x4F, + "A140_0100_V", "A140_0100_V*.BIN", AFT_CORE_X1000_SIZE }, + + { AFT_4SERIAL_RS232_SUBSYS_VENDOR, AFT_CHIP_X1000, AFT_HDLC_CORE_ID, 0x01, 0x4F, + "A140_0100_V", "A140_0100_V*.BIN", AFT_CORE_X1000_SIZE }, +#endif #if 0 { AFT_TE1_ATM_CORE_ID, NULL, NULL, 0x00, @@ -157,8 +172,7 @@ struct wan_aftup_plxctrl_data_ { { 0x09, 0x00 }, { 0x0A, 0x0C }, { 0x0B, 0x10 }, - { 0x0C, 0x10 }, - { 0x0D, 0x80 }, + { 0x0C, 0x10 }, { 0x0D, 0x80 }, { 0x0E, 0xFE }, { 0x0F, 0x0B }, { 0x10, 0x10 }, @@ -341,6 +355,22 @@ static int wan_aftup_gettype(wan_aftup_t *aft, char *type) //strcpy(aft->prefix_fw, "AFT_RM"); aft->cpld.adptr_type = A300_ADPTR_U_1TE3; aft->cpld.iface = &aftup_shark_flash_iface; + }else if (strncmp(type,"AFT-A056",8) == 0){ + //strcpy(aft->prefix_fw, "AFT_RM"); + aft->cpld.adptr_type = AFT_ADPTR_56K; + aft->cpld.iface = &aftup_shark_flash_iface; + }else if (strncmp(type,"AFT-A500",8) == 0){ + //strcpy(aft->prefix_fw, "AFT_RM"); + aft->cpld.adptr_type = AFT_ADPTR_ISDN; + aft->cpld.iface = &aftup_shark_flash_iface; + }else if (strncmp(type,"AFT-A142",8) == 0){ + //strcpy(aft->prefix_fw, "AFT_RM"); + aft->cpld.adptr_type = AFT_ADPTR_2SERIAL_RS232; + aft->cpld.iface = &aftup_shark_flash_iface; + }else if (strncmp(type,"AFT-A144",8) == 0){ + //strcpy(aft->prefix_fw, "AFT_RM"); + aft->cpld.adptr_type = AFT_ADPTR_4SERIAL_RS232; + aft->cpld.iface = &aftup_shark_flash_iface; }else{ return -EINVAL; } @@ -581,7 +611,7 @@ static int wan_aftup_program_card(wan_aftup_t *aft) static int wan_aftup_program(struct wan_aftup_head_t *head) { wan_aftup_t *aft = NULL; - int tmp = 0x00; + unsigned int tmp = 0x00; int err, i; WAN_LIST_FOREACH(aft, head, next){ @@ -606,13 +636,13 @@ static int wan_aftup_program(struct wan_aftup_head_t *head) exec_read_cmd(aft, 0x08, 1, (unsigned int*)&aft->revision_id); #if defined(__OpenBSD__) exec_read_cmd(aft, - PCI_SUBSYS_VENDOR_WORD, 4, &aft->board_id); + PCI_SUBSYS_VENDOR_WORD, 4, (unsigned int*)&aft->board_id); aft->board_id &= 0xFFFF; #else exec_read_cmd(aft, PCI_SUBSYS_VENDOR_WORD, 2, (unsigned int*)&aft->board_id); #endif - exec_read_cmd(aft, PCI_SUBSYS_ID_WORD, 2, (unsigned int*)&tmp); + exec_read_cmd(aft, PCI_SUBSYS_ID_WORD, 2, &tmp); aft->core_rev = AFT_CORE_REV(tmp); aft->core_id = AFT_CORE_ID(tmp); @@ -701,6 +731,16 @@ static int wan_aftup_program(struct wan_aftup_head_t *head) case A300_UTE3_SHARK_SUBSYS_VENDOR: aft->cpld.iface = &aftup_shark_flash_iface; break; + case AFT_56K_SHARK_SUBSYS_VENDOR: + aft->cpld.iface = &aftup_shark_flash_iface; + break; + case AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR: + aft->cpld.iface = &aftup_shark_flash_iface; + break; + case AFT_2SERIAL_RS232_SUBSYS_VENDOR: + case AFT_4SERIAL_RS232_SUBSYS_VENDOR: + aft->cpld.iface = &aftup_shark_flash_iface; + break; default: printf("\n%s: These board are not supported (subvendor_id=%04X)!\n", aft->if_name, diff --git a/util/wan_aftup/wan_plxctrl.c b/util/wan_aftup/wan_plxctrl.c index ae91c2f..33582bb 100644 --- a/util/wan_aftup/wan_plxctrl.c +++ b/util/wan_aftup/wan_plxctrl.c @@ -1,399 +1,403 @@ - -/*********************************************************************** -* wan_plxctr.c Sangoma PLX Control Utility. -* -* Copyright: (c) 2005 AMFELTEC Corp. -* -* ---------------------------------------------------------------------- -* Nov 1, 2006 Alex Feldman Initial version. -***********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//This is the address of the ECCTL register , page 149 of PEX8111 datasheet. -#define EECTL 0x1004 - -//Change this accordingly.!!! -#define EEPROM_SIZE 0xFF - -#define EEPROM_BUSY 19 -#define EEPROM_CS_ENABLE 18 -#define EEPROM_BYTE_READ_START 17 -#define EEPROM_READ_DATA 8 -#define EEPROM_WRITE_DATA 0 -#define EEPROM_BYTE_WRITE_START 16 - - -//EEPROM COMMANDS -#define READ_STATUS_EE_OPCODE 0x05 -#define WREN_EE_OPCODE 0x06 -#define WRITE_EE_OPCODE 0x02 -#define READ_EE_OPCODE 0x03 - - -/************************************************************************/ -/* GLOBAL VARIABLES */ -/************************************************************************/ - -/************************************************************************/ -/* FUNCTION PROTOTYPES */ -/************************************************************************/ -void PEX_8111Read(void *info, int addr, int *data); -void PEX_8111Write(void *info, int addr, int data); -int EE_WaitIdle(void *info); -void EE_Off(void *info); -unsigned char EE_ReadByte(void *info); -void EE_WriteByte(void *info, unsigned char val); - -unsigned char read_eeprom_status(void *info); -unsigned char read_eeprom_data8(void *info, short address); -void write_eeprom_data8(void *info, short address, unsigned char data); - -extern int exec_bridge_read_cmd(void*, unsigned int, unsigned int, unsigned int*); -extern int exec_bridge_write_cmd(void*, unsigned int, unsigned int, unsigned int); - -/*********************************************** -****************FUNCTION PROTOTYPES************* -************************************************/ -//These functions are taken from page 37 of PEX8111 datasheet. - - -//Write the value read into the dst pointer. -void PEX_8111Read(void *info, int addr, int *data) -{ - if (addr < 0x1000){ - exec_bridge_read_cmd(info, addr, 4, (unsigned int*)data); - }else if (addr >= 0x1000 && addr <= 0x1FFF){ - - exec_bridge_write_cmd(info, 0x84, 4, addr); - exec_bridge_read_cmd(info, 0x88, 4, (unsigned int*)data); - } -} - - -void PEX_8111Write(void *info, int addr, int data) -{ - if (addr < 0x1000){ - exec_bridge_write_cmd(info, addr, 4, data); - }else if (addr >= 0x1000 && addr <= 0x1FFF){ - - exec_bridge_write_cmd(info, 0x84, 4, addr); - exec_bridge_write_cmd(info, 0x88, 4, data); - } - usleep(100); -} - -/////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////// - - -int EE_WaitIdle(void *info) -{ - int eeCtl, ii; - for (ii = 0; ii < 100; ii++) - { - /* read current value in EECTL */ - PEX_8111Read(info, EECTL, &eeCtl); - /* loop until idle */ - if ((eeCtl & (1 << EEPROM_BUSY)) == 0) - return(eeCtl); - } - printf("ERROR: EEPROM Busy timeout!\n"); - while(1); -} - - -/////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////// - - - -void EE_Off(void *info) -{ - int t = 0; - - EE_WaitIdle(info); /* make sure EEPROM is idle */ - PEX_8111Write(info, EECTL, t); /* turn off everything (especially EEPROM_CS_ENABLE)*/ -} - -/////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////// - - -unsigned char EE_ReadByte(void *info) -{ - /* make sure EEPROM is idle */ - int eeCtl = EE_WaitIdle(info); - - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_READ_START); - PEX_8111Write(info, EECTL, eeCtl); /* start reading */ - eeCtl = EE_WaitIdle(info); /* wait until read is done */ - - /* extract read data from EECTL */ - return (unsigned char)((eeCtl >> EEPROM_READ_DATA) & 0xff); -} - -/////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////// - -void EE_WriteByte(void *info, unsigned char val) -{ - int eeCtl = EE_WaitIdle(info); /* make sure EEPROM is idle */ - - /* clear current WRITE value */ - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - ((val & 0xff) << EEPROM_WRITE_DATA); - - PEX_8111Write(info, EECTL, eeCtl); -} -/////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////// - -//These are the high level functions - -unsigned char read_eeprom_status(void *info) -{ - unsigned char status = 0; - - EE_WriteByte(info, READ_STATUS_EE_OPCODE); /* read status opcode */ - status = EE_ReadByte(info); /* get EEPROM status */ - EE_Off(info); /* turn off EEPROM */ - - return status; -} - - -void wan_plxctrl_write_ebyte(void *info, unsigned char addr, unsigned char data) -{ - int i = 0, eeCtl = 0; - - /* busy verification */ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 19)) != 0){ - printf("ERROR: EEPROM is busy %08X (init)!\n", eeCtl); - return; - } - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (6 << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (wren cmd)!\n"); - return; - } - - EE_Off(info); /* turn off EEPROM */ - - /* busy verification */ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 19)) != 0){ - printf("ERROR: EEPROM is busy!\n"); - return; - } - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (2 << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (write cmd)!\n"); - return; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (addr << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (addr)!\n"); - return; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (data << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (0x5A)!\n"); - return; - } - - EE_Off(info); /* turn off EEPROM */ - return; -} - - -unsigned char wan_plxctrl_read_ebyte(void *info, unsigned char addr, int silent) -{ - int i = 0, eeCtl = 0; - unsigned char data; - - /* busy verification */ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 19)) != 0){ - if (!silent) printf("ERROR: EEPROM is busy!\n"); - return 0xFF; - } - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (3 << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (write cmd)!\n"); - return 0xFF; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (addr << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (addr)!\n"); - return 0xFF; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_READ_START); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 17)) == 0){ - break; - } - } - if ((eeCtl & (1 << 17)) != 0){ - printf("ERROR: EEPROM timeout (read)!\n"); - return 0xFF; - } - EE_WaitIdle(info); - PEX_8111Read(info, EECTL, &eeCtl); - data = (eeCtl >> 8) & 0xFF; - EE_Off(info); /* turn off EEPROM */ - return data; -} - -void write_eeprom_data8(void *info, short addr, unsigned char data) -{ - - - EE_WriteByte(info, WREN_EE_OPCODE); /* must first write-enable */ - EE_Off(info); /* turn off EEPROM */ - EE_WriteByte(info, WRITE_EE_OPCODE); /* opcode to write bytes */ - - /* Send low byte of address */ - EE_WriteByte(info, (unsigned char)(addr & 0xFF)); - - EE_WriteByte(info, 0xFF & data); /* send data to be written */ - - EE_Off(info); /* turn off EEPROM */ -} - -/////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////// - -unsigned char read_eeprom_data8(void *info, short addr) -{ - unsigned char ch; - - EE_WriteByte(info, READ_EE_OPCODE); - EE_WriteByte(info, (unsigned char)(addr & 0xFF)); - - ch = EE_ReadByte(info); - EE_Off(info); - return ch; -} - -void erase_eeprom_data(void *info) -{ - int t; - - for(t = 0; t < EEPROM_SIZE; t++){ - write_eeprom_data8(info, t, 0xFF); - } - return; -} + +/*********************************************************************** +* wan_plxctr.c Sangoma PLX Control Utility. +* +* Copyright: (c) 2005 AMFELTEC Corp. +* +* ---------------------------------------------------------------------- +* Nov 1, 2006 Alex Feldman Initial version. +***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//This is the address of the ECCTL register , page 149 of PEX8111 datasheet. +#define EECTL 0x1004 + +//Change this accordingly.!!! +#define EEPROM_SIZE 0xFF + +#define EEPROM_BUSY 19 +#define EEPROM_CS_ENABLE 18 +#define EEPROM_BYTE_READ_START 17 +#define EEPROM_READ_DATA 8 +#define EEPROM_WRITE_DATA 0 +#define EEPROM_BYTE_WRITE_START 16 + + +//EEPROM COMMANDS +#define READ_STATUS_EE_OPCODE 0x05 +#define WREN_EE_OPCODE 0x06 +#define WRITE_EE_OPCODE 0x02 +#define READ_EE_OPCODE 0x03 + + +/************************************************************************/ +/* GLOBAL VARIABLES */ +/************************************************************************/ + +/************************************************************************/ +/* FUNCTION PROTOTYPES */ +/************************************************************************/ +void PEX_8111Read(void *info, int addr, int *data); +void PEX_8111Write(void *info, int addr, int data); +int EE_WaitIdle(void *info); +void EE_Off(void *info); +unsigned char EE_ReadByte(void *info); +void EE_WriteByte(void *info, unsigned char val); + +unsigned char read_eeprom_status(void *info); +unsigned char read_eeprom_data8(void *info, short address); +void write_eeprom_data8(void *info, short address, unsigned char data); + +extern int exec_bridge_read_cmd(void*, unsigned int, unsigned int, unsigned int*); +extern int exec_bridge_write_cmd(void*, unsigned int, unsigned int, unsigned int); + +void wan_plxctrl_write_ebyte(void *info, unsigned char, unsigned char); +unsigned char wan_plxctrl_read_ebyte(void *info, unsigned char, int); +void erase_eeprom_data(void *info); + +/*********************************************** +****************FUNCTION PROTOTYPES************* +************************************************/ +//These functions are taken from page 37 of PEX8111 datasheet. + + +//Write the value read into the dst pointer. +void PEX_8111Read(void *info, int addr, int *data) +{ + if (addr < 0x1000){ + exec_bridge_read_cmd(info, addr, 4, (unsigned int*)data); + }else if (addr >= 0x1000 && addr <= 0x1FFF){ + + exec_bridge_write_cmd(info, 0x84, 4, addr); + exec_bridge_read_cmd(info, 0x88, 4, (unsigned int*)data); + } +} + + +void PEX_8111Write(void *info, int addr, int data) +{ + if (addr < 0x1000){ + exec_bridge_write_cmd(info, addr, 4, data); + }else if (addr >= 0x1000 && addr <= 0x1FFF){ + + exec_bridge_write_cmd(info, 0x84, 4, addr); + exec_bridge_write_cmd(info, 0x88, 4, data); + } + usleep(100); +} + +/////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + + +int EE_WaitIdle(void *info) +{ + int eeCtl, ii; + for (ii = 0; ii < 100; ii++) + { + /* read current value in EECTL */ + PEX_8111Read(info, EECTL, &eeCtl); + /* loop until idle */ + if ((eeCtl & (1 << EEPROM_BUSY)) == 0) + return(eeCtl); + } + printf("ERROR: EEPROM Busy timeout!\n"); + while(1); +} + + +/////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + + + +void EE_Off(void *info) +{ + int t = 0; + + EE_WaitIdle(info); /* make sure EEPROM is idle */ + PEX_8111Write(info, EECTL, t); /* turn off everything (especially EEPROM_CS_ENABLE)*/ +} + +/////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + + +unsigned char EE_ReadByte(void *info) +{ + /* make sure EEPROM is idle */ + int eeCtl = EE_WaitIdle(info); + + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_READ_START); + PEX_8111Write(info, EECTL, eeCtl); /* start reading */ + eeCtl = EE_WaitIdle(info); /* wait until read is done */ + + /* extract read data from EECTL */ + return (unsigned char)((eeCtl >> EEPROM_READ_DATA) & 0xff); +} + +/////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +void EE_WriteByte(void *info, unsigned char val) +{ + int eeCtl = EE_WaitIdle(info); /* make sure EEPROM is idle */ + + /* clear current WRITE value */ + eeCtl &= ~(0xff << EEPROM_WRITE_DATA); + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_WRITE_START) | + ((val & 0xff) << EEPROM_WRITE_DATA); + + PEX_8111Write(info, EECTL, eeCtl); +} +/////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +//These are the high level functions + +unsigned char read_eeprom_status(void *info) +{ + unsigned char status = 0; + + EE_WriteByte(info, READ_STATUS_EE_OPCODE); /* read status opcode */ + status = EE_ReadByte(info); /* get EEPROM status */ + EE_Off(info); /* turn off EEPROM */ + + return status; +} + + +void wan_plxctrl_write_ebyte(void *info, unsigned char addr, unsigned char data) +{ + int i = 0, eeCtl = 0; + + /* busy verification */ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 19)) != 0){ + printf("ERROR: EEPROM is busy %08X (init)!\n", eeCtl); + return; + } + eeCtl = 0x00000000; + eeCtl |= (1 << EEPROM_CS_ENABLE); + PEX_8111Write(info, EECTL, eeCtl); + + eeCtl &= ~(0xff << EEPROM_WRITE_DATA); + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_WRITE_START) | + (6 << EEPROM_WRITE_DATA); + PEX_8111Write(info, EECTL, eeCtl); + + for(i=0; i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 16)) == 0){ + break; + } + } + if ((eeCtl & (1 << 16)) != 0){ + printf("ERROR: EEPROM timeout (wren cmd)!\n"); + return; + } + + EE_Off(info); /* turn off EEPROM */ + + /* busy verification */ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 19)) != 0){ + printf("ERROR: EEPROM is busy!\n"); + return; + } + eeCtl = 0x00000000; + eeCtl |= (1 << EEPROM_CS_ENABLE); + PEX_8111Write(info, EECTL, eeCtl); + + eeCtl &= ~(0xff << EEPROM_WRITE_DATA); + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_WRITE_START) | + (2 << EEPROM_WRITE_DATA); + PEX_8111Write(info, EECTL, eeCtl); + for(i=0; i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 16)) == 0){ + break; + } + } + if ((eeCtl & (1 << 16)) != 0){ + printf("ERROR: EEPROM timeout (write cmd)!\n"); + return; + } + + eeCtl = 0x00000000; + eeCtl |= (1 << EEPROM_CS_ENABLE); + PEX_8111Write(info, EECTL, eeCtl); + + eeCtl &= ~(0xff << EEPROM_WRITE_DATA); + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_WRITE_START) | + (addr << EEPROM_WRITE_DATA); + PEX_8111Write(info, EECTL, eeCtl); + for(i=0; i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 16)) == 0){ + break; + } + } + if ((eeCtl & (1 << 16)) != 0){ + printf("ERROR: EEPROM timeout (addr)!\n"); + return; + } + + eeCtl = 0x00000000; + eeCtl |= (1 << EEPROM_CS_ENABLE); + PEX_8111Write(info, EECTL, eeCtl); + + eeCtl &= ~(0xff << EEPROM_WRITE_DATA); + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_WRITE_START) | + (data << EEPROM_WRITE_DATA); + PEX_8111Write(info, EECTL, eeCtl); + for(i=0; i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 16)) == 0){ + break; + } + } + if ((eeCtl & (1 << 16)) != 0){ + printf("ERROR: EEPROM timeout (0x5A)!\n"); + return; + } + + EE_Off(info); /* turn off EEPROM */ + return; +} + + +unsigned char wan_plxctrl_read_ebyte(void *info, unsigned char addr, int silent) +{ + int i = 0, eeCtl = 0; + unsigned char data; + + /* busy verification */ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 19)) != 0){ + if (!silent) printf("ERROR: EEPROM is busy!\n"); + return 0xFF; + } + eeCtl = 0x00000000; + eeCtl |= (1 << EEPROM_CS_ENABLE); + PEX_8111Write(info, EECTL, eeCtl); + + eeCtl &= ~(0xff << EEPROM_WRITE_DATA); + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_WRITE_START) | + (3 << EEPROM_WRITE_DATA); + PEX_8111Write(info, EECTL, eeCtl); + for(i=0; i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 16)) == 0){ + break; + } + } + if ((eeCtl & (1 << 16)) != 0){ + printf("ERROR: EEPROM timeout (write cmd)!\n"); + return 0xFF; + } + + eeCtl = 0x00000000; + eeCtl |= (1 << EEPROM_CS_ENABLE); + PEX_8111Write(info, EECTL, eeCtl); + + eeCtl &= ~(0xff << EEPROM_WRITE_DATA); + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_WRITE_START) | + (addr << EEPROM_WRITE_DATA); + PEX_8111Write(info, EECTL, eeCtl); + for(i=0; i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 16)) == 0){ + break; + } + } + if ((eeCtl & (1 << 16)) != 0){ + printf("ERROR: EEPROM timeout (addr)!\n"); + return 0xFF; + } + + eeCtl = 0x00000000; + eeCtl |= (1 << EEPROM_CS_ENABLE) | + (1 << EEPROM_BYTE_READ_START); + PEX_8111Write(info, EECTL, eeCtl); + for(i=0; i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & (1 << 17)) == 0){ + break; + } + } + if ((eeCtl & (1 << 17)) != 0){ + printf("ERROR: EEPROM timeout (read)!\n"); + return 0xFF; + } + EE_WaitIdle(info); + PEX_8111Read(info, EECTL, &eeCtl); + data = (eeCtl >> 8) & 0xFF; + EE_Off(info); /* turn off EEPROM */ + return data; +} + +void write_eeprom_data8(void *info, short addr, unsigned char data) +{ + + + EE_WriteByte(info, WREN_EE_OPCODE); /* must first write-enable */ + EE_Off(info); /* turn off EEPROM */ + EE_WriteByte(info, WRITE_EE_OPCODE); /* opcode to write bytes */ + + /* Send low byte of address */ + EE_WriteByte(info, (unsigned char)(addr & 0xFF)); + + EE_WriteByte(info, 0xFF & data); /* send data to be written */ + + EE_Off(info); /* turn off EEPROM */ +} + +/////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +unsigned char read_eeprom_data8(void *info, short addr) +{ + unsigned char ch; + + EE_WriteByte(info, READ_EE_OPCODE); + EE_WriteByte(info, (unsigned char)(addr & 0xFF)); + + ch = EE_ReadByte(info); + EE_Off(info); + return ch; +} + +void erase_eeprom_data(void *info) +{ + int t; + + for(t = 0; t < EEPROM_SIZE; t++){ + write_eeprom_data8(info, t, 0xFF); + } + return; +} diff --git a/util/wan_plxctrl/check_plx.sh b/util/wan_plxctrl/check_plx.sh deleted file mode 100755 index bf42837..0000000 --- a/util/wan_plxctrl/check_plx.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -cmd=$1; - -eval "make clean > /dev/null" -eval "make > /dev/null" - -if [ -e /proc/net/wanrouter ]; then - - echo - echo "Warning: Wanpipe modules loaded" - echo " Please remove wanpipe modules from the kernel" - echo - echo " eg: wanrouter stop" - echo - exit 1 -fi - - -trap '' 2 - -eval "../wan_aftup/scripts/load.sh" - -sleep 1 - -IFACES=`cat /proc/net/dev | cut -d":" -f 1 | grep "w.*g" | xargs` -cfg=0 - -for ifdev in $IFACES -do -#echo $ifdev -val=`./wan_plxup -i $ifdev -r F` -echo "Reading $val from $ifdev" -usleep 50000 -done - -eval "../wan_aftup/scripts/unload.sh" - - diff --git a/util/wan_plxctrl/wan_plxctrl.c b/util/wan_plxctrl/wan_plxctrl.c index df23f47..f8c564f 100644 --- a/util/wan_plxctrl/wan_plxctrl.c +++ b/util/wan_plxctrl/wan_plxctrl.c @@ -29,15 +29,15 @@ #define EECTL 0x1004 //Change this accordingly.!!! -#define EEPROM_SIZE 0xFF +#define PLXE_SIZE 0xFF -#define EEPROM_BUSY 19 -#define EEPROM_CS_ENABLE 18 -#define EEPROM_BYTE_READ_START 17 -#define EEPROM_READ_DATA 8 -#define EEPROM_WRITE_DATA 0 -#define EEPROM_BYTE_WRITE_START 16 +#define PLXE_READ_DATA_SHIFT 8 +#define PLXE_WRITE_DATA_SHIFT 0 +#define PLXE_BUSY_MASK (1<<19) +#define PLXE_CS_ENABLE_MASK (1<<18) +#define PLXE_BYTE_READ_START_MASK (1<<17) +#define PLXE_BYTE_WRITE_START_MASK (1<<16) //EEPROM COMMANDS #define READ_STATUS_EE_OPCODE 0x05 @@ -55,14 +55,16 @@ /************************************************************************/ void PEX_8111Read(void *info, int addr, int *data); void PEX_8111Write(void *info, int addr, int data); -int EE_WaitIdle(void *info); -void EE_Off(void *info); -unsigned char EE_ReadByte(void *info); -void EE_WriteByte(void *info, unsigned char val); +int EE_WaitIdle(void *info); +int EE_Off(void *info); +int EE_ReadByte(void *info, unsigned char*); +int EE_WriteByte(void *info, unsigned char val); -unsigned char read_eeprom_status(void *info); -unsigned char read_eeprom_data8(void *info, short address); -void write_eeprom_data8(void *info, short address, unsigned char data); +unsigned char wan_plxctrl_status(void *info); + +int wan_plxctrl_write8(void *info, unsigned char addr, unsigned char data); +int wan_plxctrl_read8(void *info, unsigned char, unsigned char*); +int wan_plxctrl_erase(void *info); extern int exec_read_cmd(void*, unsigned int, unsigned int, unsigned int*); extern int exec_write_cmd(void*, unsigned int, unsigned int, unsigned int); @@ -104,16 +106,16 @@ void PEX_8111Write(void *info, int addr, int data) int EE_WaitIdle(void *info) { int eeCtl, ii; - for (ii = 0; ii < 100; ii++) + for (ii = 0; ii < 1000; ii++) { /* read current value in EECTL */ PEX_8111Read(info, EECTL, &eeCtl); /* loop until idle */ - if ((eeCtl & (1 << EEPROM_BUSY)) == 0) + if ((eeCtl & PLXE_BUSY_MASK) == 0) return(eeCtl); } printf("ERROR: EEPROM Busy timeout!\n"); - while(1); + return PLXE_BUSY_MASK; } @@ -122,246 +124,98 @@ int EE_WaitIdle(void *info) -void EE_Off(void *info) +int EE_Off(void *info) { int t = 0; - EE_WaitIdle(info); /* make sure EEPROM is idle */ - PEX_8111Write(info, EECTL, t); /* turn off everything (especially EEPROM_CS_ENABLE)*/ + /* make sure EEPROM is idle */ + EE_WaitIdle(info); + /* turn off everything (especially PLXE_CS_ENABLE_MASK)*/ + PEX_8111Write(info, EECTL, t); + return 0; } /////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// -unsigned char EE_ReadByte(void *info) +int EE_ReadByte(void *info, unsigned char *data) { /* make sure EEPROM is idle */ - int eeCtl = EE_WaitIdle(info); + int eeCtl,i; - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_READ_START); + *data = 0x00; + eeCtl = EE_WaitIdle(info); + + eeCtl = 0; + eeCtl |= PLXE_CS_ENABLE_MASK | PLXE_BYTE_READ_START_MASK; PEX_8111Write(info, EECTL, eeCtl); /* start reading */ - eeCtl = EE_WaitIdle(info); /* wait until read is done */ + + for (i=0;i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & PLXE_BYTE_READ_START_MASK) == 0){ + break; + } + } + if ((eeCtl & PLXE_BYTE_READ_START_MASK) != 0){ + printf("ERROR: EEPROM is still reading byte (busy)!\n"); + return -EBUSY; + } + + EE_WaitIdle(info); /* wait until read is done */ + PEX_8111Read(info, EECTL, &eeCtl); + *data = (eeCtl >> PLXE_READ_DATA_SHIFT) & 0xFF; /* extract read data from EECTL */ - return (unsigned char)((eeCtl >> EEPROM_READ_DATA) & 0xff); + return 0; } /////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// -void EE_WriteByte(void *info, unsigned char val) +int EE_WriteByte(void *info, unsigned char val) { - int eeCtl = EE_WaitIdle(info); /* make sure EEPROM is idle */ + int eeCtl,i; + + eeCtl = EE_WaitIdle(info); /* make sure EEPROM is idle */ /* clear current WRITE value */ - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - ((val & 0xff) << EEPROM_WRITE_DATA); - + eeCtl = 0; + eeCtl &= ~(0xff << PLXE_WRITE_DATA_SHIFT); + eeCtl |= PLXE_CS_ENABLE_MASK | PLXE_BYTE_WRITE_START_MASK | + ((val & 0xff) << PLXE_WRITE_DATA_SHIFT); PEX_8111Write(info, EECTL, eeCtl); + + for (i=0;i<1000;i++){ + PEX_8111Read(info, EECTL, &eeCtl); + if ((eeCtl & PLXE_BYTE_WRITE_START_MASK) == 0){ + break; + } + } + if ((eeCtl & PLXE_BYTE_WRITE_START_MASK) != 0){ + printf("ERROR: EEPROM is still writting byte (busy)!\n"); + return -EBUSY; + } + return 0; } /////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// //These are the high level functions -unsigned char read_eeprom_status(void *info) +unsigned char wan_plxctrl_status(void *info) { unsigned char status = 0; EE_WriteByte(info, READ_STATUS_EE_OPCODE); /* read status opcode */ - status = EE_ReadByte(info); /* get EEPROM status */ + EE_ReadByte(info, &status); /* get EEPROM status */ EE_Off(info); /* turn off EEPROM */ return status; } - -void wan_plxctrl_write_ebyte(void *info, unsigned char addr, unsigned char data) +int wan_plxctrl_write8(void *info, unsigned char addr, unsigned char data) { - int i = 0, eeCtl = 0; - - /* busy verification */ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 19)) != 0){ - printf("ERROR: EEPROM is busy %08X (init)!\n", eeCtl); - return; - } - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (6 << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (wren cmd)!\n"); - return; - } - - EE_Off(info); /* turn off EEPROM */ - - /* busy verification */ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 19)) != 0){ - printf("ERROR: EEPROM is busy!\n"); - return; - } - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (2 << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (write cmd)!\n"); - return; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (addr << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (addr)!\n"); - return; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (data << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (0x5A)!\n"); - return; - } - - EE_Off(info); /* turn off EEPROM */ - return; -} - - -unsigned char wan_plxctrl_read_ebyte(void *info, unsigned char addr) -{ - int i = 0, eeCtl = 0; - unsigned char data; - - /* busy verification */ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 19)) != 0){ - printf("ERROR: EEPROM is busy!\n"); - return 0xFF; - } - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (3 << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (write cmd)!\n"); - return 0xFF; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE); - PEX_8111Write(info, EECTL, eeCtl); - - eeCtl &= ~(0xff << EEPROM_WRITE_DATA); - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_WRITE_START) | - (addr << EEPROM_WRITE_DATA); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 16)) == 0){ - break; - } - } - if ((eeCtl & (1 << 16)) != 0){ - printf("ERROR: EEPROM timeout (addr)!\n"); - return 0xFF; - } - - eeCtl = 0x00000000; - eeCtl |= (1 << EEPROM_CS_ENABLE) | - (1 << EEPROM_BYTE_READ_START); - PEX_8111Write(info, EECTL, eeCtl); - for(i=0; i<1000;i++){ - PEX_8111Read(info, EECTL, &eeCtl); - if ((eeCtl & (1 << 17)) == 0){ - break; - } - } - if ((eeCtl & (1 << 17)) != 0){ - printf("ERROR: EEPROM timeout (read)!\n"); - return 0xFF; - } - EE_WaitIdle(info); - PEX_8111Read(info, EECTL, &eeCtl); - data = (eeCtl >> 8) & 0xFF; - EE_Off(info); /* turn off EEPROM */ - - sleep(1); /* wait until PLX EEPROM finish write command */ - return data; -} - -void write_eeprom_data8(void *info, short addr, unsigned char data) -{ - - EE_WriteByte(info, WREN_EE_OPCODE); /* must first write-enable */ EE_Off(info); /* turn off EEPROM */ EE_WriteByte(info, WRITE_EE_OPCODE); /* opcode to write bytes */ @@ -372,29 +226,30 @@ void write_eeprom_data8(void *info, short addr, unsigned char data) EE_WriteByte(info, 0xFF & data); /* send data to be written */ EE_Off(info); /* turn off EEPROM */ + return 0; } /////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// -unsigned char read_eeprom_data8(void *info, short addr) +int wan_plxctrl_read8(void *info, unsigned char addr, unsigned char *data) { - unsigned char ch; - + + *data = 0x00; EE_WriteByte(info, READ_EE_OPCODE); EE_WriteByte(info, (unsigned char)(addr & 0xFF)); - ch = EE_ReadByte(info); + EE_ReadByte(info, data); EE_Off(info); - return ch; + return 0; } -void erase_eeprom_data(void *info) +int wan_plxctrl_erase(void *info) { int t; - for(t = 0; t < EEPROM_SIZE; t++){ - write_eeprom_data8(info, t, 0xFF); + for(t = 0; t < PLXE_SIZE; t++){ + wan_plxctrl_write8(info, t, 0xFF); } - return; + return 0; } diff --git a/util/wan_plxctrl/wan_plxup.c b/util/wan_plxctrl/wan_plxup.c index 5b6d2f2..3552cf9 100644 --- a/util/wan_plxctrl/wan_plxup.c +++ b/util/wan_plxctrl/wan_plxup.c @@ -63,9 +63,11 @@ static wan_cmd_api_t api_cmd; /*********************************************************************** ** F U N C T I O N P R O T O T Y P E S ***********************************************************************/ -extern unsigned char wan_plxctrl_read_ebyte(void*, unsigned char); -extern void wan_plxctrl_write_ebyte(void*, unsigned char, unsigned char); +extern int wan_plxctrl_read8(void*, unsigned char, unsigned char*); +extern int wan_plxctrl_write8(void*, unsigned char, unsigned char); +int exec_read_cmd(void*, unsigned int, unsigned int, unsigned int*); +int exec_write_cmd(void*, unsigned int, unsigned int, unsigned int); /*********************************************************************** ** F U N C T I O N D E F I N I T I O N S @@ -189,7 +191,8 @@ int exec_write_cmd(void *arg, unsigned int off, unsigned int len, unsigned int d static int wan_plxup_read_cmd(wan_plxup_t *info) { FILE *f; - unsigned int off, value; + unsigned char off, value; + int err = 0; if (info->file){ f = fopen(info->file, "w");//open the .HEX file for reading @@ -199,16 +202,26 @@ static int wan_plxup_read_cmd(wan_plxup_t *info) printf("Uploading to file: %s\n", info->file); } for(off=0; off <= WAN_PLXUP_MAX_ESIZE; off++){ - value = wan_plxctrl_read_ebyte(info, (unsigned char)off); - fprintf(f, "%04X:%02X\n", off, value); - printf("Reading %02X from %04X\n", value, off); + printf("Reading from %02X = ", off); + err = wan_plxctrl_read8(info, off, &value); + if (err){ + printf("Failed (err=%d)\n", err); + break; + } + fprintf(f, "%02X:%02X\n", off, value); + printf("%02X\n", value); } if (f) fclose(f); }else{ - value = wan_plxctrl_read_ebyte(info, (unsigned char)info->addr); - printf("Reading %02X from %04X\n", value, info->addr); + printf("Reading from %02X = ", (unsigned char)info->addr); + err = wan_plxctrl_read8(info, (unsigned char)info->addr, &value); + if (!err){ + printf("%02X\n", value); + }else{ + printf("Failed (err=%d)\n", err); + } } - return 0; + return err; } @@ -217,6 +230,7 @@ static int wan_plxup_write_cmd(wan_plxup_t *info) { FILE *f; unsigned int offset, value; + int err; if (info->file){ f = fopen(info->file, "r");//open the .HEX file for reading @@ -226,22 +240,36 @@ static int wan_plxup_write_cmd(wan_plxup_t *info) }else{ printf("Uploading file: %s\n", info->file); } - while(fgets((char*)buffer, 99 , f) != NULL){ + while(fgets(buffer, 99 , f) != NULL){ sscanf(buffer, "%X:%X", &offset, &value); - printf("Writting %02X to %04X\n", value, offset); - wan_plxctrl_write_ebyte(info, - (unsigned char)offset, - (unsigned char)value); + printf("Writting %02X to %02X ...", + (unsigned char)value, + (unsigned char)offset); + err = wan_plxctrl_write8(info, + (unsigned char)offset, + (unsigned char)value); + if (err){ + printf("Failed (err=%d)\n", err); + break; + } + printf("OK\n"); } if (f) fclose(f); }else{ - printf("Writting %02X to %04X\n", info->value, info->addr); - wan_plxctrl_write_ebyte(info, + printf("Writting %02X to %02X ...", + (unsigned char)info->value, + (unsigned char)info->addr); + err = wan_plxctrl_write8(info, (unsigned char)info->addr, - (unsigned char)info->value); + (unsigned char)info->value); + if (err){ + printf("Failed (err=%d)\n", err); + }else{ + printf("OK!\n"); + } } - return 0; + return err; } static int wan_plxup_cmd(int cmd, wan_plxup_t *info) diff --git a/util/wan_plxctrl/wan_plxup.h b/util/wan_plxctrl/wan_plxup.h index c4e884e..bcfa22f 100644 --- a/util/wan_plxctrl/wan_plxup.h +++ b/util/wan_plxctrl/wan_plxup.h @@ -17,7 +17,7 @@ #define MAX_IFNAME_LEN 20 #define WAN_PLXUP_NAME_LEN 50 -#define WAN_PLXUP_MAX_ESIZE 0xFF +#define WAN_PLXUP_MAX_ESIZE 0x7F enum { WAN_PLXUP_WRITE_EFILE_CMD = 0x01, diff --git a/util/wancfg/.#menu_hardware_probe.cpp.1.20 b/util/wancfg/.#menu_hardware_probe.cpp.1.20 new file mode 100644 index 0000000..9e25d39 --- /dev/null +++ b/util/wancfg/.#menu_hardware_probe.cpp.1.20 @@ -0,0 +1,997 @@ +/*************************************************************************** + menu_hardware_probe.cpp - description + ------------------- + begin : Wed Mar 31 2004 + copyright : (C) 2004 by David Rokhvarg + email : davidr@sangoma.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ +/* + * old +------------------------------- +| Wanpipe Hardware Probe Info | +------------------------------- +1 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=A : PORT=PRI +2 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=A : PORT=SEC +3 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=B : PORT=PRI +4 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=B : PORT=SEC +5 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=21 : CPU=A : PORT=PRI +6 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=21 : CPU=B : PORT=PRI +7 . AFT-A102 : SLOT=2 : BUS=1 : IRQ=22 : CPU=A : PORT=PRI +8 . AFT-A102 : SLOT=2 : BUS=1 : IRQ=22 : CPU=B : PORT=PRI +9 . AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : LINE=0 +10. AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : LINE=1 +11. AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : LINE=2 +12. AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : LINE=3 + +Card Cnt: S508=0 S514X=2 S518=0 AFT=2 +------------------------------------------------------------------ +new1: +------------------------------- +| Wanpipe Hardware Probe Info | +------------------------------- +1 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=A : PORT=PRI +2 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=A : PORT=SEC +3 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=B : PORT=PRI +4 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=18 : CPU=B : PORT=SEC +5 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=21 : CPU=A : PORT=PRI +6 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=21 : CPU=B : PORT=PRI +7 . AFT-A102 : SLOT=2 : BUS=1 : IRQ=22 : CPU=A : PORT=PRI +8 . AFT-A102 : SLOT=2 : BUS=1 : IRQ=22 : CPU=B : PORT=PRI +9 . AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : PORT=0 +10. AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : PORT=1 +11. AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : PORT=2 +12. AFT-A104 : SLOT=6 : BUS=0 : IRQ=16 : CPU=A : PORT=3 + +new2: +------------------------------- +| Wanpipe Hardware Probe Info | +------------------------------- +1 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=PRI +2 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=SEC +3 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=177 : CPU=B : PORT=PRI +4 . S514-2-PCI : SLOT=4 : BUS=0 : IRQ=177 : CPU=B : PORT=SEC +5 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=217 : CPU=A : PORT=PRI +6 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=217 : CPU=B : PORT=PRI +7 . AFT-A104-SH : SLOT=6 : BUS=0 : IRQ=193 : CPU=A : PORT=1 +8 . AFT-A104-SH : SLOT=6 : BUS=0 : IRQ=193 : CPU=A : PORT=2 +9 . AFT-A104-SH : SLOT=6 : BUS=0 : IRQ=193 : CPU=A : PORT=3 +10. AFT-A104-SH : SLOT=6 : BUS=0 : IRQ=193 : CPU=A : PORT=4 +11. AFT-A102c : SLOT=2 : BUS=1 : IRQ=209 : CPU=A : PORT=PRI +12. AFT-A102c : SLOT=2 : BUS=1 : IRQ=209 : CPU=B : PORT=PRI +13. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=1 +14. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=2 +15. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=3 +16. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=4 + +Card Cnt: S508=0 S514X=2 S518=0 A101-2=1 A104=2 A300=0 + +new3 +------------------------------- +| Wanpipe Hardware Probe Info | +------------------------------- +1 . S514-2-PCI : SLOT=3 : BUS=0 : IRQ=177 : CPU=A : PORT=PRI +2 . S514-2-PCI : SLOT=3 : BUS=0 : IRQ=177 : CPU=A : PORT=SEC +3 . S514-2-PCI : SLOT=3 : BUS=0 : IRQ=177 : CPU=B : PORT=PRI +4 . S514-2-PCI : SLOT=3 : BUS=0 : IRQ=177 : CPU=B : PORT=SEC +5 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=225 : CPU=A : PORT=PRI +6 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=225 : CPU=B : PORT=PRI +7 . AFT-A104-SHc : SLOT=4 : BUS=0 : IRQ=185 : CPU=A : PORT=1 : HWEC=128 +8 . AFT-A104-SHc : SLOT=4 : BUS=0 : IRQ=185 : CPU=A : PORT=2 : HWEC=128 +9 . AFT-A104-SHc : SLOT=4 : BUS=0 : IRQ=185 : CPU=A : PORT=3 : HWEC=128 +10. AFT-A104-SHc : SLOT=4 : BUS=0 : IRQ=185 : CPU=A : PORT=4 : HWEC=128 +11. AFT-A200-SH : SLOT=6 : BUS=0 : IRQ=201 : CPU=A : PORT=PRI : HWEC=16 +12. AFT-A102c : SLOT=2 : BUS=1 : IRQ=217 : CPU=A : PORT=PRI +13. AFT-A102c : SLOT=2 : BUS=1 : IRQ=217 : CPU=B : PORT=PRI +14. AFT-A104u : SLOT=5 : BUS=0 : IRQ=193 : CPU=A : PORT=1 +15. AFT-A104u : SLOT=5 : BUS=0 : IRQ=193 : CPU=A : PORT=2 +16. AFT-A104u : SLOT=5 : BUS=0 : IRQ=193 : CPU=A : PORT=3 +17. AFT-A104u : SLOT=5 : BUS=0 : IRQ=193 : CPU=A : PORT=4 + +Card Cnt: S508=0 S514X=2 S518=0 A101-2=1 A104=2 A300=0 A200=1 + +new March 1, 2006 - A108 + +------------------------------- +| Wanpipe Hardware Probe Info | +------------------------------- +1 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=217 : CPU=A : PORT=PRI +2 . S514-7-PCI : SLOT=3 : BUS=1 : IRQ=217 : CPU=B : PORT=PRI +3 . AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=1 : HWEC=0 +4 . AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=2 : HWEC=0 +5 . AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=3 : HWEC=0 +6 . AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=4 : HWEC=0 +7 . AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=5 : HWEC=0 +8 . AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=6 : HWEC=0 +9 . AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=7 : HWEC=0 +10. AFT-A108-SH : SLOT=4 : BUS=0 : IRQ=177 : CPU=A : PORT=8 : HWEC=0 +11. AFT-A200-SH : SLOT=6 : BUS=0 : IRQ=193 : CPU=A : PORT=PRI : HWEC=0 +12. AFT-A102c : SLOT=2 : BUS=1 : IRQ=209 : CPU=A : PORT=PRI +13. AFT-A102c : SLOT=2 : BUS=1 : IRQ=209 : CPU=B : PORT=PRI +14. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=1 +15. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=2 +16. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=3 +17. AFT-A104u : SLOT=5 : BUS=0 : IRQ=185 : CPU=A : PORT=4 + +Card Cnt: S508=0 S514X=1 S518=0 A101-2=1 A104=1 A300=0 A200=1 A108=1 +*/ + +#include "menu_hardware_probe.h" +#include "text_box_help.h" + +char* no_sangoma_cards_detected_str = "No Sangoma cards detected!"; +char* hw_probe_help_str = +"Select a card for WANPIPE device\n" +"from a list of cards detected on the system."; + +//PCI +int get_slot_from_str(char * str_buff, unsigned* PCI_slot_no); +int get_bus_from_str(char * str_buff, unsigned* pci_bus_no); +int get_cpu_from_str(char * str_buff, char* S514_CPU_no); +//ISA +int get_io_port_from_str(char * str_buff, unsigned* ioport); + +#define DBG_MENU_HARDWARE_PROBE 1 +#define DBG_CARD_LIST 1 + +static unsigned int longest_line_in_hwprobe_output = MENU_WIDTH+2; + +menu_hardware_probe::menu_hardware_probe( IN char * lxdialog_path, + IN conf_file_reader* ptr_cfr) + +{ + Debug(DBG_MENU_HARDWARE_PROBE, ("menu_hardware_probe::menu_hardware_probe()\n")); + + snprintf(this->lxdialog_path, MAX_PATH_LENGTH, "%s", lxdialog_path); + this->cfr = ptr_cfr; +#if defined(ZAPTEL_PARSER) + sang_card_list = NULL; +#endif +} + +menu_hardware_probe::~menu_hardware_probe() +{ + Debug(DBG_MENU_HARDWARE_PROBE, ("menu_hardware_probe::~menu_hardware_probe()\n")); +} + +#if defined(ZAPTEL_PARSER) +menu_hardware_probe::menu_hardware_probe( IN sangoma_card_list *sang_card_list) + +{ + Debug(DBG_MENU_HARDWARE_PROBE, + ("menu_hardware_probe::menu_hardware_probe(IN sangoma_card_list *sang_card_list)\n")); + this->sang_card_list = sang_card_list; +} +#endif + +int menu_hardware_probe::run(OUT int * selection_index) +{ + + int rc; + char tmp_buff[MAX_PATH_LENGTH]; + unsigned int option_selected; + char exit_dialog; + int number_of_items; + + //help text box + text_box tb; + + link_def_t * link_def; + wandev_conf_t *linkconf; + sdla_fe_cfg_t* fe_cfg; + + Debug(DBG_MENU_HARDWARE_PROBE, ("menu_net_interface_setup::run()\n")); + +again: + number_of_items = 6; + rc = YES; + option_selected = 0; + exit_dialog = NO; + + link_def = cfr->link_defs; + linkconf = cfr->link_defs->linkconf; + fe_cfg = &linkconf->fe_cfg; + + Debug(DBG_MENU_HARDWARE_PROBE, ("cfr->link_defs->name: %s\n", link_def->name)); + Debug(DBG_MENU_HARDWARE_PROBE, ("current card_type: DEC:%d, HEX: 0x%X\n", + linkconf->card_type, linkconf->card_type)); + + + menu_str = " "; + if(hardware_probe() == NO){ + return NO; + } + + Debug(DBG_MENU_HARDWARE_PROBE, ("returned from: hardware_probe()\n")); + + ////////////////////////////////////////////////////////////////////////////////////// + //create the explanation text for the menu + snprintf(tmp_buff, MAX_PATH_LENGTH, +"\nSelect card from the list of detected cards."); + + if(set_configuration( YES,//indicates to call V2 of the function + MENU_BOX_BACK,//MENU_BOX_SELECT, + lxdialog_path, + "SELECT CARD FROM LIST", + WANCFG_PROGRAM_NAME, + tmp_buff, + MENU_HEIGTH, + //MENU_WIDTH+2,//some strings are very long, like for A104D-SH.... + //MENU_WIDTH+5,//some strings are very long, like for A104D-SH.... + //MENU_WIDTH+10,//some strings are very long, like for A104D-SH.... + longest_line_in_hwprobe_output+6, + number_of_items, + (char*)menu_str.c_str() + ) == NO){ + rc = NO; + goto cleanup; + } + + if(show(selection_index) == NO){ + rc = NO; + goto cleanup; + } + ////////////////////////////////////////////////////////////////////////////////////// + + exit_dialog = NO; + switch(*selection_index) + { + case MENU_BOX_BUTTON_SELECT: + Debug(DBG_MENU_HARDWARE_PROBE, + ("hardware_setup: option selected for editing: %s\n", get_lxdialog_output_string())); + + //if no cards detected, return + if(strcmp(replace_new_line_with_zero_term(get_lxdialog_output_string()), + no_sangoma_cards_detected_str) == 0){ + rc = YES; + goto cleanup; + } + + if(parse_selected_card_line( + replace_new_line_with_zero_term(get_lxdialog_output_string()), + &linkconf->card_type, + &link_def->card_version, + &link_def->card_sub_version) == NO){ + ERR_DBG_OUT(("Failed to get Card Type from selected card line!! line: %s\n", + get_lxdialog_output_string())); + rc = NO; + goto cleanup; + } + + //get card location + if(get_card_location_from_hwprobe_line(linkconf, + link_def, + replace_new_line_with_zero_term(get_lxdialog_output_string())) == NO){ + ERR_DBG_OUT(("Failed to get Card Location from selected card line!! line: %s\n", + get_lxdialog_output_string())); + rc = NO; + goto cleanup; + } + + linkconf->auto_pci_cfg = WANOPT_NO; + + rc = YES; + exit_dialog = YES; + break; + + case MENU_BOX_BUTTON_HELP: + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, hw_probe_help_str); + break; + + case MENU_BOX_BUTTON_EXIT: + exit_dialog = YES; + break; + }//switch(*selection_index) + + if(exit_dialog == NO){ + goto again; + } + +cleanup: + return rc; +} + +int menu_hardware_probe::hardware_probe() +{ + int system_rc; + FILE * hwprobe_file_tmp; + char str_buff[MAX_PATH_LENGTH]; + char shell_command_line[MAX_PATH_LENGTH]; + char* tmp_hwprobe_file_full_path = "tmp_hwprobe_file"; + int probed_cards_count=0; + string local_menu_str; + + local_menu_str = " "; + + snprintf(shell_command_line, MAX_PATH_LENGTH, "wanrouter hwprobe > %s", tmp_hwprobe_file_full_path); + + Debug(DBG_MENU_HARDWARE_PROBE, ("hardware_probe(): shell_command_line : %s\n", + shell_command_line)); + system_rc = system(shell_command_line); + if(system_rc){ + ERR_DBG_OUT( + ("The hardware probe command failed! Check WANPIPE is installed properly.(system_rc : 0x%X)\n", + system_rc)); + return NO; + } + + + if(verify_hwprobe_command_is_successfull() == NO){ + ERR_DBG_OUT(("Hardware probe failed!! Check wanpipe installation.\n")); + return NO; + } + + hwprobe_file_tmp = fopen(tmp_hwprobe_file_full_path, "r+"); + if(hwprobe_file_tmp == NULL){ + ERR_DBG_OUT(("Failed to open %s file for reading!!\n", tmp_hwprobe_file_full_path)); + return NO; + } + + do{ + fgets(str_buff, MAX_PATH_LENGTH, hwprobe_file_tmp); + + if(!feof(hwprobe_file_tmp)){ + Debug(DBG_MENU_HARDWARE_PROBE, ("%s\n", str_buff)); + + //skip irrelevant lines + //only lines starting with numbers (0 not allowed) should be displayed. + if(atoi(&str_buff[0]) != 0){ + + //this pointer skips the the line number by searching for first dot '.' + char* tmp_str = strchr(str_buff, '.'); + if(tmp_str == NULL){ + ERR_DBG_OUT(("Invalid format of 'hwprobe' output line!! (not '.' found)\n")); + return NO; + } + tmp_str += 2; + + //tokens separated by ':' chars and UNKNOWN number of ' ' (space) chars. + //remove all ' ' chars, so only ':' will remain. + tokenize_string(tmp_str, " ", shell_command_line, MAX_PATH_LENGTH); + + //now replace each ':' with a single ' ' (space), so it will be + //displayed nicely in the dialog. + replace_char_with_other_char_in_str(shell_command_line, ':', ' '); + + memcpy(str_buff, shell_command_line, MAX_PATH_LENGTH); + + replace_new_line_with_zero_term(str_buff); + + if(longest_line_in_hwprobe_output < strlen(str_buff)){ + longest_line_in_hwprobe_output = strlen(str_buff); + } + + //tag and item strings are the same. + snprintf(shell_command_line, MAX_PATH_LENGTH, " \"%s\" ", str_buff); + Debug(DBG_MENU_HARDWARE_PROBE, ("1.shell_command_line: %s\n", shell_command_line)); + local_menu_str += shell_command_line; + + snprintf(shell_command_line, MAX_PATH_LENGTH, " \"%s\" ", str_buff); + Debug(DBG_MENU_HARDWARE_PROBE, ("2.shell_command_line: %s\n", shell_command_line)); + local_menu_str += shell_command_line; + + probed_cards_count++; + +#if defined(ZAPTEL_PARSER) + if(sang_card_list != NULL){ + add_card_to_list(shell_command_line); + } +#endif + } + } + + }while(!feof(hwprobe_file_tmp)); + + fclose(hwprobe_file_tmp); + + snprintf(shell_command_line, MAX_PATH_LENGTH, "rm -rf %s", tmp_hwprobe_file_full_path); + system_rc = system(shell_command_line); + if(system_rc){ + ERR_DBG_OUT(("Failed to remove temporary file: %s! (system_rc : 0x%X)\n", + tmp_hwprobe_file_full_path, system_rc)); + } + + if(probed_cards_count == 0){ + local_menu_str = " "; + snprintf(shell_command_line, MAX_PATH_LENGTH, " \"%s\" ", no_sangoma_cards_detected_str); + local_menu_str += shell_command_line; + snprintf(shell_command_line, MAX_PATH_LENGTH, " \"%s\" ", no_sangoma_cards_detected_str); + local_menu_str += shell_command_line; + } + + menu_str = local_menu_str.c_str(); + + Debug(DBG_MENU_HARDWARE_PROBE, ("returning from hardware_probe()\n")); + return YES; +} + +int menu_hardware_probe::parse_selected_card_line(char *selected_card_line, + char *card_type, + unsigned int *card_version, + unsigned int *card_sub_version) +{ + char * tmp; + int rc = NO; + + // + //S514 cards: + // + tmp = strstr(selected_card_line, "S514-1"); + if(tmp != NULL){ + rc = YES; + *card_type = WANOPT_S51X; + *card_version = S5141_ADPTR_1_CPU_SERIAL; + goto done; + } + + tmp = strstr(selected_card_line, "S514-2"); + if(tmp != NULL){ + rc = YES; + //used the same way as S5141 + *card_type = WANOPT_S51X; + *card_version = S5141_ADPTR_1_CPU_SERIAL; + goto done; + } + + tmp = strstr(selected_card_line, "S514-3"); + if(tmp != NULL){ + rc = YES; + //FT1 is the same as Serial S5141 + *card_type = WANOPT_S51X; + *card_version = S5141_ADPTR_1_CPU_SERIAL; + goto done; + } + + tmp = strstr(selected_card_line, "S514-4"); + if(tmp != NULL){ + rc = YES; + *card_type = WANOPT_S51X; + *card_version = S5144_ADPTR_1_CPU_T1E1; + goto done; + } + + tmp = strstr(selected_card_line, "S514-5"); + if(tmp != NULL){ + rc = YES; + *card_type = WANOPT_S51X; + *card_version = S5145_ADPTR_1_CPU_56K; + goto done; + } + + tmp = strstr(selected_card_line, "S514-7"); + if(tmp != NULL){ + rc = YES; + //the same as S5144 + *card_type = WANOPT_S51X; + *card_version = S5144_ADPTR_1_CPU_T1E1; + goto done; + } + + tmp = strstr(selected_card_line, "S514-8"); + if(tmp != NULL){ + rc = YES; + //the same as S5144 + *card_type = WANOPT_S51X; + *card_version = S5144_ADPTR_1_CPU_T1E1; + goto done; + } + + // + //POS card treated as S5141 + // + tmp = strstr(selected_card_line, "S515"); + if(tmp != NULL){ + rc = YES; + //the same as S5141 + *card_type = WANOPT_S51X; + *card_version = S5144_ADPTR_1_CPU_T1E1; + goto done; + } + + // + //S508 card: + // + tmp = strstr(selected_card_line, "S508"); + if(tmp != NULL){ + rc = YES; + *card_type = WANOPT_S50X; + *card_version = NOT_SET; + goto done; + } + + // + //ADSL card + // + tmp = strstr(selected_card_line, "S518"); + if(tmp != NULL){ + rc = YES; + *card_type = WANOPT_ADSL; + *card_version = NOT_SET; + goto done; + } + + // + //A104 (AFT) quad port T1/E1 card. A108 handled the same way as A104. + //August 11, 2006: added A101/A102 Shark + if( strstr(selected_card_line, "AFT-A104") != NULL || + strstr(selected_card_line, "AFT-A108") != NULL || + strstr(selected_card_line, "AFT-A101-SH") != NULL || + strstr(selected_card_line, "AFT-A102-SH") != NULL){ + + Debug(DBG_MENU_HARDWARE_PROBE, ("found \"AFT-A104\" string\n")); + + rc = YES; + *card_type = WANOPT_AFT; + *card_version = A104_ADPTR_4TE1;//indicates A104 and A101/A102 Shark + + char *hw_ec_max_num_ptr = strstr(selected_card_line, "HWEC="); + if(hw_ec_max_num_ptr != NULL){ + char *max_ec_str = strdup(hw_ec_max_num_ptr); + char *max_ec_ptr = max_ec_str; + char *tmp_str = strstr(max_ec_str, ":"); + if (tmp_str != NULL) { + *(tmp_str-1)='\0'; + } + Debug(DBG_MENU_HARDWARE_PROBE, ("hw_ec_max_num_ptr: %s\n", hw_ec_max_num_ptr)); + max_ec_str += strlen("HWEC="); + //valid values are: 0, 32, 128, 256. + //0 (zero) means there is no HWEC on the card. + global_hw_ec_max_num = atoi(max_ec_str); + Debug(DBG_MENU_HARDWARE_PROBE, ("global_hw_ec_max_num: %d\n", global_hw_ec_max_num)); + free(max_ec_ptr); + } +#if defined(ZAPTEL_PARSER) + if( strstr(selected_card_line, "SH") != NULL){ + Debug(DBG_MENU_HARDWARE_PROBE, ("*card_sub_version = A104D\n")); + *card_sub_version = A104D; + }else{ + Debug(DBG_MENU_HARDWARE_PROBE, ("*card_sub_version = A104\n")); + *card_sub_version = A104; + } +#endif + goto done; + } + + // + //Old (original) A101/2 (AFT) T1/E1 card + // + if( strstr(selected_card_line, "A100") != NULL || + strstr(selected_card_line, "AFT-A101") != NULL || + strstr(selected_card_line, "AFT-A102") != NULL ){ + rc = YES; + *card_type = WANOPT_AFT; + *card_version = A101_ADPTR_1TE1;//WAN_MEDIA_T1;//indicates A101 + goto done; + } + + + + + // + //A105 (AFT) T3/E3 card + // + if( strstr(selected_card_line, "A105-1-PCI") != NULL || + strstr(selected_card_line, "A105-2-PCI") != NULL || + strstr(selected_card_line, "AFT-A301") != NULL || + strstr(selected_card_line, "AFT-A300") != NULL){ + rc = YES; + *card_type = WANOPT_AFT; + *card_version = A300_ADPTR_U_1TE3;//WAN_MEDIA_DS3;//indicates A105 + goto done; + } + + // + //Analog card + // + if( strstr(selected_card_line, "AFT-A200-SH") != NULL || + strstr(selected_card_line, "AFT-A400-SH") != NULL ){ + rc = YES; + *card_type = WANOPT_AFT; + *card_version = A200_ADPTR_ANALOG; + global_card_type = WANOPT_AFT; + global_card_version = A200_ADPTR_ANALOG; + + char *hw_ec_max_num_ptr = strstr(selected_card_line, "HWEC="); + if(hw_ec_max_num_ptr != NULL){ + Debug(DBG_MENU_HARDWARE_PROBE, ("hw_ec_max_num_ptr: %s\n", hw_ec_max_num_ptr)); + hw_ec_max_num_ptr += strlen("HWEC="); + //valid values are: 0, 32, 128. + //0 (zero) means there is no HWEC on the card. + global_hw_ec_max_num = atoi(hw_ec_max_num_ptr); + Debug(DBG_MENU_HARDWARE_PROBE, ("global_hw_ec_max_num: %d\n", global_hw_ec_max_num)); + } + + goto done; + } + + // + //A056 (AFT) 56k DDS card + // + if( strstr(selected_card_line, "AFT-A056-SH") != NULL){ + rc = YES; + *card_type = WANOPT_AFT; + *card_version = AFT_ADPTR_56K; + goto done; + } + +done: + + if(global_hw_ec_max_num == 1){ + //it is default value! it means the card does NOT have HWEC. + global_hw_ec_max_num = 0; + } + return rc; +} + +int menu_hardware_probe::get_card_location_from_hwprobe_line( wandev_conf_t* linkconf, + link_def_t * link_def, + char* selected_card_line) +{ + text_box tb; + sdla_fe_cfg_t* fe_cfg; + + fe_cfg = &linkconf->fe_cfg; + + switch(linkconf->card_type) + { + case WANOPT_S50X: + //get ISA stuff. only IO port is detected + if(get_io_port_from_str(selected_card_line, &linkconf->ioport) == NO){ + ERR_DBG_OUT(("Failed to get 'ioport' from line: %s!\n", + selected_card_line)); + return NO; + } + break; + + case WANOPT_S51X: + case WANOPT_ADSL: + case WANOPT_AFT: + //get PCI stuff + if(get_slot_from_str(selected_card_line, &linkconf->PCI_slot_no) == NO){ + ERR_DBG_OUT(("Failed to get 'PCI_slot_no' from line: %s!\n", + selected_card_line)); + return NO; + } + + if(get_bus_from_str(selected_card_line, &linkconf->pci_bus_no) == NO){ + ERR_DBG_OUT(("Failed to get 'pci_bus_no' from line: %s!\n", + selected_card_line)); + return NO; + } + + //ADSL card always have only one CPU. But check anyway + if(get_cpu_from_str(selected_card_line, linkconf->S514_CPU_no) == NO){ + ERR_DBG_OUT(("Failed to get 'S514_CPU_no' from line: %s!\n", + selected_card_line)); + return NO; + } + break; + + default: + ERR_DBG_OUT(("Unsupported card type selected %d!\n", + linkconf->card_type)); + + tb.show_error_message(lxdialog_path, NO_PROTOCOL_NEEDED, + "Unsupported card type selected"); + return NO; + } + + if(link_def->card_version != A104_ADPTR_4TE1){ + //get the port + return get_port_from_str(selected_card_line, &linkconf->comm_port); + }else{ + //get line_no + return get_line_number_from_str(selected_card_line, &fe_cfg->line_no); + } +} + +int get_slot_from_str(char * str_buff, unsigned* PCI_slot_no) +{ + char * tmp; + int i_tmp; + + tmp = strstr(str_buff, "SLOT="); + if(tmp == NULL){ + return NO; + } + + tmp += strlen("SLOT="); + i_tmp = atoi(tmp); + + Debug(DBG_MENU_HARDWARE_PROBE, ("get_slot_from_str() : slot : %d\n", i_tmp)); + + *PCI_slot_no = i_tmp; + return YES; +} + +int get_bus_from_str(char * str_buff, unsigned* pci_bus_no) +{ + char * tmp; + int i_tmp; + + tmp = strstr(str_buff, "BUS="); + if(tmp == NULL){ + return NO; + } + + tmp += strlen("BUS="); + i_tmp = atoi(tmp); + + Debug(DBG_MENU_HARDWARE_PROBE, ("get_bus_from_str() : bus : %d\n", i_tmp)); + + *pci_bus_no = i_tmp; + return YES; +} + +int get_cpu_from_str(char * str_buff, char* S514_CPU_no) +{ + char * tmp; + int i_tmp; + + tmp = strstr(str_buff, "CPU="); + if(tmp == NULL){ + return NO; + } + + tmp += strlen("CPU="); + i_tmp = *tmp; + + Debug(DBG_MENU_HARDWARE_PROBE, + ("get_cpu_from_str() : CPU : %c\n", (i_tmp == 'A') ? 'A' : 'B')); + + //*S514_CPU_no = i_tmp; + S514_CPU_no[0] = i_tmp; + return YES; +} + +int menu_hardware_probe::get_port_from_str(char * str_buff, unsigned int* comm_port) +{ + char * tmp = str_buff; + + link_def_t * link_def; + wandev_conf_t *linkconf; + + link_def = cfr->link_defs; + linkconf = cfr->link_defs->linkconf; + + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): str_buff: %s\n", str_buff)); + + //for ISA card the 'ioport' is displayed first, + //it may fail the 'comms port' parsing. skip past the 'ioport'. + if(linkconf->card_type == WANOPT_S50X){ + tmp = strstr(str_buff, "IOPORT="); + if(tmp == NULL){ + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): failed to find IOPORT str.\n")); + return NO; + } + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): skipping past IOPORT...\n")); + tmp += strlen("IOPORT="); + } + + tmp = strstr(tmp, "PORT="); + if(tmp == NULL){ + return NO; + } + + tmp += strlen("PORT="); +/* + if(strcmp(tmp, "PRI") == 0){ + *comm_port = 0; + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): PORT : PRI\n")); + }else if(strcmp(tmp, "SEC") == 0){ + *comm_port = 1; + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): PORT : SEC\n")); + }else{ + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): Invalid Port!!\n")); + ERR_DBG_OUT(("Failed to get 'comm_port' from line: %s!\n", str_buff)); + return NO; + } +*/ + if(strstr(tmp, "PRI") != NULL){ + *comm_port = 0; + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): PORT : PRI\n")); + }else if(strstr(tmp, "SEC") != NULL){ + *comm_port = 1; + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): PORT : SEC\n")); + }else{ + *comm_port = 0; + //Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): Invalid Port!!\n")); + //ERR_DBG_OUT(("Failed to get 'comm_port' from line: %s!\n", str_buff)); + //return NO; + } + return YES; +} + +int get_io_port_from_str(char * str_buff, unsigned* ioport) +{ + char * tmp; + + tmp = strstr(str_buff, "IOPORT"); + if(tmp == NULL){ + return NO; + } + + //skip past '=' + tmp = strstr(str_buff, "="); + if(tmp == NULL){ + return NO; + } + tmp += strlen("="); + + *ioport = strtoul(tmp, NULL, 16); + Debug(DBG_MENU_HARDWARE_PROBE, ("get_port_from_str(): IOPORT: 0x%X\n", *ioport)); + + return YES; +} + +//original 'LINE=' was changed to 'PORT=' in the 'hwprobe' +int menu_hardware_probe::get_line_number_from_str(char * str_buff, unsigned int* line_no) +{ + char * tmp = str_buff; + + Debug(DBG_MENU_HARDWARE_PROBE, ("get_line_number_from_str(): str_buff: %s\n", str_buff)); + + //tmp = strstr(tmp, "LINE="); + tmp = strstr(tmp, "PORT="); + if(tmp == NULL){ + return NO; + } + + //tmp += strlen("LINE="); + tmp += strlen("PORT="); + + *line_no = atoi(tmp); + + Debug(DBG_MENU_HARDWARE_PROBE, ("got line_no: %d\n", *line_no)); + + return YES; +} + +int menu_hardware_probe::verify_hwprobe_command_is_successfull() +{ + char* expected_str = "Wanpipe Hardware Probe Info"; + FILE * hwprobe_file_tmp; + char str_buff[MAX_PATH_LENGTH]; + char* tmp_hwprobe_file_full_path = "tmp_hwprobe_file"; + char rc = NO; + + hwprobe_file_tmp = fopen(tmp_hwprobe_file_full_path, "r+"); + if(hwprobe_file_tmp == NULL){ + ERR_DBG_OUT(("Failed to open %s file for reading!!\n", tmp_hwprobe_file_full_path)); + return NO; + } + + do{ + fgets(str_buff, MAX_PATH_LENGTH, hwprobe_file_tmp); + + if(!feof(hwprobe_file_tmp)){ + Debug(DBG_MENU_HARDWARE_PROBE, ("%s\n", str_buff)); + //search for the 'expected_str' + + if(strstr(str_buff, expected_str)){ + //exit(0); + rc = YES; + break; + } + } + + }while(!feof(hwprobe_file_tmp)); + + fclose(hwprobe_file_tmp); + + return rc; +} + +#if defined(ZAPTEL_PARSER) +int menu_hardware_probe::add_card_to_list(IN char *hw_probe_output_line) +{ + int rc = YES, key; + char card_type; + int card_version = 0, card_sub_version = 0; + unsigned int line_no, PCI_slot_no, pci_bus_no; + char S514_CPU_no[10]; + + list_element_sangoma_card *sangoma_card, *last_in_list_card; + + replace_new_line_with_zero_term(hw_probe_output_line); + + if(parse_selected_card_line( + hw_probe_output_line, + (char*)&card_type, + (unsigned int*)&card_version, + (unsigned int*)&card_sub_version) == NO){ + ERR_DBG_OUT(("Failed to get Card Type from from Hardware Proble output line!! line: %s\n", + hw_probe_output_line)); + rc = NO; + goto cleanup; + } + + switch(sang_card_list->get_list_card_type()) + { + case CARD_TYPE_ANY: + //caller needs ALL detected cards + break; + + case WANOPT_AFT: + //caller needs only TE1 cards + if(card_type == WANOPT_AFT && (card_version == A101_ADPTR_1TE1 || card_version == A104_ADPTR_4TE1)){ + break; + }else{ + rc = YES; + goto cleanup; + } + + case WANOPT_AFT_ANALOG: + //caller needs only Analog cards + if(card_type == WANOPT_AFT && card_version == A200_ADPTR_ANALOG){ + break; + }else{ + rc = YES; + goto cleanup; + } + + default: + //not interested in other cards + rc = YES; + goto cleanup; + } + + if(get_line_number_from_str(hw_probe_output_line, &line_no) == NO){ + ERR_DBG_OUT(("Failed to get Line Number (Port) from Hardware Proble output line!! line: %s\n", + hw_probe_output_line)); + rc = NO; + goto cleanup; + } + + if(get_slot_from_str(hw_probe_output_line, &PCI_slot_no) == NO){ + ERR_DBG_OUT(("Failed to get 'PCI_slot_no' from line: %s!\n", + hw_probe_output_line)); + return NO; + } + + if(get_bus_from_str(hw_probe_output_line, &pci_bus_no) == NO){ + ERR_DBG_OUT(("Failed to get 'pci_bus_no' from line: %s!\n", + hw_probe_output_line)); + return NO; + } + + //ADSL card always have only one CPU. But check anyway + if(get_cpu_from_str(hw_probe_output_line, S514_CPU_no) == NO){ + ERR_DBG_OUT(("Failed to get 'S514_CPU_no' from line: %s!\n", + hw_probe_output_line)); + return NO; + } + + Debug(DBG_CARD_LIST, ("%s(): adding card_type: %d, card_version: %d\n\ +line_no: %d, PCI_slot_no: %d, pci_bus_no: %d, CPU: %c\n", + __FUNCTION__, card_type, card_version, line_no, PCI_slot_no, pci_bus_no, + S514_CPU_no[0])); + + sangoma_card = new list_element_sangoma_card( card_type, card_version, + line_no, PCI_slot_no, pci_bus_no, + S514_CPU_no[0], card_sub_version); + + if((last_in_list_card = (list_element_sangoma_card*)sang_card_list->get_last()) == NULL){ + key = 1; + }else{ + key = last_in_list_card->get_key() + 1; + } + + sangoma_card->set_key(key); + + sang_card_list->insert((list_element*)sangoma_card); + +cleanup: + + return rc; +} +#endif + diff --git a/util/wancfg/.zaptel_conf_file_reader.cpp.swp b/util/wancfg/.zaptel_conf_file_reader.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..46457003e2a1808b9bbc1d246329e2b8a8888034 GIT binary patch literal 16384 zcmeI2O^h7H701gYK-w4xB*#QN&kB2XwVs(>$BE>%4a0t6X?IxJUJSdoS~cC(Gp+6J z8mfABcGp@C4u?oNqaYzZd;p092k;pV=1Wlo1i=L*65^Cxa*QHkC*)r*ss61F#YYlf86!nKE{-ksVTl)N`;R2 z?HZx}dE>C?i**snMl6!+k6S!xgbm?(GLB_ZL^hQ&(&oSmYQ-(yNJWI&ByfW;60Q>5 z7pmYj8hvzan^*;`0?c6tCnriHxxMt0hnKA$RspMkRlq7>6|f3e1*`&A0jt3OnF49U zVc%oScY!ltSH|~9Z{hfCmj5^M=W%=w8kjc!LO#alZ?gOq0jq#jz$#!BunJfOtO8a6tAJI&Dqt13 zLke)8v7f@%OXeXRzyF&(fQt_@7K0<;A@Jn`jJ*cdz|Xn;@24COH*qcCu$H5-(^*xNe0iFX>;BN5w z-54XNffBg#L&iPx=_q5{ zQ_KmIl=3&ddyNIS@r>p%%N32SiOrT&{y25AT-Ed_JX}{fbz_g`aO>{Gu$8)IwPfLW z-s;LJcd`78JN;z2Qkh*id3K7SPN$iB9oGI!3lpx6!bBu;XRT8lqXpDa(u}JZZL2Pn zAUH~R1e+S^hVa556h4g=d*jM(7_O0zwtT%>SzdH!o~@J@k54145!@S$+n!QqqBQx7 zo{^c5vXMnsM|N_lTrtC9Ch8!>t-sxaq@#3TA}g*%vdSaZ+*Xbf6j>;rb{CiNe~J~0 zVM?JUu5~j;%xRscRK{3jjqs9Y=m|}@q@o;yXW*-Iel^JN;B;&Ye5HFq=7X(1wkO#18{}L|U*B3KK7C`ht#h=5(QcjE#f= z^fG7A&%5rz@yhZut~(0LZrhwWbDft~TPjTP(rP`|Q+t!uaebrCTd<~#4KLPCeT(o$ zcPfo_oaHf%Hf2+hY^0$~Mu{hzm^&CZtqY}5ROq9}%$b>db4mz0DTB1dvEJtJW!2}# z^Aw2?^;g}}B*~yXT^BHU6D`I`s&-eIGt76`!oYY%JhAQ?%vY9aUL->Ch?bhwDD<$> z+di;7s9{QU9c!ezNt8J|Rma+CC|OfHHp?h5QR*zpDWd>+Snf*TD|)KJYBLpt0C1%& zBC1$oR$X(}hai148DrVn+IgafD7n)!&2b!zVOnDKR5`w?kxb0rR*KiV3m){7F|D-U z@}>s&)_6@6SjVO)E+CStN%J<5II8 z`gB6B)z@)%p(DP@tH(7@YBJ^pym@|%nYL9?3lnqDn-0@y#9WcPEU%>m|9q=}| z0A2?#fEw_@X|N0)1INHYFaeCeBCyFSU=^?mSOu&CRspMkRlq7>6|f3e1*`)9lL~Az zM~Sql60`BioQA^YYmm>);CIKundD58Gkey|3A{*Zk@o_Vh0WE5M`jc3d;~Oyy^3R5 zb8H~yI~%0?sCO506uaBbcCpy1qj7!|UW})1|JdS11{comm_port = WANOPT_PRI; linkconf->auto_pci_cfg = WANOPT_YES; //serial config - linkconf->interface = WANOPT_V35; + linkconf->electrical_interface = WANOPT_V35; //front end config fe_cfg = &linkconf->fe_cfg; @@ -1078,27 +1085,36 @@ int conf_file_reader::read_conf_file() if (err){ return err; } -/////////////////////////////////////////////////////// - #if DBG_FLAG + + ///////////////////////////////////////////////////////////////////////////////////////////// sdla_fe_cfg_t* fe_cfg = &link_defs->linkconf->fe_cfg; //sdla_te_cfg_t* te_cfg = &fe_cfg->cfg.te_cfg; +#if DBG_FLAG sdla_te3_cfg_t* te3_cfg= &fe_cfg->cfg.te3_cfg; - #endif - - Debug(DBG_CONF_FILE_READER, ("%s(): fe_cfg->media: %d\n",__FUNCTION__, - fe_cfg->media)); +#endif + + switch(link_defs->card_version) + { + case AFT_ADPTR_2SERIAL_V35X21: /* AFT (shark) Serial card */ + fe_cfg->media = WAN_MEDIA_SERIAL; + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + Debug(DBG_CONF_FILE_READER, ("%s(): fe_cfg->media: 0x%x\n",__FUNCTION__, + fe_cfg->media)); Debug(DBG_CONF_FILE_READER, ("%s(): fe_cfg->line_no: %d\n",__FUNCTION__, - fe_cfg->line_no)); + fe_cfg->line_no)); Debug(DBG_CONF_FILE_READER, ("%s(): te3_cfg->fcs: %d\n",__FUNCTION__, - te3_cfg->fcs)); + te3_cfg->fcs)); Debug(DBG_CONF_FILE_READER, ("%s(): te3_cfg->liu_cfg.rx_equal: %d\n",__FUNCTION__, - te3_cfg->liu_cfg.rx_equal)); + te3_cfg->liu_cfg.rx_equal)); Debug(DBG_CONF_FILE_READER, ("%s(): te3_cfg->liu_cfg.taos: %d\n",__FUNCTION__, - te3_cfg->liu_cfg.taos)); + te3_cfg->liu_cfg.taos)); ///////////////////////////////////////////////////////////////////////////////////////////// //if S514X card, get the version (S514-1/2/3...7) @@ -1139,7 +1155,7 @@ int conf_file_reader::read_conf_file() break; }//switch(adsl_cfg->EncapMode) }//if() - + ///////////////////////////////////////////////////////////////////////////////////////////// int current_line_number = 0; err = read_interfaces_section( @@ -1236,8 +1252,19 @@ int conf_file_reader::read_devices_section(FILE* file) link_defs->linkconf->config_id = WANCONFIG_AFT;//WANCONFIG_AFT_56K; link_defs->card_version = AFT_ADPTR_56K; break; + + case WANCONFIG_AFT_ISDN_BRI: /* AFT (shark) ISDN BRI card */ + link_defs->linkconf->config_id = WANCONFIG_AFT; + link_defs->card_version = AFT_ADPTR_ISDN; + break; + + case WANCONFIG_AFT_SERIAL: /* AFT (shark) Serial card */ + link_defs->linkconf->config_id = WANCONFIG_AFT; + link_defs->card_version = AFT_ADPTR_2SERIAL_V35X21;//this will indicate "Serial" card, number of ports is not important. + break; } + Debug(DBG_CONF_FILE_READER, ("Updated link_defs->linkconf->config_id: %d\n", link_defs->linkconf->config_id)); @@ -1308,11 +1335,13 @@ int conf_file_reader::read_wanpipe_section(FILE* file) */ strupcase(token[0]); //common key value - err = set_conf_param(token[0], token[1], common_conftab, link_defs->linkconf, link_defs, NULL); + err = set_conf_param(token[0], token[1], + common_conftab, link_defs->linkconf, sizeof(wandev_conf_t),link_defs, NULL); // 'config_id' specific if ((err < 0) && (conf_table != NULL)){ - err = set_conf_param(token[0], token[1], conf_table, &link_defs->linkconf->u, link_defs, NULL); + err = set_conf_param(token[0], token[1], + conf_table, &link_defs->linkconf->u, sizeof(link_defs->linkconf->u), link_defs, NULL); } if(err < 0) { @@ -1342,14 +1371,14 @@ char* conf_file_reader::read_conf_section (FILE* file, char* section) { char key[MAX_CFGLINE]; /* key buffer */ char* buf = NULL; - int found = 0, offs = 0, len; + int found = 0, offs = 0, len, buf_len = 0; int dbg_len = 0; Debug(DBG_CONF_FILE_READER, ("conf_file_reader::read_conf_section ():%s\n", section)); rewind(file); - while ((len = read_conf_record(file, key)) > 0) { + while ((len = read_conf_record(file, key, MAX_CFGLINE)) > 0) { char* tmp; dbg_len += len; @@ -1361,14 +1390,16 @@ char* conf_file_reader::read_conf_section (FILE* file, char* section) } if (buf){ + buf_len = offs+len+1; tmp = (char*)realloc(buf, offs + len + 1); }else{ tmp = (char*)malloc(len + 1); + buf_len = len+1; } if (tmp) { buf = tmp; - strcpy(&buf[offs], key); + strlcpy(&buf[offs], key, buf_len-offs); offs += len; buf[offs] = '\0'; }else{ @@ -1422,7 +1453,7 @@ char* conf_file_reader::read_conf_section (FILE* file, char* section) * Return string length (incl. terminating zero) or 0 if end of file has been * reached. */ -int conf_file_reader::read_conf_record (FILE* file, char* key) +int conf_file_reader::read_conf_record (FILE* file, char* key, int max_len) { char buf[MAX_CFGLINE]; /* line buffer */ @@ -1445,7 +1476,7 @@ int conf_file_reader::read_conf_record (FILE* file, char* key) //Debug(DBG_CONF_FILE_READER, ("read_conf_record():str: %s\n", str)); - strcpy(key, str); + strlcpy(key, str, max_len); return len + 1; } } @@ -1652,7 +1683,7 @@ int conf_file_reader::read_interfaces_section( if(toknum == 6){ if(strcmp(token[4],"tty") == 0){ - strcpy(chandef->addr, token[2]); + strlcpy(chandef->addr, token[2], MAX_ADDR_STR_LEN); } } //print 'addr' after all the updates @@ -1676,8 +1707,10 @@ int conf_file_reader::read_interfaces_section( case BRIDGE_NODE: //case ANNEXG: case TDM_VOICE: + case TDM_VOICE_API: case TTY: case PPPoE: + case WP_NETGRAPH: //do nothing special break; @@ -1812,8 +1845,8 @@ int conf_file_reader::read_interfaces_section( * 1 - error * -1 - not found */ -int conf_file_reader::set_conf_param (char* key, char* val, key_word_t* dtab, void* conf, link_def_t* lnks_def, - chan_def_t* chan_def) +int conf_file_reader::set_conf_param (char* key, char* val, key_word_t* dtab, + void* conf, int size, link_def_t* lnks_def, chan_def_t* chan_def) { unsigned int tmp = 0; @@ -1846,7 +1879,7 @@ int conf_file_reader::set_conf_param (char* key, char* val, key_word_t* dtab, vo } if (dtab->dtype == DTYPE_STR) { - strcpy((char*)conf + dtab->offset, val); + strlcpy((char*)conf + dtab->offset, val, size-dtab->offset); return 0; } @@ -2037,9 +2070,13 @@ int conf_file_reader::configure_chan (chan_def_t* chandef, int id) chandef->chanconf->config_id)); if(chandef->usedby == TDM_VOICE){ - Debug(DBG_CONF_FILE_READER, ("VOICE channel!!\n")); + Debug(DBG_CONF_FILE_READER, ("TDM_VOICE channel!!\n")); chandef->chanconf->config_id = PROTOCOL_TDM_VOICE; } + if(chandef->usedby == TDM_VOICE_API){ + Debug(DBG_CONF_FILE_READER, ("TDM_VOICE_API channel!!\n")); + chandef->chanconf->config_id = PROTOCOL_TDM_VOICE_API; + } Debug(DBG_CONF_FILE_READER, ("Final 'chandef->chanconf->config_id': %d.\n", chandef->chanconf->config_id)); @@ -2195,15 +2232,15 @@ int conf_file_reader::configure_chan (chan_def_t* chandef, int id) // Look up a keyword first in common, then media-specific // configuration definition tables. strupcase(token[0]); - if (set_conf_param(token[0], token[1], chan_conftab, chandef->chanconf, NULL, chandef)) { + if (set_conf_param(token[0], token[1], chan_conftab, chandef->chanconf, sizeof(wanif_conf_t), NULL, chandef)) { if (!conf_table || - set_conf_param(token[0], token[1], conf_table, &chandef->chanconf->u, NULL, chandef)) { + set_conf_param(token[0], token[1], conf_table, &chandef->chanconf->u, sizeof(chandef->chanconf->u), NULL, chandef)) { if(id == WANCONFIG_ADSL && link_defs->sub_config_id == WANCONFIG_MPPP){ //on ADSL there can be PPP without the LIP layer!! - if(set_conf_param(token[0], token[1], sppp_conftab, &chandef->chanconf->u.ppp, - NULL, chandef)) { + if(set_conf_param(token[0], token[1], + sppp_conftab, &chandef->chanconf->u.ppp,sizeof(wan_sppp_if_conf_t),NULL, chandef)) { ERR_DBG_OUT(("Invalid parameter %s\n", token[0])); return ERR_CONFIG; }//if() @@ -2231,9 +2268,13 @@ Nov 21, 2006 - not done anymore - all configuration is in profile chandef->chanconf->config_id)); if(chandef->usedby == TDM_VOICE){ - Debug(DBG_CONF_FILE_READER, ("VOICE channel!!\n")); + Debug(DBG_CONF_FILE_READER, ("2. TDM_VOICE channel!!\n")); chandef->chanconf->config_id = PROTOCOL_TDM_VOICE; } + if(chandef->usedby == TDM_VOICE_API){ + Debug(DBG_CONF_FILE_READER, ("2. TDM_VOICE_API channel!!\n")); + chandef->chanconf->config_id = PROTOCOL_TDM_VOICE_API; + } Debug(DBG_CONF_FILE_READER, ("Final 'chandef->chanconf->config_id': %d.\n", chandef->chanconf->config_id)); @@ -2242,7 +2283,7 @@ Nov 21, 2006 - not done anymore - all configuration is in profile }//if(chandef->conf) else - { Debug(DBG_CONF_FILE_READER, ("chandef->conf == NULL!!\n")); + { Debug(DBG_CONF_FILE_READER, ("chandef->conf == NULL!!\n")); } //if there is anything in [profile] section, get it @@ -2273,8 +2314,8 @@ Nov 21, 2006 - not done anymore - all configuration is in profile case WANCONFIG_MFR: Debug(DBG_CONF_FILE_READER_AFT, ("WANCONFIG_MFR\n")); - if(set_conf_param(token[0], token[1], fr_conftab, &chandef->chanconf->u.fr, - NULL, chandef)) { + if(set_conf_param(token[0], token[1], + fr_conftab, &chandef->chanconf->u.fr, sizeof(wan_fr_conf_t),NULL, chandef)) { ERR_DBG_OUT(("Invalid parameter %s\n", token[0])); return ERR_CONFIG; }//if() @@ -2296,8 +2337,8 @@ Nov 21, 2006 - not done anymore - all configuration is in profile Debug(DBG_CONF_FILE_READER_AFT, ("token[0]: %s\n", token[0])); Debug(DBG_CONF_FILE_READER_AFT, ("token[1]: %s\n", token[1])); - if(set_conf_param(token[0], token[1], sppp_conftab, &chandef->chanconf->u.ppp, - NULL, chandef)) { + if(set_conf_param(token[0], token[1], + sppp_conftab, &chandef->chanconf->u.ppp,sizeof(wan_sppp_if_conf_t),NULL, chandef)) { ERR_DBG_OUT(("Invalid parameter %s\n", token[0])); return ERR_CONFIG; }//if() @@ -2313,8 +2354,8 @@ Nov 21, 2006 - not done anymore - all configuration is in profile Debug(DBG_CONF_FILE_READER_AFT, ("token[0]: %s\n", token[0])); Debug(DBG_CONF_FILE_READER_AFT, ("token[1]: %s\n", token[1])); - if(set_conf_param(token[0], token[1], sppp_conftab, &chandef->chanconf->u.ppp, - NULL, chandef)) { + if(set_conf_param(token[0], token[1], + sppp_conftab, &chandef->chanconf->u.ppp,sizeof(wan_sppp_if_conf_t), NULL, chandef)) { ERR_DBG_OUT(("Invalid parameter %s\n", token[0])); return ERR_CONFIG; }//if() @@ -2326,8 +2367,8 @@ Nov 21, 2006 - not done anymore - all configuration is in profile Debug(DBG_CONF_FILE_READER_AFT, ("token[0]: %s\n", token[0])); Debug(DBG_CONF_FILE_READER_AFT, ("token[1]: %s\n", token[1])); - if(set_conf_param(token[0], token[1], lapb_annexg_conftab, &chandef->chanconf->u.lapb, - NULL, chandef)) { + if(set_conf_param(token[0], token[1], + lapb_annexg_conftab, &chandef->chanconf->u.lapb,sizeof(wan_lapb_if_conf_t), NULL, chandef)) { ERR_DBG_OUT(("Invalid parameter %s\n", token[0])); return ERR_CONFIG; }//if() diff --git a/util/wancfg/conf_file_reader.h b/util/wancfg/conf_file_reader.h index fcc6e9c..11d38a1 100644 --- a/util/wancfg/conf_file_reader.h +++ b/util/wancfg/conf_file_reader.h @@ -129,10 +129,10 @@ class conf_file_reader { int parse_conf_file(char* fname); - int read_conf_record (FILE* file, char* key); + int read_conf_record (FILE* file, char* key, int max_len); char* read_conf_section (FILE* file, char* section); - int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf, link_def_t* lnk_def, + int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf, int size, link_def_t* lnk_def, chan_def_t* chan_def); int read_devices_section(FILE* file); diff --git a/util/wancfg/conf_file_writer.cpp b/util/wancfg/conf_file_writer.cpp index 06e27bc..dc5541a 100644 --- a/util/wancfg/conf_file_writer.cpp +++ b/util/wancfg/conf_file_writer.cpp @@ -66,10 +66,11 @@ look_up_t physical_medium_options_table[] = { WAN_MEDIA_T1, (void*)"T1" }, { WAN_MEDIA_E1, (void*)"E1" }, { WAN_MEDIA_56K, (void*)"56K" }, - { WAN_MEDIA_DS3, (void*)"DS3" }, - { WAN_MEDIA_E3, (void*)"E3" }, - { WAN_MEDIA_FXOFXS, (void*)"FXO/FXS"}, - { 0, NULL } + { WAN_MEDIA_DS3, (void*)"DS3" }, + { WAN_MEDIA_E3, (void*)"E3" }, + { WAN_MEDIA_FXOFXS, (void*)"FXO/FXS"}, + { WAN_MEDIA_BRI, (void*)"BRI" }, + { 0, NULL } }; look_up_t te1_line_code_options_table[] = @@ -572,6 +573,28 @@ get_keyword_from_look_up_t_table(config_id_str, WANCONFIG_AFT_56K),//for A056 cfr->link_defs->name, get_keyword_from_look_up_t_table(config_id_str, WANCONFIG_AFT_ANALOG),//for AFT Analog card (cfr->link_defs->descr == NULL ? "Comment" : cfr->link_defs->descr) +); + break; + + case AFT_ADPTR_ISDN: + snprintf(tmp_buff, MAX_PATH_LENGTH, +"\n\ +[devices]\n\ +%s = %s, %s\n", +cfr->link_defs->name, +get_keyword_from_look_up_t_table(config_id_str, WANCONFIG_AFT_ISDN_BRI),//for AFT BRI card +(cfr->link_defs->descr == NULL ? "Comment" : cfr->link_defs->descr) +); + break; + + case AFT_ADPTR_2SERIAL_V35X21: + snprintf(tmp_buff, MAX_PATH_LENGTH, +"\n\ +[devices]\n\ +%s = %s, %s\n", +cfr->link_defs->name, +get_keyword_from_look_up_t_table(config_id_str, WANCONFIG_AFT_SERIAL),//for AFT Serial card +(cfr->link_defs->descr == NULL ? "Comment" : cfr->link_defs->descr) ); break; @@ -783,6 +806,7 @@ int conf_file_writer::form_interface_str(string& interfaces_section_str, case WANCONFIG_HDLC: case WANCONFIG_EDUKIT: case PROTOCOL_TDM_VOICE: + case PROTOCOL_TDM_VOICE_API: case WANCONFIG_AFT: //if TTY, config_id is set to 'WANCONFIG_AFT' //because 'PROTOCOL' is expected (by the driver) to be set to 'NONE' //wp1edu = wanpipe1, , WANPIPE, Comment @@ -1344,11 +1368,12 @@ LBO = 0DB //write stuff needed for cards with an integrated dsu/csu int conf_file_writer::form_fe_card_cfg_str(string& te1_cfg_string, sdla_fe_cfg_t* fe_cfg) { - char tmp_buff[MAX_PATH_LENGTH]; + char tmp_buff[MAX_PATH_LENGTH]; sdla_te_cfg_t* te_cfg = &fe_cfg->cfg.te_cfg; sdla_te3_cfg_t* te3_cfg= &fe_cfg->cfg.te3_cfg; - Debug(DBG_CONF_FILE_WRITER, ("form_fe_card_cfg_str()\n")); + Debug(DBG_CONF_FILE_WRITER, ("%s()\n", __FUNCTION__)); + Debug(DBG_CONF_FILE_WRITER, ("fe_cfg->media: 0x%x\n", fe_cfg->media)); switch(fe_cfg->media) { @@ -1358,11 +1383,15 @@ int conf_file_writer::form_fe_card_cfg_str(string& te1_cfg_string, sdla_fe_cfg_t case WAN_MEDIA_E3: case WAN_MEDIA_56K: case WAN_MEDIA_FXOFXS: + case WAN_MEDIA_BRI: snprintf(tmp_buff, MAX_PATH_LENGTH, "FE_MEDIA = %s\n", get_keyword_from_look_up_t_table( physical_medium_options_table, fe_cfg->media)); te1_cfg_string = tmp_buff; break; + case WAN_MEDIA_SERIAL: + ;//do nothing + break; } ///////////////////////////////////////////////////////////////////////////////// @@ -1382,6 +1411,9 @@ int conf_file_writer::form_fe_card_cfg_str(string& te1_cfg_string, sdla_fe_cfg_t fe_cfg->frame)); te1_cfg_string += tmp_buff; break; + case WAN_MEDIA_SERIAL: + ;//do nothing + break; } ///////////////////////////////////////////////////////////////////////////////// @@ -1419,7 +1451,16 @@ int conf_file_writer::form_fe_card_cfg_str(string& te1_cfg_string, sdla_fe_cfg_t (te_cfg->high_impedance_mode == WANOPT_YES ? "YES" : "NO")); te1_cfg_string += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, "TE_RX_SLEVEL = %i\n", te_cfg->rx_slevel); + te1_cfg_string += tmp_buff; + break; + + case WAN_MEDIA_BRI: + case WAN_MEDIA_SERIAL: + snprintf(tmp_buff, MAX_PATH_LENGTH, "FE_LINE = %d\n", fe_cfg->line_no); + te1_cfg_string += tmp_buff; + break; } ///////////////////////////////////////////////////////////////////////////////// @@ -1552,12 +1593,31 @@ TE3_TXLBO = NO # NO (default) / YES fe_cfg->cfg.remora.battthresh); te1_cfg_string += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, "RM_BATTDEBOUNCE= %d\n", + snprintf(tmp_buff, MAX_PATH_LENGTH, "RM_BATTDEBOUNCE = %d\n", fe_cfg->cfg.remora.battdebounce); te1_cfg_string += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, "RM_NETWORK_SYNC = %s\n", + fe_cfg->cfg.remora.network_sync == WANOPT_YES ? "YES" : "NO"); + te1_cfg_string += tmp_buff; + break; + case WAN_MEDIA_BRI: + snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_LAW = %s\n", + get_keyword_from_look_up_t_table( tdmv_law_options_table, + fe_cfg->tdmv_law)); + te1_cfg_string += tmp_buff; + + snprintf(tmp_buff, MAX_PATH_LENGTH, "RM_BRI_CLOCK_MASTER = %s\n", + (fe_cfg->cfg.bri.clock_mode == WANOPT_YES ? "YES":"NO")); + te1_cfg_string += tmp_buff; + break; + + case WAN_MEDIA_SERIAL: + ;//do nothing + break; + default: snprintf(tmp_buff, MAX_PATH_LENGTH, "FE_TXTRISTATE = %s\n", (fe_cfg->tx_tristate_mode == WANOPT_YES ? "YES" : "NO")); @@ -1582,11 +1642,13 @@ int conf_file_writer::form_wanpipe_card_miscellaneous_options_str(string& misc_o char tmp_buff[MAX_PATH_LENGTH]; wan_xilinx_conf_t *wan_xilinx_conf; wan_tdmv_conf_t *tdmv_conf; + wandev_conf_t *linkconf; Debug(DBG_CONF_FILE_WRITER, ("form_wanpipe_card_miscellaneous_options_str()\n")); wan_xilinx_conf = &cfr->link_defs->linkconf->u.aft; tdmv_conf = &cfr->link_defs->linkconf->tdmv_conf; + linkconf = cfr->link_defs->linkconf; switch(cfr->link_defs->linkconf->card_type) { @@ -1618,17 +1680,21 @@ int conf_file_writer::form_wanpipe_card_miscellaneous_options_str(string& misc_o cfr->link_defs->linkconf->card_type != WANOPT_AFT){ misc_opt_string += form_keyword_and_value_str( common_conftab, - offsetof(wandev_conf_t, interface), + offsetof(wandev_conf_t, electrical_interface), serial_interface_type_options_table, - cfr->link_defs->linkconf->interface); + cfr->link_defs->linkconf->electrical_interface); misc_opt_string += form_keyword_and_value_str( common_conftab, offsetof(wandev_conf_t, clocking), serial_clock_type_options_table, cfr->link_defs->linkconf->clocking); - snprintf(tmp_buff, MAX_PATH_LENGTH, "BaudRate = %d\n", - cfr->link_defs->linkconf->bps); + if(cfr->link_defs->linkconf->clocking == WANOPT_INTERNAL && + cfr->link_defs->linkconf->bps == 0){ + //zero baud rate not allowed with internal clock, set to default. + cfr->link_defs->linkconf->bps = 9600; + } + snprintf(tmp_buff, MAX_PATH_LENGTH, "BaudRate = %d\n", cfr->link_defs->linkconf->bps); misc_opt_string += tmp_buff; } @@ -1657,6 +1723,7 @@ int conf_file_writer::form_wanpipe_card_miscellaneous_options_str(string& misc_o cfr->link_defs->linkconf->card_type != WANOPT_S50X && cfr->link_defs->linkconf->card_type != WANOPT_S51X && cfr->link_defs->card_version != A200_ADPTR_ANALOG && + cfr->link_defs->card_version != AFT_ADPTR_ISDN && is_there_a_voice_if == YES){ snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_SPAN\t= %u\n", @@ -1678,10 +1745,22 @@ int conf_file_writer::form_wanpipe_card_miscellaneous_options_str(string& misc_o //} } + if(cfr->link_defs->linkconf->card_type == WANOPT_AFT && - ( cfr->link_defs->card_version == A104_ADPTR_4TE1 || - cfr->link_defs->card_version == A101_ADPTR_1TE1 || - cfr->link_defs->card_version == A200_ADPTR_ANALOG)){ + cfr->link_defs->card_version == AFT_ADPTR_ISDN){ + if(is_there_a_voice_if == YES){ + snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_SPAN\t= %u\n", + tdmv_conf->span_no); + misc_opt_string += tmp_buff; + } + } + + if(cfr->link_defs->linkconf->card_type == WANOPT_AFT && + (cfr->link_defs->card_version == A104_ADPTR_4TE1 || + cfr->link_defs->card_version == A101_ADPTR_1TE1 || + cfr->link_defs->card_version == A200_ADPTR_ANALOG || + cfr->link_defs->card_version == AFT_ADPTR_ISDN || + cfr->link_defs->card_version == AFT_ADPTR_2SERIAL_V35X21)){ /* //moved to per-interface section snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_HWEC\t= %s\n", @@ -1699,6 +1778,46 @@ int conf_file_writer::form_wanpipe_card_miscellaneous_options_str(string& misc_o */ } + if(cfr->link_defs->card_version != AFT_ADPTR_2SERIAL_V35X21){ + if(cfr->link_defs->linkconf->card_type == WANOPT_AFT){ + snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_HW_DTMF\t= %s\n", + get_keyword_from_look_up_t_table(yes_no_options_table, + tdmv_conf->hw_dtmf)); + misc_opt_string += tmp_buff; + } + } + + if(cfr->link_defs->card_version == AFT_ADPTR_2SERIAL_V35X21){ + + misc_opt_string += form_keyword_and_value_str( common_conftab, + offsetof(wandev_conf_t, connection), + connection_type_options_table, + cfr->link_defs->linkconf->connection); + + misc_opt_string += form_keyword_and_value_str( common_conftab, + offsetof(wandev_conf_t, line_coding), + data_encoding_options_table, + cfr->link_defs->linkconf->line_coding); + + misc_opt_string += form_keyword_and_value_str( common_conftab, + offsetof(wandev_conf_t, line_idle), + line_idle_options_table, + cfr->link_defs->linkconf->line_idle); + + misc_opt_string += form_keyword_and_value_str( common_conftab, + offsetof(wandev_conf_t, clocking), + serial_clock_type_options_table, + cfr->link_defs->linkconf->clocking); + + if( cfr->link_defs->linkconf->clocking == WANOPT_INTERNAL && + cfr->link_defs->linkconf->bps == 0){ + //zero baud rate not allowed with internal clock, set to default. + cfr->link_defs->linkconf->bps = 9600; + } + snprintf(tmp_buff, MAX_PATH_LENGTH, "BaudRate = %d\n", cfr->link_defs->linkconf->bps); + misc_opt_string += tmp_buff; + } + return YES; } @@ -2161,7 +2280,7 @@ int conf_file_writer::form_per_interface_str( string& wp_interface, interface_type = config_id; //} - if(interface_type == PROTOCOL_TDM_VOICE){ + if(interface_type == PROTOCOL_TDM_VOICE || interface_type == PROTOCOL_TDM_VOICE_API){ interface_type = WANCONFIG_HDLC; } @@ -2625,7 +2744,8 @@ int conf_file_writer::form_hardware_interface_str(string& wp_interface, if(cfr->link_defs->linkconf->card_type != WANOPT_ADSL && chandef->usedby != TDM_VOICE && - chandef->usedby != TDM_API){ + chandef->usedby != TDM_API && + chandef->usedby != TDM_VOICE_API){ wp_interface += form_keyword_and_value_str( chan_conftab, offsetof(wanif_conf_t, hdlc_streaming), @@ -2633,7 +2753,7 @@ int conf_file_writer::form_hardware_interface_str(string& wp_interface, list_el_chan_def->data.chanconf->hdlc_streaming); } - //AFT onlu options: + //AFT only options: if(cfr->link_defs->linkconf->card_type != WANOPT_S51X && cfr->link_defs->linkconf->card_type != WANOPT_S50X && cfr->link_defs->linkconf->card_type != WANOPT_ADSL ){ @@ -2644,7 +2764,7 @@ int conf_file_writer::form_hardware_interface_str(string& wp_interface, wp_interface += list_el_chan_def->data.active_channels_string; wp_interface += "\n"; - if(chandef->usedby != TDM_VOICE && chandef->usedby != TDM_API){ + if(chandef->usedby != TDM_VOICE && chandef->usedby != TDM_API && chandef->usedby != TDM_VOICE_API){ if(list_el_chan_def->data.chanconf->hdlc_streaming == WANOPT_NO){ wp_interface += "IDLE_FLAG", @@ -2671,7 +2791,8 @@ int conf_file_writer::form_hardware_interface_str(string& wp_interface, wp_interface += tmp_buff; wp_interface += "\n"; - if(cfr->link_defs->card_version != A200_ADPTR_ANALOG){ + if( cfr->link_defs->card_version != A200_ADPTR_ANALOG && + cfr->link_defs->card_version != AFT_ADPTR_2SERIAL_V35X21){ wp_interface += "DATA_MUX"; wp_interface += "\t= "; snprintf(tmp_buff, MAX_PATH_LENGTH, "%s", @@ -2682,7 +2803,7 @@ int conf_file_writer::form_hardware_interface_str(string& wp_interface, } } - if(chandef->usedby == TDM_VOICE){ + if(chandef->usedby == TDM_VOICE || chandef->usedby == TDM_VOICE_API){ wp_interface += "TDMV_ECHO_OFF"; wp_interface += "\t= "; @@ -2693,21 +2814,24 @@ int conf_file_writer::form_hardware_interface_str(string& wp_interface, wp_interface += "\n"; } - //YATE is running in API mode, and may need HWEC, make it possible. - if(chandef->usedby == TDM_VOICE || chandef->usedby == TDM_API || chandef->usedby == API){ - snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_HWEC\t= %s\n", - get_keyword_from_look_up_t_table(yes_no_options_table, - chandef->chanconf->hwec.enable)); //chandef->chanconf->xoff_char)); - wp_interface += tmp_buff; + if(cfr->link_defs->card_version != AFT_ADPTR_2SERIAL_V35X21){ + //YATE is running in API mode, and may need HWEC, make it possible. + if( chandef->usedby == TDM_VOICE || chandef->usedby == TDM_API || + chandef->usedby == API || chandef->usedby == TDM_VOICE_API){ + + snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_HWEC\t= %s\n", + get_keyword_from_look_up_t_table(yes_no_options_table, + chandef->chanconf->hwec.enable)); //chandef->chanconf->xoff_char)); + wp_interface += tmp_buff; /* - if(chandef->hwec_flag == WANOPT_YES){ - snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_HWEC_MAP\t= %s\n", - chandef->active_hwec_channels_string); - wp_interface += tmp_buff; - } + if(chandef->hwec_flag == WANOPT_YES){ + snprintf(tmp_buff, MAX_PATH_LENGTH, "TDMV_HWEC_MAP\t= %s\n", + chandef->active_hwec_channels_string); + wp_interface += tmp_buff; + } */ + } } - }else{ /* //HDLC streamin runs on CHDLC firmware diff --git a/util/wancfg/cpp_string.cpp b/util/wancfg/cpp_string.cpp index f656cf6..b4f9b79 100644 --- a/util/wancfg/cpp_string.cpp +++ b/util/wancfg/cpp_string.cpp @@ -55,7 +55,7 @@ void cpp_string::operator= (char* param) char tmp[MAX_STR]; snprintf(tmp, MAX_STR, param); - strcpy(cstr, tmp); + strlcpy(cstr, tmp, MAX_STR); Debug(DBG_CPP_STR, ("end of 'operator=' cstr: %s\n", cstr)); } diff --git a/util/wancfg/input_box_number_of_logical_channels.cpp b/util/wancfg/input_box_number_of_logical_channels.cpp index da4ca44..c0a0356 100644 --- a/util/wancfg/input_box_number_of_logical_channels.cpp +++ b/util/wancfg/input_box_number_of_logical_channels.cpp @@ -59,6 +59,10 @@ int input_box_number_of_logical_channels::show( IN char * lxdialog_path, max_valid_number_of_channels = MAX_FXOFXS_CHANNELS; } + if(link_defs->card_version == AFT_ADPTR_ISDN){ + max_valid_number_of_channels = MAX_BRI_TIMESLOTS; + } + snprintf(backtitle, MAX_PATH_LENGTH, "WANPIPE Configuration Utility "); // snprintf(&backtitle[strlen(backtitle)], MAX_PATH_LENGTH, // "%s Setup", get_protocol_string(protocol)); @@ -100,6 +104,12 @@ again: "Invalid number of Channels. Minimum: 1, Max: %d.", MAX_FXOFXS_CHANNELS); goto again; + }else if(link_defs->card_version == AFT_ADPTR_ISDN){ + + tb.show_error_message(lxdialog_path, WANCONFIG_AFT, +"Invalid number of Channels. Minimum: 1, Max: %d.", MAX_BRI_TIMESLOTS); + goto again; + }else{ tb.show_error_message(lxdialog_path, WANCONFIG_AFT, "Invalid number of %s.\n\ diff --git a/util/wancfg/list_element.h b/util/wancfg/list_element.h index 937a6f7..124d5e7 100644 --- a/util/wancfg/list_element.h +++ b/util/wancfg/list_element.h @@ -48,7 +48,7 @@ public: //must be set to real value in the subclasses list_element_type = BASE_LIST_ELEMENT; } - virtual ~list_element() { } + virtual ~list_element() {} /* //no real work is done here. comment it out to reduce number of warnings diff --git a/util/wancfg/list_element_chan_def.h b/util/wancfg/list_element_chan_def.h index 08f5bb6..a2160b5 100644 --- a/util/wancfg/list_element_chan_def.h +++ b/util/wancfg/list_element_chan_def.h @@ -52,7 +52,7 @@ public: Debug(DBG_LIST_ELEMENT_CHAN_DEF, ("list_element_chan_def::list_element_chan_def()\n")); memset(&data, 0x00, sizeof(data)); - strcpy(data.name, CHAN_NOT_CONFIGURED); + strlcpy(data.name, CHAN_NOT_CONFIGURED, WAN_IFNAME_SZ); list_element_type = CHAN_DEF_LIST_ELEMENT; @@ -93,10 +93,17 @@ public: //FIXME: David to set active_ch to ALL for VOICE and 1 for API // For now 99% is VOICE which should have ALL set - if(global_card_type == WANOPT_AFT && - (global_card_version == A200_ADPTR_ANALOG||global_card_version == A400_ADPTR_ANALOG)){ - snprintf(data.active_channels_string, MAX_LEN_OF_ACTIVE_CHANNELS_STRING, "ALL"); - data.chanconf->active_ch = ENABLE_ALL_CHANNELS; + if( global_card_type == WANOPT_AFT){ + if( global_card_version == A200_ADPTR_ANALOG || + global_card_version == A400_ADPTR_ANALOG || + global_card_version == AFT_ADPTR_ISDN){ + + snprintf(data.active_channels_string, MAX_LEN_OF_ACTIVE_CHANNELS_STRING, "ALL"); + data.chanconf->active_ch = ENABLE_ALL_CHANNELS; + }else{ + snprintf(data.active_channels_string, MAX_LEN_OF_ACTIVE_CHANNELS_STRING, "1"); + data.chanconf->active_ch = 1; + } }else{ snprintf(data.active_channels_string, MAX_LEN_OF_ACTIVE_CHANNELS_STRING, "ALL"); data.chanconf->active_ch = ENABLE_ALL_CHANNELS; diff --git a/util/wancfg/list_element_sangoma_card.h b/util/wancfg/list_element_sangoma_card.h index 50f7490..06030ef 100644 --- a/util/wancfg/list_element_sangoma_card.h +++ b/util/wancfg/list_element_sangoma_card.h @@ -109,6 +109,7 @@ public: return 1; } dchan = new_dchan; + return 0; } int set_key(int new_key) @@ -145,6 +146,11 @@ public: spanno, (fe_cfg.tdmv_law == ZT_LAW_MULAW ? "MuLaw" : "ALaw")); break; + case AFT_ADPTR_ISDN: + printf("\tSpan: %d, Line: ISDN BRI, Law: %s.\n", + spanno, (fe_cfg.tdmv_law == ZT_LAW_MULAW ? "MuLaw" : "ALaw")); + break; + case A101_ADPTR_1TE1: case A104_ADPTR_4TE1: snprintf(dchan_str, 10, "%d", dchan); diff --git a/util/wancfg/main.cpp b/util/wancfg/main.cpp index 8ae3882..6d5fc4b 100644 --- a/util/wancfg/main.cpp +++ b/util/wancfg/main.cpp @@ -1,9 +1,9 @@ /*************************************************************************** main.cpp - description ------------------- - begin : Wed Feb 25 16:17:53 EST 2004 - copyright : (C) 2004 by David Rokhvarg - email : davidr@sangoma.com + begin : Wed Feb 25 16:17:53 EST 2004 + author : David Rokhvarg + email : davidr@sangoma.com ***************************************************************************/ /*************************************************************************** @@ -50,11 +50,16 @@ int zaptel_to_wanpipe(); char lxdialog_path[MAX_PATH_LENGTH];// usually /usr/sbin/wanpipe_lxdialog char wan_bin_dir[MAX_PATH_LENGTH]; +#if defined(__LINUX__) const char * wanpipe_cfg_dir = "/etc/wanpipe/"; +char * interfaces_cfg_dir = "/etc/wanpipe/interfaces/"; +#else +const char * wanpipe_cfg_dir = "/usr/local/etc/wanpipe/"; +char * interfaces_cfg_dir = "/usr/local/etc/wanpipe/interfaces/"; +#endif char * start_stop_scripts_dir = "scripts"; -char * interfaces_cfg_dir = "/etc/wanpipe/interfaces/"; -char * date_and_time_file_name = "date_and_time_file.tmp"; +char * date_and_time_file_name = "/tmp/date_and_time_file.tmp"; int global_card_type = 0; int global_card_version = 0; @@ -68,8 +73,11 @@ int global_card_version = 0; int global_hw_ec_max_num = 1; char zaptel_conf_path[MAX_PATH_LENGTH];// usually /etc/ +#if defined(__LINUX__) +char *zaptel_default_conf_path = "/usr/local/etc/"; +#else char *zaptel_default_conf_path = "/etc/"; - +#endif //////////////////////////////////////////////////////////// //help messages //indicates error. @@ -98,12 +106,15 @@ char* fr_cir_help_str = //globals from wanconfig.c char prognamed[20] = "wancfg";//"wanconfig"; char progname_sp[] = " "; +#if defined(__LINUX__) char def_conf_file[] = "/etc/wanpipe/wanpipe1.conf"; /* default name */ char def_adsl_file[] = "/etc/wanpipe/wan_adsl.list"; /* default name */ char tmp_adsl_file[] = "/etc/wanpipe/wan_adsl.tmp"; /* default name */ -#if defined(__LINUX__) char router_dir[] = "/proc/net/wanrouter"; /* location of WAN devices */ #else +char def_conf_file[] = "/usr/local/etc/wanpipe/wanpipe1.conf"; /* default name */ +char def_adsl_file[] = "/usr/local/etc/wanpipe/wan_adsl.list"; /* default name */ +char tmp_adsl_file[] = "/usr/local/etc/wanpipe/wan_adsl.tmp"; /* default name */ char router_dir[] = "/var/lock/wanrouter"; /* location of WAN devices */ #endif @@ -120,6 +131,7 @@ char is_there_a_lip_atm_if=NO; int active_channels_str_invalid_characters_check(char* active_ch_str); int read_wanrouter_rc_file(); +int check_directory(); int main_loop(); void cleanup(); @@ -267,6 +279,10 @@ char * get_protocol_string(int protocol) case PROTOCOL_TDM_VOICE: snprintf((char*)protocol_name, MAX_PATH_LENGTH, "TDM Voice"); break; + + case PROTOCOL_TDM_VOICE_API: + snprintf((char*)protocol_name, MAX_PATH_LENGTH, "TDM Voice API"); + break; case WANCONFIG_LAPB: snprintf((char*)protocol_name, MAX_PATH_LENGTH, "HDLC LAPB"); @@ -275,7 +291,7 @@ char * get_protocol_string(int protocol) case WANCONFIG_LIP_ATM: snprintf((char*)protocol_name, MAX_PATH_LENGTH, "ATM (LIP)"); break; - + default: ERR_DBG_OUT(("Invalid protocol: %d\n", protocol)); snprintf((char*)protocol_name, MAX_PATH_LENGTH, INVALID_PROTOCOL); @@ -510,7 +526,7 @@ int adjust_number_of_logical_channels_in_list( int config_id, snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%sfr", name_of_parent_layer); #elif (defined __FreeBSD__) || (defined __OpenBSD__) || defined(__NetBSD__) || BSD_DEBG - snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%sfr0", + snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%sf0", //underlying layer name ends with digit - change it replace_numeric_with_char(name_of_parent_layer)); #endif @@ -535,7 +551,7 @@ int adjust_number_of_logical_channels_in_list( int config_id, snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%sppp", name_of_parent_layer); #elif (defined __FreeBSD__) || (defined __OpenBSD__) || defined(__NetBSD__) || BSD_DEBG - snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%sppp0", + snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%sp0", //underlying layer name ends with digit - change it replace_numeric_with_char(name_of_parent_layer)); #endif @@ -559,7 +575,7 @@ int adjust_number_of_logical_channels_in_list( int config_id, snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%schdl", name_of_parent_layer); #elif (defined __FreeBSD__) || (defined __OpenBSD__) || defined(__NetBSD__) || BSD_DEBG - snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%schdlc0", + snprintf(chan_def_tmp->data.name, WAN_IFNAME_SZ, "%sc0", //underlying layer name ends with digit - change it replace_numeric_with_char(name_of_parent_layer)); #endif @@ -722,19 +738,25 @@ char * get_card_type_string(int card_type, int card_version) { case A101_ADPTR_1TE1://WAN_MEDIA_T1: snprintf(card_type_name, MAX_PATH_LENGTH, "A101/2"); - break; + break; case A104_ADPTR_4TE1://including A101-SH and A102-SH snprintf(card_type_name, MAX_PATH_LENGTH, "A101/2/4/8"); - break; + break; case A300_ADPTR_U_1TE3://WAN_MEDIA_DS3: snprintf(card_type_name, MAX_PATH_LENGTH, "A301-T3/E3"); - break; + break; case A200_ADPTR_ANALOG: snprintf(card_type_name, MAX_PATH_LENGTH, "A200/A400-Analog"); - break; - case AFT_ADPTR_56K: - snprintf(card_type_name, MAX_PATH_LENGTH, "A056-56k DDS"); - break; + break; + case AFT_ADPTR_56K: + snprintf(card_type_name, MAX_PATH_LENGTH, "A056-56k DDS"); + break; + case AFT_ADPTR_ISDN: + snprintf(card_type_name, MAX_PATH_LENGTH, "A500-ISDN BRI"); + break; + case AFT_ADPTR_2SERIAL_V35X21: + snprintf(card_type_name, MAX_PATH_LENGTH, "A14X-Serial"); + break; default: ERR_DBG_OUT(("Invalid AFT card version: 0x%x!\n", card_version)); } @@ -1412,7 +1434,7 @@ char* remove_spaces_in_int_string(char* input) //remove spaces and zero terminate. snprintf(output, LEN_OF_DBG_BUFF, "%d", atoi(input)); //copy back to caller's buffer - strcpy(input, output); + strlcpy(input, output, MAX_PATH_LENGTH); return input; } @@ -1553,6 +1575,10 @@ int get_used_by_integer_value(char* used_by_str) return TTY; }else if(strcmp(used_by_str, "PPPoE") == 0){ return PPPoE; + }else if(strcmp(used_by_str, "NETGRAPH") == 0){ + return WP_NETGRAPH; + }else if(strcmp(used_by_str, "TDM_VOICE_API") == 0){ + return TDM_VOICE_API; }else{ return -1; } @@ -1595,6 +1621,12 @@ char* get_used_by_string(int used_by) case TTY: return "TTY"; + case WP_NETGRAPH: + return "NETGRAPH"; + + case TDM_VOICE_API: + return "TDM_VOICE_API"; + default: return "Unknown Operation Mode"; } @@ -1973,7 +2005,8 @@ void set_default_t1_configuration(sdla_fe_cfg_t* fe_cfg) te1_cfg->lbo = WAN_T1_LBO_0_DB; te1_cfg->te_clock = WAN_NORMAL_CLK; te1_cfg->active_ch = ENABLE_ALL_CHANNELS; - te1_cfg->high_impedance_mode = WANOPT_NO; + te1_cfg->high_impedance_mode = WANOPT_NO; + te1_cfg->rx_slevel = 120; } /* EncapMode = ETH_LLC_OA @@ -2071,6 +2104,20 @@ char* replace_numeric_with_char(char* str) return new_str; } +// Verify and create directories +int check_directory() +{ + char command_line[MAX_PATH_LENGTH]; + + // Verify/Create etc/wanpipe/interfaces directory + snprintf(command_line, MAX_PATH_LENGTH, "mkdir -p %s", interfaces_cfg_dir); + Debug(DBG_WANCFG_MAIN, ("check_directory(): command line: %s\n", + command_line)); + system(command_line); + + return 0; +} + //Read location of "lxdialog" and other configrable path settings. int read_wanrouter_rc_file() { @@ -2116,7 +2163,7 @@ int main(int argc, char *argv[]) Debug(DBG_WANCFG_MAIN, ("%s: main()\n", WANCFG_PROGRAM_NAME)); if(argc == 2 && !strcmp(argv[1], "version")){ - printf("\nwancfg version: 1.30\n"); + printf("\nwancfg version: 1.34\n"); return EXIT_SUCCESS; } @@ -2137,7 +2184,9 @@ int main(int argc, char *argv[]) err_printf("Failed to read 'WAN_BIN_DIR' in 'wanrouter.rc'! Using default: '%s'.", wan_bin_dir); } - + + check_directory(); + if(is_console_size_valid() == NO){ rc = EXIT_FAILURE; goto cleanup; diff --git a/util/wancfg/menu_aft_logical_channel_cfg.cpp b/util/wancfg/menu_aft_logical_channel_cfg.cpp index 7c38b79..95eb48e 100644 --- a/util/wancfg/menu_aft_logical_channel_cfg.cpp +++ b/util/wancfg/menu_aft_logical_channel_cfg.cpp @@ -184,7 +184,8 @@ again: lxdialog_path, (char*)(link_defs->card_version != A200_ADPTR_ANALOG ? "AFT DS0 CHANNEL CONFIGURATION" : - "AFT ANALOG CHANNEL CONFIGURATION"), + (link_defs->card_version == A200_ADPTR_ANALOG ? + "AFT ANALOG CHANNEL CONFIGURATION": "ISDN BRI CHANNEL CONFIGURATION")), WANCFG_PROGRAM_NAME, tmp_buff, MENU_HEIGTH, MENU_WIDTH, diff --git a/util/wancfg/menu_aft_logical_channels_list.cpp b/util/wancfg/menu_aft_logical_channels_list.cpp index 4188b5c..372654b 100644 --- a/util/wancfg/menu_aft_logical_channels_list.cpp +++ b/util/wancfg/menu_aft_logical_channels_list.cpp @@ -264,6 +264,8 @@ int menu_aft_logical_channels_list::create_logical_channels_list_str(string& men if(link_defs->card_version == A200_ADPTR_ANALOG){ max_valid_number_of_logical_channels = MAX_FXOFXS_CHANNELS; + }else if(link_defs->card_version == AFT_ADPTR_ISDN){ + max_valid_number_of_logical_channels = MAX_BRI_TIMESLOTS; }else{ if(fe_cfg->media == WAN_MEDIA_T1){ @@ -320,6 +322,8 @@ int menu_aft_logical_channels_list:: if(link_defs->card_version == A200_ADPTR_ANALOG){ max_valid_number_of_logical_channels = MAX_FXOFXS_CHANNELS; + }else if(link_defs->card_version == AFT_ADPTR_ISDN){ + max_valid_number_of_logical_channels = MAX_BRI_TIMESLOTS; }else{ if(fe_cfg->media == WAN_MEDIA_T1){ diff --git a/util/wancfg/menu_hardware_card_type.cpp b/util/wancfg/menu_hardware_card_type.cpp index d339446..a5b7b04 100644 --- a/util/wancfg/menu_hardware_card_type.cpp +++ b/util/wancfg/menu_hardware_card_type.cpp @@ -78,7 +78,7 @@ int menu_hardware_card_type::run(OUT int * selection_index) unsigned int option_selected; char exit_dialog; int number_of_items; - int old_card_type; + unsigned int old_card_type; //help text box text_box tb; @@ -278,16 +278,27 @@ again: set_default_t3_configuration(fe_cfg); break; - case A200_ADPTR_ANALOG: + case A200_ADPTR_ANALOG: fe_cfg->media = WAN_MEDIA_FXOFXS; fe_cfg->tdmv_law = WAN_TDMV_MULAW; - snprintf(fe_cfg->cfg.remora.opermode_name, WAN_RM_OPERMODE_LEN, "%s", "FCC"); - fe_cfg->cfg.remora.battthresh = 3; + snprintf(fe_cfg->cfg.remora.opermode_name, WAN_RM_OPERMODE_LEN, "%s", "FCC"); + fe_cfg->cfg.remora.battthresh = 3; fe_cfg->cfg.remora.battdebounce = 16; - break; - case AFT_ADPTR_56K: - fe_cfg->media = WAN_MEDIA_56K; - break; + break; + + case AFT_ADPTR_56K: + fe_cfg->media = WAN_MEDIA_56K; + break; + + case AFT_ADPTR_ISDN: + fe_cfg->media = WAN_MEDIA_BRI; + fe_cfg->line_no = 1;//for manual card type selection assume line 1 + fe_cfg->tdmv_law = WAN_TDMV_ALAW; + break; + + case AFT_ADPTR_2SERIAL_V35X21: + fe_cfg->media = WAN_MEDIA_SERIAL; + break; } break; @@ -352,14 +363,23 @@ again: case A200_ADPTR_ANALOG: fe_cfg->media = WAN_MEDIA_FXOFXS; fe_cfg->tdmv_law = WAN_TDMV_MULAW; - snprintf(fe_cfg->cfg.remora.opermode_name, WAN_RM_OPERMODE_LEN, "%s", "FCC"); - fe_cfg->cfg.remora.battthresh = 3; - fe_cfg->cfg.remora.battdebounce = 16; - break; - - case AFT_ADPTR_56K: - fe_cfg->media = WAN_MEDIA_56K; - break; + snprintf(fe_cfg->cfg.remora.opermode_name, WAN_RM_OPERMODE_LEN, "%s", "FCC"); + fe_cfg->cfg.remora.battthresh = 3; + fe_cfg->cfg.remora.battdebounce = 16; + break; + + case AFT_ADPTR_56K: + fe_cfg->media = WAN_MEDIA_56K; + break; + + case AFT_ADPTR_ISDN: + fe_cfg->media = WAN_MEDIA_BRI; + fe_cfg->tdmv_law = WAN_TDMV_ALAW; + break; + + case AFT_ADPTR_2SERIAL_V35X21: + fe_cfg->media = WAN_MEDIA_SERIAL; + break; } break; diff --git a/util/wancfg/menu_hardware_probe.cpp b/util/wancfg/menu_hardware_probe.cpp index 90011b9..596868d 100644 --- a/util/wancfg/menu_hardware_probe.cpp +++ b/util/wancfg/menu_hardware_probe.cpp @@ -305,7 +305,7 @@ int menu_hardware_probe::hardware_probe() FILE * hwprobe_file_tmp; char str_buff[MAX_PATH_LENGTH]; char shell_command_line[MAX_PATH_LENGTH]; - char* tmp_hwprobe_file_full_path = "tmp_hwprobe_file"; + char* tmp_hwprobe_file_full_path = "/tmp/tmp_hwprobe_file"; int probed_cards_count=0; string local_menu_str; @@ -414,7 +414,7 @@ int menu_hardware_probe::hardware_probe() } int menu_hardware_probe::parse_selected_card_line(char *selected_card_line, - char *card_type, + unsigned int *card_type, unsigned int *card_version, unsigned int *card_sub_version) { @@ -583,7 +583,7 @@ int menu_hardware_probe::parse_selected_card_line(char *selected_card_line, strstr(selected_card_line, "AFT-A301") != NULL || strstr(selected_card_line, "AFT-A300") != NULL){ rc = YES; - *card_type = WANOPT_AFT; + *card_type = WANOPT_AFT; *card_version = A300_ADPTR_U_1TE3;//WAN_MEDIA_DS3;//indicates A105 goto done; } @@ -611,16 +611,54 @@ int menu_hardware_probe::parse_selected_card_line(char *selected_card_line, goto done; } - - // - //A056 (AFT) 56k DDS card - // - if( strstr(selected_card_line, "AFT-A056-SH") != NULL){ - rc = YES; - *card_type = WANOPT_AFT; - *card_version = AFT_ADPTR_56K; - goto done; - } + + // + //A056 (AFT) 56k DDS card + // + if( strstr(selected_card_line, "AFT-A056-SH") != NULL){ + rc = YES; + *card_type = WANOPT_AFT; + *card_version = AFT_ADPTR_56K; + goto done; + } + + + // + //ISDN BRI card + // + if( strstr(selected_card_line, "AFT-A500-SH") != NULL || + strstr(selected_card_line, "AFT-A500-SH") != NULL ){ + rc = YES; + *card_type = WANOPT_AFT; + *card_version = AFT_ADPTR_ISDN; + global_card_type = WANOPT_AFT; + global_card_version = AFT_ADPTR_ISDN; + + char *hw_ec_max_num_ptr = strstr(selected_card_line, "HWEC="); + if(hw_ec_max_num_ptr != NULL){ + Debug(DBG_MENU_HARDWARE_PROBE, ("hw_ec_max_num_ptr: %s\n", hw_ec_max_num_ptr)); + hw_ec_max_num_ptr += strlen("HWEC="); + //valid values are: 0, 32, 128. + //0 (zero) means there is no HWEC on the card. + global_hw_ec_max_num = atoi(hw_ec_max_num_ptr); + Debug(DBG_MENU_HARDWARE_PROBE, ("global_hw_ec_max_num: %d\n", global_hw_ec_max_num)); + } + + goto done; + } + + // + //A14X (AFT) Serial card + // + if( strstr(selected_card_line, "AFT-A142-SH") != NULL || + strstr(selected_card_line, "AFT-A144-SH") != NULL){ + rc = YES; + *card_type = WANOPT_AFT; + *card_version = AFT_ADPTR_2SERIAL_V35X21; + global_card_type = WANOPT_AFT; + global_card_version = AFT_ADPTR_2SERIAL_V35X21; + goto done; + } done: @@ -668,7 +706,8 @@ int menu_hardware_probe::get_card_location_from_hwprobe_line( wandev_conf_t* lin } //ADSL card always have only one CPU. But check anyway - if(get_cpu_from_str(selected_card_line, linkconf->S514_CPU_no) == NO){ + if(get_cpu_from_str(selected_card_line, linkconf->S514_CPU_no) == NO && + linkconf->card_type == WANOPT_S51X){ ERR_DBG_OUT(("Failed to get 'S514_CPU_no' from line: %s!\n", selected_card_line)); return NO; @@ -684,12 +723,14 @@ int menu_hardware_probe::get_card_location_from_hwprobe_line( wandev_conf_t* lin return NO; } - if(link_def->card_version != A104_ADPTR_4TE1){ - //get the port - return get_port_from_str(selected_card_line, &linkconf->comm_port); + if( (link_def->card_version != A104_ADPTR_4TE1) && + (link_def->card_version != AFT_ADPTR_ISDN) && + (link_def->card_version != AFT_ADPTR_2SERIAL_V35X21)){ + //get the port + return get_port_from_str(selected_card_line, &linkconf->comm_port); }else{ - //get line_no - return get_line_number_from_str(selected_card_line, &fe_cfg->line_no); + //get line_no + return get_line_number_from_str(selected_card_line, &fe_cfg->line_no); } } @@ -857,7 +898,7 @@ int menu_hardware_probe::verify_hwprobe_command_is_successfull() char* expected_str = "Wanpipe Hardware Probe Info"; FILE * hwprobe_file_tmp; char str_buff[MAX_PATH_LENGTH]; - char* tmp_hwprobe_file_full_path = "tmp_hwprobe_file"; + char* tmp_hwprobe_file_full_path = "/tmp/tmp_hwprobe_file"; char rc = NO; hwprobe_file_tmp = fopen(tmp_hwprobe_file_full_path, "r+"); @@ -891,18 +932,17 @@ int menu_hardware_probe::verify_hwprobe_command_is_successfull() int menu_hardware_probe::add_card_to_list(IN char *hw_probe_output_line) { int rc = YES, key; - char card_type; + unsigned int card_type; int card_version = 0, card_sub_version = 0; unsigned int line_no, PCI_slot_no, pci_bus_no; char S514_CPU_no[10]; list_element_sangoma_card *sangoma_card, *last_in_list_card; - replace_new_line_with_zero_term(hw_probe_output_line); if(parse_selected_card_line( - hw_probe_output_line, - (char*)&card_type, + replace_new_line_with_zero_term(hw_probe_output_line), + (unsigned int*)&card_type, (unsigned int*)&card_version, (unsigned int*)&card_sub_version) == NO){ ERR_DBG_OUT(("Failed to get Card Type from from Hardware Proble output line!! line: %s\n", diff --git a/util/wancfg/menu_hardware_probe.h b/util/wancfg/menu_hardware_probe.h index 32b77bf..762bd4b 100644 --- a/util/wancfg/menu_hardware_probe.h +++ b/util/wancfg/menu_hardware_probe.h @@ -40,7 +40,7 @@ class menu_hardware_probe : public menu_base { #endif int parse_selected_card_line(char *selected_card_line, - char *card_type, + unsigned int *card_type, unsigned int *card_version, unsigned int *card_sub_version); diff --git a/util/wancfg/menu_hardware_serial_select_medium.cpp b/util/wancfg/menu_hardware_serial_select_medium.cpp index a86f708..5527eda 100644 --- a/util/wancfg/menu_hardware_serial_select_medium.cpp +++ b/util/wancfg/menu_hardware_serial_select_medium.cpp @@ -119,12 +119,12 @@ again: switch(atoi(get_lxdialog_output_string())) { case WANOPT_RS232: - linkconf->interface = WANOPT_RS232; + linkconf->electrical_interface = WANOPT_RS232; exit_dialog = YES; break; case WANOPT_V35: - linkconf->interface = WANOPT_V35; + linkconf->electrical_interface = WANOPT_V35; exit_dialog = YES; break; diff --git a/util/wancfg/menu_hardware_setup.cpp b/util/wancfg/menu_hardware_setup.cpp index a5516a2..8b93c98 100644 --- a/util/wancfg/menu_hardware_setup.cpp +++ b/util/wancfg/menu_hardware_setup.cpp @@ -170,8 +170,11 @@ enum HW_SETUP_OPTIONS { TIMESLOT_GROUP_CFG, ADVANCED_PCI_CFG, TDMV_LAW_SELECT, - TDMV_OPERMODE, - AFT_ANALOG_ADVANCED + TDMV_OPERMODE, + AFT_ANALOG_ADVANCED, + AFT_SERIAL_CONNECTION_TYPE, + AFT_SERIAL_LINE_CODING, + AFT_SERIAL_LINE_IDLE }; menu_hardware_setup::menu_hardware_setup( IN char * lxdialog_path, @@ -353,7 +356,7 @@ again: menu_str += tmp_buff; number_of_items++; break; - + case A200_ADPTR_ANALOG: snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TDMV_LAW_SELECT); menu_str += tmp_buff; @@ -378,11 +381,11 @@ again: snprintf(tmp_buff, MAX_PATH_LENGTH, " \" \" "); menu_str += tmp_buff; number_of_items++; - - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_ANALOG_ADVANCED); - menu_str += tmp_buff; - menu_str += " \"Advanced Physical Medium Configuration\" "; - number_of_items++; + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_ANALOG_ADVANCED); + menu_str += tmp_buff; + menu_str += " \"Advanced Physical Medium Configuration\" "; + number_of_items++; //timeslot group configuration snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TIMESLOT_GROUP_CFG); @@ -404,8 +407,31 @@ again: snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_TE3_ADVANCED); menu_str += tmp_buff; menu_str += " \"Advanced Physical Medium Configuration\" "; - break; + case AFT_ADPTR_ISDN://WAN_MEDIA_BRI: + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", EMPTY_LINE); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \" \" "); + menu_str += tmp_buff; + number_of_items++; + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_TE1_ADVANCED); + menu_str += tmp_buff; + menu_str += " \"Advanced Physical Medium Configuration\" "; + break; + case AFT_ADPTR_2SERIAL_V35X21: + form_AFT_Serial_options_menu(menu_str, number_of_items); + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", EMPTY_LINE); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \" \" "); + menu_str += tmp_buff; + number_of_items++; + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", S514_SERIAL_ADVANCED); + menu_str += tmp_buff; + menu_str += " \"Advanced Physical Medium Configuration\" "; + break; } form_pci_card_locations_options_menu(menu_str, number_of_items); @@ -700,17 +726,17 @@ display_hardware_selection_label: } } break; - - case AFT_ANALOG_ADVANCED: - { - menu_hardware_analog_card_advanced_options hardware_analog_card_advanced_options( - lxdialog_path, cfr); - if(hardware_analog_card_advanced_options.run(selection_index) == NO){ - rc = NO; - exit_dialog = YES; - } - } - break; + + case AFT_ANALOG_ADVANCED: + { + menu_hardware_analog_card_advanced_options hardware_analog_card_advanced_options( + lxdialog_path, cfr); + if(hardware_analog_card_advanced_options.run(selection_index) == NO){ + rc = NO; + exit_dialog = YES; + } + } + break; case AFT_TE3_ADVANCED: { @@ -779,21 +805,21 @@ display_hardware_selection_label: case ADSL_ENCAPSULATION_MODE: { - int old_encapsulation = adsl_cfg->EncapMode; + int old_encapsulation = adsl_cfg->EncapMode; - menu_adsl_encapsulation adsl_encapsulation(lxdialog_path, adsl_cfg); - if(adsl_encapsulation.run(selection_index) == NO){ + menu_adsl_encapsulation adsl_encapsulation(lxdialog_path, adsl_cfg); + if(adsl_encapsulation.run(selection_index) == NO){ rc = NO; exit_dialog = YES; } - if(old_encapsulation != adsl_cfg->EncapMode){ - //change the 'sub_config_id' accordingly + if(old_encapsulation != adsl_cfg->EncapMode){ + //change the 'sub_config_id' accordingly switch(adsl_cfg->EncapMode) { case RFC_MODE_BRIDGED_ETH_LLC: case RFC_MODE_BRIDGED_ETH_VC: - link_def->sub_config_id = PROTOCOL_ETHERNET; + link_def->sub_config_id = PROTOCOL_ETHERNET; break; case RFC_MODE_ROUTED_IP_LLC: @@ -807,37 +833,37 @@ display_hardware_selection_label: link_def->sub_config_id = WANCONFIG_MPPP; break; }//switch(adsl_cfg->EncapMode) - } + } } break; case ADSL_ATM_AUTOCFG: snprintf(tmp_buff, MAX_PATH_LENGTH, "Do you want to %s ADSL autoconfiguration?", - (adsl_cfg->atm_autocfg == WANOPT_NO ? "Enable" : "Disable")); + (adsl_cfg->atm_autocfg == WANOPT_NO ? "Enable" : "Disable")); if(yes_no_question( selection_index, lxdialog_path, NO_PROTOCOL_NEEDED, tmp_buff) == NO){ - //error displaying dialog - rc = NO; - goto cleanup; + //error displaying dialog + rc = NO; + goto cleanup; } switch(*selection_index) { case YES_NO_TEXT_BOX_BUTTON_YES: - if(adsl_cfg->atm_autocfg == WANOPT_NO){ - //disabled, user wants to enable - adsl_cfg->atm_autocfg = WANOPT_YES; - }else{ - adsl_cfg->atm_autocfg = WANOPT_NO; - } + if(adsl_cfg->atm_autocfg == WANOPT_NO){ + //disabled, user wants to enable + adsl_cfg->atm_autocfg = WANOPT_YES; + }else{ + adsl_cfg->atm_autocfg = WANOPT_NO; + } break; case YES_NO_TEXT_BOX_BUTTON_NO: - //don't do anything - break; + //don't do anything + break; } break; @@ -862,7 +888,7 @@ show_vci_input_box: break; case INPUT_BOX_BUTTON_HELP: - tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, option_not_implemented_yet_help_str); + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, option_not_implemented_yet_help_str); goto show_vci_input_box; }//switch(*selection_index) break; @@ -952,6 +978,38 @@ show_vpi_input_box: } } break; + case AFT_SERIAL_CONNECTION_TYPE: + { + menu_hardware_serial_connection_type hardware_serial_connection_type( + lxdialog_path, cfr); + if(hardware_serial_connection_type.run(selection_index) == NO){ + rc = NO; + exit_dialog = YES; + } + } + break; + + case AFT_SERIAL_LINE_CODING: + { + menu_hardware_serial_line_coding hardware_serial_line_coding( + lxdialog_path, cfr); + if(hardware_serial_line_coding.run(selection_index) == NO){ + rc = NO; + exit_dialog = YES; + } + } + break; + + case AFT_SERIAL_LINE_IDLE: + { + menu_hardware_serial_line_idle hardware_serial_line_idle( + lxdialog_path, cfr); + if(hardware_serial_line_idle.run(selection_index) == NO){ + rc = NO; + exit_dialog = YES; + } + } + break; default: ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", @@ -1043,12 +1101,55 @@ void menu_hardware_setup::form_s514_serial_options_menu(string& str, int& number snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Physical Medium-> %s\" ", //snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Interface------> %s\" ", - (linkconf->interface == WANOPT_V35 ? "V.35" : "RS232")); + (linkconf->electrical_interface == WANOPT_V35 ? "V.35" : "RS232")); str += tmp_buff; number_of_items++; } +void menu_hardware_setup::form_AFT_Serial_options_menu(string& str, int& number_of_items) +{ + char tmp_buff[MAX_PATH_LENGTH]; + link_def_t * link_def; + wandev_conf_t *linkconf; + + Debug(DBG_MENU_HARDWARE_SETUP, ("menu_net_interface_setup::%s()\n", __FUNCTION__)); + + link_def = cfr->link_defs; + linkconf = cfr->link_defs->linkconf; + + ////////////////////////////////////////////////////////////////////////////////////////// + //Serial connection type + //Permanent - CTS/RTS are always up + //Switched - CTS/RTS are only brought up tx + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_SERIAL_CONNECTION_TYPE); + str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Connection Type-> %s\" ", + (linkconf->connection == WANOPT_PERMANENT ? "Permanent" : (linkconf->connection == WANOPT_SWITCHED?"Switched":"Unknown!"))); + str += tmp_buff; + number_of_items++; + ////////////////////////////////////////////////////////////////////////////////////////// + //Serial LineCoding: NRZ or NRZI + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_SERIAL_LINE_CODING); + str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Line Coding-----> %s\" ", + (linkconf->line_coding == WANOPT_NRZ ? "NRZ" : (linkconf->line_coding == WANOPT_NRZI ? "NRZI":"Unknown!"))); + str += tmp_buff; + number_of_items++; + ////////////////////////////////////////////////////////////////////////////////////////// + //Serial LineIdle: + //Flag - use flags to idle on the line + //Mark - use mark to idle on the line + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_SERIAL_LINE_IDLE); + str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Line Idle-------> %s\" ", + (linkconf->line_idle == WANOPT_IDLE_FLAG ? "Flag" : (linkconf->line_idle == WANOPT_IDLE_MARK ? "Mark":"Unknown!"))); + str += tmp_buff; + number_of_items++; + ////////////////////////////////////////////////////////////////////////////////////////// + +} + void menu_hardware_setup::form_s514_TE1_options_menu(string& str, int& number_of_items) { char tmp_buff[MAX_PATH_LENGTH]; @@ -1113,3 +1214,477 @@ void menu_hardware_setup::form_pci_card_locations_options_menu(string& str, int& number_of_items++; } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +enum SERIAL_CONNECTION_TYPE{ + PERMANENT, + SWITCHED +}; + +#define DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE 1 + +menu_hardware_serial_connection_type:: + menu_hardware_serial_connection_type(IN char * lxdialog_path, + IN conf_file_reader* ptr_cfr) +{ + Debug(DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE, + ("menu_hardware_serial_connection_type::%s()\n", __FUNCTION__)); + + snprintf(this->lxdialog_path, MAX_PATH_LENGTH, "%s", lxdialog_path); + this->cfr = ptr_cfr; +} + +menu_hardware_serial_connection_type::~menu_hardware_serial_connection_type() +{ + Debug(DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE, + ("menu_hardware_serial_connection_type::%s()\n", __FUNCTION__)); +} + +int menu_hardware_serial_connection_type::run(OUT int * selection_index) +{ + string menu_str; + int rc; + char tmp_buff[MAX_PATH_LENGTH]; + char exit_dialog; + int number_of_items; + + //help text box + text_box tb; + + link_def_t * link_def; + wandev_conf_t *linkconf; + + Debug(DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE, + ("menu_hardware_serial_connection_type::%s()\n", __FUNCTION__)); + +again: + number_of_items = 2; + + link_def = cfr->link_defs; + linkconf = cfr->link_defs->linkconf; + + Debug(DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE, ("cfr->link_defs->name: %s\n", link_def->name)); + + rc = YES; + exit_dialog = NO; + menu_str = " "; + + Debug(DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE, ("linkconf->card_type: DEC:%d, HEX: 0x%X\n", + linkconf->card_type, linkconf->card_type)); + + ///////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANOPT_PERMANENT); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Permanent\" "); + menu_str += tmp_buff; + + ///////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANOPT_SWITCHED); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Switched\" "); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////////////////// + //create the explanation text for the menu + snprintf(tmp_buff, MAX_PATH_LENGTH, +"\n------------------------------------------\ +\nSelect Serial Connection type for Wan Device: %s", link_def->name); + + if(set_configuration( YES,//indicates to call V2 of the function + MENU_BOX_BACK,//MENU_BOX_SELECT, + lxdialog_path, + "SELECT CONNECTION TYPE", + WANCFG_PROGRAM_NAME, + tmp_buff, + MENU_HEIGTH, MENU_WIDTH, + number_of_items, + (char*)menu_str.c_str() + ) == NO){ + rc = NO; + goto cleanup; + } + + if(show(selection_index) == NO){ + rc = NO; + goto cleanup; + } + ////////////////////////////////////////////////////////////////////////////////////// + + exit_dialog = NO; + switch(*selection_index) + { + case MENU_BOX_BUTTON_SELECT: + Debug(DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE, + ("hardware_setup: option selected for editing: %s\n", get_lxdialog_output_string())); + + Debug(DBG_MENU_HARDWARE_SERIAL_CONNECTION_TYPE, + ("serial select clock: atoi(get_lxdialog_output_string(): %d\n", + atoi(get_lxdialog_output_string()))); + + switch(atoi(get_lxdialog_output_string())) + { + case WANOPT_PERMANENT: + linkconf->connection = WANOPT_PERMANENT; + exit_dialog = YES; + break; + + case WANOPT_SWITCHED: + linkconf->connection = WANOPT_SWITCHED; + exit_dialog = YES; + break; + + default: + ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", + get_lxdialog_output_string())); + rc = NO; + exit_dialog = YES; + } + break; + + case MENU_BOX_BUTTON_HELP: + + switch(atoi(get_lxdialog_output_string())) + { + case WANOPT_PERMANENT: + case WANOPT_SWITCHED: + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, + "Please select Serial Connection type."); + break; + + default: + ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", + get_lxdialog_output_string())); + rc = NO; + exit_dialog = YES; + } + break; + + case MENU_BOX_BUTTON_EXIT: + exit_dialog = YES; + break; + }//switch(*selection_index) + + if(exit_dialog == NO){ + goto again; + } + +cleanup: + return rc; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + +enum SERIAL_LINE_CODING{ + NRZ, + NRZI +}; + +#define DBG_MENU_HARDWARE_SERIAL_LINE_CODING 1 + +menu_hardware_serial_line_coding:: + menu_hardware_serial_line_coding(IN char * lxdialog_path, + IN conf_file_reader* ptr_cfr) +{ + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_CODING, + ("menu_hardware_serial_line_coding::%s()\n", __FUNCTION__)); + + snprintf(this->lxdialog_path, MAX_PATH_LENGTH, "%s", lxdialog_path); + this->cfr = ptr_cfr; +} + +menu_hardware_serial_line_coding::~menu_hardware_serial_line_coding() +{ + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_CODING, + ("menu_hardware_serial_line_coding::%s()\n", __FUNCTION__)); +} + +int menu_hardware_serial_line_coding::run(OUT int * selection_index) +{ + string menu_str; + int rc; + char tmp_buff[MAX_PATH_LENGTH]; + char exit_dialog; + int number_of_items; + + //help text box + text_box tb; + + link_def_t * link_def; + wandev_conf_t *linkconf; + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_CODING, + ("menu_hardware_serial_line_coding::%s()\n", __FUNCTION__)); + +again: + number_of_items = 2; + + link_def = cfr->link_defs; + linkconf = cfr->link_defs->linkconf; + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_CODING, ("cfr->link_defs->name: %s\n", link_def->name)); + + rc = YES; + exit_dialog = NO; + menu_str = " "; + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_CODING, ("linkconf->card_type: DEC:%d, HEX: 0x%X\n", + linkconf->card_type, linkconf->card_type)); + + ///////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANOPT_NRZ); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"NRZ\" "); + menu_str += tmp_buff; + + ///////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANOPT_NRZI); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"NRZI\" "); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////////////////// + //create the explanation text for the menu + snprintf(tmp_buff, MAX_PATH_LENGTH, +"\n------------------------------------------\ +\nSelect Serial Line Coding type for Wan Device: %s", link_def->name); + + if(set_configuration( YES,//indicates to call V2 of the function + MENU_BOX_BACK,//MENU_BOX_SELECT, + lxdialog_path, + "SELECT LINE CODING", + WANCFG_PROGRAM_NAME, + tmp_buff, + MENU_HEIGTH, MENU_WIDTH, + number_of_items, + (char*)menu_str.c_str() + ) == NO){ + rc = NO; + goto cleanup; + } + + if(show(selection_index) == NO){ + rc = NO; + goto cleanup; + } + ////////////////////////////////////////////////////////////////////////////////////// + + exit_dialog = NO; + switch(*selection_index) + { + case MENU_BOX_BUTTON_SELECT: + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_CODING, + ("hardware_setup: option selected for editing: %s\n", get_lxdialog_output_string())); + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_CODING, + ("serial select clock: atoi(get_lxdialog_output_string(): %d\n", + atoi(get_lxdialog_output_string()))); + + switch(atoi(get_lxdialog_output_string())) + { + case WANOPT_NRZ: + linkconf->line_coding = WANOPT_NRZ; + exit_dialog = YES; + break; + + case WANOPT_NRZI: + linkconf->line_coding = WANOPT_NRZI; + exit_dialog = YES; + break; + + default: + ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", + get_lxdialog_output_string())); + rc = NO; + exit_dialog = YES; + } + break; + + case MENU_BOX_BUTTON_HELP: + + switch(atoi(get_lxdialog_output_string())) + { + case WANOPT_NRZ: + case WANOPT_NRZI: + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, + "Please select Serial Line coding."); + break; + + default: + ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", + get_lxdialog_output_string())); + rc = NO; + exit_dialog = YES; + } + break; + + case MENU_BOX_BUTTON_EXIT: + exit_dialog = YES; + break; + }//switch(*selection_index) + + if(exit_dialog == NO){ + goto again; + } + +cleanup: + return rc; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +enum SERIAL_LINE_IDLE{ + FLAG, + MARK +}; + +#define DBG_MENU_HARDWARE_SERIAL_LINE_IDLE 1 + +menu_hardware_serial_line_idle:: + menu_hardware_serial_line_idle(IN char * lxdialog_path, + IN conf_file_reader* ptr_cfr) +{ + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_IDLE, + ("menu_hardware_serial_line_idle::%s()\n", __FUNCTION__)); + + snprintf(this->lxdialog_path, MAX_PATH_LENGTH, "%s", lxdialog_path); + this->cfr = ptr_cfr; +} + +menu_hardware_serial_line_idle::~menu_hardware_serial_line_idle() +{ + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_IDLE, + ("menu_hardware_serial_line_idle::%s()\n", __FUNCTION__)); +} + +int menu_hardware_serial_line_idle::run(OUT int * selection_index) +{ + string menu_str; + int rc; + char tmp_buff[MAX_PATH_LENGTH]; + char exit_dialog; + int number_of_items; + + //help text box + text_box tb; + + link_def_t * link_def; + wandev_conf_t *linkconf; + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_IDLE, + ("menu_hardware_serial_line_idle::%s()\n", __FUNCTION__)); + +again: + number_of_items = 2; + + link_def = cfr->link_defs; + linkconf = cfr->link_defs->linkconf; + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_IDLE, ("cfr->link_defs->name: %s\n", link_def->name)); + + rc = YES; + exit_dialog = NO; + menu_str = " "; + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_IDLE, ("linkconf->card_type: DEC:%d, HEX: 0x%X\n", + linkconf->card_type, linkconf->card_type)); + + ///////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANOPT_IDLE_FLAG); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Flag\" "); + menu_str += tmp_buff; + + ///////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANOPT_IDLE_MARK); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Mark\" "); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////////////////// + //create the explanation text for the menu + snprintf(tmp_buff, MAX_PATH_LENGTH, +"\n------------------------------------------\ +\nSelect Serial Line Idle for Wan Device: %s", link_def->name); + + if(set_configuration( YES,//indicates to call V2 of the function + MENU_BOX_BACK,//MENU_BOX_SELECT, + lxdialog_path, + "SELECT LINE IDLE", + WANCFG_PROGRAM_NAME, + tmp_buff, + MENU_HEIGTH, MENU_WIDTH, + number_of_items, + (char*)menu_str.c_str() + ) == NO){ + rc = NO; + goto cleanup; + } + + if(show(selection_index) == NO){ + rc = NO; + goto cleanup; + } + ////////////////////////////////////////////////////////////////////////////////////// + + exit_dialog = NO; + switch(*selection_index) + { + case MENU_BOX_BUTTON_SELECT: + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_IDLE, + ("hardware_setup: option selected for editing: %s\n", get_lxdialog_output_string())); + + Debug(DBG_MENU_HARDWARE_SERIAL_LINE_IDLE, + ("serial select clock: atoi(get_lxdialog_output_string(): %d\n", + atoi(get_lxdialog_output_string()))); + + switch(atoi(get_lxdialog_output_string())) + { + case WANOPT_IDLE_FLAG: + linkconf->line_idle = WANOPT_IDLE_FLAG; + exit_dialog = YES; + break; + + case WANOPT_IDLE_MARK: + linkconf->line_idle = WANOPT_IDLE_MARK; + exit_dialog = YES; + break; + + default: + ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", + get_lxdialog_output_string())); + rc = NO; + exit_dialog = YES; + } + break; + + case MENU_BOX_BUTTON_HELP: + + switch(atoi(get_lxdialog_output_string())) + { + case WANOPT_IDLE_FLAG: + case WANOPT_IDLE_MARK: + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, + "Please select Serial Line Idle."); + break; + + default: + ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", + get_lxdialog_output_string())); + rc = NO; + exit_dialog = YES; + } + break; + + case MENU_BOX_BUTTON_EXIT: + exit_dialog = YES; + break; + }//switch(*selection_index) + + if(exit_dialog == NO){ + goto again; + } + +cleanup: + return rc; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/util/wancfg/menu_hardware_setup.h b/util/wancfg/menu_hardware_setup.h index e1a9504..3a5ef4d 100644 --- a/util/wancfg/menu_hardware_setup.h +++ b/util/wancfg/menu_hardware_setup.h @@ -34,6 +34,7 @@ class menu_hardware_setup : public menu_base { void form_s514_serial_options_menu(string& str, int& number_of_items); void form_s514_TE1_options_menu(string& str, int& number_of_items); void form_TE3_options_menu(string& str, int& number_of_items); + void form_AFT_Serial_options_menu(string& str, int& number_of_items); public: @@ -44,4 +45,48 @@ public: int run(OUT int * selection_index); }; + +class menu_hardware_serial_connection_type : public menu_base { + + char lxdialog_path[MAX_PATH_LENGTH]; + conf_file_reader* cfr; + +public: + menu_hardware_serial_connection_type( IN char * lxdialog_path, + IN conf_file_reader* ptr_cfr); + + ~menu_hardware_serial_connection_type(); + + int run(OUT int * selection_index); +}; + +class menu_hardware_serial_line_coding : public menu_base { + + char lxdialog_path[MAX_PATH_LENGTH]; + conf_file_reader* cfr; + +public: + menu_hardware_serial_line_coding( IN char * lxdialog_path, + IN conf_file_reader* ptr_cfr); + + ~menu_hardware_serial_line_coding(); + + int run(OUT int * selection_index); +}; + +class menu_hardware_serial_line_idle : public menu_base { + + char lxdialog_path[MAX_PATH_LENGTH]; + conf_file_reader* cfr; + +public: + menu_hardware_serial_line_idle( IN char * lxdialog_path, + IN conf_file_reader* ptr_cfr); + + ~menu_hardware_serial_line_idle(); + + int run(OUT int * selection_index); +}; + #endif + diff --git a/util/wancfg/menu_hardware_te1_card_advanced_options.cpp b/util/wancfg/menu_hardware_te1_card_advanced_options.cpp index 6d9a9f4..f863d3c 100644 --- a/util/wancfg/menu_hardware_te1_card_advanced_options.cpp +++ b/util/wancfg/menu_hardware_te1_card_advanced_options.cpp @@ -125,6 +125,17 @@ char* te1_options_help_str = " from wanpipe1, will loose its clock thus\n" " resulting in unpredictable operation.\n"; +char* bri_options_help_str = +"BRI Master Clock Port:\n" +"YES - this port is MASTER clock for all OTHER\n" +" ports on this A500 card\n" +"NO - this port is in NORMAL clock mode\n" +"\n" +"IMPORTANT:\n" +" If MASTER port is in disconnected state or\n" +" stopped, all ports on the A500 card will\n" +" run on internal card's clock.\n"; + enum TE1_ADVANCED_OPTIONS{ TE1_MEDIA=1, @@ -137,9 +148,74 @@ enum TE1_ADVANCED_OPTIONS{ AFT_FE_TXTRISTATE, TE_REF_CLOCK, E1_SIG_MODE, - TE_HIGHIMPEDANCE + TE_HIGHIMPEDANCE, + BRI_CLOCK_MASTER, + TE_RX_SLEVEL }; + +//////////////////////////////////////////////////////////////////////////////////// +/* +TE_RX_SLEVEL: Receiver Sensitivity (Max Cable Loss Allowed) (dB) +The user will have the following option to choose: +1. Hi-Imedance mode: +30 dB +22.5 dB +17.5 dB +12 dB + +Depending on selection, write the following values into configuration files: +300 +225 +175 +120 + +2. Normal mode: +12 dB +18 dB +30 dB +36 dB (for T1) +43 dB (for E1) + +Depending on selection, write the following values into configuration files: +120 +180 +300 +360 +430 +*/ +typedef struct _te_rx_slevel +{ + const char* name; + unsigned int value; +}te_rx_slevel_t; + +const te_rx_slevel_t high_impedance_rx_slevel[] = { + {"30 dB", 300}, + {"22.5 dB", 225}, + {"17.5 dB", 175}, + {"12 dB", 120}, + {NULL, 0} +}; + +const te_rx_slevel_t t1_normal_mode_rx_slevel[] = { + {"12 dB", 120}, + {"18 dB", 180}, + {"30 dB", 300}, + {"36 dB", 360}, + {NULL, 0} +}; + +const te_rx_slevel_t e1_normal_mode_rx_slevel[] = { + {"12 dB", 120}, + {"18 dB", 180}, + {"30 dB", 300}, + {"43 dB", 430}, + {NULL, 0} +}; +//////////////////////////////////////////////////////////////////////////////////// + + #define DBG_MENU_HARDWARE_TE1_CARD_ADVANCED_OPTIONS 1 menu_hardware_te1_card_advanced_options:: @@ -166,7 +242,7 @@ int menu_hardware_te1_card_advanced_options::run(OUT int * selection_index) char tmp_buff[MAX_PATH_LENGTH]; unsigned int option_selected; char exit_dialog; - int number_of_items; + int number_of_items, n, rx_slevel_ind; //help text box text_box tb; @@ -174,6 +250,7 @@ int menu_hardware_te1_card_advanced_options::run(OUT int * selection_index) link_def_t * link_def; wandev_conf_t *linkconf; sdla_te_cfg_t* te_cfg; + const te_rx_slevel_t *te_rx_slevel_ptr; input_box_active_channels act_channels_ip; @@ -198,110 +275,158 @@ again: Debug(DBG_MENU_HARDWARE_TE1_CARD_ADVANCED_OPTIONS, ("cfr->link_defs->name: %s\n", link_def->name)); + if(te_cfg->high_impedance_mode){ + te_rx_slevel_ptr = &high_impedance_rx_slevel[0]; + }else{ + if( linkconf->fe_cfg.media == WAN_MEDIA_T1){ + te_rx_slevel_ptr = &t1_normal_mode_rx_slevel[0]; + }else{ + te_rx_slevel_ptr = &e1_normal_mode_rx_slevel[0]; + } + } + + ///////////////////////////////////////////////////////////////////////////////////// + //find index of line in menue using current rx_slevel + n=0;rx_slevel_ind=0; + while(te_rx_slevel_ptr[n].name != NULL){ + if(te_rx_slevel_ptr[n].value == (unsigned int)te_cfg->rx_slevel){ + rx_slevel_ind = n; + break; + } + n++; + } + + ///////////////////////////////////////////////////////////////////////////////////// if(linkconf->fe_cfg.media == WAN_MEDIA_T1){ - number_of_items = 7; + number_of_items = 7; }else if(linkconf->fe_cfg.media == WAN_MEDIA_E1){ - number_of_items = 7; + number_of_items = 7; + }else if(linkconf->fe_cfg.media == WAN_MEDIA_BRI){ + number_of_items = 1; }else{ - ERR_DBG_OUT(("Unknown Media Type!! te_cfg.media: 0x%X\n", linkconf->fe_cfg.media)); - return NO; + ERR_DBG_OUT(("Unknown Media Type!! te_cfg.media: 0x%X\n", linkconf->fe_cfg.media)); + return NO; } menu_str = ""; - ////////////////////////////////////////////////////////////////////////////////////// - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_MEDIA); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Physical Medium--> %s\" ", - MEDIA_DECODE(&linkconf->fe_cfg)); - menu_str += tmp_buff; - - ////////////////////////////////////////////////////////////////////////////////////// - - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_LCODE); - menu_str += tmp_buff; - - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Line decoding----> %s\" ", - LCODE_DECODE(&linkconf->fe_cfg)); - menu_str += tmp_buff; - - ////////////////////////////////////////////////////////////////////////////////////// - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_FRAME); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Framing----------> %s\" ", - FRAME_DECODE(&linkconf->fe_cfg)); - menu_str += tmp_buff; - - ////////////////////////////////////////////////////////////////////////////////////// - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_CLOCK); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"TE clock mode----> %s\" ", - TECLK_DECODE(&linkconf->fe_cfg)); + if(linkconf->fe_cfg.media == WAN_MEDIA_BRI){ + ////////////////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", BRI_CLOCK_MASTER); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"BRI Master Clock Port--> %s\" ", + (linkconf->fe_cfg.cfg.bri.clock_mode == WANOPT_YES ? "Yes":"No")); #if 0 - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"TE clock mode----> %s\" ", - (linkconf->fe_cfg.cfg.te_cfg.te_clock == WANOPT_NORMAL_CLK ? "Normal" : "Master")); + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"TE clock mode----> %s\" ", + (linkconf->fe_cfg.cfg.te_cfg.te_clock == WANOPT_NORMAL_CLK ? "Normal" : "Master")); #endif - menu_str += tmp_buff; - ////////////////////////////////////////////////////////////////////////////////////// + menu_str += tmp_buff; + + }else{ + ////////////////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_MEDIA); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Physical Medium--> %s\" ", + MEDIA_DECODE(&linkconf->fe_cfg)); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////////////////// + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_LCODE); + menu_str += tmp_buff; + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Line decoding----> %s\" ", + LCODE_DECODE(&linkconf->fe_cfg)); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_FRAME); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Framing----------> %s\" ", + FRAME_DECODE(&linkconf->fe_cfg)); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_CLOCK); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"TE clock mode----> %s\" ", + TECLK_DECODE(&linkconf->fe_cfg)); +#if 0 + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"TE clock mode----> %s\" ", + (linkconf->fe_cfg.cfg.te_cfg.te_clock == WANOPT_NORMAL_CLK ? "Normal" : "Master")); +#endif + menu_str += tmp_buff; + ////////////////////////////////////////////////////////////////////////////////////// + } //on AFT it must be 'ALL' because channelization is done on per-group-of-channels basis. //on S514-cards it is configurable here if(linkconf->card_type == WANOPT_S51X){ - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_ACTIVE_CH); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Act. channels----> %s\" ", - link_def->active_channels_string); - menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE1_ACTIVE_CH); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Act. channels----> %s\" ", + link_def->active_channels_string); + menu_str += tmp_buff; } ////////////////////////////////////////////////////////////////////////////////////// if(linkconf->fe_cfg.media == WAN_MEDIA_T1){ - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", T1_LBO); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"LBO--------------> %s\" ", - LBO_DECODE(&linkconf->fe_cfg)); - menu_str += tmp_buff; - }else{ - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", E1_LBO); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"LBO--------------> %s\" ", - LBO_DECODE(&linkconf->fe_cfg)); - menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", T1_LBO); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"LBO--------------> %s\" ", + LBO_DECODE(&linkconf->fe_cfg)); + menu_str += tmp_buff; + }else if(linkconf->fe_cfg.media == WAN_MEDIA_E1){ + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", E1_LBO); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"LBO--------------> %s\" ", + LBO_DECODE(&linkconf->fe_cfg)); + menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", E1_SIG_MODE); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Signalling Mode--> %s\" ", - (FE_SIG_MODE(&linkconf->fe_cfg) == WAN_TE1_SIG_CCS ? "CCS":"CAS")); - menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", E1_SIG_MODE); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Signalling Mode--> %s\" ", + (FE_SIG_MODE(&linkconf->fe_cfg) == WAN_TE1_SIG_CCS ? "CCS":"CAS")); + menu_str += tmp_buff; } ////////////////////////////////////////////////////////////////////////////////////// - if(linkconf->card_type == WANOPT_AFT || - linkconf->card_type == WANOPT_AFT104 ){ - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_FE_TXTRISTATE); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Disable Transmitter---> %s\" ", - (linkconf->fe_cfg.tx_tristate_mode == WANOPT_YES ? "YES" : "NO")); - menu_str += tmp_buff; + if(linkconf->fe_cfg.media != WAN_MEDIA_BRI && + (linkconf->card_type == WANOPT_AFT || linkconf->card_type == WANOPT_AFT104)){ - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE_REF_CLOCK); - menu_str += tmp_buff; - if(te_cfg->te_ref_clock == 0){ - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Reference Clock Port--> %s\" ", "Not Used"); - }else{ - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Reference Clock Port--> %d\" ", - te_cfg->te_ref_clock); - } - menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_FE_TXTRISTATE); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Disable Transmitter---> %s\" ", + (linkconf->fe_cfg.tx_tristate_mode == WANOPT_YES ? "YES" : "NO")); + menu_str += tmp_buff; + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE_REF_CLOCK); + menu_str += tmp_buff; + if(te_cfg->te_ref_clock == 0){ + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Reference Clock Port--> %s\" ", "Not Used"); + }else{ + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Reference Clock Port--> %d\" ", + te_cfg->te_ref_clock); + } + menu_str += tmp_buff; } - ////////////////////////////////////////////////////////////////////////////////////// - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE_HIGHIMPEDANCE); - menu_str += tmp_buff; - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"High Impedance----------> %s\" ", - (te_cfg->high_impedance_mode == WANOPT_YES ? "YES" : "NO")); - menu_str += tmp_buff; + if(linkconf->fe_cfg.media != WAN_MEDIA_BRI){ + ////////////////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE_HIGHIMPEDANCE); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"High Impedance----------> %s\" ", + (te_cfg->high_impedance_mode == WANOPT_YES ? "YES" : "NO")); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TE_RX_SLEVEL); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Rx Sensetivity Level----> %s\" ", + te_rx_slevel_ptr[rx_slevel_ind].name); + menu_str += tmp_buff; + } ////////////////////////////////////////////////////////////////////////////////////// //create the explanation text for the menu @@ -432,6 +557,46 @@ again: break; } break; +#if 1 + case TE_RX_SLEVEL: + { + menu_rx_slevel rx_slevel(lxdialog_path, cfr); + if(rx_slevel.run(selection_index) == NO){ + rc = NO; + exit_dialog = YES; + } + } + break; +#endif + case BRI_CLOCK_MASTER: + if(linkconf->fe_cfg.cfg.bri.clock_mode == WANOPT_YES){ + //It is currently Master, ask if user wants to change Normal mode + snprintf(tmp_buff, MAX_PATH_LENGTH, "Do you want to use this line in Normal clock mode?"); + }else{ + //It is currently in Normal mode, ask if user wants to change Master mode + snprintf(tmp_buff, MAX_PATH_LENGTH, "Do you want to use this line in Normal clock mode?"); + } + + if(yes_no_question( selection_index, + lxdialog_path, + NO_PROTOCOL_NEEDED, + tmp_buff) == NO){ + return NO; + } + + switch(*selection_index) + { + case YES_NO_TEXT_BOX_BUTTON_YES: + if(linkconf->fe_cfg.cfg.bri.clock_mode == WANOPT_NO){ + //was Normal - change to Master + linkconf->fe_cfg.cfg.bri.clock_mode = WANOPT_YES; + }else{ + //was Master - change to Normal + linkconf->fe_cfg.cfg.bri.clock_mode = WANOPT_NO; + } + break; + } + break; case TE_REF_CLOCK: { @@ -542,7 +707,11 @@ If this option is used, TE1 Clock MUST be set to Master!"); break; case MENU_BOX_BUTTON_HELP: - tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, te1_options_help_str); + if(linkconf->fe_cfg.media == WAN_MEDIA_BRI){ + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, bri_options_help_str); + }else{ + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, te1_options_help_str); + } break; case MENU_BOX_BUTTON_EXIT: @@ -566,7 +735,8 @@ cleanup: enum { RM_BATTTHRESH=1, - RM_BATTDEBOUNCE + RM_BATTDEBOUNCE, + RM_NETWORK_SYNC }; menu_hardware_analog_card_advanced_options:: @@ -642,6 +812,13 @@ again: menu_str += tmp_buff; number_of_items++; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", RM_NETWORK_SYNC); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"External Network Sync--> %s\" ", + (remora_cfg->network_sync == WANOPT_YES ? "Yes" : "No")); + menu_str += tmp_buff; + number_of_items++; + ////////////////////////////////////////////////////////////////////////////////////// //create the explanation text for the menu snprintf(tmp_buff, MAX_PATH_LENGTH, @@ -749,6 +926,33 @@ show_RM_BATTDEBOUNCE_input_box: }//switch(*selection_index) break; + case RM_NETWORK_SYNC: + snprintf(tmp_buff, MAX_PATH_LENGTH, "Do you want to %s External Network Sync?", + (remora_cfg->network_sync == WANOPT_NO ? "Enable" : "Disable")); + + if(yes_no_question( selection_index, + lxdialog_path, + NO_PROTOCOL_NEEDED, + tmp_buff) == NO){ + return NO; + } + + switch(*selection_index) + { + case YES_NO_TEXT_BOX_BUTTON_YES: + if(remora_cfg->network_sync == WANOPT_NO){ + //was disabled - enable + remora_cfg->network_sync = WANOPT_YES; + }else{ + //was enabled - disable + remora_cfg->network_sync = WANOPT_NO; + } + break; + } + break; + + + default: ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", get_lxdialog_output_string())); @@ -758,7 +962,11 @@ show_RM_BATTDEBOUNCE_input_box: break; case MENU_BOX_BUTTON_HELP: - tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, te1_options_help_str); + if(linkconf->fe_cfg.media == WAN_MEDIA_BRI){ + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, bri_options_help_str); + }else{ + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, te1_options_help_str); + } break; case MENU_BOX_BUTTON_EXIT: @@ -773,3 +981,146 @@ show_RM_BATTDEBOUNCE_input_box: cleanup: return rc; } + +#if 1 +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +//RX SLEVEL +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define DBG_MENU_RX_SLEVEL 1 + +menu_rx_slevel::menu_rx_slevel(IN char * lxdialog_path, IN conf_file_reader* ptr_cfr) +{ + Debug(DBG_MENU_RX_SLEVEL, ("menu_rx_slevel::%s()\n", __FUNCTION__)); + snprintf(this->lxdialog_path, MAX_PATH_LENGTH, "%s", lxdialog_path); + this->cfr = ptr_cfr; +} + +menu_rx_slevel::~menu_rx_slevel() +{ + Debug(DBG_MENU_RX_SLEVEL, ("menu_rx_slevel::~%s()\n", __FUNCTION__)); +} + +int menu_rx_slevel::run(OUT int * selection_index) +{ + string menu_str; + int rc; + char tmp_buff[MAX_PATH_LENGTH]; + char exit_dialog; + int number_of_items, n; + unsigned char media; + + //help text box + text_box tb; + + link_def_t * link_def; + wandev_conf_t *linkconf; + const te_rx_slevel_t *te_rx_slevel_ptr; + + Debug(DBG_MENU_RX_SLEVEL, ("menu_rx_slevel::%s()\n", __FUNCTION__)); + +again: + + link_def = cfr->link_defs; + linkconf = cfr->link_defs->linkconf; + + Debug(DBG_MENU_RX_SLEVEL, ("cfr->link_defs->name: %s\n", link_def->name)); + + rc = YES; + exit_dialog = NO; + media = linkconf->fe_cfg.media; + + if(linkconf->fe_cfg.cfg.te_cfg.high_impedance_mode){ + te_rx_slevel_ptr = &high_impedance_rx_slevel[0]; + }else{ + if( media == WAN_MEDIA_T1){ + te_rx_slevel_ptr = &t1_normal_mode_rx_slevel[0]; + }else{ + te_rx_slevel_ptr = &e1_normal_mode_rx_slevel[0]; + } + } + + + Debug(DBG_MENU_RX_SLEVEL, ("linkconf->card_type: DEC:%d, HEX: 0x%X\n", + linkconf->card_type, linkconf->card_type)); + + number_of_items = 0; + menu_str = " "; +/* + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WAN_E1_75); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"75 OH\" "); + menu_str += tmp_buff; +*/ + //add the lines to the menue + n=0; + while(te_rx_slevel_ptr[n].name != NULL){ + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", te_rx_slevel_ptr[n].value); + menu_str += (char*)tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", te_rx_slevel_ptr[n].name); + menu_str += tmp_buff; + number_of_items++; + n++; + } + + ////////////////////////////////////////////////////////////////////////////////////// + //create the explanation text for the menu + snprintf(tmp_buff, MAX_PATH_LENGTH, +"\n------------------------------------------\ +\nSelect Receiver Sensitivity for Wan Device: %s", link_def->name); + + if(set_configuration( YES,//indicates to call V2 of the function + MENU_BOX_BACK,//MENU_BOX_SELECT, + lxdialog_path, + "SELECT RX SENSETIVITY LEVEL", + WANCFG_PROGRAM_NAME, + tmp_buff, + MENU_HEIGTH, MENU_WIDTH, + number_of_items, + (char*)menu_str.c_str() + ) == NO){ + rc = NO; + goto cleanup; + } + + if(show(selection_index) == NO){ + rc = NO; + goto cleanup; + } + ////////////////////////////////////////////////////////////////////////////////////// + + exit_dialog = NO; + switch(*selection_index) + { + case MENU_BOX_BUTTON_SELECT: + Debug(DBG_MENU_RX_SLEVEL, + ("hardware_setup: option selected for editing: %s\n", get_lxdialog_output_string())); + + linkconf->fe_cfg.cfg.te_cfg.rx_slevel = atoi(get_lxdialog_output_string()); + exit_dialog = YES; + break; + + case MENU_BOX_BUTTON_HELP: + + switch(atoi(get_lxdialog_output_string())) + { + default: + tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, + option_not_implemented_yet_help_str); + break; + } + break; + + case MENU_BOX_BUTTON_EXIT: + exit_dialog = YES; + break; + }//switch(*selection_index) + + + if(exit_dialog == NO){ + goto again; + } + +cleanup: + return rc; +} +#endif diff --git a/util/wancfg/menu_hardware_te1_card_advanced_options.h b/util/wancfg/menu_hardware_te1_card_advanced_options.h index 4d37d34..f795085 100644 --- a/util/wancfg/menu_hardware_te1_card_advanced_options.h +++ b/util/wancfg/menu_hardware_te1_card_advanced_options.h @@ -56,4 +56,18 @@ public: int run(OUT int * selection_index); }; +#if 1 +class menu_rx_slevel : public menu_base { + + char lxdialog_path[MAX_PATH_LENGTH]; + conf_file_reader* cfr; + +public: + menu_rx_slevel(IN char * lxdialog_path, IN conf_file_reader* ptr_cfr); + ~menu_rx_slevel(); + + int run(OUT int * selection_index); + +}; +#endif #endif diff --git a/util/wancfg/menu_net_interface_ip_configuration.cpp b/util/wancfg/menu_net_interface_ip_configuration.cpp index f70b812..27fc632 100644 --- a/util/wancfg/menu_net_interface_ip_configuration.cpp +++ b/util/wancfg/menu_net_interface_ip_configuration.cpp @@ -413,10 +413,11 @@ as a default route?"); //if p-to-p is know use it for gateway, if not put '0.0.0.0' if(interface_file_reader.if_config.point_to_point_ipaddr[0] != '\0'){ - strcpy(interface_file_reader.if_config.gateway, - interface_file_reader.if_config.point_to_point_ipaddr); + strlcpy(interface_file_reader.if_config.gateway, + interface_file_reader.if_config.point_to_point_ipaddr, + IF_CONFIG_BUF_LEN); }else{ - strcpy(interface_file_reader.if_config.gateway, "0.0.0.0"); + strlcpy(interface_file_reader.if_config.gateway, "0.0.0.0",IF_CONFIG_BUF_LEN); } break; diff --git a/util/wancfg/menu_net_interface_operation_mode.cpp b/util/wancfg/menu_net_interface_operation_mode.cpp index 37c04e8..6552d9e 100644 --- a/util/wancfg/menu_net_interface_operation_mode.cpp +++ b/util/wancfg/menu_net_interface_operation_mode.cpp @@ -162,7 +162,7 @@ again: if(show(selection_index) == NO){ rc = NO; goto cleanup; - } + } ////////////////////////////////////////////////////////////////////////////////////// Debug(DBG_MENU_NET_INTERFACE_OPERATION_MODE, @@ -232,6 +232,16 @@ again: exit_dialog = YES; break; + case 12: + chandef->usedby = WP_NETGRAPH; + exit_dialog = YES; + break; + + case 13: + chandef->usedby = TDM_VOICE_API; + exit_dialog = YES; + break; + default: ERR_DBG_OUT(("Invalid option selected for editing!! selection: %s\n", get_lxdialog_output_string())); @@ -255,6 +265,8 @@ again: case 9: case 10: case 11: + case 12: + case 13: tb.show_help_message(lxdialog_path, NO_PROTOCOL_NEEDED, net_if_operational_mode_help_str); break; @@ -294,6 +306,8 @@ int menu_net_interface_operation_mode::form_operation_modes_menu_for_protocol( Debug(DBG_MENU_NET_INTERFACE_OPERATION_MODE, ("protocol: %d\n", protocol)); + number_of_items_in_menu = 0; + switch(protocol) { case PROTOCOL_TDM_VOICE: @@ -302,6 +316,13 @@ int menu_net_interface_operation_mode::form_operation_modes_menu_for_protocol( number_of_items_in_menu = 1; break; + + case PROTOCOL_TDM_VOICE_API: + operation_modes_str = QUOTED_13; + operation_modes_str += OP_MODE_TDMV_API; + + number_of_items_in_menu = 1; + break; case WANCONFIG_X25: operation_modes_str = QUOTED_1; @@ -317,37 +338,58 @@ int menu_net_interface_operation_mode::form_operation_modes_menu_for_protocol( case WANCONFIG_MFR: operation_modes_str = QUOTED_1; operation_modes_str += OP_MODE_WANPIPE; + number_of_items_in_menu++; operation_modes_str += QUOTED_2; operation_modes_str += OP_MODE_API; + number_of_items_in_menu++; +#if defined(__LINUX__) operation_modes_str += QUOTED_3; operation_modes_str += OP_MODE_BRIDGE; + number_of_items_in_menu++; operation_modes_str += QUOTED_4; operation_modes_str += OP_MODE_BRIDGE_NODE; - + number_of_items_in_menu++; +#endif operation_modes_str += QUOTED_6; operation_modes_str += OP_MODE_STACK; + number_of_items_in_menu++; + +#if defined(__FreeBSD__) + operation_modes_str += QUOTED_12; + operation_modes_str += OP_MODE_NETGRAPH; + number_of_items_in_menu ++; +#endif - number_of_items_in_menu = 5; break; //case WANCONFIG_PPP: case WANCONFIG_MPPP://and WANCONFIG_MPROT too operation_modes_str = QUOTED_1; operation_modes_str += OP_MODE_WANPIPE; + number_of_items_in_menu++; +#if defined(__LINUX__) operation_modes_str += QUOTED_3; operation_modes_str += OP_MODE_BRIDGE; + number_of_items_in_menu++; operation_modes_str += QUOTED_4; operation_modes_str += OP_MODE_BRIDGE_NODE; - + number_of_items_in_menu++; +#endif operation_modes_str += QUOTED_6; operation_modes_str += OP_MODE_STACK; - - number_of_items_in_menu = 4; + number_of_items_in_menu++; + +#if defined(__FreeBSD__) + operation_modes_str += QUOTED_12; + operation_modes_str += OP_MODE_NETGRAPH; + number_of_items_in_menu ++; +#endif + break; case WANCONFIG_HDLC: @@ -356,18 +398,24 @@ int menu_net_interface_operation_mode::form_operation_modes_menu_for_protocol( operation_modes_str = QUOTED_1; operation_modes_str += OP_MODE_WANPIPE; + number_of_items_in_menu ++; operation_modes_str += QUOTED_2; operation_modes_str += OP_MODE_API; - - number_of_items_in_menu = 2; + number_of_items_in_menu ++; if(linkconf->card_type == WANOPT_AFT || linkconf->card_type == WANOPT_AFT104){ operation_modes_str += QUOTED_11; operation_modes_str += OP_MODE_TDM_API; - number_of_items_in_menu = 3; + number_of_items_in_menu ++; } +#if defined(__FreeBSD__) + operation_modes_str += QUOTED_12; + operation_modes_str += OP_MODE_NETGRAPH; + number_of_items_in_menu ++; +#endif + //treaded as a protocol //operation_modes_str += QUOTED_8; //operation_modes_str += OP_MODE_VoIP; @@ -383,20 +431,30 @@ int menu_net_interface_operation_mode::form_operation_modes_menu_for_protocol( operation_modes_str = QUOTED_1; operation_modes_str += OP_MODE_WANPIPE; + number_of_items_in_menu ++; operation_modes_str += QUOTED_2; operation_modes_str += OP_MODE_API; + number_of_items_in_menu ++; +#if defined(__LINUX__) operation_modes_str += QUOTED_3; operation_modes_str += OP_MODE_BRIDGE; + number_of_items_in_menu ++; operation_modes_str += QUOTED_4; operation_modes_str += OP_MODE_BRIDGE_NODE; - + number_of_items_in_menu ++; +#endif operation_modes_str += QUOTED_6; operation_modes_str += OP_MODE_STACK; + number_of_items_in_menu ++; - number_of_items_in_menu = 5; +#if defined(__FreeBSD__) + operation_modes_str += QUOTED_12; + operation_modes_str += OP_MODE_NETGRAPH; + number_of_items_in_menu ++; +#endif break; case WANCONFIG_LIP_ATM: @@ -540,15 +598,19 @@ int menu_net_interface_operation_mode::form_operation_modes_menu_for_protocol( case WANCONFIG_AFT: //"AFT Mode" - if(link_defs->card_version != A200_ADPTR_ANALOG){ + if(link_defs->card_version != A200_ADPTR_ANALOG ){ + operation_modes_str = QUOTED_1; operation_modes_str += OP_MODE_WANPIPE; + number_of_items_in_menu ++; operation_modes_str += QUOTED_2; operation_modes_str += OP_MODE_API; + number_of_items_in_menu ++; operation_modes_str += QUOTED_11; operation_modes_str += OP_MODE_TDM_API; + number_of_items_in_menu ++; //operation_modes_str += QUOTED_8; //operation_modes_str += OP_MODE_VoIP; @@ -559,7 +621,12 @@ int menu_net_interface_operation_mode::form_operation_modes_menu_for_protocol( // operation_modes_str += QUOTED_6; // operation_modes_str += OP_MODE_STACK; - number_of_items_in_menu = 3; +#if defined(__FreeBSD__) + operation_modes_str += QUOTED_12; + operation_modes_str += OP_MODE_NETGRAPH; + number_of_items_in_menu ++; +#endif + }else{ operation_modes_str += QUOTED_2; operation_modes_str += OP_MODE_API; diff --git a/util/wancfg/menu_net_interface_setup.cpp b/util/wancfg/menu_net_interface_setup.cpp index e4243d4..82849b4 100644 --- a/util/wancfg/menu_net_interface_setup.cpp +++ b/util/wancfg/menu_net_interface_setup.cpp @@ -40,7 +40,8 @@ enum NET_IF_OPTIONS{ TDMV_D_CHANNEL, CONFIGURE_NEXT_LEVEL, TDMV_HWEC, - TDMV_HWEC_MAP + TDMV_HWEC_MAP, + TDMV_HW_DTMF }; char* net_if_name_help_str = @@ -255,6 +256,7 @@ again: { case WANPIPE: case BRIDGE_NODE: + case WP_NETGRAPH: //check what was in the parsed file: if(interface_file_reader->if_config.gateway[0] != '\0'){ @@ -285,6 +287,7 @@ again: break; case TDM_VOICE: + case TDM_VOICE_API: snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TDMV_SPAN_NUMBER); menu_str += tmp_buff; snprintf(tmp_buff, MAX_PATH_LENGTH, " \"TDM Voice Span-----------------> %d\" ", @@ -300,7 +303,8 @@ again: menu_str += tmp_buff; */ - if(link_defs->card_version != A200_ADPTR_ANALOG){ + if(link_defs->card_version != A200_ADPTR_ANALOG && link_defs->card_version != AFT_ADPTR_ISDN){ + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TDMV_D_CHANNEL); menu_str += tmp_buff; @@ -315,19 +319,20 @@ again: } //add_hw_echo_cancel_items(menu_str, link_defs, wan_xilinx_conf); - add_hw_echo_cancel_items(menu_str, chandef); + add_hw_echo_cancel_items(menu_str, chandef, tdmv_conf); //} + break; case API: case TDM_API: //if(link_defs->card_version == A200_ADPTR_ANALOG){ if(local_cfr->link_defs->linkconf->card_type == WANOPT_AFT && - (link_defs->card_version == A104_ADPTR_4TE1 || link_defs->card_version == A101_ADPTR_1TE1 || - link_defs->card_version == A200_ADPTR_ANALOG)){ + (link_defs->card_version == A104_ADPTR_4TE1 || link_defs->card_version == A101_ADPTR_1TE1 || + link_defs->card_version == A200_ADPTR_ANALOG || link_defs->card_version == AFT_ADPTR_ISDN)){ //add_hw_echo_cancel_items(menu_str, link_defs, wan_xilinx_conf); - add_hw_echo_cancel_items(menu_str, chandef); + add_hw_echo_cancel_items(menu_str, chandef, tdmv_conf); } break; @@ -776,6 +781,32 @@ show_hwec_map_input_box: }else{ //was enabled - disable chandef->chanconf->hwec.enable = WANOPT_NO; + tdmv_conf->hw_dtmf = WANOPT_NO; + } + break; + } + break; + + case TDMV_HW_DTMF: + snprintf(tmp_buff, MAX_PATH_LENGTH, "Do you want to %s Hardware DTMF Detection?", + (tdmv_conf->hw_dtmf == WANOPT_NO ? "Enable" : "Disable")); + + if(yes_no_question( selection_index, + lxdialog_path, + NO_PROTOCOL_NEEDED, + tmp_buff) == NO){ + return NO; + } + + switch(*selection_index) + { + case YES_NO_TEXT_BOX_BUTTON_YES: + if(tdmv_conf->hw_dtmf == WANOPT_NO){ + //was disabled - enable + tdmv_conf->hw_dtmf = WANOPT_YES; + }else{ + //was enabled - disable + tdmv_conf->hw_dtmf = WANOPT_NO; } break; } @@ -892,7 +923,8 @@ void menu_net_interface_setup::add_hw_echo_cancel_items(string& menu_str, #endif void menu_net_interface_setup::add_hw_echo_cancel_items(string& menu_str, - chan_def_t* chandef) + chan_def_t* chandef, + wan_tdmv_conf_t* tdmv_conf) { char tmp_buff[MAX_PATH_LENGTH]; @@ -914,4 +946,12 @@ void menu_net_interface_setup::add_hw_echo_cancel_items(string& menu_str, menu_str += tmp_buff; } */ + if(chandef->chanconf->hwec.enable == WANOPT_YES){ + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", TDMV_HW_DTMF); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Hardware DTMF Detection---------> %s\" ", + (tdmv_conf->hw_dtmf == WANOPT_YES ? "Yes" : "No")); + menu_str += tmp_buff; + } + } diff --git a/util/wancfg/menu_net_interface_setup.h b/util/wancfg/menu_net_interface_setup.h index 199d5df..2c20b9a 100644 --- a/util/wancfg/menu_net_interface_setup.h +++ b/util/wancfg/menu_net_interface_setup.h @@ -34,7 +34,7 @@ class menu_net_interface_setup : public menu_base{ wan_xilinx_conf_t *wan_xilinx_conf); #endif - void add_hw_echo_cancel_items(string& menu_str, chan_def_t* chandef); + void add_hw_echo_cancel_items(string& menu_str, chan_def_t* chandef, wan_tdmv_conf_t* tdmv_conf); public: menu_net_interface_setup( IN char * lxdialog_path, diff --git a/util/wancfg/menu_new_device_configuration.cpp b/util/wancfg/menu_new_device_configuration.cpp index 7831f9c..2a26c13 100644 --- a/util/wancfg/menu_new_device_configuration.cpp +++ b/util/wancfg/menu_new_device_configuration.cpp @@ -150,6 +150,7 @@ again: case WAN_MEDIA_56K: case WAN_MEDIA_DS3: case WAN_MEDIA_E3: + case WAN_MEDIA_SERIAL: //for now only un-channelized TE3 supported max_valid_number_of_logical_channels = 1; break; @@ -158,6 +159,10 @@ again: max_valid_number_of_logical_channels = MAX_FXOFXS_CHANNELS; break; + case WAN_MEDIA_BRI: + max_valid_number_of_logical_channels = MAX_BRI_TIMESLOTS; + break; + default: ERR_DBG_OUT(("Invalid Media Type!! (0x%X)\n", fe_cfg->media)); return NO; @@ -190,11 +195,16 @@ again: snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Hardware Setup--> %s\" ", get_card_type_string(linkconf->card_type, link_def->card_version)); break; - - case AFT_ADPTR_56K: - snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Hardware Setup--> %s\" ", - get_card_type_string(linkconf->card_type, link_def->card_version)); - break; + + case AFT_ADPTR_56K: + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Hardware Setup--> %s\" ", + get_card_type_string(linkconf->card_type, link_def->card_version)); + break; + + case AFT_ADPTR_ISDN: + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Hardware Setup--> %s (Line No: %d)\" ", + get_card_type_string(linkconf->card_type, link_def->card_version), fe_cfg->line_no); + break; default: snprintf(tmp_buff, MAX_PATH_LENGTH, " \"Hardware Setup--> %s\" ", @@ -683,7 +693,7 @@ should be 'wagappp0' or 'waga?#' where '?' is alphabetical and '#' is numerical. if(obj_list->get_size() > 1){ Debug(DBG_MENU_NEW_DEVICE_CONFIG, ("-- 3\n")); - + //General case - more than one logical channel. //Usually AFT groups of channels because protocols are in the LIP layer. @@ -703,7 +713,7 @@ should be 'wagappp0' or 'waga?#' where '?' is alphabetical and '#' is numerical. }else{ Debug(DBG_MENU_NEW_DEVICE_CONFIG, ("-- 4\n")); - + //Special case - exactly one logical channel. if(chandef->chanconf->config_id == WANCONFIG_AFT || chandef->chanconf->config_id == WANCONFIG_AFT_TE3){ @@ -712,6 +722,7 @@ should be 'wagappp0' or 'waga?#' where '?' is alphabetical and '#' is numerical. "Protocol-------->", "HDLC Streaming"); }else{ + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s %s\" ", "Protocol-------->", get_protocol_string(chandef->chanconf->config_id)); @@ -749,6 +760,8 @@ should be 'wagappp0' or 'waga?#' where '?' is alphabetical and '#' is numerical. //new configuration - NO protocol yet if(obj_list->get_size() > 1){ + FUNC_DBG(); + //general case - more than one snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s %s: %s\" ", TIME_SLOT_GROUP_STR, @@ -812,6 +825,7 @@ int menu_new_device_configuration::check_aft_timeslot_groups_cfg() switch(chandef->usedby) { case TDM_VOICE: + case TDM_VOICE_API: local_is_there_a_voice_if = YES; if(tdmv_conf->span_no == 0){ diff --git a/util/wancfg/menu_select_card_type_manualy.cpp b/util/wancfg/menu_select_card_type_manualy.cpp index 73f513a..b329a89 100644 --- a/util/wancfg/menu_select_card_type_manualy.cpp +++ b/util/wancfg/menu_select_card_type_manualy.cpp @@ -166,6 +166,26 @@ again: snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", "A056 - 56k DDS"); menu_str += tmp_buff; + ////////////////////////////////////////////////////////////////////////// + // + // A500 - ISDN BRI Card + // + ////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_ADPTR_ISDN); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", "A500 - ISDN BRI"); + menu_str += tmp_buff; + + ////////////////////////////////////////////////////////////////////////// + // + // A14X - AFT Serial Card + // + ////////////////////////////////////////////////////////////////////////// + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", AFT_ADPTR_2SERIAL_V35X21); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", "A14X - Serial"); + menu_str += tmp_buff; + ////////////////////////////////////////////////////////////////////////// // // A300 Card @@ -276,6 +296,20 @@ again: global_card_version = A200_ADPTR_ANALOG; break; + case AFT_ADPTR_ISDN: + linkconf->card_type = WANOPT_AFT; + link_def->card_version = AFT_ADPTR_ISDN; + global_card_type = WANOPT_AFT; + global_card_version = AFT_ADPTR_ISDN; + break; + + case AFT_ADPTR_2SERIAL_V35X21: + linkconf->card_type = WANOPT_AFT; + link_def->card_version = AFT_ADPTR_2SERIAL_V35X21; + global_card_type = WANOPT_AFT; + global_card_version = AFT_ADPTR_2SERIAL_V35X21; + break; + case A300_ADPTR_U_1TE3: linkconf->card_type = WANOPT_AFT; link_def->card_version = A300_ADPTR_U_1TE3; diff --git a/util/wancfg/menu_select_protocol.cpp b/util/wancfg/menu_select_protocol.cpp index c1d8ca3..9d28933 100644 --- a/util/wancfg/menu_select_protocol.cpp +++ b/util/wancfg/menu_select_protocol.cpp @@ -154,14 +154,14 @@ int menu_select_protocol::form_protocol_list_valid_for_lip_layer(OUT string& men snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(WANCONFIG_MFR)); menu_str += tmp_buff; num_of_items++; - -#if defined(CONFIG_PRODUCT_WANPIPE_LIP_ATM) + +#if defined(CONFIG_PRODUCT_WANPIPE_LIP_ATM) if(link_defs->card_version != AFT_ADPTR_56K){ snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANCONFIG_LIP_ATM); menu_str += tmp_buff; snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(WANCONFIG_LIP_ATM)); menu_str += tmp_buff; - num_of_items++; + num_of_items++; } #endif } @@ -207,11 +207,12 @@ int menu_select_protocol::form_protocol_list_valid_for_hardware(string& menu_str break; case WANOPT_S51X: -#if defined(__LINUX__) && !BSD_DEBG snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANCONFIG_HDLC); menu_str += tmp_buff; snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(WANCONFIG_HDLC)); menu_str += tmp_buff; + num_of_items += 1; +#if defined(__LINUX__) && !BSD_DEBG switch(comm_port) { case WANOPT_PRI: @@ -219,9 +220,9 @@ int menu_select_protocol::form_protocol_list_valid_for_hardware(string& menu_str menu_str += tmp_buff; snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(WANCONFIG_EDUKIT)); menu_str += tmp_buff; + num_of_items += 1; break; } - num_of_items += 2; #endif break; @@ -236,27 +237,38 @@ int menu_select_protocol::form_protocol_list_valid_for_hardware(string& menu_str case A101_ADPTR_1TE1://WAN_MEDIA_T1: case A104_ADPTR_4TE1: case A200_ADPTR_ANALOG: - //the 'TDM_VOICE' should be displayed as protocol, not 'operational mode' + case AFT_ADPTR_ISDN: + //the 'TDM_VOICE' and 'TDM_VOICE_API' should be displayed as protocol, not 'operational mode' +#if defined(__LINUX__) || defined(__FreeBSD__) snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", PROTOCOL_TDM_VOICE); menu_str += tmp_buff; snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(PROTOCOL_TDM_VOICE)); menu_str += tmp_buff; + num_of_items ++; + + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", PROTOCOL_TDM_VOICE_API); + menu_str += tmp_buff; + snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(PROTOCOL_TDM_VOICE_API)); + menu_str += tmp_buff; + num_of_items ++; +#endif snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANCONFIG_HDLC); menu_str += tmp_buff; snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(WANCONFIG_HDLC)); menu_str += tmp_buff; + num_of_items ++; - num_of_items += 2; break; - - case A300_ADPTR_U_1TE3://WAN_MEDIA_DS3: + + case A300_ADPTR_U_1TE3://WAN_MEDIA_DS3: case AFT_ADPTR_56K: + case AFT_ADPTR_2SERIAL_V35X21://AFT Serial card snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%d\" ", WANCONFIG_HDLC); menu_str += tmp_buff; snprintf(tmp_buff, MAX_PATH_LENGTH, " \"%s\" ", get_protocol_string(WANCONFIG_HDLC)); menu_str += tmp_buff; - + num_of_items += 1; break; } diff --git a/util/wancfg/menu_wan_channel_cfg.cpp b/util/wancfg/menu_wan_channel_cfg.cpp index 3c1ed0d..7914d37 100644 --- a/util/wancfg/menu_wan_channel_cfg.cpp +++ b/util/wancfg/menu_wan_channel_cfg.cpp @@ -193,6 +193,7 @@ again: case WANCONFIG_TTY: case WANCONFIG_HDLC: case PROTOCOL_TDM_VOICE: + case PROTOCOL_TDM_VOICE_API: case WANCONFIG_AFT: //do nothing - there is nothing to configure. break; @@ -220,6 +221,7 @@ again: //case WANCONFIG_EDUKIT: //case WANCONFIG_HDLC: //case PROTOCOL_TDM_VOICE: + //case PROTOCOL_TDM_VOICE_API: //no interface setup needed //break; @@ -394,6 +396,7 @@ select_new_protocol: case WANCONFIG_LAPB: case WANCONFIG_HDLC: //exception case PROTOCOL_TDM_VOICE: //exception + case PROTOCOL_TDM_VOICE_API: //exception linkconf->config_id = WANCONFIG_AFT; break; @@ -692,9 +695,21 @@ int menu_wan_channel_cfg::handle_protocol_change( chanconf->mc = WANOPT_NO; chanconf->true_if_encoding = WANOPT_NO; chanconf->if_down = WANOPT_NO; - break; + case PROTOCOL_TDM_VOICE_API: + //no LIP layer + chandef->usedby = TDM_VOICE_API; + chanconf->hdlc_streaming = WANOPT_YES; + + chanconf->config_id = PROTOCOL_TDM_VOICE_API;//WANCONFIG_HDLC; + + chanconf->mtu = 1500; + chanconf->mc = WANOPT_NO; + chanconf->true_if_encoding = WANOPT_NO; + chanconf->if_down = WANOPT_NO; + break; + case WANCONFIG_MPPP: //special code for ADSL: diff --git a/util/wancfg/menu_wan_channel_cfg_v1.cpp b/util/wancfg/menu_wan_channel_cfg_v1.cpp index 19f8c9a..26e64e6 100644 --- a/util/wancfg/menu_wan_channel_cfg_v1.cpp +++ b/util/wancfg/menu_wan_channel_cfg_v1.cpp @@ -274,11 +274,12 @@ display_this_dialog: Debug(DBG_MENU_WAN_CHANNEL_CFG_V1, ("old_protocol: %d, new_protocol: %d\n", old_protocol, new_protocol)); +// ADBG +exit(0); if(new_protocol == 0){ //no protocol was selected, just redisplay goto again; } - if(old_protocol == new_protocol){ //no change, just redisplay goto again; diff --git a/util/wancfg/text_box.cpp b/util/wancfg/text_box.cpp index d630edc..d90540b 100644 --- a/util/wancfg/text_box.cpp +++ b/util/wancfg/text_box.cpp @@ -139,7 +139,7 @@ void text_box::show_help_message( IN char * lxdialog_path, FILE * help_msg_file; char dbg_tmp_buff[LEN_OF_DBG_BUFF]; va_list ap; - char* help_msg_file_name = "./wancfg_help_msg_file_name"; + char* help_msg_file_name = "/tmp/wancfg_help_msg_file_name"; char* remove_help_msg_file = "rm -rf wancfg_help_msg_file_name"; va_start(ap, format); diff --git a/util/wancfg/wancfg.h b/util/wancfg/wancfg.h index ac1427f..5f1a4ea 100644 --- a/util/wancfg/wancfg.h +++ b/util/wancfg/wancfg.h @@ -96,6 +96,7 @@ BSD interface names rules: # include #else # include +# include # include # include # include @@ -108,6 +109,16 @@ BSD interface names rules: #define NO 1 #define YES 2 +#if defined(__LINUX__) +# if !defined(strlcpy) +# define strlcpy(d,s,l) strcpy((d),(s)) +# endif +#elif defined(__FreeBSD__) +# if !defined(strlcpy) +# define strlcpy(d,s,l) strcpy((d),(s)) +# endif +#endif + //end of settings for the 'adapter_type' ////////////////////////////////////////////////////////////////////////// #define MAX_LEN_OF_ACTIVE_CHANNELS_STRING 100 @@ -154,12 +165,11 @@ typedef struct link_def /* WAN Link definition */ //#define DBG_FLAG 1 #define DBG_FLAG 0 -//#define Debug(dbg_flag, message) if(dbg_flag){printf message;} -#define Debug(dbg_flag, message) - #if DBG_FLAG -#define FUNC_DBG() printf("%s(), Line: %d\n", __FUNCTION__, __LINE__) +#define Debug(dbg_flag, message) if(dbg_flag){printf message;} +#define FUNC_DBG() printf("%s(), Line: %d\n", __FUNCTION__, __LINE__) #else +#define Debug(dbg_flag, message) #define FUNC_DBG() #endif @@ -190,7 +200,9 @@ Press to go back, for help." #define IN //value passed to a function #define OUT //function sets value on return -#define LXDIALOG_OUTPUT_FILE_NAME "lxdialog_output" +//The '/tmp' directory is ALWAYS writable, this important when running off CD-ROM +//because the current directory on CD is NOT writable. +#define LXDIALOG_OUTPUT_FILE_NAME "/tmp/lxdialog_output" //SELECTION can be a button number or a selected menu number. #define SELECTION_0 0 @@ -216,6 +228,8 @@ Press to go back, for help." #define OP_MODE_PPPoE " \"PPPoE\" " //9 #define OP_MODE_TTY " \"TTY\" " //10 #define OP_MODE_TDM_API " \"TDM_API\" " //11 +#define OP_MODE_NETGRAPH " \"NETGRAPH\" " //12 +#define OP_MODE_TDMV_API " \"TDM_VOICE_API\" " //13 #define PPPoE TTY+10 //a valid Operation Mode for ADSL card. //(but not defined in wanpipe_cfg.h !) @@ -231,6 +245,8 @@ Press to go back, for help." #define QUOTED_9 " \"9\" " #define QUOTED_10 " \"10\" " #define QUOTED_11 " \"11\" " +#define QUOTED_12 " \"12\" " +#define QUOTED_13 " \"13\" " //////////////////////////////////////////////////// //Frame Relay definitions @@ -289,13 +305,14 @@ typedef struct _if_config{ char * get_protocol_string(int protocol); #define NO_PROTOCOL_NEEDED WANCONFIG_X25-1 #define PROTOCOL_NOT_SET 0 -//the TDM_VOICE is actually an Operation Mode (like API...) +//the TDM_VOICE and TDM_VOICE_API is actually an Operation Mode (like API...) //but there is a need to display and configure it as a Protocol. //no such 'config_id' in wanpipe_cfg.h', so have to define my own enum NOT_REAL_PROTOCOLS{ PROTOCOL_TDM_VOICE = 60, PROTOCOL_IP, - PROTOCOL_ETHERNET + PROTOCOL_ETHERNET, + PROTOCOL_TDM_VOICE_API }; #define ADSL_IP_STR "ADSL (IP)" diff --git a/util/wancfg_legacy/Makefile b/util/wancfg_legacy/Makefile deleted file mode 100644 index 7b2fafb..0000000 --- a/util/wancfg_legacy/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -install: - install -D -m 755 wancfg_legacy $(WAN_VIRTUAL)/usr/sbin/wancfg_legacy - install -D -m 755 pppconfig $(WAN_VIRTUAL)/usr/sbin/wp_pppconfig - -uninstall: - rm -f $(WAN_VIRTUAL)/usr/sbin/wancfg_legacy - rm -f $(WAN_VIRTUAL)/usr/sbin/wp_pppconfig diff --git a/util/wancfg_legacy/Makefile b/util/wancfg_legacy/Makefile new file mode 120000 index 0000000..b00583b --- /dev/null +++ b/util/wancfg_legacy/Makefile @@ -0,0 +1 @@ +Makefile.Linux \ No newline at end of file diff --git a/util/wancfg_legacy/Makefile.BSD b/util/wancfg_legacy/Makefile.BSD new file mode 100644 index 0000000..5ef55e2 --- /dev/null +++ b/util/wancfg_legacy/Makefile.BSD @@ -0,0 +1,5 @@ +install: + install -D -m 755 wancfg_legacy $(WAN_VIRTUAL)/usr/local/sbin/wancfg_legacy + +clean: + rm -f $(WAN_VIRTUAL)/usr/local/sbin/wancfg_legacy diff --git a/util/wancfg_legacy/Makefile.Linux b/util/wancfg_legacy/Makefile.Linux new file mode 100644 index 0000000..7b2fafb --- /dev/null +++ b/util/wancfg_legacy/Makefile.Linux @@ -0,0 +1,7 @@ +install: + install -D -m 755 wancfg_legacy $(WAN_VIRTUAL)/usr/sbin/wancfg_legacy + install -D -m 755 pppconfig $(WAN_VIRTUAL)/usr/sbin/wp_pppconfig + +uninstall: + rm -f $(WAN_VIRTUAL)/usr/sbin/wancfg_legacy + rm -f $(WAN_VIRTUAL)/usr/sbin/wp_pppconfig diff --git a/util/wancfg_legacy/wancfg_legacy b/util/wancfg_legacy/wancfg_legacy index 8211ded..d599e3b 100755 --- a/util/wancfg_legacy/wancfg_legacy +++ b/util/wancfg_legacy/wancfg_legacy @@ -1299,12 +1299,12 @@ EOM exit 1 fi - if [ ! -f "$PROD_HOME/wanrouter.rc" ]; then + if [ ! -f "${META_CONF}" ]; then cat << EOM BAD CONFIGURATION - FILE MISSING - $PROD_HOME/wanrouter.rc file could not + ${META_CONF} file could not be found. Please make sure that the wanpipe pacakge has been correctly installed before proceeding to configure a Sangoma device. @@ -1409,19 +1409,31 @@ fi } +function read_meta_conf () +{ + if [ $OSYSTEM = "Linux" ]; then + PROD_HOME=/etc/wanpipe + elif [ $OSYSTEM = "FreeBSD" -o $OSYSTEM = "OpenBSD" ]; then + PROD_HOME=/usr/local/etc/wanpipe + wanrouter_rc_file="" + if [ -r /etc/rc.conf ]; then + . /etc/rc.conf + fi + if [ -n "$wanrouter_rc_file" ]; then + PROD_HOME=${wanrouter_rc_file%/*} + fi + fi + META_CONF=$PROD_HOME/wanrouter.rc + return 0 +} #============================================================ # VARIABLE DEFINITION #============================================================ WAN_CONF=wanpipe -PROD_HOME=/etc/wanpipe -TEMP=$PROD_HOME/wacfg_temp.$$ -MYCMD=$PROD_HOME/Mycmd -DEVOPT=$PROD_HOME/dev_options.$$ -MENU_TMP=$PROD_HOME/menu.tmp.$$ -RC=$PROD_HOME/return_code -GET_RC="cat $RC" +OSYSTEM=`uname -s` +RELEASE=`uname -r` EXIT=0 BACK=1 LINUX_DISTR=unknown @@ -1442,11 +1454,19 @@ Press to go back, for help." backtitle="WANPIPE Configuration Utility" +read_meta_conf + +TEMP=$PROD_HOME/wacfg_temp.$$ +MYCMD=$PROD_HOME/Mycmd +DEVOPT=$PROD_HOME/dev_options.$$ +MENU_TMP=$PROD_HOME/menu.tmp.$$ +RC=$PROD_HOME/return_code +GET_RC="cat $RC" check_setup 1 #Load the library files -source $PROD_HOME/wanrouter.rc +source ${META_CONF} check_setup 2 diff --git a/util/wancfg_legacy/xupdate b/util/wancfg_legacy/xupdate new file mode 100755 index 0000000..0534061 --- /dev/null +++ b/util/wancfg_legacy/xupdate @@ -0,0 +1,4 @@ +#!/bin/sh + +cp -f lib/*sh /etc/wanpipe/lib/ +cp -f wancfg_legacy /usr/sbin/wancfg_legacy diff --git a/util/wancfg_zaptel/.#wancfg_zaptel.1.5 b/util/wancfg_zaptel/.#wancfg_zaptel.1.5 deleted file mode 100755 index 51fba37..0000000 --- a/util/wancfg_zaptel/.#wancfg_zaptel.1.5 +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -home=`pwd` -cd $home - -read_meta_conf () -{ - - if [ $ostype = "Linux" ]; then - WAN_HOME=/etc - META_CONF=/etc/wanpipe/wanrouter.rc - elif [ $ostype = "FreeBSD" -o $ostype = "OpenBSD" ]; then - WAN_HOME=/usr/local/etc - wanrouter_rc_file="" - if [ -r /etc/rc.conf ]; then - . /etc/rc.conf - fi - if [ -n "$wanrouter_rc_file" ]; then - WAN_HOME=${wanrouter_rc_file%/*} - fi - META_CONF=$wanrouter_rc_file - fi - - # Read meta-configuration file. - if [ -f $META_CONF ] - then . $META_CONF - else - return 1 - fi - return 0 -} - -ostype=`/sbin/sysctl -a |grep ostype` -#ostype=`echo $ostype | sed 's/.*: //'` -ostype=`echo $ostype | sed 's/.* //'` - -read_meta_conf -if [ $? -ne 0 ]; then - echo "ERROR: Failed to find Wanpipe meta config file!" - exit 1 -fi - - -cd ${WAN_HOME}/wanpipe/wancfg_zaptel -./wancfg_zaptel.pl --conf_dir=$WAN_HOME -cd $home diff --git a/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 deleted file mode 100755 index 1b96e67..0000000 --- a/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.27 +++ /dev/null @@ -1,1920 +0,0 @@ -#!/usr/bin/perl -# config-zaptel.pl -# Sangoma Zaptel/TDM API/SMG Configuration Script. -# -# Copyright (c) 2006, Sangoma Technologies Inc. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# ---------------------------------------------------------------------------- -# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option -# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode -# Jul 20, 2007 2.5 David Yat Sin silent option -# Jun 13, 2007 Yuan Shen SS7 support -# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major -# changes to script. -# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl -# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong -# context -# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards -# Oct 13, 2006 David Yat Sin Added --opermode and --law option -# Oct 12, 2006 David Yat Sin Initial version -# ============================================================================ - -system('clear'); -print "\n###################################################################"; -print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; -print "\n# v2.7 #"; -print "\n# Sangoma Technologies Inc. #"; -print "\n# Copyright(c) 2007. #"; -print "\n###################################################################\n\n"; - -use strict; -#use warnings; -#use diagnostics; -use Card; -use A10x; -use A10u; -use A20x; -use A50x; - -my $FALSE = 1; -my $TRUE = 0; -my $zaptelprobe=' '; - -my $etc_dir=""; -my $module_list=""; -my $module_load=""; -my $module_unload=""; -my $os_type_name=""; - - -my $os_type_list=`sysctl -a |grep ostype`; -if ($os_type_list =~ m/Linux/){ - $os_type_name="Linux"; - $etc_dir="/etc"; - $module_load="modprobe"; - $module_unload="modprobe -r"; - $module_list="modprobe -l"; -}elsif ($os_type_list =~ m/FreeBSD/){ - $os_type_name="FreeBSD"; - $etc_dir="/usr/local/etc"; - $module_load="kldload"; - $module_unload="kldunload"; - $module_list="kldstat"; -}else{ - print("Failed to determine OS type\n"); - print("Exiting...\n"); - exit(1); -} - - -my $startup_string=""; -my $zaptel_conf=""; -my $zapata_conf=""; -my $bri_conf=""; -my $devnum=1; -my $current_zap_span=1; -my $current_tdmapi_span=1; -my $current_bri_span=1; -my $current_zap_channel=1; -my $num_analog_devices=0; -my $num_analog_devices_total=0; -my $num_bri_devices=0; -my $num_bri_devices_total=0; -my $num_digital_devices=0; -my $num_digital_devices_total=0; -my $num_ss7_config=0; -my $num_zaptel_config=0; -my $line_media=''; -my $max_chans=0; -my $ss7_tdmvoicechans=''; -my $ss7_array_length=0; - -my $device_has_hwec=$FALSE; -my $device_has_normal_clock=$FALSE; -my @device_normal_clocks=("0"); - -my $is_tdm_api=$FALSE; - -my $def_femedia=''; -my $def_feframe=''; -my $def_feclock=''; -my $def_bri_option=''; -my $def_signalling=''; -my $def_switchtype=''; -my $def_zapata_context=''; -my $def_zapata_group=''; -my $def_te_ref_clock=''; -my $def_tdmv_dchan=0; -my $def_bri_group=''; -my $def_felcode=''; -my $def_feframe=''; -my $def_te_sig_mode=''; - -my $def_hw_dtmf="YES"; - -my $silent_femedia="T1"; -my $silent_feframe="ESF"; -my $silent_feframe_e1="CRC4"; - -my $silent_felcode="B8ZS"; - -my $silent_feclock="NORMAL"; -my $silent_signalling="PRI CPE"; -my $silent_switchtype="National"; -my $silent_zapata_context="from-pstn"; -my $silent_zapata_group="0"; -my $silent_te_sig_mode='CCS'; - -my $def_bri_country="europe"; -my $def_bri_operator="etsi"; -my $def_bri_conn_type="Point to point"; - -my $is_trixbox = $FALSE; -my $silent = $FALSE; -my $config_zaptel = $TRUE; -my $config_zapata = $TRUE; -my $is_smg = $FALSE; - -my $tdm_api_span_num=0; -my $zaptel_installed=$FALSE; -my $modprobe_list=`$module_list`; - - -read_args(); -check_zaptel(); -my $current_dir=`pwd`; -chomp($current_dir); -my $cfg_dir='tmp_cfg'; -my $curdircfg="$current_dir"."/"."$cfg_dir"; - -unless ( -d $curdircfg ) { - $curdircfg = "mkdir " . $curdircfg; - system ($curdircfg); -} - - -my $debug_info_file="$current_dir/$cfg_dir/debug_info"; -my @hwprobe=`wanrouter hwprobe verbose`; - -my $wanpipe_conf_dir="$etc_dir/wanpipe"; -my $asterisk_conf_dir="$etc_dir/asterisk"; - -my $wanrouter_rc_template="$current_dir/templates/rc.template"; - -my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; -my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; -my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; - -my $zapata_conf_template="$current_dir/templates/zapata.conf"; -my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; -my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; - -my $bri_conf_template="$current_dir/templates/smg_bri.conf"; -my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; -my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; - -my $date=`date +%F`; -chomp($date); -my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; - -prepare_files(); -config_t1e1(); -config_bri(); -config_analog(); -summary(); -apply_changes(); -config_boot(); -config_ztcfg_start(); -config_smg_ctrl_start(); -clean_files(); -print "\n\n"; - - -#######################################FUNCTIONS################################################## - -sub config_boot{ - my $script_name="wanrouter"; - my $current_run_level=3; - my $zaptel_start_level=9; - my $zaptel_stop_level=92; - my $wanrouter_start_level=8; - my $wanrouter_stop_level=93; - my $command=''; - my $rc_dir=$etc_dir; - - my $res=`cat $etc_dir/inittab |grep id`; - if ($res =~ /id:(\d+):initdefault/){ - $current_run_level=$1; -# print "Current boot level is $current_run_level\n"; - } else { - print "Warning: Failed to determine init boot level, assuming 3\n"; - $current_run_level=3; - } - - - print "\nWanrouter boot scripts configuration...\n\n"; - print "Removing existing $script_name boot scripts..."; - $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; - if(system($command) == 0){ - print "OK\n"; - } else { - print "Not installed\n"; - } - if($num_ss7_config!=0){ - $script_name="smgss7_ctrl"; - } - - print ("Would you like $script_name to start on system boot?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - #examine system bootstrap files - $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $rc_dir=$rc_dir; - } else { - $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $rc_dir=$etc_dir."/rc.d"; - } else { - print "Failed to locate boostrap directory\n"; - print "wanrouter boot scripts will not be installed\n"; - return; - } - } - - if($zaptel_installed==$TRUE){ - print "Verifying Zaptel boot scripts..."; - #find zaptel start scripts - $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; - $res=`$command`; - if ($res =~ /.*S(\d+)zaptel/){ - $zaptel_start_level=$1; - print "Enabled (level:$zaptel_start_level)\n"; - } else { - print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; - } - } else { - print "Not installed\n"; - $zaptel_start_level=0; - } - - #find zaptel stop scripts - print "Verifying Zaptel shutdown scripts..."; - $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="find ".$rc_dir."/rc6.d/*zaptel"; - $res=`$command`; - if ($res =~ /.*K(\d+)zaptel/){ - $zaptel_stop_level=$1; - print "Enabled (level:$zaptel_stop_level)\n"; - } else { - print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; - } - } else { - print "Not installed\n"; - $zaptel_stop_level=0; - } - if ($zaptel_start_level != 0){ - $wanrouter_start_level=$zaptel_start_level-1; - } - if ($zaptel_stop_level != 0){ - $wanrouter_stop_level=$zaptel_stop_level+1; - } - } - my $wanrouter_start_script=''; - if($wanrouter_start_level < 10){ - $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; - } else { - $wanrouter_start_script="S".$wanrouter_start_level.$script_name; - } - my $wanrouter_stop_script=''; - if($wanrouter_stop_level < 10){ - $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; - } else { - $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; - } - - $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; - if(system($command) !=0){ - $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; - if(system($command) !=0){ - print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; - print "$script_name boot scripts not installed\n"; - return; - } - } - print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; - my @run_levels= ("2","3","4","5"); - foreach my $run_level (@run_levels) { - $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; - if(system($command) !=0){ - print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; - print "$script_name start scripts not installed\n"; - return; - } - } - - print "Enabling wanrouter shutdown scripts ...(level:$wanrouter_stop_level)\n"; - @run_levels= ("0","1","6"); - foreach my $run_level (@run_levels) { - $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; - if(system($command) !=0){ - print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; - print "$script_name stop scripts not installed\n"; - return; - } - } - } - -} - - -sub config_ztcfg_start{ - if ($num_zaptel_config ==0){ - return; - } - my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; - if (system($command) != 0){ - #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script - print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - exec_command("cp -f $current_dir/templates/zaptel_start_script $wanpipe_conf_dir/scripts/start"); - } - } -} - -sub config_smg_ctrl_start{ - if($num_bri_devices == 0){ - return; - } - print ("Would you like smg_ctrl to start on wanrouter start?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite - my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; - } else { - $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; - } - if (system($command) == 0){ - print "smgbri start script installed successfully"; - } else { - print "failed to install smgbri start script"; - } - } -} - -sub check_zaptel{ - if ($modprobe_list =~ /zaptel.ko/){ - $zaptel_installed=$TRUE; - } -} - -sub apply_changes{ - my $asterisk_command=''; - my $bri_command=''; - my $asterisk_restart=$FALSE; - my $res=''; - - system('clear'); - - if($silent==$TRUE){ - $res="Stop now"; - }elsif($is_tdm_api==$TRUE){ - print "\n Wanpipe configuration complete: choose action\n"; - $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", - "Do not save cfg: Exit", - ""); - }else{ - print "\nZaptel and Wanpipe configuration complete: choose action\n"; - $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", - "Save cfg: Restart Asterisk & Wanpipe when convenient", - "Save cfg: Stop Asterisk & Wanpipe now", - "Save cfg: Stop Asterisk & Wanpipe when convenient", - "Do not save cfg: Exit", - ""); - } - - - if ($res =~ m/Exit/){ - print "No changes made to your configuration files\n"; - exit 0; - } - if ($res =~ m/now/){ - $asterisk_command='stop now'; - } else { - $asterisk_command='stop when convenient'; - } - - if ($res =~ m/Restart/){ - $asterisk_restart=$TRUE; - } else { - $asterisk_restart=$FALSE; - } - - if ($is_trixbox==$TRUE){ - exec_command("amportal stop"); - unload_zap_modules(); - } elsif ($is_tdm_api==$FALSE ){ - if (`(pidof asterisk)` != 0 ){ - print "\nStopping Asterisk...\n"; - exec_command("asterisk -rx \"$asterisk_command\""); - sleep 2; - while (`(pidof asterisk)` != 0 ){ - if ($asterisk_command eq "stop now"){ - print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; - my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); - my $res=&prompt_user_list(@options,""); - - if ( $res =~ m/Force Stop/){ - execute_command("kill -KILL \$(pidof asterisk)"); - } elsif ( $res =~ m/Exit/ ){ - exit(1); - } else { - print "Waiting for asterisk to stop...\n"; - sleep 5; - exec_command("asterisk -rx \"$asterisk_command\""); - } - } else { - #stop when convenient option was selected - print "Waiting for asterisk to stop...\n"; - sleep 3; - } - } - - - - - - }else { - print "\nAsterisk is not running...\n"; - } - - } - - if($num_bri_devices != 0){ - exec_command("/usr/sbin/smg_ctrl stop"); - } - - print "\nStopping Wanpipe...\n"; - exec_command("wanrouter stop all"); - - if ($zaptel_installed==$TRUE){ - if($is_tdm_api==$FALSE){ - print "\nUnloading Zaptel modules...\n"; - unload_zap_modules(); - } - } - - print "\nRemoving old configuration files...\n"; - - exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); - - gen_wanrouter_rc(); - - print "\nCopying new Wanpipe configuration files...\n"; - copy_config_files(); - if($num_bri_devices != 0){ - print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; - exec_command("cp -f $bri_conf_file $bri_conf_file_t"); - } - - if ($zaptel_installed==$TRUE){ - if($config_zaptel==$TRUE){ - if ($num_zaptel_config !=0){ - print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; - exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); - } - } - } - - if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ - print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; - exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); - } - - if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ - print "\nStarting Wanpipe...\n"; - exec_command("wanrouter start"); - - if($num_bri_devices != 0){ - print "Loading SMG BRI...\n"; - sleep 2; - exec_command("/usr/sbin/smg_ctrl start"); - } - -# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ - if ($num_zaptel_config != 0){ - print "Loading Zaptel...\n"; - sleep 2; - exec_command("ztcfg -v"); -# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); -# if (&prompt_user_list("YES","NO","") eq 'YES'){ -# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); -# } - } - if ($is_trixbox==$TRUE){ - print "\nStarting Amportal...\n"; - exec_command("amportal start"); - sleep 2; - }elsif($config_zapata==$TRUE){ - print "\nStarting Asterisk...\n"; - exec_command("asterisk"); - sleep 2; - - print "\nListing Asterisk channels...\n\n"; - exec_command("asterisk -rx \"zap show channels\""); - print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; - }else{ - } - } - print "\nWanrouter start complete...\n"; -} - - - -sub save_debug_info{ - my $version=`wanrouter version`; - chomp($version); - - my $uname=`uname -a`; - chomp($uname); - - my $issue=''; - - if ($os_type_list =~ m/Linux/){ - $issue=`cat $etc_dir/issue`; - chomp($issue); - } - - my $debug_info="\n"; - $debug_info.="===============================================================\n"; - $debug_info.=" SANGOMA DEBUG INFO FILE \n"; - $debug_info.=" Generated on $date \n"; - $debug_info.="===============================================================\n"; - - $debug_info.="\n\nwanrouter hwprobe\n"; - $debug_info.="@hwprobe\n"; - $debug_info.="\nwanrouter version\n"; - $debug_info.="$version\n"; - $debug_info.="\nKernel \"uname -a\"\n"; - $debug_info.="$uname\n"; - if ($os_type_list =~ m/Linux/){ - $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; - $debug_info.="$issue\n"; - } - $debug_info.="EOF\n"; - - open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; - print FH $debug_info; - close (FH); - exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); -} - - - - - - - - - -sub get_zapata_context{ - my ($card_model,$card_port)=@_; - my $context=''; - my @options = ("from-pstn", "from-internal","Custom"); - - if($is_trixbox==$TRUE){ - @options = ("PSTN", "INTERNAL"); - } - if ($silent==$FALSE){ - printf ("Select dialplan context for A%s on port %s\n", $card_model, $card_port); - my $res = &prompt_user_list(@options,$def_zapata_context); - if($res eq "PSTN"){ - $context="from-zaptel"; - }elsif($res eq "INTERNAL"| $res eq "from-internal"){ - $context="from-internal"; - }elsif($res eq "from-pstn"){ - $context="from-pstn"; - }elsif($res eq "Custom"){ - my $res_context=&prompt_user("Input the context for this port"); - while(length($res_context)==0){ - print "Invalid context, input a non-empty string\n"; - $res_context=&prompt_user("Input the context for this port",$def_zapata_context); - } - - $context=$res_context; - }elsif($res eq $def_zapata_context){ - $context=$def_zapata_context; - }else{ - print "Internal error:invalid context,group\n"; - exit 1; - } - } else { - $context=$silent_zapata_context; - } - $def_zapata_context=$context; - return $context; -} - -sub gen_wanrouter_rc{ - #update wanpipe startup sequence - my $rcfile=""; - if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { - open (FH,"$wanrouter_rc_template"); - } - while () { - $rcfile .= $_; - } - close (FH); - open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); - $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; - print FH $rcfile; - close (FH); -} - -sub prepare_files{ - - if ($is_trixbox==$TRUE){ - $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; - $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; - $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; - } - - if ($silent==$FALSE){ - if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ - print "Would you like to generate $zapata_conf_file_t\n"; - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $config_zapata = $FALSE; - } - } - } - -#remove temp files - exec_command("rm -f $current_dir/$cfg_dir/*"); - -#backup existing configuration files - exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); - exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); - -} - -sub clean_files{ - exec_command("rm -rf $current_dir/$cfg_dir"); -} - - -sub write_zapata_conf{ - my $zp_file=""; - open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; - while () { - $zp_file .= $_; -} - close (FH); - - $zp_file.=$zapata_conf; - - open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; - print FH $zp_file; - close(FH); -} - -sub copy_config_files{ - my @wanpipe_files = split / /, $startup_string; - exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); - foreach my $wanpipe_file (@wanpipe_files) { - exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); - } -} - - - - - - - - - - - - -sub unload_zap_modules{ - my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); - foreach my $module (@modules_list) { - if ($modprobe_list =~ m/$module/){ - exec_command("$module_unload -r $module"); - } - } -} - -sub write_zaptel_conf{ - my $zp_file=""; - open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; - while () { - $zp_file .= $_; -} - close (FH); - $zp_file=$zp_file.$zaptel_conf; - open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; - print FH $zp_file; - close(FH); -} - -sub summary{ - if($devnum==1){ - system('clear'); - print "\n###################################################################"; - print "\n# SUMMARY #"; - print "\n###################################################################\n\n"; - - print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); - exit 0; - }else{ - if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ - write_zaptel_conf(); - } - if ($num_bri_devices != 0 ){ - write_bri_conf(); - } - if ($config_zapata==$TRUE){ - write_zapata_conf(); - } - save_debug_info(); - system('clear'); - my $file_list = 1; - print "\n###################################################################"; - print "\n# SUMMARY #"; - print "\n###################################################################\n\n"; - - print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); - print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); - print(" $num_bri_devices_total ISDN BRI card(s) detected, $num_bri_devices configured\n"); - - print "\nConfigurator has created the following files:\n"; - print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; - $file_list++; - - if ($num_bri_devices != 0){ - print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; - $file_list++; - } - - if ($num_zaptel_config != 0){ - print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; - $file_list++; - } - if ($config_zapata==$TRUE){ - print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; - } - - if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ - print "\n\nYour original configuration files will be saved to:\n"; - $file_list=1; - } - - if ($num_zaptel_config != 0){ - print "\t$file_list. $zaptel_conf_file_t.bak \n"; - $file_list++; - } - if ($config_zapata==$TRUE){ - print "\t$file_list. $zapata_conf_file_t.bak \n\n"; - } - - print "\nYour configuration has been saved in $debug_tarball.\n"; - print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - } -} - - -sub exec_command{ - my @command = @_; - if (system(@command) != 0 ){ - print "Error executing command:\n@command\n\n"; - } - return $?; -} - -sub prompt_user{ - my($promptString, $defaultValue) = @_; - if ($defaultValue) { - print $promptString, "def=\"$defaultValue\": "; - } else { - print $promptString, ": "; - } - - $| = 1; # force a flush after our print - $_ = ; # get the input from STDIN (presumably the keyboard) - chomp; - if ("$defaultValue") { - return $_ ? $_ : $defaultValue; # return $_ if it has a value - } else { - return $_; - } -} - -sub prompt_user_list{ - my @list = @_; - my $defaultValue = @list[$#list]; - - my $i; - my $valid = 0; - for $i (0..$#list-1) { - printf(" %s\. %s\n",$i+1, @list[$i]); - } - while ($valid == 0){ - my $list_sz = $#list; - print "[1-$list_sz"; - if ( ! $defaultValue eq ''){ - print ", ENTER=\'$defaultValue\']:"; - }else{ - print "]:"; - } - $| = 1; - $_ = ; - chomp; - if ( $_ eq '' & ! $defaultValue eq ''){ - print "\n"; - return $defaultValue; - } - - if ( $_ =~ /(\d+)/ ){ - if ( $1 > $list_sz) { - print "\nError: Invalid option, input a value between 1 and $list_sz \n"; - } else { - print "\n"; - return @list[$1-1] ; - } - } else { - print "\nError: Invalid option, input an integer\n"; - } - } -} - -sub read_args { - my $arg_num; - foreach $arg_num (0 .. $#ARGV) { - $_ = $ARGV[$arg_num]; - if( /^--trixbox$/){ - $is_trixbox=$TRUE; - }elsif ( /^--tdm_api/){ - $is_tdm_api=$TRUE; - }elsif ( /^--smg$/){ - $is_smg=$TRUE; - }elsif ( /^--silent$/){ - $silent=$TRUE; - }elsif ( /^--no-zapata$/){ - $config_zapata=$FALSE; - }elsif ( /^--no-zaptel$/){ - $config_zaptel=$FALSE; - }elsif ( $_ =~ /--fe_media=(\w+)/){ - $silent_femedia=$1; - if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ - printf("Invalid value for fe_media, should be T1/E1\n"); - exit(1); - } - }elsif ( $_ =~ /--fe_frame=(\w+)/){ - $silent_feframe=$1; - if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ - printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); - exit(1); - } - }elsif ( $_ =~ /--fe_clock=(\w+)/){ - $silent_feclock=$1; - if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ - printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); - exit(1); - } - }elsif ( $_ =~ /--signalling=(\w+)/){ - my $tmp_signalling=$1; - if ($tmp_signalling eq 'em'){ - $silent_signalling="E & M"; - }elsif ($tmp_signalling eq 'em_w'){ - $silent_signalling="E & M Wink"; - }elsif ($tmp_signalling eq 'pri_cpe'){ - $silent_signalling="PRI CPE"; - }elsif ($tmp_signalling eq 'pri_net'){ - $silent_signalling="PRI NET"; - }elsif ($tmp_signalling eq 'fxs_ls'){ - $silent_signalling="FXS - Loop Start"; - }elsif ($tmp_signalling eq 'fxs_gs'){ - $silent_signalling="FXS - Ground Start"; - }elsif ($tmp_signalling eq 'fxs_ks'){ - $silent_signalling="FXS - Kewl Start"; - }elsif ($tmp_signalling eq 'fxo_ls'){ - $silent_signalling="FXO - Loop Start"; - }elsif ($tmp_signalling eq 'fxo_gs'){ - $silent_signalling="FXO - Ground Start"; - }elsif ($tmp_signalling eq 'fxo_ks'){ - $silent_signalling="FXO - Kewl Start"; - }else{ - printf("Invalid option for --signalling, options are\n"); - printf("\t pri_cpe/pri_net/em/em_w\n"); - printf("\t em/em_w\n"); - printf("\t fxo_ls/fxo_gs/fxo_ks\n"); - printf("\t fxs_ls/fxs_gs/fxs_ks\n"); - exit(1); - } - }elsif ( $_ =~ /--conf_dir=(.*)/){ - $etc_dir=$1; - if (! -d $etc_dir){ - printf("Error: directory $1 does not exist\n"); - exit(1); - } - } - } - - if ($is_trixbox==$TRUE){ - print "\nGenerating configuration files for Trixbox\n"; - } - if ($is_smg==$TRUE){ - print "\nGenerating configuration files for SS7\n"; - } - if ($is_tdm_api==$TRUE){ - $config_zapata = $FALSE; - } - -} - -#------------------------------BRI FUNCTIONS------------------------------------# -sub get_bri_country { - $def_bri_country = "europe"; - return $def_bri_country; -} - -sub get_bri_group{ - my $group; - my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); - while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ - print "Invalid group, input an integer greater than 0\n"; - $res_group=&prompt_user("Input the group for this port",$def_bri_group); - } - $group=$res_group; - $def_bri_group=$group; - return $def_bri_group; -} - - -sub get_bri_operator { -#warning returning ETSI - $def_bri_operator = "etsi"; - return $def_bri_operator; - - - - my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", - "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", - "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); - - my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); - - my $res = &prompt_user_list(@options,$def_switchtype); - - my $i; - for $i (0..$#options){ - if ( $res eq @options[$i] ){ - $def_bri_operator=@options[$i]; - return @options_val[$i]; - } - } - print "Internal error: Invalid PRI switchtype\n"; - exit 1; -} - -sub write_bri_conf{ - my $bri_file=""; - open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; - while () { - $bri_file .= $_; -} - close (FH); - $bri_file=$bri_file.$bri_conf; - open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; - print FH $bri_file; - close(FH); -} - - -sub get_bri_conn_type{ - my $conn_type; - - my @options = ( "Point to multipoint", "Point to point"); - my @options_val = ("point_to_multipoint", "point_to_point"); - - my $res = &prompt_user_list(@options,$def_bri_conn_type); - - my $i; - for $i (0..$#options){ - if ( $res eq @options[$i] ){ - $def_bri_conn_type=@options[$i]; - return @options_val[$i]; - } - } - print "Internal error: Invalid BRI connection type\n"; - exit 1; -} - - - - -sub config_bri{ - if($is_smg!=$TRUE){ - return; - } - my $a50x; - system('clear'); - print "------------------------------------\n"; - print "Configuring ISDN BRI cards [A500]\n"; - print "------------------------------------\n"; - my $skip_card=$FALSE; - $zaptel_conf.="\n"; - $zapata_conf.="\n"; - foreach my $dev (@hwprobe) { - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ - $skip_card=$FALSE; - if ($1 eq '500'){ - my $card = eval {new Card(); } or die ($@); - - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - - my $hwec=0; - if($6 gt 0){ - $hwec=1; - } - if ($hwec==0){ - $card->hwec_mode('NO'); - }else{ - $card->hwec_mode('YES'); - } - - if ($card->card_model eq '500'){ - $num_bri_devices_total++; - system('clear'); - print "\n-----------------------------------------------------------\n"; - print "A$1 detected on slot:$3 bus:$4\n"; - print "-----------------------------------------------------------\n"; - - if($is_trixbox==$FALSE){ -select_bri_option: - print "\nWould you like to configure A$1 port $5 on slot:$3 bus:$4\n"; - my @options=("YES", "NO", "Exit"); - $def_bri_option=&prompt_user_list(@options,$def_bri_option); - if($def_bri_option eq 'YES'){ - $skip_card=$FALSE; - $bri_conf.="\n;Sangoma A$1 port $5 [slot:$3 bus:$4 span:$devnum]"; - }elsif($def_bri_option eq 'NO'){ - $skip_card=$TRUE; - }else{ - print "Exit without applying changes?\n"; - if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ - print "No changes made to your configuration files.\n\n"; - exit 0; - } else { - goto select_bri_option; - } - } - } - if ($skip_card==$FALSE){ -# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; -# prompt_user("Press any key to continue"); - - $startup_string.="wanpipe$devnum "; - $a50x = eval {new A50x(); } or die ($@); - $a50x->card($card); - $a50x->fe_line($5); - $devnum++; - $num_bri_devices++; - $card->tdmv_span_no($current_tdmapi_span); - $current_tdmapi_span++; - $a50x->gen_wanpipe_conf(); - }else{ - print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; - prompt_user("Press any key to continue"); - } - - } - } - }elsif ( $dev =~ /(\d+):NT/ & $skip_card==$FALSE){ - printf("\nConfiguring port %d as NT\n", $a50x->fe_line()); - printf("\nSelect connection type for port %d\n", $a50x->fe_line()); - my $bri_pos=$current_bri_span; - - $current_bri_span=$current_bri_span+1; - my $conn_type=get_bri_conn_type(); - my $group=get_bri_group(); - my $country=get_bri_country(); - - my $operator=get_bri_operator(); - $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); - }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ - printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); - printf("\nSelect connection type for port %d\n", $a50x->fe_line()); - my $bri_pos=$current_bri_span; - - $current_bri_span=$current_bri_span+1; - my $conn_type=get_bri_conn_type(); - my $group=get_bri_group(); - my $country=get_bri_country(); - - my $operator=get_bri_operator(); - $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); - } - } - prompt_user("Press any key to continue"); - if($num_bri_devices_total!=0){ - print("\nISBN BRI card configuration complete\n\n"); - prompt_user("Press any key to continue"); - } -} - - - - - -#------------------------------T1/E1 FUNCTIONS------------------------------------# - -sub get_te_ref_clock{ - my @list_normal_clocks=@_; - my @f_list_normal_clocks; - my $f_port; - foreach my $port (@list_normal_clocks) { - if ($port eq '0'){ - $f_port = "Free run"; -} else { - $f_port = "Port ".$port; -} - push(@f_list_normal_clocks, $f_port); -} - - my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); - my $i; - - for $i (0..$#f_list_normal_clocks){ - if ( $res eq @f_list_normal_clocks[$i] ){ - return @list_normal_clocks[$i]; -} -} - - print "Internal error: Invalid reference clock\n"; - exit 1; - -} - - -sub prompt_user_hw_dchan{ - my ($card_model, $port, $port_femedia) = @_; - my $res_dchan=''; - my $dchan; - - printf("Hardware HDLC can be performed on the data channel.\n"); -prompt_hw_dchan: - my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); - while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ - print "Invalid channel, input an integer (0 for unused).\n"; - $res_dchan=&prompt_user("Select the data channel","0"); - } - if ( $res_dchan < 0){ - printf("Error: channel cannot have negative value\n"); - $res_dchan=''; - goto prompt_hw_dchan; - } - if ( $port_femedia eq 'T1' && $res_dchan > 24){ - printf("Error: only 24 channels available on T1\n"); - $res_dchan=''; - goto prompt_hw_dchan; - }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ - printf("Error: only 31 channels available on E1\n"); - $res_dchan=''; - goto prompt_hw_dchan; - } - if ($res_dchan == 0){ - printf("HW HDLC channel not used\n"); - }else{ - printf("HW HDLC channel set to:%d\n", $res_dchan); - } - return $res_dchan; -} - - - -sub get_zapata_group{ - my ($card_model,$card_port,$context)=@_; - my $group=''; - if($is_trixbox==$TRUE){ - if($context eq "from-zaptel"){ - $group=0; - return $group; - }elsif($context eq "from-internal"){ - $group=1; - return $group; - }else{ - print "Internal error:invalid group for Trixbox\n"; - } - }else{ - if($context eq "from-pstn"){ - $group=0; - }elsif($context eq "from-internal"){ - $group=1; - }else{ - my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); - while(length($res_group)==0 |!($res_group =~/(\d+)/)){ - print "Invalid group, input an integer.\n"; - $res_group=&prompt_user("Input the group for this port",$def_zapata_group); - } - $group=$res_group; - $def_zapata_group=$group; - } - } - - return $group; -} - - - -sub prompt_hw_dtmf { - print("Would you like to enable hardware DTMF detection?\n"); - my @options = ("YES","NO"); - $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); - return $def_hw_dtmf; - -} - -sub get_pri_switchtype { - my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); - my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); - my $res = &prompt_user_list(@options,$def_switchtype); - my $i; - for $i (0..$#options){ - if ( $res eq @options[$i] ){ - $def_switchtype=@options[$i]; - return @options_val[$i]; -} -} - print "Internal error: Invalid PRI switchtype\n"; - exit 1; -} - - -sub gen_ss7_voicechans{ - my @ss7_array = @_; - my $T1CHANS = pop(@ss7_array); - my $count = @ss7_array; - my $output =''; - my $chan_in = 1; - my $chan_de = 0; - my $flag = 0; - my $i = 0; - my $j = 0; - - while($i < $count){ - $j = $i + 1; - if ($ss7_array[$i] > 2 && $i == 0){ - $chan_de = $ss7_array[$i] - 1; - $output .= "1-$chan_de"; - $flag = 1; - }elsif ($ss7_array[$i] == 2 && $i == 0){ - $output .= "1"; - $flag = 1; - } - - if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ - goto Incrementing; - }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ - goto Incrementing; - } - - if ($i < ($count-1)){ - $chan_in = $ss7_array[$i]+1; - if ($chan_in < ($ss7_array[$j]-1)){ - $chan_de = $ss7_array[$j] - 1; - if ($flag != 0){ - $output .= ".$chan_in-$chan_de"; - }else{ - $output .= "$chan_in-$chan_de"; - $flag = 1; - } - }else{ - if ($flag != 0){ - $output .= ".$chan_in"; - }else{ - $output .= "$chan_in"; - $flag = 1; - } - } - }else{ - $chan_in = $ss7_array[$i]+1; - if ($chan_in < $T1CHANS){ - $chan_de = $T1CHANS; - if ($flag != 0){ - $output .= ".$chan_in-$chan_de"; - }else{ - $output .= "$chan_in-$chan_de"; - $flag = 1; - } - }else{ - if ($flag != 0){ - $output .= ".$T1CHANS"; - }else{ - $output .= "$T1CHANS"; - $flag = 1; - } - } - } - -Incrementing: - $i++; - } - return $output; -} - -sub prompt_user_ss7_chans{ - my @ss7_string = @_; - my $def_ss7_group_chan = ''; - - my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - -CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ - print("ERROR: Invalid channel number, input an integer only.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); -} - if ($line_media eq 'T1'){ - while ($ss7_group_chan>24 || $ss7_group_chan<1){ - print("Invalid channel number, there are only 24 channels in T1.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - goto CHECK1; -} -}elsif ($line_media eq 'E1'){ - while ($ss7_group_chan>31 || $ss7_group_chan<1){ - print("Invalid channel number, there are only 31 channels in E1.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - goto CHECK1; -} -} - return $ss7_group_chan; -} - - - - - - -sub config_t1e1{ - system('clear'); - print "---------------------------------------------\n"; - print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; - print "---------------------------------------------\n"; - - foreach my $dev (@hwprobe) { - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - - if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ - #do not count analog devices - $num_digital_devices_total++; - } - my $card = eval {new Card(); } or die ($@); - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - $card->fe_cpu($5); - - my $hwec=0; - if ( $dev =~ /HWEC=(\d+)/){ - if($1 gt 0){ - $hwec=1; - } - } - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - my $abc=0; - } - if ($hwec==0){ - $card->hwec_mode('NO'); - }else{ - $card->hwec_mode('YES'); - } - my $port=$6; - if ($6 eq 'PRI') { - $port=$5; - } - - if ( $card->card_model eq '101' | - $card->card_model eq '102' | - $card->card_model eq '104' | - $card->card_model eq '108' ){ - system('clear'); - if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ - print "A$1 detected on slot:$3 bus:$4\n"; - $device_has_normal_clock=$FALSE; - @device_normal_clocks = ("0"); - } - system('clear'); - my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; - print "\n-----------------------------------------------------------\n"; - print "$msg"; - print "-----------------------------------------------------------\n"; - my $fe_media = ''; - if ($silent==$TRUE){ - $fe_media = $silent_femedia; - } else { - printf ("\nSelect media type for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - my @options = ("T1", "E1", "Unused","Exit"); - $fe_media = prompt_user_list( @options, $def_femedia); - } - - if ( $fe_media eq 'Exit'){ - print "Exit without applying changes?\n"; - if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ - print "No changes made to your configuration files.\n\n"; - exit 0; - } - }elsif ( $fe_media eq 'Unused'){ - $def_femedia=$fe_media; - my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; - print "$msg"; - prompt_user("Press any key to continue"); - }else{ - if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ - $device_has_hwec=$TRUE; - } - - $def_femedia=$fe_media; - $startup_string.="wanpipe$devnum "; - my $a10x; - - if ($1 !~ m/104/ && $2 !~ m/SH/) { - $a10x = eval {new A10u(); } or die ($@); - $a10x->card($card); - if ($5 eq "A") { - $a10x->fe_line("1"); - } else { - $a10x->fe_line("2"); - } - } else { - $a10x = eval {new A10x(); } or die ($@); - if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - my $abc=0; - } - $a10x->card($card); - $a10x->fe_line($6); - } - - $card->first_chan($current_zap_channel); - $a10x->fe_media($fe_media); - if ( $fe_media eq 'T1' ){ - $current_zap_channel+=24; - $max_chans = 24; - $line_media = 'T1'; - - $def_te_sig_mode=''; - if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ - $def_felcode='B8ZS'; - } - if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ - $def_feframe='ESF'; - } - - - if ($silent==$FALSE){ - printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s.\n", - $port, - $card->card_model, - $fe_media, - $def_felcode, - $def_feframe, - $port); - my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); - my $res = &prompt_user_list(@options, "YES"); - if ($res =~ m/NO/){ - printf("Select line coding for port %s on %s\n", $port, $card->card_model); - my @options = ("B8ZS", "AMI"); - $def_felcode= &prompt_user_list(@options, $def_felcode); - - - printf("Select framing for port %s on %s\n", $port, $card->card_model); - my @options = ("ESF", "D4"); - $def_feframe= &prompt_user_list(@options, $def_feframe); - } - - - } else { - $def_felcode=$silent_felcode; - } - - - }else{ #fe_media = E1 - $current_zap_channel+=31; - $max_chans = 31; - $line_media = 'E1'; - - - if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ - $def_felcode='HDB3'; - } - if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ - $def_feframe='CRC4'; - } - - if ($silent==$FALSE){ - printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", - $port, - $card->card_model, - $fe_media, - $def_felcode, - $def_feframe); - my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); - my $res = &prompt_user_list(@options, "YES"); - if ($res =~ m/NO/){ - printf("Select line coding for port %s on %s\n", $port, $card->card_model); - my @options = ("HDB3", "AMI"); - $def_felcode= &prompt_user_list(@options, $def_felcode); - - - printf("Select framing for port %s on %s\n", $port, $card->card_model); - my @options = ("CRC4", "NCRC4","UNFRAMED"); - $def_feframe = &prompt_user_list(@options, $def_feframe); - -# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); -# my @options = ("CCS - Clear channel signalling ", "CAS"); -# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); - - } - if ($def_signalling eq 'TDM API'){ - printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); - my @options=("CCS","CAS"); - $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); - - } elsif ($def_signalling eq 'PRI CPE' | - $def_signalling eq 'PRI NET' | - $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| - $def_signalling eq 'No Signaling (Voice Only)'){ - - $def_te_sig_mode="CCS"; - } else { - $def_te_sig_mode="CAS"; - } - - - } else { - $def_felcode=$silent_felcode; - } - - - } - $a10x->fe_lcode($def_felcode); - $a10x->fe_frame($def_feframe); - $a10x->te_sig_mode($def_te_sig_mode); - if($silent==$FALSE){ - my @options = ("NORMAL", "MASTER"); - printf ("Select clock for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_feclock=&prompt_user_list(@options, $def_feclock); - } else { - $def_feclock=$silent_feclock; - } - - $a10x->fe_clock($def_feclock); - if ( $def_feclock eq 'NORMAL') { - $device_has_normal_clock=$TRUE; - push(@device_normal_clocks, $a10x->fe_line); - } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ - printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", - $card->card_model, - $port, - $card->pci_slot, - $card->pci_bus); - printf(" Free run: Use internal oscillator on card [default] \n"); - printf(" Port N: Sync with clock from port N \n\n"); - - printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); - $a10x->te_ref_clock($def_te_ref_clock); - } - - my @options=""; - if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ -# if ($is_smg==$TRUE && ($zaptelprobe =~ /zaptel.ko/)){ - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ -# } elsif ($is_smg==$TRUE && ($zaptelprobe !~ /zaptel.ko/)){ - @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } elsif ($is_tdm_api==$TRUE){ - $def_signalling="TDM API"; - } else { - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); - } - if ($silent==$FALSE){ - if( $is_tdm_api == $FALSE){ - printf ("Select signalling type for %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_signalling=&prompt_user_list(@options,$def_signalling); - } - } else { - $def_signalling=$silent_signalling; - } - $a10x->signalling($def_signalling); - - - - - if ($silent==$FALSE){ - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf(&prompt_hw_dtmf()); - } else { - $card->hw_dtmf("NO"); - } - } else { - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf("YES"); - } else { - $card->hw_dtmf("NO"); - } - } - - my $ss7_chan; - my $ss7_group_start; - my $ss7_group_end; - my @ss7_chan_array; - my @ss7_sorted; - if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10x->ss7_option(1); - print("Choose an option below to configure SS7 signalling channels:\n"); - my @options =("Configure consecutive signalling channels(e.g #1-#16)", - "Configure separate signalling channels(e.g #1,#10)"); - my $res = &prompt_user_list(@options, ""); - if ( $res eq 'Configure separate signalling channels(e.g #1,#10)'){ - goto SS7CHAN; - while (1){ - print("\nAny other SS7 signalling channel to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG; - }else{ -SS7CHAN: - $ss7_chan = prompt_user_ss7_chans('Specify the time slot for SS7 signalling(24 for T1? 16 for E1?)'); - push(@ss7_chan_array, $ss7_chan); - $ss7_array_length = @ss7_chan_array; - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG; - } - } - } - }else{ - goto SS7GROUP; - while(1){ - print("\nAny other SS7 consecutive signalling channels to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG; - }else{ -SS7GROUP: - $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); - $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); - if ($ss7_group_start > $ss7_group_end){ - print("The starting channel number is bigger than the ending one!\n"); - goto SS7GROUP; - } - my $i = 0; - for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ - push(@ss7_chan_array, $i); - my @remove_duplicate; - @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); - $ss7_array_length = @ss7_chan_array; - - if ($ss7_array_length > $max_chans){ - print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); - - @ss7_chan_array = (); - goto SS7GROUP; - } - } - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG; - } - } - } - } - -ENDSS7CONFIG: - @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; - - print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); - my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); - $ss7_tdmvoicechans = $ss7_voicechans; - - if ($ss7_voicechans =~ m/(\d+)/){ - $a10x->ss7_tdminterface($1); - } - - $a10x->ss7_tdmchan($ss7_voicechans); - $num_ss7_config++; - }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ - $a10x->ss7_option(2); - $num_ss7_config++; - }elsif ($a10x->signalling eq 'TDM API'){ - if ($a10x->te_sig_mode eq "CAS"){ - $a10x->hw_dchan('0'); - } else { - $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); - } - $card->tdmv_span_no($current_tdmapi_span); - $current_tdmapi_span++; - }else{ - $num_zaptel_config++; - $card->tdmv_span_no($current_zap_span); - $current_zap_span++; - } - - - if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ - if ($silent==$FALSE && $config_zapata==$TRUE){ - printf ("Select switchtype for %s on port %s \n", $card->card_model, $port); - $a10x->pri_switchtype(get_pri_switchtype()); - } else { - $a10x->pri_switchtype($silent_switchtype); - } - } - - if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10x->ss7_subinterface(1); - $a10x->gen_wanpipe_ss7_subinterfaces(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(2); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - my $ss7_element; - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(3); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - - $a10x->gen_wanpipe_conf(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(5); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(6); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - }else{ - $a10x->gen_wanpipe_conf(); - } - - if ($is_smg==$TRUE && $config_zapata==$FALSE){ - if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' - | $a10x->signalling eq 'No Signaling (Voice Only)')){ - } - $zaptel_conf.=$a10x->gen_zaptel_conf(); - }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ - if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ - - $zaptel_conf.=$a10x->gen_zaptel_conf(); - $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); - $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); - $zapata_conf.=$a10x->gen_zapata_conf(); - } - }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); - $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); - $zapata_conf.=$a10x->gen_zapata_conf(); - }elsif ($is_tdm_api == $FALSE){ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - } - $devnum++; - $num_digital_devices++; - my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; - print "$msg"; - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - - } - } - - } - } - if($num_digital_devices_total!=0){ - print("\nT1/E1 card configuration complete.\n"); - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - } -# close SCR; -} - - -#------------------------------ANALOG FUNCTIONS------------------------------------# - - -sub config_analog{ - my $a20x; - system('clear'); - print "------------------------------------\n"; - print "Configuring analog cards [A200/A400]\n"; - print "------------------------------------\n"; - - my $skip_card=$FALSE; - $zaptel_conf.="\n"; - $zapata_conf.="\n"; - foreach my $dev (@hwprobe) { - if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ - $skip_card=$FALSE; - my $card = eval {new Card(); } or die ($@); - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - $card->fe_cpu($5); - my $hwec=$7; - if ($hwec==0){ - $card->hwec_mode('NO'); - } - else{ - $card->hwec_mode('YES'); - } - if ($card->card_model eq '200' | $card->card_model eq '400'){ - $num_analog_devices_total++; - system('clear'); - print "\n-----------------------------------------------------------\n"; - print "A$1 detected on slot:$3 bus:$4\n"; - print "-----------------------------------------------------------\n"; - if($is_trixbox==$FALSE){ - print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $skip_card=$TRUE; - } - } - if ($skip_card==$FALSE){ - print "A$1 configured on slot:$3 bus:$4 span:$devnum\n"; - prompt_user("Press any key to continue"); - $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; - $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; - $startup_string.="wanpipe$devnum "; - - $a20x = eval {new A20x(); } or die ($@); - $a20x->card($card); - $card->first_chan($current_zap_channel); - $current_zap_channel+=24; - my $i; - $devnum++; - $num_analog_devices++; - $num_zaptel_config++; - $card->tdmv_span_no($current_zap_span); - $current_zap_span++; - $a20x->gen_wanpipe_conf(); - - - if ($silent==$FALSE){ - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf(&prompt_hw_dtmf()); - } else { - $card->hw_dtmf("NO"); - } - } else { - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf("YES"); - } else { - $card->hw_dtmf("NO"); - } - } - }else{ - print "A$1 on slot:$3 bus:$4 not configured\n"; - prompt_user("Press any key to continue"); - } - } - }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ - my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-internal"); - $a20x->card->zap_group("1"); - $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); - $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); - }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ - my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-zaptel"); - $a20x->card->zap_group("0"); - $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); - $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); - } - } - if($num_analog_devices_total!=0){ - print("\nAnalog card configuration complete\n\n"); - prompt_user("Press any key to continue"); - } - -} - diff --git a/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 b/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 deleted file mode 100755 index 073845d..0000000 --- a/util/wancfg_zaptel/.#wancfg_zaptel.pl.1.32 +++ /dev/null @@ -1,1977 +0,0 @@ -#!/usr/bin/perl -# config-zaptel.pl -# Sangoma Zaptel/TDM API/SMG Configuration Script. -# -# Copyright (c) 2006, Sangoma Technologies Inc. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# ---------------------------------------------------------------------------- -# Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option -# Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode -# Jul 20, 2007 2.5 David Yat Sin silent option -# Jun 13, 2007 Yuan Shen SS7 support -# Jan 15, 2007 David Yat Sin support for non-trixbox installations. Major -# changes to script. -# Jan 8, 2007 David Yat Sin script renamed to config-zaptel.pl -# Jan 5, 2007 2.1 David Yat Sin v2.1 fix for analog cards inserted in wrong -# context -# Dec 12, 2006 2.0 David Yat Sin 2.0 support for T1/E1 cards -# Oct 13, 2006 David Yat Sin Added --opermode and --law option -# Oct 12, 2006 David Yat Sin Initial version -# ============================================================================ - -system('clear'); -print "\n###################################################################"; -print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; -print "\n# v2.7 #"; -print "\n# Sangoma Technologies Inc. #"; -print "\n# Copyright(c) 2007. #"; -print "\n###################################################################\n\n"; - -use strict; -#use warnings; -#use diagnostics; -use Card; -use A10x; -use A10u; -use A20x; -use A50x; - -my $FALSE = 1; -my $TRUE = 0; -my $zaptelprobe=' '; - -my $etc_dir=""; -my $module_list=""; -my $module_load=""; -my $module_unload=""; -my $os_type_name=""; - - -my $os_type_list=`sysctl -a |grep ostype`; -if ($os_type_list =~ m/Linux/){ - $os_type_name="Linux"; - $etc_dir="/etc"; - $module_load="modprobe"; - $module_unload="modprobe -r"; - $module_list="modprobe -l"; -}elsif ($os_type_list =~ m/FreeBSD/){ - $os_type_name="FreeBSD"; - $etc_dir="/usr/local/etc"; - $module_load="kldload"; - $module_unload="kldunload"; - $module_list="kldstat"; -}else{ - print("Failed to determine OS type\n"); - print("Exiting...\n"); - exit(1); -} - - -my $startup_string=""; -my $cfg_string=""; -my $first_cfg=1; -my $zaptel_conf=""; -my $zapata_conf=""; -my $bri_conf=""; -my $devnum=1; -my $current_zap_span=1; -my $current_tdmapi_span=1; -my $current_bri_span=1; -my $current_zap_channel=1; -my $num_analog_devices=0; -my $num_analog_devices_total=0; -my $num_bri_devices=0; -my $num_bri_devices_total=0; -my $num_digital_devices=0; -my $num_digital_devices_total=0; -my $num_ss7_config=0; -my $num_zaptel_config=0; -my $line_media=''; -my $max_chans=0; -my $ss7_tdmvoicechans=''; -my $ss7_array_length=0; - -my $device_has_hwec=$FALSE; -my $device_has_normal_clock=$FALSE; -my @device_normal_clocks=("0"); - -my $is_tdm_api=$FALSE; - -my $def_femedia=''; -my $def_feframe=''; -my $def_feclock=''; -my $def_bri_option=''; -my $def_signalling=''; -my $def_switchtype=''; -my $def_zapata_context=''; -my $def_zapata_group=''; -my $def_te_ref_clock=''; -my $def_tdmv_dchan=0; -my $def_bri_group=''; -my $def_felcode=''; -my $def_feframe=''; -my $def_te_sig_mode=''; - -my $def_hw_dtmf="YES"; - -my $silent_femedia="T1"; -my $silent_feframe="ESF"; -my $silent_feframe_e1="CRC4"; - -my $silent_felcode="B8ZS"; - -my $silent_feclock="NORMAL"; -my $silent_signalling="PRI CPE"; -my $silent_switchtype="National"; -my $silent_zapata_context="from-pstn"; -my $silent_zapata_group="0"; -my $silent_te_sig_mode='CCS'; - -my $def_bri_country="europe"; -my $def_bri_operator="etsi"; -my $def_bri_conn_type="Point to point"; - -my $is_trixbox = $FALSE; -my $silent = $FALSE; -my $config_zaptel = $TRUE; -my $config_zapata = $TRUE; -my $is_smg = $FALSE; - -my $tdm_api_span_num=0; -my $zaptel_installed=$FALSE; -my $modprobe_list=`$module_list`; - - -read_args(); -check_zaptel(); -my $current_dir=`pwd`; -chomp($current_dir); -my $cfg_dir='tmp_cfg'; -my $curdircfg="$current_dir"."/"."$cfg_dir"; - -unless ( -d $curdircfg ) { - $curdircfg = "mkdir " . $curdircfg; - system ($curdircfg); -} - - -my $debug_info_file="$current_dir/$cfg_dir/debug_info"; -my @hwprobe=`wanrouter hwprobe verbose`; - -my $wanpipe_conf_dir="$etc_dir/wanpipe"; -my $asterisk_conf_dir="$etc_dir/asterisk"; - -my $wanrouter_rc_template="$current_dir/templates/wanrouter.rc.template"; - -my $zaptel_conf_template="$current_dir/templates/zaptel.conf"; -my $zaptel_conf_file="$current_dir/$cfg_dir/zaptel.conf"; -my $zaptel_conf_file_t="$etc_dir/zaptel.conf"; - -my $zapata_conf_template="$current_dir/templates/zapata.conf"; -my $zapata_conf_file="$current_dir/$cfg_dir/zapata.conf"; -my $zapata_conf_file_t="$asterisk_conf_dir/zapata.conf"; - -my $bri_conf_template="$current_dir/templates/smg_bri.conf"; -my $bri_conf_file="$current_dir/$cfg_dir/smg_bri.conf"; -my $bri_conf_file_t="$wanpipe_conf_dir/smg_bri.conf"; - -my $date=`date +%F`; -chomp($date); -my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; - -prepare_files(); -config_t1e1(); -config_bri(); -config_analog(); -summary(); -apply_changes(); -config_boot(); -config_ztcfg_start(); -config_smg_ctrl_start(); -clean_files(); -print "\n\n"; - - -#######################################FUNCTIONS################################################## - -sub config_boot{ - my $script_name="wanrouter"; - my $current_run_level=3; - my $zaptel_start_level=9; - my $zaptel_stop_level=92; - my $wanrouter_start_level=8; - my $wanrouter_stop_level=93; - my $command=''; - my $rc_dir=$etc_dir; - - if ($os_type_list =~ m/FreeBSD/){ - return; - } - my $res=`cat $etc_dir/inittab |grep id`; - if ($res =~ /id:(\d+):initdefault/){ - $current_run_level=$1; -# print "Current boot level is $current_run_level\n"; - } else { - print "Warning: Failed to determine init boot level, assuming 3\n"; - $current_run_level=3; - } - - - print "\nWanrouter boot scripts configuration...\n\n"; - print "Removing existing $script_name boot scripts..."; - $command="rm -f $rc_dir/rc?.d/*$script_name >/dev/null 2>/dev/null"; - if(system($command) == 0){ - print "OK\n"; - } else { - print "Not installed\n"; - } - if($num_ss7_config!=0){ - $script_name="smgss7_init_ctrl"; - } - - print ("Would you like $script_name to start on system boot?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - #examine system bootstrap files - $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $rc_dir=$rc_dir; - } else { - $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $rc_dir=$etc_dir."/rc.d"; - } else { - print "Failed to locate boostrap directory\n"; - print "wanrouter boot scripts will not be installed\n"; - return; - } - } - - if($zaptel_installed==$TRUE){ - print "Verifying Zaptel boot scripts..."; - #find zaptel start scripts - $command="find $rc_dir/rc".$current_run_level.".d/*zaptel >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="find $rc_dir/rc".$current_run_level.".d/*zaptel"; - $res=`$command`; - if ($res =~ /.*S(\d+)zaptel/){ - $zaptel_start_level=$1; - print "Enabled (level:$zaptel_start_level)\n"; - } else { - print "\nfailed to parse zaptel boot level, assuming $zaptel_start_level"; - } - } else { - print "Not installed\n"; - $zaptel_start_level=0; - } - - #find zaptel stop scripts - print "Verifying Zaptel shutdown scripts..."; - $command="find ".$rc_dir."/rc6.d/*zaptel >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="find ".$rc_dir."/rc6.d/*zaptel"; - $res=`$command`; - if ($res =~ /.*K(\d+)zaptel/){ - $zaptel_stop_level=$1; - print "Enabled (level:$zaptel_stop_level)\n"; - } else { - print "\nfailed to parse zaptel boot level, assuming $zaptel_stop_level\n"; - } - } else { - print "Not installed\n"; - $zaptel_stop_level=0; - } - if ($zaptel_start_level != 0){ - $wanrouter_start_level=$zaptel_start_level-1; - } - if ($zaptel_stop_level != 0){ - $wanrouter_stop_level=$zaptel_stop_level+1; - } - } - my $wanrouter_start_script=''; - if($wanrouter_start_level < 10){ - $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; - } else { - $wanrouter_start_script="S".$wanrouter_start_level.$script_name; - } - my $wanrouter_stop_script=''; - if($wanrouter_stop_level < 10){ - $wanrouter_stop_script="K0".$wanrouter_stop_level.$script_name; - } else { - $wanrouter_stop_script="K".$wanrouter_stop_level.$script_name; - } - - $command="find $etc_dir/init.d/$script_name >/dev/null 2>/dev/null"; - if(system($command) !=0){ - $command="install -D -m 755 /usr/sbin/$script_name $rc_dir/init.d/$script_name"; - if(system($command) !=0){ - print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; - print "$script_name boot scripts not installed\n"; - return; - } - } - print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; - my @run_levels= ("2","3","4","5"); - foreach my $run_level (@run_levels) { - $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_start_script; - if(system($command) !=0){ - print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; - print "$script_name start scripts not installed\n"; - return; - } - } - - print "Enabling $script_name shutdown scripts ...(level:$wanrouter_stop_level)\n"; - @run_levels= ("0","1","6"); - foreach my $run_level (@run_levels) { - $command="ln -sf $rc_dir/init.d/$script_name ".$rc_dir."/rc".$run_level.".d/".$wanrouter_stop_script; - if(system($command) !=0){ - print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; - print "$script_name stop scripts not installed\n"; - return; - } - } - } - -} - - -sub config_ztcfg_start{ - if ($num_zaptel_config ==0){ - return; - } - my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; - if (system($command) != 0){ - #Zaptel init scripts not installed, prompt for wanpipe_zaptel_start_script - print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - exec_command("cp -f $current_dir/templates/zaptel_cfg_script $wanpipe_conf_dir/scripts/start"); - } - } -} - -sub config_smg_ctrl_start{ - if($num_bri_devices == 0){ - return; - } - print ("Would you like smg_ctrl to start on wanrouter start?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite - my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; - } else { - $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; - } - if (system($command) == 0){ - print "smgbri start script installed successfully"; - } else { - print "failed to install smgbri start script"; - } - } -} - -sub check_zaptel{ - if ($modprobe_list =~ /zaptel.ko/){ - $zaptel_installed=$TRUE; - } -} - -sub apply_changes{ - my $asterisk_command=''; - my $bri_command=''; - my $asterisk_restart=$FALSE; - my $res=''; - - system('clear'); - - if($silent==$TRUE){ - $res="Stop now"; - }elsif($is_tdm_api==$TRUE){ - print "\n Wanpipe configuration complete: choose action\n"; - $res=&prompt_user_list( "Save cfg: Stop Wanpipe now", - "Do not save cfg: Exit", - ""); - }else{ - print "\nZaptel and Wanpipe configuration complete: choose action\n"; - $res=&prompt_user_list("Save cfg: Restart Asterisk & Wanpipe now", - "Save cfg: Restart Asterisk & Wanpipe when convenient", - "Save cfg: Stop Asterisk & Wanpipe now", - "Save cfg: Stop Asterisk & Wanpipe when convenient", - "Do not save cfg: Exit", - ""); - } - - - if ($res =~ m/Exit/){ - print "No changes made to your configuration files\n"; - exit 0; - } - if ($res =~ m/now/){ - $asterisk_command='stop now'; - } else { - $asterisk_command='stop when convenient'; - } - - if ($res =~ m/Restart/){ - $asterisk_restart=$TRUE; - } else { - $asterisk_restart=$FALSE; - } - - if ($is_trixbox==$TRUE){ - exec_command("amportal stop"); - unload_zap_modules(); - } elsif ($is_tdm_api==$FALSE ){ - if (`(pidof asterisk)` != 0 ){ - print "\nStopping Asterisk...\n"; - exec_command("asterisk -rx \"$asterisk_command\""); - sleep 2; - while (`(pidof asterisk)` != 0 ){ - if ($asterisk_command eq "stop now"){ - print "Failed to stop asterisk using command: \'$asterisk_command\' \n"; - my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes"); - my $res=&prompt_user_list(@options,""); - - if ( $res =~ m/Force Stop/){ - execute_command("kill -KILL \$(pidof asterisk)"); - } elsif ( $res =~ m/Exit/ ){ - exit(1); - } else { - print "Waiting for asterisk to stop...\n"; - sleep 5; - exec_command("asterisk -rx \"$asterisk_command\""); - } - } else { - #stop when convenient option was selected - print "Waiting for asterisk to stop...\n"; - sleep 3; - } - } - - - - - - }else { - print "\nAsterisk is not running...\n"; - } - - } - - if($num_bri_devices != 0){ - exec_command("/usr/sbin/smg_ctrl stop"); - } - - print "\nStopping Wanpipe...\n"; - exec_command("wanrouter stop all"); - - if ($zaptel_installed==$TRUE){ - if($is_tdm_api==$FALSE){ - print "\nUnloading Zaptel modules...\n"; - unload_zap_modules(); - } - } - - print "\nRemoving old configuration files...\n"; - - exec_command("rm -f $wanpipe_conf_dir/wanpipe*.conf"); - - gen_wanrouter_rc(); - - print "\nCopying new Wanpipe configuration files...\n"; - copy_config_files(); - if($num_bri_devices != 0){ - print "\nCopying new sangoma_brid configuration files ($bri_conf_file_t)...\n"; - exec_command("cp -f $bri_conf_file $bri_conf_file_t"); - } - - if ($zaptel_installed==$TRUE){ - if($config_zaptel==$TRUE){ - if ($num_zaptel_config !=0){ - print "\nCopying new Zaptel configuration file ($zaptel_conf_file_t)...\n"; - exec_command("cp -f $zaptel_conf_file $zaptel_conf_file_t"); - } - } - } - - if ($config_zapata==$TRUE || $is_trixbox==$TRUE){ - print "\nCopying new chan_zap configuration files ($zapata_conf_file_t)...\n"; - exec_command("cp -f $zapata_conf_file $zapata_conf_file_t"); - } - - if( $asterisk_restart == $TRUE && $is_tdm_api==$FALSE){ - print "\nStarting Wanpipe...\n"; - exec_command("wanrouter start"); - - if($num_bri_devices != 0){ - print "Loading SMG BRI...\n"; - sleep 2; - exec_command("/usr/sbin/smg_ctrl start"); - } - -# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ - if ($num_zaptel_config != 0){ - print "Loading Zaptel...\n"; - sleep 2; - exec_command("ztcfg -v"); -# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); -# if (&prompt_user_list("YES","NO","") eq 'YES'){ -# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); -# } - } - if ($is_trixbox==$TRUE){ - print "\nStarting Amportal...\n"; - exec_command("amportal start"); - sleep 2; - }elsif($config_zapata==$TRUE){ - print "\nStarting Asterisk...\n"; - exec_command("asterisk"); - sleep 2; - - print "\nListing Asterisk channels...\n\n"; - exec_command("asterisk -rx \"zap show channels\""); - print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; - }else{ - } - } - print "\nWanrouter start complete...\n"; -} - - - -sub save_debug_info{ - my $version=`wanrouter version`; - chomp($version); - - my $uname=`uname -a`; - chomp($uname); - - my $issue=''; - - if ($os_type_list =~ m/Linux/){ - $issue=`cat $etc_dir/issue`; - chomp($issue); - } - - my $debug_info="\n"; - $debug_info.="===============================================================\n"; - $debug_info.=" SANGOMA DEBUG INFO FILE \n"; - $debug_info.=" Generated on $date \n"; - $debug_info.="===============================================================\n"; - - $debug_info.="\n\nwanrouter hwprobe\n"; - $debug_info.="@hwprobe\n"; - $debug_info.="\nwanrouter version\n"; - $debug_info.="$version\n"; - $debug_info.="\nKernel \"uname -a\"\n"; - $debug_info.="$uname\n"; - if ($os_type_list =~ m/Linux/){ - $debug_info.="\n$os_type_name distribution \"cat $etc_dir/issue\"\n"; - $debug_info.="$issue\n"; - } - $debug_info.="EOF\n"; - - open (FH,">$debug_info_file") or die "Could not open $debug_info_file"; - print FH $debug_info; - close (FH); - exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); -} - - - - - - - - - -sub get_zapata_context{ - my ($card_model,$card_port)=@_; - my $context=''; - my @options = ("from-pstn", "from-internal","Custom"); - - if($is_trixbox==$TRUE){ - @options = ("PSTN", "INTERNAL"); - } - if ($silent==$FALSE){ - printf ("Select dialplan context for A%s on port %s\n", $card_model, $card_port); - my $res = &prompt_user_list(@options,$def_zapata_context); - if($res eq "PSTN"){ - $context="from-zaptel"; - }elsif($res eq "INTERNAL"| $res eq "from-internal"){ - $context="from-internal"; - }elsif($res eq "from-pstn"){ - $context="from-pstn"; - }elsif($res eq "Custom"){ - my $res_context=&prompt_user("Input the context for this port"); - while(length($res_context)==0){ - print "Invalid context, input a non-empty string\n"; - $res_context=&prompt_user("Input the context for this port",$def_zapata_context); - } - - $context=$res_context; - }elsif($res eq $def_zapata_context){ - $context=$def_zapata_context; - }else{ - print "Internal error:invalid context,group\n"; - exit 1; - } - } else { - $context=$silent_zapata_context; - } - $def_zapata_context=$context; - return $context; -} - -sub gen_wanrouter_rc{ - #update wanpipe startup sequence - my $rcfile=""; - if (!open (FH,"$wanpipe_conf_dir/wanrouter.rc")) { - open (FH,"$wanrouter_rc_template"); - } - while () { - $rcfile .= $_; - } - close (FH); - open (FH,">$current_dir/$cfg_dir/wanrouter.rc"); - $rcfile =~ s/WAN_DEVICES\s*=.*/WAN_DEVICES="$startup_string"/g; - print FH $rcfile; - close (FH); -} - -sub prepare_files{ - - if ($is_trixbox==$TRUE){ - $zapata_conf_template="$current_dir/templates/zapata-auto.conf"; - $zapata_conf_file="$current_dir/$cfg_dir/zapata-auto.conf"; - $zapata_conf_file_t="$asterisk_conf_dir/zapata-auto.conf"; - } - - if ($silent==$FALSE){ - if ($is_trixbox==$FALSE && $is_smg==$FALSE && $is_tdm_api==$FALSE){ - print "Would you like to generate $zapata_conf_file_t\n"; - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $config_zapata = $FALSE; - } - } - } - -#remove temp files - my $tmp_cfg_dir="$current_dir"."/"."$cfg_dir"; - if ( -d "$current_dir"."/"."$cfg_dir") { - exec_command("rm -f $current_dir/$cfg_dir/*"); - } -#backup existing configuration files - if ( -f $zaptel_conf_file_t ) { - exec_command("cp -f $zaptel_conf_file_t $zaptel_conf_file_t.bak "); - } - - if ( -f $zapata_conf_file_t ) { - exec_command("cp -f $zapata_conf_file_t $zapata_conf_file_t.bak"); - } -} - -sub clean_files{ - exec_command("rm -rf $current_dir/$cfg_dir"); -} - - -sub write_zapata_conf{ - my $zp_file=""; - open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; - while () { - $zp_file .= $_; -} - close (FH); - - $zp_file.=$zapata_conf; - - open(FH, ">$zapata_conf_file") or die "cannot open $zapata_conf_file"; - print FH $zp_file; - close(FH); -} - -sub copy_config_files{ - my @wanpipe_files = split / /, $cfg_string; - exec_command("cp -f $current_dir/$cfg_dir/wanrouter.rc $wanpipe_conf_dir"); - foreach my $wanpipe_file (@wanpipe_files) { - exec_command("cp -f $current_dir/$cfg_dir/$wanpipe_file.conf $wanpipe_conf_dir"); - } -} - -sub unload_zap_modules{ - my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); - foreach my $module (@modules_list) { - if ($modprobe_list =~ m/$module/){ - exec_command("$module_unload $module"); - } - } -} - -sub write_zaptel_conf{ - my $zp_file=""; - open(FH, "$zaptel_conf_template") or die "cannot open $zaptel_conf_template"; - while () { - $zp_file .= $_; -} - close (FH); - $zp_file=$zp_file.$zaptel_conf; - open(FH, ">$zaptel_conf_file") or die "cannot open $zaptel_conf_file"; - print FH $zp_file; - close(FH); -} - -sub summary{ - if($devnum==1){ - system('clear'); - print "\n###################################################################"; - print "\n# SUMMARY #"; - print "\n###################################################################\n\n"; - - print("\n\nNo Sangoma voice compatible cards found/configured\n\n"); - exit 0; - }else{ - if ($num_zaptel_config != 0 && $config_zaptel==$TRUE){ - write_zaptel_conf(); - } - if ($num_bri_devices != 0 ){ - write_bri_conf(); - } - if ($config_zapata==$TRUE){ - write_zapata_conf(); - } - save_debug_info(); - system('clear'); - my $file_list = 1; - print "\n###################################################################"; - print "\n# SUMMARY #"; - print "\n###################################################################\n\n"; - - print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); - print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); - print(" $num_bri_devices_total ISDN BRI card(s) detected, $num_bri_devices configured\n"); - - print "\nConfigurator has created the following files:\n"; - print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; - $file_list++; - - if ($num_bri_devices != 0){ - print "\t$file_list. sangoma_brid config file $wanpipe_conf_dir/smg_bri\n"; - $file_list++; - } - - if ($num_zaptel_config != 0){ - print "\t$file_list. Zaptel config file $zaptel_conf_file_t\n"; - $file_list++; - } - if ($config_zapata==$TRUE){ - print "\t$file_list. Zapata config file $zapata_conf_file_t\n"; - } - - if (($num_zaptel_config != 0) | ($config_zapata==$TRUE)){ - print "\n\nYour original configuration files will be saved to:\n"; - $file_list=1; - } - - if ($num_zaptel_config != 0){ - print "\t$file_list. $zaptel_conf_file_t.bak \n"; - $file_list++; - } - if ($config_zapata==$TRUE){ - print "\t$file_list. $zapata_conf_file_t.bak \n\n"; - } - - print "\nYour configuration has been saved in $debug_tarball.\n"; - print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - } -} - - -sub exec_command{ - my @command = @_; - if (system(@command) != 0 ){ - print "Error executing command:\n@command\n\n"; - } - return $?; -} - -sub prompt_user{ - my($promptString, $defaultValue) = @_; - if ($defaultValue) { - print $promptString, "def=\"$defaultValue\": "; - } else { - print $promptString, ": "; - } - - $| = 1; # force a flush after our print - $_ = ; # get the input from STDIN (presumably the keyboard) - chomp; - if ("$defaultValue") { - return $_ ? $_ : $defaultValue; # return $_ if it has a value - } else { - return $_; - } -} - -sub prompt_user_list{ - my @list = @_; - my $defaultValue = @list[$#list]; - - my $i; - my $valid = 0; - for $i (0..$#list-1) { - printf(" %s\. %s\n",$i+1, @list[$i]); - } - while ($valid == 0){ - my $list_sz = $#list; - print "[1-$list_sz"; - if ( ! $defaultValue eq ''){ - print ", ENTER=\'$defaultValue\']:"; - }else{ - print "]:"; - } - $| = 1; - $_ = ; - chomp; - if ( $_ eq '' & ! $defaultValue eq ''){ - print "\n"; - return $defaultValue; - } - - if ( $_ =~ /(\d+)/ ){ - if ( $1 > $list_sz) { - print "\nError: Invalid option, input a value between 1 and $list_sz \n"; - } else { - print "\n"; - return @list[$1-1] ; - } - } else { - print "\nError: Invalid option, input an integer\n"; - } - } -} - -sub read_args { - my $arg_num; - foreach $arg_num (0 .. $#ARGV) { - $_ = $ARGV[$arg_num]; - if( /^--trixbox$/){ - $is_trixbox=$TRUE; - }elsif ( /^--tdm_api/){ - $is_tdm_api=$TRUE; - }elsif ( /^--smg$/){ - $is_smg=$TRUE; - }elsif ( /^--silent$/){ - $silent=$TRUE; - }elsif ( /^--no-zapata$/){ - $config_zapata=$FALSE; - }elsif ( /^--no-zaptel$/){ - $config_zaptel=$FALSE; - }elsif ( $_ =~ /--fe_media=(\w+)/){ - $silent_femedia=$1; - if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ - printf("Invalid value for fe_media, should be T1/E1\n"); - exit(1); - } - }elsif ( $_ =~ /--fe_frame=(\w+)/){ - $silent_feframe=$1; - if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ - printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); - exit(1); - } - }elsif ( $_ =~ /--fe_clock=(\w+)/){ - $silent_feclock=$1; - if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ - printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); - exit(1); - } - }elsif ( $_ =~ /--signalling=(\w+)/){ - my $tmp_signalling=$1; - if ($tmp_signalling eq 'em'){ - $silent_signalling="E & M"; - }elsif ($tmp_signalling eq 'em_w'){ - $silent_signalling="E & M Wink"; - }elsif ($tmp_signalling eq 'pri_cpe'){ - $silent_signalling="PRI CPE"; - }elsif ($tmp_signalling eq 'pri_net'){ - $silent_signalling="PRI NET"; - }elsif ($tmp_signalling eq 'fxs_ls'){ - $silent_signalling="FXS - Loop Start"; - }elsif ($tmp_signalling eq 'fxs_gs'){ - $silent_signalling="FXS - Ground Start"; - }elsif ($tmp_signalling eq 'fxs_ks'){ - $silent_signalling="FXS - Kewl Start"; - }elsif ($tmp_signalling eq 'fxo_ls'){ - $silent_signalling="FXO - Loop Start"; - }elsif ($tmp_signalling eq 'fxo_gs'){ - $silent_signalling="FXO - Ground Start"; - }elsif ($tmp_signalling eq 'fxo_ks'){ - $silent_signalling="FXO - Kewl Start"; - }else{ - printf("Invalid option for --signalling, options are\n"); - printf("\t pri_cpe/pri_net/em/em_w\n"); - printf("\t em/em_w\n"); - printf("\t fxo_ls/fxo_gs/fxo_ks\n"); - printf("\t fxs_ls/fxs_gs/fxs_ks\n"); - exit(1); - } - }elsif ( $_ =~ /--conf_dir=(.*)/){ - $etc_dir=$1; - if (! -d $etc_dir){ - printf("Error: directory $1 does not exist\n"); - exit(1); - } - } - } - - if ($is_trixbox==$TRUE){ - print "\nGenerating configuration files for Trixbox\n"; - } - if ($is_smg==$TRUE){ - print "\nGenerating configuration files for SS7\n"; - } - if ($is_tdm_api==$TRUE){ - $config_zapata = $FALSE; - } - -} - -#------------------------------BRI FUNCTIONS------------------------------------# -sub get_bri_country { - $def_bri_country = "europe"; - return $def_bri_country; -} - -sub get_bri_group{ - my $group; - my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); - while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ - print "Invalid group, input an integer greater than 0\n"; - $res_group=&prompt_user("Input the group for this port",$def_bri_group); - } - $group=$res_group; - $def_bri_group=$group; - return $def_bri_group; -} - - -sub get_bri_operator { -#warning returning ETSI - $def_bri_operator = "etsi"; - return $def_bri_operator; - - - - my @options = ( "European ETSI Technical Comittee", "France Telecom VN2", "France Telecom VN3", - "France Telecom VN6", "Deutsche Telekom 1TR6", "British Telecom ISDN2", - "Belgian V1", "Sweedish Televerket", "ECMA 143 QSIG"); - - my @options_val = ("etsi", "ft_vn2", "ft_vn3", "ft_vn6", "dt_1tr6", "bt_isdn2", "bg_vi", "st_swd", "ecma_qsi"); - - my $res = &prompt_user_list(@options,$def_switchtype); - - my $i; - for $i (0..$#options){ - if ( $res eq @options[$i] ){ - $def_bri_operator=@options[$i]; - return @options_val[$i]; - } - } - print "Internal error: Invalid PRI switchtype\n"; - exit 1; -} - -sub write_bri_conf{ - my $bri_file=""; - open(FH, "$bri_conf_template") or die "cannot open $bri_conf_template"; - while () { - $bri_file .= $_; -} - close (FH); - $bri_file=$bri_file.$bri_conf; - open(FH, ">$bri_conf_file") or die "cannot open $bri_conf_file"; - print FH $bri_file; - close(FH); -} - - -sub get_bri_conn_type{ - my $conn_type; - - my @options = ( "Point to multipoint", "Point to point"); - my @options_val = ("point_to_multipoint", "point_to_point"); - - my $res = &prompt_user_list(@options,$def_bri_conn_type); - - my $i; - for $i (0..$#options){ - if ( $res eq @options[$i] ){ - $def_bri_conn_type=@options[$i]; - return @options_val[$i]; - } - } - print "Internal error: Invalid BRI connection type\n"; - exit 1; -} - - - - -sub config_bri{ - if($is_smg!=$TRUE){ - return; - } - my $a50x; - if (!$first_cfg) { - system('clear'); - } - $first_cfg=0; - print "------------------------------------\n"; - print "Configuring ISDN BRI cards [A500]\n"; - print "------------------------------------\n"; - my $skip_card=$FALSE; - $zaptel_conf.="\n"; - $zapata_conf.="\n"; - foreach my $dev (@hwprobe) { - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\w+).*HWEC=(\w+).*/){ - $skip_card=$FALSE; - if ($1 eq '500'){ - my $card = eval {new Card(); } or die ($@); - - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - - my $hwec=0; - if($6 gt 0){ - $hwec=1; - } - if ($hwec==0){ - $card->hwec_mode('NO'); - }else{ - $card->hwec_mode('YES'); - } - - if ($card->card_model eq '500'){ - $num_bri_devices_total++; - system('clear'); - print "\n-----------------------------------------------------------\n"; - print "A$1 detected on slot:$3 bus:$4\n"; - print "-----------------------------------------------------------\n"; - - if($is_trixbox==$FALSE){ -select_bri_option: - print "\nWould you like to configure A$1 port $5 on slot:$3 bus:$4\n"; - my @options=("YES", "NO", "Exit"); - $def_bri_option=&prompt_user_list(@options,$def_bri_option); - if($def_bri_option eq 'YES'){ - $skip_card=$FALSE; - $bri_conf.="\n;Sangoma A$1 port $5 [slot:$3 bus:$4 span:$devnum]"; - }elsif($def_bri_option eq 'NO'){ - $skip_card=$TRUE; - }else{ - print "Exit without applying changes?\n"; - if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ - print "No changes made to your configuration files.\n\n"; - exit 0; - } else { - goto select_bri_option; - } - } - } - if ($skip_card==$FALSE){ -# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; -# prompt_user("Press any key to continue"); - - $startup_string.="wanpipe$devnum "; - $cfg_string.="wanpipe$devnum "; - $a50x = eval {new A50x(); } or die ($@); - $a50x->card($card); - $a50x->fe_line($5); - $devnum++; - $num_bri_devices++; - $card->tdmv_span_no($current_tdmapi_span); - $current_tdmapi_span++; - $a50x->gen_wanpipe_conf(); - }else{ - print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; - prompt_user("Press any key to continue"); - } - - } - } - }elsif ( $dev =~ /(\d+):NT/ & $skip_card==$FALSE){ - printf("\nConfiguring port %d as NT\n", $a50x->fe_line()); - printf("\nSelect connection type for port %d\n", $a50x->fe_line()); - my $bri_pos=$current_bri_span; - - $current_bri_span=$current_bri_span+1; - my $conn_type=get_bri_conn_type(); - my $group=get_bri_group(); - my $country=get_bri_country(); - - my $operator=get_bri_operator(); - $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); - }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ - printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); - printf("\nSelect connection type for port %d\n", $a50x->fe_line()); - my $bri_pos=$current_bri_span; - - $current_bri_span=$current_bri_span+1; - my $conn_type=get_bri_conn_type(); - my $group=get_bri_group(); - my $country=get_bri_country(); - - my $operator=get_bri_operator(); - $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); - } - } -# prompt_user("Press any key to continue"); - if($num_bri_devices_total!=0){ - print("\nISBN BRI card configuration complete\n\n"); - prompt_user("Press any key to continue"); - } else { - print("\nNo Sangoma ISDN BRI cards detected\n\n"); - prompt_user("Press any key to continue"); - - } -} - - - - - -#------------------------------T1/E1 FUNCTIONS------------------------------------# - -sub get_te_ref_clock{ - my @list_normal_clocks=@_; - my @f_list_normal_clocks; - my $f_port; - foreach my $port (@list_normal_clocks) { - if ($port eq '0'){ - $f_port = "Free run"; -} else { - $f_port = "Port ".$port; -} - push(@f_list_normal_clocks, $f_port); -} - - my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); - my $i; - - for $i (0..$#f_list_normal_clocks){ - if ( $res eq @f_list_normal_clocks[$i] ){ - return @list_normal_clocks[$i]; -} -} - - print "Internal error: Invalid reference clock\n"; - exit 1; - -} - - -sub prompt_user_hw_dchan{ - my ($card_model, $port, $port_femedia) = @_; - my $res_dchan=''; - my $dchan; - - printf("Hardware HDLC can be performed on the data channel.\n"); -prompt_hw_dchan: - my $res_dchan = &prompt_user("Select the data channel on A$card_model, port:$port, select 0 for unused.\n","0"); - while(length($res_dchan)==0 |!($res_dchan =~/(\d+)/)){ - print "Invalid channel, input an integer (0 for unused).\n"; - $res_dchan=&prompt_user("Select the data channel","0"); - } - if ( $res_dchan < 0){ - printf("Error: channel cannot have negative value\n"); - $res_dchan=''; - goto prompt_hw_dchan; - } - if ( $port_femedia eq 'T1' && $res_dchan > 24){ - printf("Error: only 24 channels available on T1\n"); - $res_dchan=''; - goto prompt_hw_dchan; - }elsif ($port_femedia eq 'E1' && $res_dchan > 31){ - printf("Error: only 31 channels available on E1\n"); - $res_dchan=''; - goto prompt_hw_dchan; - } - if ($res_dchan == 0){ - printf("HW HDLC channel not used\n"); - }else{ - printf("HW HDLC channel set to:%d\n", $res_dchan); - } - return $res_dchan; -} - - - -sub get_zapata_group{ - my ($card_model,$card_port,$context)=@_; - my $group=''; - if($is_trixbox==$TRUE){ - if($context eq "from-zaptel"){ - $group=0; - return $group; - }elsif($context eq "from-internal"){ - $group=1; - return $group; - }else{ - print "Internal error:invalid group for Trixbox\n"; - } - }else{ - if($context eq "from-pstn"){ - $group=0; - }elsif($context eq "from-internal"){ - $group=1; - }else{ - my $res_group=&prompt_user("\nInput the group for this port\n",$def_zapata_group); - while(length($res_group)==0 |!($res_group =~/(\d+)/)){ - print "Invalid group, input an integer.\n"; - $res_group=&prompt_user("Input the group for this port",$def_zapata_group); - } - $group=$res_group; - $def_zapata_group=$group; - } - } - - return $group; -} - - - -sub prompt_hw_dtmf { - print("Would you like to enable hardware DTMF detection?\n"); - my @options = ("YES","NO"); - $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); - return $def_hw_dtmf; - -} - -sub get_pri_switchtype { - my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); - my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); - my $res = &prompt_user_list(@options,$def_switchtype); - my $i; - for $i (0..$#options){ - if ( $res eq @options[$i] ){ - $def_switchtype=@options[$i]; - return @options_val[$i]; -} -} - print "Internal error: Invalid PRI switchtype\n"; - exit 1; -} - - -sub gen_ss7_voicechans{ - my @ss7_array = @_; - my $T1CHANS = pop(@ss7_array); - my $count = @ss7_array; - my $output =''; - my $chan_in = 1; - my $chan_de = 0; - my $flag = 0; - my $i = 0; - my $j = 0; - - while($i < $count){ - $j = $i + 1; - if ($ss7_array[$i] > 2 && $i == 0){ - $chan_de = $ss7_array[$i] - 1; - $output .= "1-$chan_de"; - $flag = 1; - }elsif ($ss7_array[$i] == 2 && $i == 0){ - $output .= "1"; - $flag = 1; - } - - if ($ss7_array[$j] == ($ss7_array[$i] + 1) && $j < $count){ - goto Incrementing; - }elsif ($ss7_array[$i] == $T1CHANS && $i == ($count-1)){ - goto Incrementing; - } - - if ($i < ($count-1)){ - $chan_in = $ss7_array[$i]+1; - if ($chan_in < ($ss7_array[$j]-1)){ - $chan_de = $ss7_array[$j] - 1; - if ($flag != 0){ - $output .= ".$chan_in-$chan_de"; - }else{ - $output .= "$chan_in-$chan_de"; - $flag = 1; - } - }else{ - if ($flag != 0){ - $output .= ".$chan_in"; - }else{ - $output .= "$chan_in"; - $flag = 1; - } - } - }else{ - $chan_in = $ss7_array[$i]+1; - if ($chan_in < $T1CHANS){ - $chan_de = $T1CHANS; - if ($flag != 0){ - $output .= ".$chan_in-$chan_de"; - }else{ - $output .= "$chan_in-$chan_de"; - $flag = 1; - } - }else{ - if ($flag != 0){ - $output .= ".$T1CHANS"; - }else{ - $output .= "$T1CHANS"; - $flag = 1; - } - } - } - -Incrementing: - $i++; - } - return $output; -} - -sub prompt_user_ss7_chans{ - my @ss7_string = @_; - my $def_ss7_group_chan = ''; - - my $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - -CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ - print("ERROR: Invalid channel number, input an integer only.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); -} - if ($line_media eq 'T1'){ - while ($ss7_group_chan>24 || $ss7_group_chan<1){ - print("Invalid channel number, there are only 24 channels in T1.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - goto CHECK1; -} -}elsif ($line_media eq 'E1'){ - while ($ss7_group_chan>31 || $ss7_group_chan<1){ - print("Invalid channel number, there are only 31 channels in E1.\n\n"); - $ss7_group_chan=&prompt_user("$ss7_string[0]",$def_ss7_group_chan); - goto CHECK1; -} -} - return $ss7_group_chan; -} - - - - - - -sub config_t1e1{ - if (!$first_cfg) { - system('clear'); - } - print "---------------------------------------------\n"; - print "Configuring T1/E1 cards [A101/A102/A104/A108]\n"; - print "---------------------------------------------\n"; - - foreach my $dev (@hwprobe) { - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - - if ( ! ($1 eq '200' | $1 eq '400' | $1 eq '500') ){ - #do not count analog devices - $num_digital_devices_total++; - } - my $card = eval {new Card(); } or die ($@); - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - $card->fe_cpu($5); - - my $hwec=0; - if ( $dev =~ /HWEC=(\d+)/){ - if($1 gt 0){ - $hwec=1; - } - } - if ( $dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - my $abc=0; - } - if ($hwec==0){ - $card->hwec_mode('NO'); - }else{ - $card->hwec_mode('YES'); - } - my $port=$6; - if ($6 eq 'PRI') { - $port=$5; - } - - if ( $card->card_model eq '101' | - $card->card_model eq '102' | - $card->card_model eq '104' | - $card->card_model eq '108' ){ - if (!$first_cfg) { - system('clear'); - } - if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ - print "A$1 detected on slot:$3 bus:$4\n"; - $device_has_normal_clock=$FALSE; - @device_normal_clocks = ("0"); - } - if (!$first_cfg) { - system('clear'); - } - $first_cfg=0; - my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; - print "\n-----------------------------------------------------------\n"; - print "$msg"; - print "-----------------------------------------------------------\n"; - my $fe_media = ''; - if ($silent==$TRUE){ - $fe_media = $silent_femedia; - } else { - printf ("\nSelect media type for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - my @options = ("T1", "E1", "Unused","Exit"); - $fe_media = prompt_user_list( @options, $def_femedia); - } - - if ( $fe_media eq 'Exit'){ - print "Exit without applying changes?\n"; - if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ - print "No changes made to your configuration files.\n\n"; - exit 0; - } - }elsif ( $fe_media eq 'Unused'){ - $def_femedia=$fe_media; - my $msg= "A$1 on slot:$3 bus:$4 port:$port not configured\n"; - print "$msg"; - prompt_user("Press any key to continue"); - }else{ - if ($card->hwec_mode eq 'YES' && $device_has_hwec==$FALSE){ - $device_has_hwec=$TRUE; - } - - $def_femedia=$fe_media; - $cfg_string.="wanpipe$devnum "; - my $a10x; - - if ($1 !~ m/104/ && $2 !~ m/SH/) { - $a10x = eval {new A10u(); } or die ($@); - $a10x->card($card); - if ($5 eq "A") { - $a10x->fe_line("1"); - } else { - $a10x->fe_line("2"); - } - } else { - $a10x = eval {new A10x(); } or die ($@); - if ($dev =~ /A(\d+)(.*):.*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*/){ - my $abc=0; - } - $a10x->card($card); - $a10x->fe_line($6); - } - - $card->first_chan($current_zap_channel); - $a10x->fe_media($fe_media); - if ( $fe_media eq 'T1' ){ - $max_chans = 24; - $line_media = 'T1'; - - $def_te_sig_mode=''; - if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ - $def_felcode='B8ZS'; - } - if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ - $def_feframe='ESF'; - } - - - if ($silent==$FALSE){ - printf ("Configuring port %s on AFT-A%s as: %s, coding:%s, framing:%s.\n", - $port, - $card->card_model, - $fe_media, - $def_felcode, - $def_feframe, - $port); - my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); - my $res = &prompt_user_list(@options, "YES"); - if ($res =~ m/NO/){ - printf("Select line coding for port %s on %s\n", $port, $card->card_model); - my @options = ("B8ZS", "AMI"); - $def_felcode= &prompt_user_list(@options, $def_felcode); - - - printf("Select framing for port %s on %s\n", $port, $card->card_model); - my @options = ("ESF", "D4"); - $def_feframe= &prompt_user_list(@options, $def_feframe); - } - - - } else { - $def_felcode=$silent_felcode; - } - - - }else{ #fe_media = E1 - $max_chans = 31; - $line_media = 'E1'; - - - if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ - $def_felcode='HDB3'; - } - if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ - $def_feframe='CRC4'; - } - - if ($silent==$FALSE){ - printf ("Configuring port %s on %s as %s, line coding:%s, framing:%s \n", - $port, - $card->card_model, - $fe_media, - $def_felcode, - $def_feframe); - my @options = ("YES - Keep these settings", "NO - Configure line coding and framing"); - my $res = &prompt_user_list(@options, "YES"); - if ($res =~ m/NO/){ - printf("Select line coding for port %s on %s\n", $port, $card->card_model); - my @options = ("HDB3", "AMI"); - $def_felcode= &prompt_user_list(@options, $def_felcode); - - - printf("Select framing for port %s on %s\n", $port, $card->card_model); - my @options = ("CRC4", "NCRC4","UNFRAMED"); - $def_feframe = &prompt_user_list(@options, $def_feframe); - -# printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); -# my @options = ("CCS - Clear channel signalling ", "CAS"); -# $def_te_sig_mode = &prompt_user_list(@options, $def_te_sig_mode); - - } - if ($def_signalling eq 'TDM API'){ - printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); - my @options=("CCS","CAS"); - $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); - - } elsif ($def_signalling eq 'PRI CPE' | - $def_signalling eq 'PRI NET' | - $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| - $def_signalling eq 'No Signaling (Voice Only)'){ - - $def_te_sig_mode="CCS"; - } else { - $def_te_sig_mode="CAS"; - } - - - } else { - $def_felcode=$silent_felcode; - } - - - } - $a10x->fe_lcode($def_felcode); - $a10x->fe_frame($def_feframe); - if($silent==$FALSE){ - my @options = ("NORMAL", "MASTER"); - printf ("Select clock for A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_feclock=&prompt_user_list(@options, $def_feclock); - } else { - $def_feclock=$silent_feclock; - } - - $a10x->fe_clock($def_feclock); - if ( $def_feclock eq 'NORMAL') { - $device_has_normal_clock=$TRUE; - push(@device_normal_clocks, $a10x->fe_line); - } elsif ( $def_feclock eq 'MASTER' && $device_has_normal_clock == $TRUE ){ - printf("Clock synchronization options for %s on port %s [slot:%s bus:%s span:$devnum] \n", - $card->card_model, - $port, - $card->pci_slot, - $card->pci_bus); - printf(" Free run: Use internal oscillator on card [default] \n"); - printf(" Port N: Sync with clock from port N \n\n"); - - printf("Select clock source %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_te_ref_clock=&get_te_ref_clock(@device_normal_clocks); - $a10x->te_ref_clock($def_te_ref_clock); - } - - - - if ($silent==$FALSE){ - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf(&prompt_hw_dtmf()); - } else { - $card->hw_dtmf("NO"); - } - } else { - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf("YES"); - } else { - $card->hw_dtmf("NO"); - } - } - - - - my @options=""; - if ($is_smg==$TRUE && $zaptel_installed==$TRUE){ - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start", "SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } elsif ($is_smg==$TRUE && $zaptel_installed==$FALSE){ - @options = ("SS7 - Sangoma Signal Media Gateway", "No Signaling (Voice Only)"); - } elsif ($is_tdm_api==$TRUE){ - $def_signalling="TDM API"; - } else { - @options = ("PRI CPE", "PRI NET", "E & M", "E & M Wink", "FXS - Loop Start", "FXS - Ground Start", "FXS - Kewl Start", "FX0 - Loop Start", "FX0 - Ground Start", "FX0 - Kewl Start"); - } - if ($silent==$FALSE){ - if( $is_tdm_api == $FALSE){ - printf ("Select signalling type for %s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); - $def_signalling=&prompt_user_list(@options,$def_signalling); - } - } else { - $def_signalling=$silent_signalling; - } - $a10x->signalling($def_signalling); - - if ($def_signalling eq 'TDM API'){ - printf("Select signalling mode for port %s on %s\n", $port, $card->card_model); - my @options=("CCS","CAS"); - $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); - } elsif ($def_signalling eq 'PRI CPE' | - $def_signalling eq 'PRI NET' | - $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| - $def_signalling eq 'No Signaling (Voice Only)'){ - - $def_te_sig_mode="CCS"; - - } else { - $def_te_sig_mode="CAS"; - } - $a10x->te_sig_mode($def_te_sig_mode); - - my $ss7_chan; - my $ss7_group_start; - my $ss7_group_end; - my @ss7_chan_array; - my @ss7_sorted; - - if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10x->ss7_option(1); - print("Choose an option below to configure SS7 signalling channels:\n"); - my @options =("Configure individual signalling channels(e.g #1,#10)", - "Configure consecutive signalling channels(e.g #1-#16)"); - my $res = &prompt_user_list(@options, ""); - if ( $res eq 'Configure individual signalling channels(e.g #1,#10)'){ - goto SS7CHAN; - while (1){ - print("\nAny other SS7 signalling channel to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG; - }else{ -SS7CHAN: - $ss7_chan = prompt_user_ss7_chans('Specify the time slot for SS7 signalling(24 for T1? 16 for E1?)'); - push(@ss7_chan_array, $ss7_chan); - $ss7_array_length = @ss7_chan_array; - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG; - } - } - } - }else{ - goto SS7GROUP; - while(1){ - print("\nAny other SS7 consecutive signalling channels to configure?\n"); - if (&prompt_user_list("YES","NO","") eq 'NO'){ - goto ENDSS7CONFIG; - }else{ -SS7GROUP: - $ss7_group_start = prompt_user_ss7_chans('Consecutive signalling channels START FROM channel number'); - $ss7_group_end = prompt_user_ss7_chans('Consecutive signalling channels END AT channel number'); - if ($ss7_group_start > $ss7_group_end){ - print("The starting channel number is bigger than the ending one!\n"); - goto SS7GROUP; - } - my $i = 0; - for ($i = $ss7_group_start; $i <= $ss7_group_end; $i++){ - push(@ss7_chan_array, $i); - my @remove_duplicate; - @ss7_chan_array = grep(!$remove_duplicate[$_]++, @ss7_chan_array); - $ss7_array_length = @ss7_chan_array; - - if ($ss7_array_length > $max_chans){ - print("\nERROR : You defined more than $max_chans signalling channels in $line_media and please try to configure them again.\n\n"); - - @ss7_chan_array = (); - goto SS7GROUP; - } - } - if ($ss7_array_length == $max_chans){ - goto ENDSS7CONFIG; - } - } - } - } - -ENDSS7CONFIG: - - @ss7_sorted = sort { $a <=> $b } @ss7_chan_array; - - print("\nYou configured the following SS7 signalling channels: @ss7_sorted\n"); - my $ss7_voicechans = gen_ss7_voicechans(@ss7_sorted,$max_chans); - $ss7_tdmvoicechans = $ss7_voicechans; - - if ($ss7_voicechans =~ m/(\d+)/){ - $a10x->ss7_tdminterface($1); - } - - $a10x->ss7_tdmchan($ss7_voicechans); - - $num_ss7_config++; - }elsif ( $a10x->signalling eq 'No Signaling (Voice Only)'){ - $a10x->ss7_option(2); - $num_ss7_config++; - $startup_string.="wanpipe$devnum "; - }elsif ($a10x->signalling eq 'TDM API'){ - if ($a10x->te_sig_mode eq "CAS"){ - $a10x->hw_dchan('0'); - } else { - $a10x->hw_dchan(&prompt_user_hw_dchan($card->card_model, $port, $a10x->fe_media)); - } - $card->tdmv_span_no($current_tdmapi_span); - $current_tdmapi_span++; - $startup_string.="wanpipe$devnum "; - }else{ - $num_zaptel_config++; - $card->tdmv_span_no($current_zap_span); - $current_zap_span++; - $startup_string.="wanpipe$devnum "; - $current_zap_channel+=$max_chans; - } - - - - if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ - if ($silent==$FALSE && $config_zapata==$TRUE){ - printf ("Select switchtype for %s on port %s \n", $card->card_model, $port); - $a10x->pri_switchtype(get_pri_switchtype()); - } else { - $a10x->pri_switchtype($silent_switchtype); - } - } - - if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10x->ss7_subinterface(1); - $a10x->gen_wanpipe_ss7_subinterfaces(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(2); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - my $ss7_element; - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(3); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - - $a10x->gen_wanpipe_conf(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(5); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(6); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - }else{ - $a10x->gen_wanpipe_conf(); - } - - if ($is_smg==$TRUE && $config_zapata==$FALSE){ - if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' - | $a10x->signalling eq 'No Signaling (Voice Only)')){ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - } - }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ - if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ - - $zaptel_conf.=$a10x->gen_zaptel_conf(); - $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); - $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); - $zapata_conf.=$a10x->gen_zapata_conf(); - } - }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); - $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); - $zapata_conf.=$a10x->gen_zapata_conf(); - }elsif ($is_tdm_api == $FALSE){ - $zaptel_conf.=$a10x->gen_zaptel_conf(); - } - $devnum++; - $num_digital_devices++; - my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; - print "$msg"; - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - - } - - - } - - } - } - if($num_digital_devices_total!=0){ - print("\nT1/E1 card configuration complete.\n"); - if($silent==$FALSE){ - prompt_user("Press any key to continue"); - } - $first_cfg=0; - } -# close SCR; -} - - -#------------------------------ANALOG FUNCTIONS------------------------------------# - - -sub config_analog{ - my $a20x; - if (!$first_cfg) { - system('clear'); - } - $first_cfg=0; - print "------------------------------------\n"; - print "Configuring analog cards [A200/A400]\n"; - print "------------------------------------\n"; - - my $skip_card=$FALSE; - $zaptel_conf.="\n"; - $zapata_conf.="\n"; - foreach my $dev (@hwprobe) { - if ( $dev =~ /(\d+).(\w+\w+).*SLOT=(\d+).*BUS=(\d+).*CPU=(\w+).*PORT=(\w+).*HWEC=(\d+)/){ - $skip_card=$FALSE; - my $card = eval {new Card(); } or die ($@); - $card->current_dir($current_dir); - $card->cfg_dir($cfg_dir); - $card->span_no($devnum); - $card->card_model($1); - $card->pci_slot($3); - $card->pci_bus($4); - $card->fe_cpu($5); - my $hwec=$7; - if ($hwec==0){ - $card->hwec_mode('NO'); - } - else{ - $card->hwec_mode('YES'); - } - if ($card->card_model eq '200' | $card->card_model eq '400'){ - $num_analog_devices_total++; - system('clear'); - print "\n-----------------------------------------------------------\n"; - print "A$1 detected on slot:$3 bus:$4\n"; - print "-----------------------------------------------------------\n"; - if($is_trixbox==$FALSE){ - print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $skip_card=$TRUE; - } - } - if ($skip_card==$FALSE){ - - $a20x = eval {new A20x(); } or die ($@); - $a20x->card($card); - $card->first_chan($current_zap_channel); - - if ( $device_has_hwec==$TRUE){ - print "Will this A$1 to synchronize with an existing Sangoma T1/E1 card?\n"; - print "\n WARNING: for hardware and firmware requirements, check:\n"; - print " http://wiki.sangoma.com/t1e1analogfaxing\n"; - - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $a20x->rm_network_sync('NO'); - } else { - $a20x->rm_network_sync('YES'); - } - } - - if ($silent==$FALSE){ - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf(&prompt_hw_dtmf()); - } else { - $card->hw_dtmf("NO"); - } - } else { - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf("YES"); - } else { - $card->hw_dtmf("NO"); - } - } - - - print "A$1 configured on slot:$3 bus:$4 span:$devnum\n"; - prompt_user("Press any key to continue"); - $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; - $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$devnum]\n"; - $startup_string.="wanpipe$devnum "; - $cfg_string.="wanpipe$devnum "; - - $current_zap_channel+=24; - my $i; - $devnum++; - $num_analog_devices++; - $num_zaptel_config++; - $card->tdmv_span_no($current_zap_span); - $current_zap_span++; - $a20x->gen_wanpipe_conf(); - - }else{ - print "A$1 on slot:$3 bus:$4 not configured\n"; - prompt_user("Press any key to continue"); - } - } - }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ - my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-internal"); - $a20x->card->zap_group("1"); - $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); - $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); - }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ - my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-zaptel"); - $a20x->card->zap_group("0"); - $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); - $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); - } - } - if($num_analog_devices_total!=0){ - print("\nAnalog card configuration complete\n\n"); - prompt_user("Press any key to continue"); - } - -} - diff --git a/util/wancfg_zaptel/A10u.pm b/util/wancfg_zaptel/A10u.pm index 019fca2..c0536af 100644 --- a/util/wancfg_zaptel/A10u.pm +++ b/util/wancfg_zaptel/A10u.pm @@ -20,8 +20,6 @@ sub new { _signalling => 'PRI_CPE', _pri_switchtype => 'national', _hw_dchan => '0', - _frac_chanfirst => '0', - _frac_chanlast => '0', _ss7_sigchan => undef, _ss7_option => undef, _ss7_tdmchan => undef, @@ -42,17 +40,6 @@ sub fe_line { $self->{_fe_line} = $fe_line if defined($fe_line); return $self->{_fe_line}; } -sub frac_chan_first { - my ( $self, $frac_chan_first ) = @_; - $self->{_frac_chan_first} = $frac_chan_first if defined($frac_chan_first); - return $self->{_frac_chan_first}; -} - -sub frac_chan_last { - my ( $self, $frac_chan_last ) = @_; - $self->{_frac_chan_last} = $frac_chan_last if defined($frac_chan_last); - return $self->{_frac_chan_last}; -} sub te_ref_clock { my ( $self, $te_ref_clock ) = @_; $self->{_te_ref_clock} = $te_ref_clock if defined($te_ref_clock); @@ -324,94 +311,51 @@ sub gen_zaptel_conf{ } my $zp_file=''; - $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; - $zp_file.="span=".$self->card->tdmv_span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; - - if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ - if ( $self->fe_media eq 'T1' ){ - if($self->frac_chan_first() != 0){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - if($self->frac_chan_last == 24){ - $self->frac_chan_last(23); - } - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; - $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; - } else { - $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; - $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; - } - } else { - if($self->frac_chan_first() != 0){ - if($self->frac_chan_last() == 16){ - $self->frac_chan_last(15); - } - if($self->frac_chan_first() == 16){ - $self->frac_chan_first(17); - } - if($self->frac_chan_last() > 15){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - my $mid_ch1=$self->card->first_chan + 14; - my $mid_ch2=$self->card->first_chan + 16; - - $zp_file.="bchan=".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; - $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; - - } else { - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.="bchan=".$first_ch."-".$last_ch."\n"; - $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; - } - } else { - $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; - $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; - } - } - } else { - my $zap_signal; - if ( $self->signalling eq 'E & M' | $self->signalling eq 'E & M Wink' ){ - $zap_signal='e&m'; - } elsif ( $self->signalling eq 'FXS - Loop Start' ){ - $zap_signal='fxsls'; - } elsif ( $self->signalling eq 'FXS - Ground Start' ){ - $zap_signal='fxsgs'; - } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ - $zap_signal='fxsks'; - } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ - $zap_signal='fxols'; - } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ - $zap_signal='fxogs'; - } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ - $zap_signal='fxoks'; - } else { - printf("Error: invalid signalling %s\n", $self->card->signalling); - } - - if ( $self->fe_media eq 'T1' ){ - if($self->frac_chan_first() != 0){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; - } else { - $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; - } - } else { - if($self->frac_chan_first() != 0){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.=$zap_signal."=".$first_ch."-".$last_ch."\n"; - } else { - $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; - } - } - } - return $zp_file; + $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] card->device_no.">\n"; + + + # $zp_file.="\n\#Sangoma A".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span: ".$self->card->span_no."]\n"; + $zp_file.="span=".$self->card->tdmv_span_no.",0,0,".$zap_frame.",".$zap_lcode.$zap_crc4."\n"; + + if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ + if ( $self->fe_media eq 'T1' ){ + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+23)."\n"; + } else { + $zp_file.="bchan=".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + $zp_file.=$dchan_str."=".($self->card->first_chan+15)."\n"; + } + } else { + my $zap_signal; + if ( $self->signalling eq 'E & M' | $self->signalling eq 'E & M Wink' ){ + $zap_signal='e&m'; + } elsif ( $self->signalling eq 'FXS - Loop Start' ){ + $zap_signal='fxsls'; + } elsif ( $self->signalling eq 'FXS - Ground Start' ){ + $zap_signal='fxsgs'; + } elsif ( $self->signalling eq 'FXS - Kewl Start' ){ + $zap_signal='fxsks'; + } elsif ( $self->signalling eq 'FX0 - Loop Start' ){ + $zap_signal='fxols'; + } elsif ( $self->signalling eq 'FX0 - Ground Start' ){ + $zap_signal='fxogs'; + } elsif ( $self->signalling eq 'FX0 - Kewl Start' ){ + $zap_signal='fxoks'; + } else { + printf("Error: invalid signalling %s\n", $self->card->signalling); + } + + if ( $self->fe_media eq 'T1' ){ + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + } else { + $zp_file.=$zap_signal."=".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + } + return $zp_file; + } - sub gen_zapata_conf{ my ($self) = @_; @@ -453,62 +397,21 @@ sub gen_zapata_conf{ } if ( $self->signalling eq 'PRI NET' | $self->signalling eq 'PRI CPE' ){ - if ( $self->fe_media eq 'T1' ){ - if($self->frac_chan_first() != 0){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - if($self->frac_chan_last == 24){ - $self->frac_chan_last(23); - } - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; - } else { - $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; - } - }else{ - if($self->frac_chan_first() != 0){ - if($self->frac_chan_last() == 16){ - $self->frac_chan_last(15); - } - if($self->frac_chan_first() == 16){ - $self->frac_chan_first(17); - } - if($self->frac_chan_last() > 15){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - my $mid_ch1=$self->card->first_chan + 14; - my $mid_ch2=$self->card->first_chan + 16; - - $zp_file.="channel =>".$first_ch."-".$mid_ch1.",".$mid_ch2."-".$last_ch."\n"; - } else { - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; - } - } else { - $zp_file.="channel =>".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; - } - } - } else { - if ( $self->fe_media eq 'T1' ){ - if($self->frac_chan_first() != 0){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; - } else { - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; - } - } else { - if($self->frac_chan_first() != 0){ - my $first_ch=$self->card->first_chan + $self->frac_chan_first-1; - my $last_ch=$self->card->first_chan + $self->frac_chan_last-1; - $zp_file.="channel =>".$first_ch."-".$last_ch."\n"; - } else { - $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; - } - } - } - return $zp_file; - + if ( $self->fe_media eq 'T1' ){ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+22)."\n"; + }else{ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+14).",".($self->card->first_chan+16)."-".($self->card->first_chan+30)."\n"; + } + } else { + if ( $self->fe_media eq 'T1' ){ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+23)."\n"; + }else{ + $zp_file.="channel => ".$self->card->first_chan."-".($self->card->first_chan+30)."\n"; + } + + } + return $zp_file; + } - + 1; diff --git a/util/wancfg_zaptel/A50x.pm b/util/wancfg_zaptel/A50x.pm index 37b0e85..7e0bd6c 100644 --- a/util/wancfg_zaptel/A50x.pm +++ b/util/wancfg_zaptel/A50x.pm @@ -13,9 +13,9 @@ sub new { _card => undef, _fe_line => undef, _fe_media => 'BRI', - _bri_clock_master => 'NO', + _bri_clock_master => 'OSC', _bri_switchtype => 'etsi', - _bri_country => 'europe' + _bri_country => 'europe', }; bless $self, $class; return $self; @@ -137,7 +137,7 @@ sub gen_wanpipe_conf{ sub gen_bri_conf{ - my ($self, $span, $type, $group, $country, $operator, $conn_type) = @_; + my ($self, $span, $type, $group, $country, $operator, $conn_type, $default_tei) = @_; my $bri_file=''; $bri_file.="\n"; @@ -147,12 +147,16 @@ sub gen_bri_conf{ $bri_file.="connection_type=$conn_type\n"; - if ( $type eq 'bri_nt'){ + if ( $type eq 'bri_nt') { $bri_file.="signalling=bri_nt\n"; - }else{ + } else { $bri_file.="signalling=bri_te\n"; } + if ( ! $default_tei eq ''){ + $bri_file.="default_tei=$default_tei\n"; + + } $bri_file.="spans=$span\n"; return $bri_file; diff --git a/util/tmp_davidy/wancfg_zaptel/A50x.pm b/util/wancfg_zaptel/A50x.pm.old similarity index 88% rename from util/tmp_davidy/wancfg_zaptel/A50x.pm rename to util/wancfg_zaptel/A50x.pm.old index b9bb939..6249187 100644 --- a/util/tmp_davidy/wancfg_zaptel/A50x.pm +++ b/util/wancfg_zaptel/A50x.pm.old @@ -13,8 +13,9 @@ sub new { _card => undef, _fe_line => undef, _fe_media => 'BRI', + _bri_clock_master => 'NO', _bri_switchtype => 'etsi', - _bri_country => 'europe' + _bri_country => 'europe', }; bless $self, $class; return $self; @@ -38,12 +39,19 @@ sub fe_media { return $self->{_fe_media}; } +sub bri_clock_master { + my ( $self, $bri_clock_master ) = @_; + $self->{_bri_clock_master} = $bri_clock_master if defined($bri_clock_master); + return $self->{_bri_clock_master}; +} + sub bri_switchtype { my ( $self, $bri_switchtype ) = @_; $self->{_bri_switchtype} = $bri_switchtype if defined($bri_switchtype); return $self->{_bri_switchtype}; } + sub current_dir { my ( $self, $current_dir ) = @_; $self->{_current_dir} = $current_dir if defined($current_dir); @@ -102,6 +110,7 @@ sub gen_wanpipe_conf{ my $fe_media = $self->fe_media; my $fe_line = $self->fe_line; my $hwec_mode = $self->card->hwec_mode; + my $bri_clock_master = $self->bri_clock_master; open(FH, $wanpipe_conf_template) or die "Can't open $wanpipe_conf_template"; @@ -119,6 +128,7 @@ sub gen_wanpipe_conf{ $wp_file =~ s/FELINE/$fe_line/g; $wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g; $wp_file =~ s/HWECMODE/$hwec_mode/g; + $wp_file =~ s/RMBRICLOCKMASTER/$bri_clock_master/g; print FH $wp_file; close (FH); @@ -127,7 +137,7 @@ sub gen_wanpipe_conf{ sub gen_bri_conf{ - my ($self, $span, $type, $group, $country, $operator, $conn_type) = @_; + my ($self, $span, $type, $group, $country, $operator, $conn_type, $default_tei) = @_; my $bri_file=''; $bri_file.="\n"; @@ -137,12 +147,16 @@ sub gen_bri_conf{ $bri_file.="connection_type=$conn_type\n"; - if ( $type eq 'bri_nt'){ + if ( $type eq 'bri_nt') { $bri_file.="signalling=bri_nt\n"; - }else{ + } else { $bri_file.="signalling=bri_te\n"; } + if ( ! $default_tei eq ''){ + $bri_file.="default_tei=$default_tei\n"; + + } $bri_file.="spans=$span\n"; return $bri_file; diff --git a/util/wancfg_zaptel/diff b/util/wancfg_zaptel/diff index 539bee1..31dc29c 100644 --- a/util/wancfg_zaptel/diff +++ b/util/wancfg_zaptel/diff @@ -1,100 +1,22 @@ ---- wancfg_zaptel.pl.old 2008-03-18 19:16:59.000000000 -0400 -+++ wancfg_zaptel.pl 2008-05-23 14:38:23.000000000 -0400 -@@ -9,6 +9,8 @@ - # as published by the Free Software Foundation; either version - # 2 of the License, or (at your option) any later version. - # ---------------------------------------------------------------------------- -+# May 22 2008 2.12 Jignesh Patel Added confirmation check /dev/zap* for hardhdlc -+# May 22 2008 2.12 Jignesh Patel Update zaptel module list - # Jan 02 2008 2.11 David Yat Sin Support for per span configuration in silent mode - # Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock - # Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 -@@ -30,9 +32,9 @@ - system('clear'); - print "\n#############################################i##########################"; - print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; --print "\n# v2.10 #"; -+print "\n# v2.12 #"; - print "\n# Sangoma Technologies Inc. #"; --print "\n# Copyright(c) 2007. #"; -+print "\n# Copyright(c) 2008. #"; - print "\n########################################################################\n\n"; - - use strict; -@@ -255,11 +257,31 @@ - - - sub set_zaptel_hwhdlc{ -- if ((system("ztcfg -t -c $current_dir/templates/zaptel.conf_test > /dev/null 2>/dev/null")==0)){ -+ print "Checking for native zaptel hardhdlc support..."; -+ my $cnt = 0; -+ while ($cnt++ < 30) { -+ if ((system("ls /dev/zap* > /dev/null 2> /dev/null")) == 0) { -+ goto wait_done; -+ } else { -+ print "." ; -+ sleep(1); -+ } -+ } -+ print "Error"; -+ print "\n\n No /dev/zap* Found on the system \n"; -+ printf " Contact Sangoma Support\n"; -+ print " Send e-mail to techdesk\@sangoma\.com \n\n"; -+ exit 1; -+wait_done: -+ -+ if ((system("ztcfg -t -c $current_dir/templates/zaptel.conf_test > /dev/null 2>/dev/null")==0)){ - $dchan_str="hardhdlc"; -+ print "Yes \n\n"; -+ -+ } else { -+ print "No \n\n"; - } - } -- - sub config_boot{ - if($no_boot==$TRUE){ - return 1; -@@ -897,7 +919,8 @@ - } - - sub unload_zap_modules{ -- my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp", "zaptel"); -+ my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp","xpp_usb","xpp" ,"wcte12xp","opvxa1200", "zaptel"); -+ - foreach my $module (@modules_list) { - if ($modprobe_list =~ m/$module/){ - exec_command("$module_unload $module"); -@@ -949,7 +972,7 @@ - print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); - print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); - -- print "\nConfigurator has created the following files:\n"; -+ print "\nConfigurator will create the following files:\n"; - print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; - $file_list++; - -@@ -982,12 +1005,21 @@ - print "\nYour configuration has been saved in $debug_tarball.\n"; - print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; - if($silent==$FALSE){ -- prompt_user("Press any key to continue"); -+ confirm_conf(); - } - } - } - -- -+sub confirm_conf(){ -+ print "Configuration Complete! Please select following:\n"; -+ if(&prompt_user_list("YES - Continue", "NO - Exit" ,"") =~ m/YES/){ -+ return $?; -+ } else { -+ print "No changes made to your configuration files\n"; -+ print "exiting.....\n"; -+ exit $?; -+ } -+} - sub exec_command{ - my @command = @_; - if (system(@command) != 0 ){ +18c18 +< _bri_country => 'europe', +--- +> _bri_country => 'europe' +140c140 +< my ($self, $span, $type, $group, $country, $operator, $conn_type, $default_tei) = @_; +--- +> my ($self, $span, $type, $group, $country, $operator, $conn_type) = @_; +150c150 +< if ( $type eq 'bri_nt') { +--- +> if ( $type eq 'bri_nt'){ +152c152,153 +< } else { +--- +> }else{ +> $bri_file.="default_tei=0\n"; +156,159d156 +< if ( ! $default_tei eq ''){ +< $bri_file.="default_tei=$default_tei\n"; +< +< } diff --git a/util/wancfg_zaptel/setup-sangoma b/util/wancfg_zaptel/setup-sangoma index 1690edd..b3b0bc4 100755 --- a/util/wancfg_zaptel/setup-sangoma +++ b/util/wancfg_zaptel/setup-sangoma @@ -1,5 +1,14 @@ #!/bin/sh home=`pwd` + +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + cd /etc/wanpipe/wancfg_zaptel -./wancfg_zaptel.pl --trixbox +./wancfg_zaptel.pl --trixbox $ARGS cd $home + + diff --git a/util/wancfg_zaptel/templates/smg_bri.conf b/util/wancfg_zaptel/templates/smg_bri.conf index 22d1cdb..6f3921e 100644 --- a/util/wancfg_zaptel/templates/smg_bri.conf +++ b/util/wancfg_zaptel/templates/smg_bri.conf @@ -39,9 +39,46 @@ ;network_specific ;subscriber ;abbreviated -; + ;dialplan=unknown +;Numberingplan: +;Some switches require the 'number plan' network specific facility IE to be set. +;This affects outgoing calls only. +;possible values (default:unknown): +;unknown +;isdn ;ISDN/telephony numbering plan (CCITT E.164/E.163) +;telephone ;telephony - not in CEPT +;data ;data numbering plan (CCITT X.121) +;telex ;telex numbering plan (CCITT F.69) +;national ;national standard numbering plan +;private ;private numbering plan +;reserved +; +;numberingplan=unknown + +;dialplan=unknown + +;Servicetype: +;The requested service type +;This affects outgoing calls only. +;possible values (default:voice): +; +;voice ;voice service +;voice-gci ;voice service on GCI service +;audio-7 ;7Khz audio service +;data ;data service +;data-56k ;data at 56kbs service +;data-trans ;transparent data service +;modem ;modem data service +;fax ;G3 facsimile service +;fax-4 ;G4 facsimile service +;v110 ;V.110 service +;v120 ;V.120 service +;video ;video service +; +;servicetype=voice + ;Prefix: ;Prepends digits for calling number on incoming calls based on ;"type of number" network specific facility IE. @@ -109,5 +146,3 @@ ;Physical spans ;spans=1,2,3,4 -verbose=3 -prot_capture=yes diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm.a200 b/util/wancfg_zaptel/templates/wanpipe.tdm.a200 index e6af3dc..0f94c44 100644 --- a/util/wancfg_zaptel/templates/wanpipe.tdm.a200 +++ b/util/wancfg_zaptel/templates/wanpipe.tdm.a200 @@ -31,8 +31,6 @@ FE_MEDIA = FXO/FXS TDMV_LAW = TDM_LAW TDMV_OPERMODE = TDM_OPERMODE RM_NETWORK_SYNC = RMNETSYNC -RM_BATTTHRESH = 3 -RM_BATTDEBOUNCE = 16 MTU = 1500 UDPPORT = 9000 TTL = 255 diff --git a/util/wancfg_zaptel/templates/wanpipe.tdm_api.a500 b/util/wancfg_zaptel/templates/wanpipe.tdm_api.a500 index 4ff667f..1b1b715 100755 --- a/util/wancfg_zaptel/templates/wanpipe.tdm_api.a500 +++ b/util/wancfg_zaptel/templates/wanpipe.tdm_api.a500 @@ -30,7 +30,7 @@ PCISLOT = SLOTNUM PCIBUS = BUSNUM FE_MEDIA = BRI FE_LINE = FELINE -RM_BRI_CLOCK_MASTER = RMBRICLOCKMASTER +RM_BRI_CLOCK = RMBRICLOCKMASTER TDMV_LAW = ALAW MTU = 1500 UDPPORT = 9000 diff --git a/util/wancfg_zaptel/wancfg_smg b/util/wancfg_zaptel/wancfg_smg index 34d4049..31feb04 100644 --- a/util/wancfg_zaptel/wancfg_smg +++ b/util/wancfg_zaptel/wancfg_smg @@ -34,6 +34,12 @@ read_meta_conf () ostype=`sysctl -a |grep ostype` ostype=`echo $ostype | sed 's/.* //'` +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + read_meta_conf if [ $? -ne 0 ]; then echo "ERROR: Failed to find Wanpipe meta config file!" @@ -41,5 +47,5 @@ if [ $? -ne 0 ]; then fi cd ${WAN_HOME}/wancfg_zaptel -./wancfg_zaptel.pl --smg --conf_dir=$WAN_BASE +./wancfg_zaptel.pl --smg --conf_dir=$WAN_BASE $ARGS cd $home diff --git a/util/wancfg_zaptel/wancfg_tdmapi b/util/wancfg_zaptel/wancfg_tdmapi index b48085d..f501149 100755 --- a/util/wancfg_zaptel/wancfg_tdmapi +++ b/util/wancfg_zaptel/wancfg_tdmapi @@ -34,6 +34,13 @@ read_meta_conf () ostype=`sysctl -a |grep ostype` ostype=`echo $ostype | sed 's/.* //'` +while [ ! -z "$1" ]; +do + ARGS=$ARGS"$1 " + shift +done + + read_meta_conf if [ $? -ne 0 ]; then echo "ERROR: Failed to find Wanpipe meta config file!" @@ -41,5 +48,5 @@ if [ $? -ne 0 ]; then fi cd ${WAN_HOME}/wancfg_zaptel -./wancfg_zaptel.pl --tdm_api --conf_dir=$WAN_BASE +./wancfg_zaptel.pl --tdm_api --conf_dir=$WAN_BASE $ARGS cd $home diff --git a/util/wancfg_zaptel/wancfg_zaptel.pl b/util/wancfg_zaptel/wancfg_zaptel.pl index 263da7f..18dab5e 100755 --- a/util/wancfg_zaptel/wancfg_zaptel.pl +++ b/util/wancfg_zaptel/wancfg_zaptel.pl @@ -9,9 +9,6 @@ # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ---------------------------------------------------------------------------- -# Jun 26 2008 2.13 Jingesh Patel Fixed scritp for wancfg_smg and tdm_api -# May 22 2008 2.12 Jignesh Patel Added confirmation check /dev/zap* for hardhdlc -# May 22 2008 2.12 Jignesh Patel Update zaptel module list # Jan 02 2008 2.11 David Yat Sin Support for per span configuration in silent mode # Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock # Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 @@ -31,9 +28,9 @@ # ============================================================================ system('clear'); -print "\n#############################################i##########################"; +print "\n########################################################################"; print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; -print "\n# v2.13 #"; +print "\n# v2.11 #"; print "\n# Sangoma Technologies Inc. #"; print "\n# Copyright(c) 2008. #"; print "\n########################################################################\n\n"; @@ -83,9 +80,7 @@ if ($os_type_list =~ m/Linux/){ my $no_boot=$FALSE; my $boot_only=$FALSE; -#HW DTMF NOT SUPPORTED in 3.2 drivers -#my $no_hwdtmf=$FALSE; -my $no_hwdtmf=$TRUE; +my $no_hwdtmf=$FALSE; my $startup_string=""; my $cfg_string=""; my $first_cfg=1; @@ -125,6 +120,8 @@ my $def_femedia=''; my $def_feframe=''; my $def_feclock=''; my $def_bri_option=''; +my $def_bri_default_tei=''; +my $def_bri_default_tei_opt=$FALSE; my $def_signalling=''; my $def_switchtype=''; my $def_zapata_context=''; @@ -171,6 +168,10 @@ my $silent_feclock="NORMAL"; my $silent_signalling="PRI CPE"; my $silent_pri_switchtype="national"; my $silent_zapata_context="from-pstn"; +my $silent_zapata_context_opt = $FALSE; +my $silent_zapata_group_opt = $FALSE; +my $silent_zapata_context_fxo="from-pstn"; +my $silent_zapata_context_fxs="from-internal"; my $silent_woomera_context="from-pstn"; my $silent_zapata_group="0"; my $silent_te_sig_mode='CCS'; @@ -199,8 +200,9 @@ my $modprobe_list=`$module_list`; read_args(); check_zaptel(); if($boot_only==$TRUE){ - exit( &config_boot()); + exit( &config_boot()); } + my $current_dir=`pwd`; chomp($current_dir); my $cfg_dir='tmp_cfg'; @@ -240,9 +242,7 @@ my $date=`date +%F`; chomp($date); my $debug_tarball="$wanpipe_conf_dir/debug-".$date.".tgz"; -if( $zaptel_installed == $TRUE){ - set_zaptel_hwhdlc(); -} +set_zaptel_hwhdlc(); prepare_files(); config_t1e1(); config_bri(); @@ -260,31 +260,11 @@ print "Sangoma cards configuration complete, exiting...\n\n"; sub set_zaptel_hwhdlc{ - print "Checking for native zaptel hardhdlc support..."; - my $cnt = 0; - while ($cnt++ < 30) { - if ((system("ls /dev/zap* > /dev/null 2> /dev/null")) == 0) { - goto wait_done; - } else { - print "." ; - sleep(1); - } - } - print "Error"; - print "\n\n No /dev/zap* Found on the system \n"; - printf " Contact Sangoma Support\n"; - print " Send e-mail to techdesk\@sangoma\.com \n\n"; - exit 1; -wait_done: - if ((system("ztcfg -t -c $current_dir/templates/zaptel.conf_test > /dev/null 2>/dev/null")==0)){ $dchan_str="hardhdlc"; - print "Yes \n\n"; - - } else { - print "No \n\n"; } } + sub config_boot{ if($no_boot==$TRUE){ return 1; @@ -329,7 +309,7 @@ sub config_boot{ if($silent==$FALSE){ print ("Would you like $script_name to start on system boot?\n"); $res= &prompt_user_list("YES","NO",""); - } + } if ( $res eq 'YES'){ #examine system bootstrap files @@ -337,7 +317,7 @@ sub config_boot{ if (system($command) == 0){ $rc_dir=$rc_dir; } else { - $command="find ".$etc_dir."/rc.d/rc0.d >/dev/null 2>/dev/null"; + $command="find ".$etc_dir."rc.d/rc0.d >/dev/null 2>/dev/null"; if (system($command) == 0){ $rc_dir=$etc_dir."/rc.d"; } else { @@ -408,7 +388,8 @@ sub config_boot{ if(system($command) !=0){ print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; print "$script_name boot scripts not installed\n"; - return 1; } + return 1; + } } print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; my @run_levels= ("2","3","4","5"); @@ -471,7 +452,7 @@ sub config_boot{ if(system($command) !=0){ print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; print "smg_ctrl start scripts not installed\n"; - return 1; + return; } } } @@ -508,31 +489,38 @@ sub config_smg_ctrl_start{ } else { $res = "YES"; } - - if ($res = "YES"){ - #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite - my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; - } else { - $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; - } - - if (system($command) == 0){ - print "smgbri start script installed successfully\n"; - } else { - print "failed to install smgbri start script\n"; - } + if ($res eq "YES"){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ - $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; - if (system($command) == 0){ - print "smgbri stop script installed successfully\n"; - } else { - print "failed to install smgbri start script\n"; - } - } + my $command="cat ".$wanpipe_conf_dir."/scripts/start | grep smg_ctrl >/dev/null 2>/dev/null"; + if (system($command) == 0){ + print("smgbri start script already installed!\n"); + }else{ + my $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + if (system($command) == 0){ + print("smgbri start scrtip installed scuessfully\n"); + } + } + } elsif(system($command) != 0) { + + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + if (system($command) == 0){ + print("smgbri start scrtip installed scuessfully\n"); + } + } else { + print "failed to install smgbri start script\n"; + } + my $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; + if (system($command) == 0){ + print "smgbri stop script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + } } - + sub check_zaptel{ if ($modprobe_list =~ /zaptel.ko/){ $zaptel_installed=$TRUE; @@ -922,8 +910,7 @@ sub copy_config_files{ } sub unload_zap_modules{ - my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp","xpp_usb","xpp" ,"wcte12xp","opvxa1200", "zaptel"); - + my @modules_list = ("ztdummy","wctdm","wcfxo","wcte11xp","wct1xxp","wct4xxp","tor2","zttranscode","wcusb", "wctdm24xxp","xpp_usb","xpp" ,"wcte12xp", "zaptel"); foreach my $module (@modules_list) { if ($modprobe_list =~ m/$module/){ exec_command("$module_unload $module"); @@ -975,7 +962,7 @@ sub summary{ print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); - print "\nConfigurator will create the following files:\n"; + print "\nConfigurator has created the following files:\n"; print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; $file_list++; @@ -1008,21 +995,12 @@ sub summary{ print "\nYour configuration has been saved in $debug_tarball.\n"; print "When requesting support, email this file to techdesk\@sangoma.com\n\n"; if($silent==$FALSE){ - confirm_conf(); + prompt_user("Press any key to continue"); } } } -sub confirm_conf(){ - print "Configuration Complete! Please select following:\n"; - if(&prompt_user_list("YES - Continue", "NO - Exit" ,"") =~ m/YES/){ - return $?; - } else { - print "No changes made to your configuration files\n"; - print "exiting.....\n"; - exit $?; - } -} + sub exec_command{ my @command = @_; if (system(@command) != 0 ){ @@ -1101,8 +1079,9 @@ sub read_args { $_ = $ARGV[$arg_num]; if( /^--trixbox$/){ $is_trixbox=$TRUE; - }elsif( /^--install_boot_script/){ - $boot_only=$TRUE; + }elsif ( /^--install_boot_script/){ + $boot_only=$TRUE; + }elsif ( /^--tdm_api/){ $is_tdm_api=$TRUE; }elsif ( /^--smg$/){ @@ -1118,9 +1097,11 @@ sub read_args { }elsif ( /^--no-zaptel$/){ $config_zaptel=$FALSE; }elsif ( $_ =~ /--zapata_context=(\w+)/){ + $silent_zapata_context_opt=$TRUE; $silent_zapata_context=substr($_,length("--zapata_context=")); push(@silent_zapata_contexts, $silent_zapata_context); }elsif ( $_ =~ /--zapata_group=(\d+)/){ + $silent_zapata_group_opt=$TRUE; $silent_zapata_group=$1; push(@silent_zapata_groups, $silent_zapata_group); }elsif ( $_ =~ /--woomera_context=(\w+)/){ @@ -1308,6 +1289,34 @@ sub get_woomera_group{ } + +sub get_bri_default_tei{ +# if($silent==$TRUE){ +# if($#silent_woomera_groups >= 0){ +# $silent_woomera_group=pop(@silent_woomera_groups); +# } +# return $silent_woomera_group; +# } + + my $res_default_tei; +get_bri_default_tei: + $res_default_tei=&prompt_user("\nInput the TEI for this port \n",$def_bri_default_tei); + while(length($res_default_tei)==0 |!($res_default_tei =~/(\d+)/)){ + print "Invalid TEI value, must be an integer\n"; + $res_default_tei=&prompt_user("Input the TEI for this port ",$def_bri_default_tei); + } + $res_default_tei =~ /(\d+)/; + if( $1 < 0 | $1 > 127) { + print "Invalid TEI value, must be between 0 and 127\n"; + goto get_bri_default_tei; + } + + $def_bri_default_tei=$res_default_tei; + return $def_bri_default_tei; +} + + + sub get_bri_operator { #warning returning ETSI $def_bri_operator = "etsi"; @@ -1486,7 +1495,13 @@ select_bri_option: }elsif (($dev =~ /(\d+):NT/ | $dev =~ /(\d+):TE/ )& $skip_card==$FALSE ){ - + if($bri_device_has_master_clock==$FALSE & $dev =~ /(\d+):TE/){ + print "\nWould you like to use this port as a sync source?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + $bri_device_has_master_clock=$TRUE; + $a50x->bri_clock_master("LINE"); + } + } my $context=""; my $group=""; @@ -1524,9 +1539,24 @@ select_bri_option: } $a50x->gen_wanpipe_conf(); if ( $dev =~ /(\d+):NT/ ){ - $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type); + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type, ''); } else { - $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); + my $current_bri_default_tei='127'; + if ($def_bri_default_tei_opt==$TRUE){ + $current_bri_default_tei=$def_bri_default_tei; + } + printf("\nConfiguring span:%s as TEI:%s\n", $bri_pos, $current_bri_default_tei); + my @options = ("YES - Keep this setting", "NO - Specify a different TEI"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/) { + $def_bri_default_tei_opt=$TRUE; + $current_bri_default_tei=get_bri_default_tei(); + } + if ($def_bri_default_tei_opt==$FALSE){ + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type, ''); + } else { + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type, $current_bri_default_tei); + } } if(!($context eq "WOOMERA_NO_CONFIG")){ $woomera_conf.=$a50x->gen_woomera_conf($group, $context); @@ -1545,9 +1575,6 @@ select_bri_option: } - - - #------------------------------T1/E1 FUNCTIONS------------------------------------# sub get_te_ref_clock{ @@ -2481,7 +2508,7 @@ sub config_analog{ } }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ my $zap_pos = $1+$current_zap_channel-25; - if($silent==$TRUE){ + if($silent==$TRUE & $silent_zapata_context_opt == $TRUE){ if($#silent_zapata_contexts >= 0){ $silent_zapata_context=pop(@silent_zapata_contexts); } @@ -2494,7 +2521,7 @@ sub config_analog{ $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ my $zap_pos = $1+$current_zap_channel-25; - if($silent==$TRUE){ + if($silent==$TRUE & $silent_zapata_context_opt == $TRUE){ if($#silent_zapata_contexts >= 0){ $silent_zapata_context=pop(@silent_zapata_contexts); } diff --git a/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel.pl b/util/wancfg_zaptel/wancfg_zaptel.pl.old similarity index 68% rename from util/tmp_davidy/wancfg_zaptel/wancfg_zaptel.pl rename to util/wancfg_zaptel/wancfg_zaptel.pl.old index ec5c5fd..70d3538 100755 --- a/util/tmp_davidy/wancfg_zaptel/wancfg_zaptel.pl +++ b/util/wancfg_zaptel/wancfg_zaptel.pl.old @@ -9,7 +9,9 @@ # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ---------------------------------------------------------------------------- -# Aug 22 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 +# Jan 02 2008 2.11 David Yat Sin Support for per span configuration in silent mode +# Jan 02 2008 2.10 David Yat Sin Added option for BRI master clock +# Dec 15 2007 2.9 David Yat Sin Support for Zaptel hardware hdlc for Zaptel 1.4 # Nov 29 2007 2.8 David Yat Sin Support for BRI cards on Trixbox # Aug 22 2007 2.7 David Yat Sin support for hardware DTMF option # Aug 15 2007 2.6 David Yat Sin support for BRI cards in SMG mode @@ -26,12 +28,12 @@ # ============================================================================ system('clear'); -print "\n###################################################################"; -print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI Configuration Script #"; -print "\n# v2.9 #"; -print "\n# Sangoma Technologies Inc. #"; -print "\n# Copyright(c) 2007. #"; -print "\n###################################################################\n\n"; +print "\n########################################################################"; +print "\n# Sangoma Wanpipe: Zaptel/SMG/TDMAPI/BOOT Configuration Script #"; +print "\n# v2.11 #"; +print "\n# Sangoma Technologies Inc. #"; +print "\n# Copyright(c) 2008. #"; +print "\n########################################################################\n\n"; use strict; #use warnings; @@ -76,6 +78,9 @@ if ($os_type_list =~ m/Linux/){ } +my $no_boot=$FALSE; +my $boot_only=$FALSE; +my $no_hwdtmf=$FALSE; my $startup_string=""; my $cfg_string=""; my $first_cfg=1; @@ -106,6 +111,8 @@ my $ss7_array_length=0; my $device_has_hwec=$FALSE; my $device_has_normal_clock=$FALSE; my @device_normal_clocks=("0"); +my @woomera_groups=("0"); +my $bri_device_has_master_clock=$FALSE; my $is_tdm_api=$FALSE; @@ -113,32 +120,68 @@ my $def_femedia=''; my $def_feframe=''; my $def_feclock=''; my $def_bri_option=''; +my $def_bri_default_tei=''; +my $def_bri_default_tei_opt=$FALSE; my $def_signalling=''; my $def_switchtype=''; my $def_zapata_context=''; +my $def_woomera_context=''; my $def_zapata_group=''; my $def_te_ref_clock=''; my $def_tdmv_dchan=0; -my $def_bri_group=''; +my $def_woomera_group=''; my $def_felcode=''; my $def_feframe=''; my $def_te_sig_mode=''; my $def_hw_dtmf="YES"; +my $def_tdm_law=''; + +my @silent_femedias; +my @silent_feframes; +my @silent_felcodes; +my @silent_tdm_laws; +my @silent_feclocks; +my @silent_signallings; +my @silent_pri_switchtypes; +my @silent_zapata_contexts; +my @silent_woomera_contexts; +my @silent_zapata_groups; +my @silent_bri_conn_types; +my @silent_woomera_groups; +my @silent_hwdtmfs; +my @silent_first_chans; +my @silent_last_chans; + + +my $silent_hwdtmf; my $silent_femedia="T1"; my $silent_feframe="ESF"; -my $silent_feframe_e1="CRC4"; +#my $silent_feframe_e1="CRC4"; my $silent_felcode="B8ZS"; +my $silent_tdm_law="MULAW"; + my $silent_feclock="NORMAL"; my $silent_signalling="PRI CPE"; -my $silent_switchtype="National"; +my $silent_pri_switchtype="national"; my $silent_zapata_context="from-pstn"; +my $silent_zapata_context_opt = $FALSE; +my $silent_zapata_group_opt = $FALSE; +my $silent_zapata_context_fxo="from-pstn"; +my $silent_zapata_context_fxs="from-internal"; +my $silent_woomera_context="from-pstn"; my $silent_zapata_group="0"; my $silent_te_sig_mode='CCS'; +my $silent_bri_conn_type="point_to_multipoint"; +my $silent_woomera_group="1"; + +my $silent_first_chan=1; +my $silent_last_chan=24; + my $def_bri_country="europe"; my $def_bri_operator="etsi"; my $def_bri_conn_type="Point to multipoint"; @@ -156,6 +199,10 @@ my $modprobe_list=`$module_list`; read_args(); check_zaptel(); +if($boot_only==$TRUE){ + exit( &config_boot()); +} + my $current_dir=`pwd`; chomp($current_dir); my $cfg_dir='tmp_cfg'; @@ -213,27 +260,33 @@ print "Sangoma cards configuration complete, exiting...\n\n"; sub set_zaptel_hwhdlc{ - if ((system("grep hdlc_hard_xmit '$include_dir/zaptel/zaptel.h'>/dev/null 2>/dev/null")==0)){ + if ((system("ztcfg -t -c $current_dir/templates/zaptel.conf_test > /dev/null 2>/dev/null")==0)){ $dchan_str="hardhdlc"; } } + sub config_boot{ + if($no_boot==$TRUE){ + return 1; + } my $script_name="wanrouter"; my $current_run_level=3; my $zaptel_start_level=9; my $zaptel_stop_level=92; + my $network_start_level=10; my $wanrouter_start_level=8; - my $wanrouter_stop_level=93; + my $wanrouter_stop_level=91; + my $smg_ctrl_start_level=11; my $command=''; my $rc_dir=$etc_dir; if ($os_type_list =~ m/FreeBSD/){ - return; + return 1; } my $res=`cat $etc_dir/inittab |grep id`; if ($res =~ /id:(\d+):initdefault/){ $current_run_level=$1; -# print "Current boot level is $current_run_level\n"; + print "Current boot level is $current_run_level\n"; } else { print "Warning: Failed to determine init boot level, assuming 3\n"; $current_run_level=3; @@ -252,8 +305,13 @@ sub config_boot{ $script_name="smgss7_init_ctrl"; } - print ("Would you like $script_name to start on system boot?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ + my $res='YES'; + if($silent==$FALSE){ + print ("Would you like $script_name to start on system boot?\n"); + $res= &prompt_user_list("YES","NO",""); + } + + if ( $res eq 'YES'){ #examine system bootstrap files $command="find ".$etc_dir."/rc0.d >/dev/null 2>/dev/null"; if (system($command) == 0){ @@ -265,7 +323,7 @@ sub config_boot{ } else { print "Failed to locate boostrap directory\n"; print "wanrouter boot scripts will not be installed\n"; - return; + return 1; } } @@ -307,9 +365,10 @@ sub config_boot{ $wanrouter_start_level=$zaptel_start_level-1; } if ($zaptel_stop_level != 0){ - $wanrouter_stop_level=$zaptel_stop_level+1; + $wanrouter_stop_level=$zaptel_stop_level-1; } } + my $wanrouter_start_script=''; if($wanrouter_start_level < 10){ $wanrouter_start_script="S0".$wanrouter_start_level.$script_name; @@ -329,7 +388,7 @@ sub config_boot{ if(system($command) !=0){ print "Failed to install $script_name script to $rc_dir/init.d/$script_name\n"; print "$script_name boot scripts not installed\n"; - return; + return 1; } } print "Enabling $script_name boot scripts ...(level:$wanrouter_start_level)\n"; @@ -339,7 +398,7 @@ sub config_boot{ if(system($command) !=0){ print "Failed to install $script_name init script to $rc_dir/rc$run_level.d/$wanrouter_start_script\n"; print "$script_name start scripts not installed\n"; - return; + return 1; } } @@ -350,16 +409,63 @@ sub config_boot{ if(system($command) !=0){ print "Failed to install $script_name shutdown script to $rc_dir/rc$run_level.d/$wanrouter_stop_script\n"; print "$script_name stop scripts not installed\n"; - return; + return 1; } } + + if($num_bri_devices != 0){ + #smg_ctrl must start after network + print "Verifying Network boot scripts..."; + $command="find $rc_dir/rc".$current_run_level.".d/*network >/dev/null 2>/dev/null"; + if (system($command) == 0){ + $command="find $rc_dir/rc".$current_run_level.".d/*network"; + $res=`$command`; + if ($res =~ /.*S(\d+)network/){ + $network_start_level=$1; + print "Enabled (level:$network_start_level)\n"; + } else { + print "\nfailed to parse network boot level, assuming $network_start_level"; + } + } else { + print "Not installed\n"; + $network_start_level=0; + } + if ($network_start_level != 0 && $network_start_level > $zaptel_start_level){ + $smg_ctrl_start_level=$network_start_level+1; + print "Enabling smg_ctrl start scripts...(level:$smg_ctrl_start_level)\n"; + $command="install -D -m 755 /usr/sbin/smg_ctrl $rc_dir/init.d/smg_ctrl"; + if(system($command) !=0){ + print "Failed to install smg_ctrl start scripts to $rc_dir/init.d/smg_ctrl"; + print "smg_ctrl start scripts not installed"; + return 1; + } + my $smg_ctrl_start_script=''; + if($smg_ctrl_start_level < 10){ + $smg_ctrl_start_script="S0".$smg_ctrl_start_level."smg_ctrl"; + } else { + $smg_ctrl_start_script="S".$smg_ctrl_start_level."smg_ctrl"; + } + print "Enabling smg_ctrl boot scripts ...(level:$smg_ctrl_start_level)\n"; + my @run_levels= ("2","3","4","5"); + foreach my $run_level (@run_levels) { + $command="ln -sf $rc_dir/init.d/smg_ctrl ".$rc_dir."/rc".$run_level.".d/".$smg_ctrl_start_script; + if(system($command) !=0){ + print "Failed to install smg_ctrl init script to $rc_dir/rc$run_level.d/$smg_ctrl_start_script\n"; + print "smg_ctrl start scripts not installed\n"; + return; + } + } + } + + } + } - + return 0; } sub config_ztcfg_start{ - if ($num_zaptel_config ==0){ + if ($num_zaptel_config ==0 || $silent==$TRUE){ return; } my $command="find /etc/rc?.d/*zaptel >/dev/null 2>/dev/null"; @@ -376,31 +482,45 @@ sub config_smg_ctrl_start{ if($num_bri_devices == 0){ return; } - print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); - if (&prompt_user_list("YES","NO","") eq 'YES'){ - #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite - my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; - if (system($command) == 0){ - $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; - } else { - $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; - } - - if (system($command) == 0){ - print "smgbri start script installed successfully\n"; - } else { - print "failed to install smgbri start script\n"; - } + my $res; + if($silent==$FALSE) { + print ("Would you like smg_ctrl to start/stop on wanrouter start?\n"); + $res = &prompt_user_list("YES","NO",""); + } else { + $res = "YES"; + } + if ($res eq "YES"){ + #if zaptel start script is in $wanpipe_conf_dir/scripts/start, do not overwrite + my $command="find ".$wanpipe_conf_dir."/scripts/start >/dev/null 2>/dev/null"; + if (system($command) == 0){ - $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; - if (system($command) == 0){ - print "smgbri start script installed successfully\n"; - } else { - print "failed to install smgbri start script\n"; - } - } + my $command="cat ".$wanpipe_conf_dir."/scripts/start | grep smg_ctrl >/dev/null 2>/dev/null"; + if (system($command) == 0){ + print("smgbri start script already installed!\n"); + }else{ + my $command="cat ".$current_dir."/templates/smgbri_start_script_addon >>".$wanpipe_conf_dir."/scripts/start"; + if (system($command) == 0){ + print("smgbri start scrtip installed scuessfully\n"); + } + } + } elsif(system($command) != 0) { + + $command="cp -f ".$current_dir."/templates/smgbri_start_script ".$wanpipe_conf_dir."/scripts/start"; + if (system($command) == 0){ + print("smgbri start scrtip installed scuessfully\n"); + } + } else { + print "failed to install smgbri start script\n"; + } + my $command="cp -f ".$current_dir."/templates/smgbri_stop_script ".$wanpipe_conf_dir."/scripts/stop"; + if (system($command) == 0){ + print "smgbri stop script installed successfully\n"; + } else { + print "failed to install smgbri start script\n"; + } + } } - + sub check_zaptel{ if ($modprobe_list =~ /zaptel.ko/){ $zaptel_installed=$TRUE; @@ -413,7 +533,7 @@ sub apply_changes{ my $asterisk_restart=$FALSE; my $res=''; - system('clear'); + if($silent==$FALSE) {system('clear')}; if($silent==$TRUE){ $res="Stop now"; @@ -451,7 +571,6 @@ sub apply_changes{ if ($is_trixbox==$TRUE){ exec_command("amportal stop"); - unload_zap_modules(); } elsif ($is_tdm_api==$FALSE ){ if (`(pidof asterisk)` != 0 ){ print "\nStopping Asterisk...\n"; @@ -543,14 +662,10 @@ sub apply_changes{ exec_command("/usr/sbin/smg_ctrl start"); } -# if ( ! -e "/$wanpipe_conf_dir/scripts/start" & $is_trixbox==$FALSE && $is_smg==$FALSE ){ if ($num_zaptel_config != 0){ print "Loading Zaptel...\n"; sleep 2; exec_command("ztcfg -v"); -# print ("\nWould you like to execute \'ztcfg\' each time wanrouter starts?\n"); -# if (&prompt_user_list("YES","NO","") eq 'YES'){ -# exec_command("cp -f $wanpipe_conf_dir/samples/wanpipe_zaptel_start $wanpipe_conf_dir/scripts/start"); # } } if ($is_trixbox==$TRUE){ @@ -561,9 +676,12 @@ sub apply_changes{ print "\nStarting Asterisk...\n"; exec_command("asterisk"); sleep 2; - - print "\nListing Asterisk channels...\n\n"; - exec_command("asterisk -rx \"zap show channels\""); + + + if ($num_zaptel_config != 0){ + print "\nListing Asterisk channels...\n\n"; + exec_command("asterisk -rx \"zap show channels\""); + } print "\nType \"asterisk -r\" to connect to Asterisk console\n\n"; }else{ } @@ -611,6 +729,18 @@ sub save_debug_info{ exec_command("tar cvfz $debug_tarball $cfg_dir/* >/dev/null 2>/dev/null"); } +sub get_chan_no{ + my ($chan_name,$first_ch, $last_ch)=@_; + + my $res_ch=&prompt_user("\nInput the $chan_name channel for this span [$first_ch-$last_ch]\n"); + while(length($res_ch)==0 ||!($res_ch =~/(\d+)/) + || $res_ch<$first_ch || $res_ch>$last_ch){ + print "Invalid channel, must be between $first_ch and $last_ch\n"; + $res_ch=&prompt_user("Input the channel for this port[$first_ch-$last_ch]"); + } + return $res_ch; +} + sub get_zapata_context{ my ($card_model,$card_port)=@_; my $context=''; @@ -643,12 +773,66 @@ sub get_zapata_context{ exit 1; } } else { + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } $context=$silent_zapata_context; } $def_zapata_context=$context; return $context; } + +sub get_woomera_context{ + my ($group,$card_model,$card_port,$bri_type)=@_; + + my $context=''; + my @options = ("from-pstn", "from-internal","Custom"); + + if($bri_type eq 'bri_nt'){ + @options = ("from-internal","Custom"); + } elsif ($bri_type eq 'bri_te'){ + @options = ("from-pstn","Custom"); + } + + if($is_trixbox==$TRUE){ + @options = ("PSTN", "INTERNAL"); + } + if ($silent==$FALSE){ + printf ("\nSelect dialplan context for group:%d\n", $group); + my $res = &prompt_user_list(@options,$def_woomera_context); + if($res eq "PSTN"){ + $context="from-zaptel"; + }elsif($res eq "INTERNAL"| $res eq "from-internal"){ + $context="from-internal"; + }elsif($res eq "from-pstn"){ + $context="from-pstn"; + }elsif($res eq "Custom"){ + my $res_context=&prompt_user("Input the context for this port"); + while(length($res_context)==0){ + print "Invalid context, input a non-empty string\n"; + $res_context=&prompt_user("Input the context for this port",$def_woomera_context); + } + + $context=$res_context; + }elsif($res eq $def_woomera_context){ + $context=$def_woomera_context; + }else{ + print "Internal error:invalid context,group\n"; + exit 1; + } + } else { + if($#silent_woomera_contexts >= 0){ + $silent_woomera_context=pop(@silent_woomera_contexts); + } + $context=$silent_woomera_context; + } + $def_woomera_context=$context; + return $context; +} + + + sub gen_wanrouter_rc{ #update wanpipe startup sequence my $rcfile=""; @@ -707,7 +891,7 @@ sub write_zapata_conf{ open(FH, "$zapata_conf_template") or die "cannot open $zapata_conf_template"; while () { $zp_file .= $_; -} + } close (FH); $zp_file.=$zapata_conf; @@ -749,7 +933,7 @@ sub write_zaptel_conf{ sub summary{ if($devnum==1){ - system('clear'); + if ($silent==$FALSE) {system('clear')}; print "\n###################################################################"; print "\n# SUMMARY #"; print "\n###################################################################\n\n"; @@ -764,19 +948,19 @@ sub summary{ write_bri_conf(); write_woomera_conf(); } - if ($config_zapata==$TRUE){ + if ($num_zaptel_config != 0 && $config_zapata==$TRUE){ write_zapata_conf(); } save_debug_info(); - system('clear'); + if ($silent==$FALSE) {system('clear')}; my $file_list = 1; print "\n###################################################################"; print "\n# SUMMARY #"; print "\n###################################################################\n\n"; print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n"); + print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n"); print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n"); - print(" $num_bri_devices_total ISDN BRI card(s) detected, $num_bri_devices configured\n"); print "\nConfigurator has created the following files:\n"; print "\t1. Wanpipe config files in $wanpipe_conf_dir\n"; @@ -804,7 +988,7 @@ sub summary{ print "\t$file_list. $zaptel_conf_file_t.bak \n"; $file_list++; } - if ($config_zapata==$TRUE){ + if ($num_zaptel_config !=0 && $config_zapata==$TRUE){ print "\t$file_list. $zapata_conf_file_t.bak \n\n"; } @@ -821,6 +1005,14 @@ sub exec_command{ my @command = @_; if (system(@command) != 0 ){ print "Error executing command:\n@command\n\n"; + if($silent==$FALSE){ + print "Would you like to continue?\n"; + if(&prompt_user_list("No - exit", "YES", "No") eq 'YES'){ + return $?; + } else { + exit $?; + } + } } return $?; } @@ -887,33 +1079,97 @@ sub read_args { $_ = $ARGV[$arg_num]; if( /^--trixbox$/){ $is_trixbox=$TRUE; + }elsif ( /^--install_boot_script/){ + $boot_only=$TRUE; + }elsif ( /^--tdm_api/){ $is_tdm_api=$TRUE; }elsif ( /^--smg$/){ $is_smg=$TRUE; + }elsif ( /^--no_boot$/){ + $no_boot=$TRUE; + }elsif ( /^--no_hwdtmf$/){ + $no_hwdtmf=$TRUE; }elsif ( /^--silent$/){ $silent=$TRUE; }elsif ( /^--no-zapata$/){ $config_zapata=$FALSE; }elsif ( /^--no-zaptel$/){ $config_zaptel=$FALSE; + }elsif ( $_ =~ /--zapata_context=(\w+)/){ + $silent_zapata_context_opt=$TRUE; + $silent_zapata_context=substr($_,length("--zapata_context=")); + push(@silent_zapata_contexts, $silent_zapata_context); + }elsif ( $_ =~ /--zapata_group=(\d+)/){ + $silent_zapata_group_opt=$TRUE; + $silent_zapata_group=$1; + push(@silent_zapata_groups, $silent_zapata_group); + }elsif ( $_ =~ /--woomera_context=(\w+)/){ + $silent_woomera_context=substr($_,length("--woomera_context=")); + push(@silent_woomera_contexts, $silent_woomera_context); + }elsif ( $_ =~ /--woomera_group=(\d+)/){ + $silent_woomera_group=$1; + push(@silent_woomera_groups, $silent_woomera_group); }elsif ( $_ =~ /--fe_media=(\w+)/){ $silent_femedia=$1; if(!($silent_femedia eq 'T1' || $silent_femedia eq 'E1')){ printf("Invalid value for fe_media, should be T1/E1\n"); exit(1); + } else { + push(@silent_femedias, $silent_femedia); + if($silent_femedia eq 'E1'){ + if(!($silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ + $silent_feframe='CRC4'; + } + if(!($silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + $silent_felcode='HDB3'; + } + } + } + }elsif ( $_ =~ /--fractional_chans=(\d+)-(\d+)/ ){ + $silent_first_chan=$1; + $silent_last_chan=$2; + push(@silent_first_chans, $silent_first_chan); + push(@silent_last_chans, $silent_last_chan); + }elsif ( $_ =~ /--hw_dtmf=(\w+)/){ + $silent_hwdtmf=$1; + if(!($silent_hwdtmf eq 'YES' || $silent_hwdtmf eq 'NO')){ + printf("Invalid value for hw_dtmf, should be YES/NO\n"); + exit(1); + } else { + push(@silent_hwdtmfs, $silent_hwdtmf); + } + }elsif ( $_ =~ /--fe_lcode=(\w+)/){ + $silent_felcode=$1; + if(!($silent_felcode eq 'B8ZS' || $silent_felcode eq 'HDB3' || $silent_felcode eq 'AMI')){ + printf("Invalid value for fe_lcode, should be B8ZS/HDB3/AMI \n"); + exit(1); + } else { + push(@silent_felcodes, $silent_felcode); } }elsif ( $_ =~ /--fe_frame=(\w+)/){ $silent_feframe=$1; if(!($silent_feframe eq 'ESF' || $silent_feframe eq 'D4' || $silent_feframe eq 'CRC4' || $silent_feframe eq 'NCRC4')){ printf("Invalid value for fe_frame, should be ESF/D4/CRC4/NCRC4\n"); exit(1); - } + } else { + push(@silent_feframes, $silent_feframe); + } + }elsif ( $_ =~ /--tdm_law=(\w+)/){ + $silent_tdm_law=$1; + if(!($silent_tdm_law eq 'MULAW' || $silent_tdm_law eq 'ALAW')){ + printf("Invalid value for tdm_law, should be MULAW/ALAW\n"); + exit(1); + } else { + push(@silent_tdm_laws, $silent_tdm_law); + } }elsif ( $_ =~ /--fe_clock=(\w+)/){ $silent_feclock=$1; if(!($silent_feclock eq 'NORMAL' || $silent_feclock eq 'MASTER' )){ printf("Invalid value for fe_clock, should be NORMAL/MASTER\n"); exit(1); + } else { + push(@silent_feclocks, $silent_feclock); } }elsif ( $_ =~ /--signalling=(\w+)/){ my $tmp_signalling=$1; @@ -940,25 +1196,66 @@ sub read_args { }else{ printf("Invalid option for --signalling, options are\n"); printf("\t pri_cpe/pri_net/em/em_w\n"); - printf("\t em/em_w\n"); printf("\t fxo_ls/fxo_gs/fxo_ks\n"); printf("\t fxs_ls/fxs_gs/fxs_ks\n"); exit(1); } + + push(@silent_signallings, $silent_signalling); + + }elsif ( $_ =~ /--pri_switchtype=(\w+)/){ + my $tmp_switchtype=$1; + if ($tmp_switchtype eq 'national'){ + $silent_pri_switchtype="national" + }elsif ($tmp_switchtype eq 'dms100'){ + $silent_pri_switchtype="dms100" + }elsif ($tmp_switchtype eq '4ess'){ + $silent_pri_switchtype="4ess" + }elsif ($tmp_switchtype eq '5ess'){ + $silent_pri_switchtype="5ess" + }elsif ($tmp_switchtype eq 'euroisdn'){ + $silent_pri_switchtype="euroisdn" + }elsif ($tmp_switchtype eq 'ni1'){ + $silent_pri_switchtype="ni1" + }elsif ($tmp_switchtype eq 'qsig'){ + $silent_pri_switchtype="qsig" + } else { + printf("Invalid option for --pri_switchtype, options are\n"); + printf("\t national/dms100/4ess/5ess/euroisdn/ni1/qsig"); + exit(1); + } + push(@silent_pri_switchtypes, $silent_pri_switchtype); }elsif ( $_ =~ /--conf_dir=(.*)/){ $etc_dir=$1; if (! -d $etc_dir){ printf("Error: directory $1 does not exist\n"); exit(1); } + }else { + printf("Error: Unrecognized parameter \"$_\" \n"); + exit(1); + } } - + @silent_femedias = reverse(@silent_femedias); + @silent_feframes = reverse(@silent_feframes); + @silent_felcodes = reverse(@silent_felcodes); + @silent_tdm_laws = reverse(@silent_tdm_laws); + @silent_feclocks = reverse(@silent_feclocks); + @silent_signallings = reverse(@silent_signallings); + @silent_pri_switchtypes = reverse(@silent_pri_switchtypes); + @silent_zapata_contexts = reverse(@silent_zapata_contexts); + @silent_woomera_contexts = reverse(@silent_woomera_contexts); + @silent_zapata_groups = reverse(@silent_zapata_groups); + @silent_hwdtmfs = reverse(@silent_hwdtmfs); + @silent_first_chans = reverse(@silent_first_chans); + @silent_last_chans = reverse(@silent_last_chans); + if ($is_trixbox==$TRUE){ print "\nGenerating configuration files for Trixbox\n"; } if ($is_smg==$TRUE){ - print "\nGenerating configuration files for SS7\n"; + print "\nGenerating configuration files for Sangoma Media Gateway\n"; } if ($is_tdm_api==$TRUE){ $config_zapata = $FALSE; @@ -972,19 +1269,54 @@ sub get_bri_country { return $def_bri_country; } -sub get_bri_group{ +sub get_woomera_group{ + if($silent==$TRUE){ + if($#silent_woomera_groups >= 0){ + $silent_woomera_group=pop(@silent_woomera_groups); + } + return $silent_woomera_group; + } + my $group; - my $res_group=&prompt_user("\nInput the group for this port\n",$def_bri_group); + my $res_group=&prompt_user("\nInput the group for this port\n",$def_woomera_group); while(length($res_group)==0 |!($res_group =~/(\d+)/)| $res_group eq '0'){ print "Invalid group, input an integer greater than 0\n"; - $res_group=&prompt_user("Input the group for this port",$def_bri_group); + $res_group=&prompt_user("Input the group for this port",$def_woomera_group); } $group=$res_group; - $def_bri_group=$group; - return $def_bri_group; + $def_woomera_group=$group; + return $def_woomera_group; } + +sub get_bri_default_tei{ +# if($silent==$TRUE){ +# if($#silent_woomera_groups >= 0){ +# $silent_woomera_group=pop(@silent_woomera_groups); +# } +# return $silent_woomera_group; +# } + + my $res_default_tei; +get_bri_default_tei: + $res_default_tei=&prompt_user("\nInput the TEI for this port \n",$def_bri_default_tei); + while(length($res_default_tei)==0 |!($res_default_tei =~/(\d+)/)){ + print "Invalid TEI value, must be an integer\n"; + $res_default_tei=&prompt_user("Input the TEI for this port ",$def_bri_default_tei); + } + $res_default_tei =~ /(\d+)/; + if( $1 < 0 | $1 > 127) { + print "Invalid TEI value, must be between 0 and 127\n"; + goto get_bri_default_tei; + } + + $def_bri_default_tei=$res_default_tei; + return $def_bri_default_tei; +} + + + sub get_bri_operator { #warning returning ETSI $def_bri_operator = "etsi"; @@ -1039,6 +1371,15 @@ sub write_woomera_conf{ sub get_bri_conn_type{ + my ($port)=@_; + + if($silent==$TRUE){ + if($#silent_bri_conn_types >= 0){ + $silent_bri_conn_type=pop(@silent_bri_conn_types); + } + return $silent_bri_conn_type; + } + printf("\nSelect connection type for port %d\n", $port); my $conn_type; my @options = ( "Point to multipoint", "Point to point"); @@ -1065,7 +1406,7 @@ sub config_bri{ return; } my $a50x; - if (!$first_cfg) { + if (!$first_cfg && $silent==$FALSE) { system('clear'); } $first_cfg=0; @@ -1100,18 +1441,29 @@ sub config_bri{ if ($card->card_model eq '500'){ $num_bri_devices_total++; - system('clear'); - print "\n-----------------------------------------------------------\n"; - print "A$1 detected on slot:$3 bus:$4\n"; - print "-----------------------------------------------------------\n"; + if($5 eq '1'){ + $bri_device_has_master_clock=$FALSE; + } + if ($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } select_bri_option: - print "\nWould you like to configure A$1 port $5 on slot:$3 bus:$4\n"; - my @options=("YES", "NO", "Exit"); - $def_bri_option=&prompt_user_list(@options,$def_bri_option); + if($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 port $5 on slot:$3 bus:$4\n"; + my @options=("YES", "NO", "Exit"); + $def_bri_option=&prompt_user_list(@options,$def_bri_option); + } else { + $def_bri_option="YES"; + } + + if($def_bri_option eq 'YES'){ $skip_card=$FALSE; - $bri_conf.="\n;Sangoma A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; + $bri_conf.="\n;Sangoma AFT-A$1 port $5 [slot:$3 bus:$4 span:$current_tdmapi_span]"; }elsif($def_bri_option eq 'NO'){ $skip_card=$TRUE; }else{ @@ -1124,9 +1476,6 @@ select_bri_option: } } if ($skip_card==$FALSE){ -# print "A$1 port:$5 configured on slot:$3 bus:$4 span:$devnum\n"; -# prompt_user("Press any key to continue"); - $startup_string.="wanpipe$devnum "; $cfg_string.="wanpipe$devnum "; $a50x = eval {new A50x(); } or die ($@); @@ -1136,7 +1485,6 @@ select_bri_option: $num_bri_devices++; $card->tdmv_span_no($current_tdmapi_span); $current_tdmapi_span++; - $a50x->gen_wanpipe_conf(); }else{ print "A$1 on slot:$3 bus:$4 port:$5 not configured\n"; prompt_user("Press any key to continue"); @@ -1144,62 +1492,89 @@ select_bri_option: } } - }elsif ( $dev =~ /(\d+):NT/ & $skip_card==$FALSE){ - printf("\nConfiguring port %d as NT\n", $a50x->fe_line()); - printf("\nSelect connection type for port %d\n", $a50x->fe_line()); - my $context; - my $group; + }elsif (($dev =~ /(\d+):NT/ | + $dev =~ /(\d+):TE/ )& + $skip_card==$FALSE ){ + if($bri_device_has_master_clock==$FALSE & $dev =~ /(\d+):TE/){ + print "\nWould you like to use this port as a sync source?\n"; + if (&prompt_user_list(("YES","NO","YES")) eq 'YES'){ + $bri_device_has_master_clock=$TRUE; + $a50x->bri_clock_master("YES"); + } + } + + my $context=""; + my $group=""; my $bri_pos=$a50x->card->tdmv_span_no; - my $conn_type=get_bri_conn_type(); + + printf("\nConfiguring port %d on AFT-A%d [slot:%d bus:%d span:%d]\n", $a50x->fe_line(), $a50x->card->card_model(), $a50x->card->pci_slot(), $a50x->card->pci_bus(), $current_tdmapi_span-1); + my $conn_type=get_bri_conn_type($a50x->fe_line()); my $country=get_bri_country(); my $operator=get_bri_operator(); - my $context="from-internal"; + if($is_trixbox==$TRUE && $silent==$FALSE){ + if ( $dev =~ /(\d+):NT/ ){ + $context="from-internal"; + $group=1; + } else { + $context="from-zaptel"; + $group=2; + } + } else { + $group=get_woomera_group(); + #if a context has already been assigned to this group, do not prompt for options + foreach my $f_group (@woomera_groups) { + if($f_group eq $group){ + $context="WOOMERA_NO_CONFIG"; + } + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + if ( $dev =~ /(\d+):NT/ ){ + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_nt'); + } else { + $context=get_woomera_context($group, $a50x->card->card_model(),$a50x->fe_line(),'bri_te'); + } + push(@woomera_groups, $group); - if ($is_trixbox==$TRUE){ - $context="from-internal"; - $group=1; - }else{ - $context="from-internal"; - $group=get_bri_group(); + } + } + $a50x->gen_wanpipe_conf(); + if ( $dev =~ /(\d+):NT/ ){ + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type, ''); + } else { + my $current_bri_default_tei='127'; + if ($def_bri_default_tei_opt==$TRUE){ + $current_bri_default_tei=$def_bri_default_tei; + } + printf("\nConfiguring span:%s as TEI:%s\n", $bri_pos, $current_bri_default_tei); + my @options = ("YES - Keep this setting", "NO - Specify a different TEI"); + my $res = &prompt_user_list(@options, "YES"); + if ($res =~ m/NO/) { + $def_bri_default_tei_opt=$TRUE; + $current_bri_default_tei=get_bri_default_tei(); + } + if ($def_bri_default_tei_opt==$FALSE){ + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type, ''); + } else { + $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type, $current_bri_default_tei); + } + } + if(!($context eq "WOOMERA_NO_CONFIG")){ + $woomera_conf.=$a50x->gen_woomera_conf($group, $context); } - $bri_conf.=$a50x->gen_bri_conf($bri_pos, "bri_nt" , $group, $country, $operator, $conn_type); - $woomera_conf.=$a50x->gen_woomera_conf($group, $context); - }elsif ( $dev =~ /(\d+):TE/ & $skip_card==$FALSE){ - printf("\nConfiguring port %d as TE\n", $a50x->fe_line()); - printf("\nSelect connection type for port %d\n", $a50x->fe_line()); - my $context; - my $group; - my $bri_pos=$a50x->card->tdmv_span_no; - my $conn_type=get_bri_conn_type(); - my $country=get_bri_country(); - my $operator=get_bri_operator(); - if ($is_trixbox==$TRUE){ - $context="from-zaptel"; - $group=2; - }else{ - $context="from-woomera"; - $group=get_bri_group(); - } - $bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_te", $group, $country, $operator, $conn_type); - $woomera_conf.=$a50x->gen_woomera_conf($group, $context); } } -# prompt_user("Press any key to continue"); if($num_bri_devices_total!=0){ print("\nISBN BRI card configuration complete\n\n"); - prompt_user("Press any key to continue"); } else { print("\nNo Sangoma ISDN BRI cards detected\n\n"); + } + if($silent==$FALSE){ prompt_user("Press any key to continue"); - } } - - - #------------------------------T1/E1 FUNCTIONS------------------------------------# sub get_te_ref_clock{ @@ -1209,11 +1584,11 @@ sub get_te_ref_clock{ foreach my $port (@list_normal_clocks) { if ($port eq '0'){ $f_port = "Free run"; -} else { + } else { $f_port = "Port ".$port; -} + } push(@f_list_normal_clocks, $f_port); -} + } my $res = &prompt_user_list(@f_list_normal_clocks, "Free run"); my $i; @@ -1221,8 +1596,8 @@ sub get_te_ref_clock{ for $i (0..$#f_list_normal_clocks){ if ( $res eq @f_list_normal_clocks[$i] ){ return @list_normal_clocks[$i]; -} -} + } + } print "Internal error: Invalid reference clock\n"; exit 1; @@ -1265,19 +1640,25 @@ prompt_hw_dchan: } - sub get_zapata_group{ my ($card_model,$card_port,$context)=@_; my $group=''; + if($silent==$TRUE){ + if($#silent_zapata_groups >= 0){ + $silent_zapata_group=pop(@silent_zapata_groups); + } + $silent_zapata_group = + return $silent_zapata_group; + } if($is_trixbox==$TRUE){ if($context eq "from-zaptel"){ $group=0; return $group; }elsif($context eq "from-internal"){ - $group=1; - return $group; + $group=1; + return $group; }else{ - print "Internal error:invalid group for Trixbox\n"; + print "Internal error:invalid group for Trixbox\n"; } }else{ if($context eq "from-pstn"){ @@ -1301,13 +1682,34 @@ sub get_zapata_group{ sub prompt_hw_dtmf { +#HW DTMF not supported in the 3.2 drivers +# return "NO"; + if( $no_hwdtmf == $TRUE){ + return "NO"; + } print("Would you like to enable hardware DTMF detection?\n"); my @options = ("YES","NO"); $def_hw_dtmf = prompt_user_list(@options, $def_hw_dtmf); return $def_hw_dtmf; - } +sub prompt_tdm_law { + print("Which codec will be used?\n"); + my @options = ("MULAW - North America","ALAW - Europe"); + my @options_val = ("MULAW", "ALAW"); + my $res = &prompt_user_list(@options, $def_tdm_law); + my $i; + for $i (0..$#options){ + if ( $res eq @options[$i] ){ + $def_tdm_law=@options[$i]; + return @options_val[$i]; + } + } + print "Internal error: Invalid TDM LAW type\n"; + exit 1; +} + + sub get_pri_switchtype { my @options = ( "National ISDN 2", "Nortel DMS100", "AT&T 4ESS", "Lucent 5ESS", "EuroISDN", "Old National ISDN 1", "Q.SIG" ); my @options_val = ( "national", "dms100", "4ess", "5ess", "euroisdn", "ni1", "qsig" ); @@ -1317,8 +1719,8 @@ sub get_pri_switchtype { if ( $res eq @options[$i] ){ $def_switchtype=@options[$i]; return @options_val[$i]; -} -} + } + } print "Internal error: Invalid PRI switchtype\n"; exit 1; } @@ -1428,7 +1830,7 @@ CHECK1: while (length($ss7_group_chan)==0 |!($ss7_group_chan =~ /^\d+$/)){ sub config_t1e1{ - if (!$first_cfg) { + if (!$first_cfg && $silent==$FALSE) { system('clear'); } print "---------------------------------------------\n"; @@ -1474,7 +1876,7 @@ sub config_t1e1{ $card->card_model eq '102' | $card->card_model eq '104' | $card->card_model eq '108' ){ - if (!$first_cfg) { + if (!$first_cfg && $silent==$FALSE) { system('clear'); } if (($6 eq '1' || $6 eq 'PRI') && $5 eq 'A'){ @@ -1482,16 +1884,19 @@ sub config_t1e1{ $device_has_normal_clock=$FALSE; @device_normal_clocks = ("0"); } - if (!$first_cfg) { - system('clear'); - } $first_cfg=0; - my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; - print "\n-----------------------------------------------------------\n"; - print "$msg"; - print "-----------------------------------------------------------\n"; + if($silent==$FALSE){ + my $msg ="Configuring port ".$port." on A".$card->card_model." slot:".$card->pci_slot." bus:".$card->pci_bus.".\n"; + print "\n-----------------------------------------------------------\n"; + print "$msg"; + print "-----------------------------------------------------------\n"; + } my $fe_media = ''; if ($silent==$TRUE){ + if($#silent_femedias >= 0){ + $silent_femedia=pop(@silent_femedias); + } + $fe_media = $silent_femedia; } else { printf ("\nSelect media type for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); @@ -1542,7 +1947,6 @@ sub config_t1e1{ $max_chans = 24; $line_media = 'T1'; - #$def_te_sig_mode=''; if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ $def_felcode='B8ZS'; } @@ -1574,7 +1978,23 @@ sub config_t1e1{ } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } $def_felcode=$silent_felcode; + + if(!($def_felcode eq 'B8ZS' || $def_felcode eq 'AMI')){ + $def_felcode='B8ZS'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + + if(!($def_feframe eq 'ESF' || $def_feframe eq 'D4')){ + $def_feframe='ESF'; + } } @@ -1618,7 +2038,6 @@ sub config_t1e1{ printf("Select signalling mode on AFT-A%s port %s\n",$card->card_model, $port); my @options=("CCS","CAS"); $def_te_sig_mode=&prompt_user_list(@options, $def_te_sig_mode); - } elsif ($def_signalling eq 'PRI CPE' | $def_signalling eq 'PRI NET' | $def_signalling eq 'SS7 - Sangoma Signal Media Gateway'| @@ -1631,7 +2050,21 @@ sub config_t1e1{ } else { + if($#silent_felcodes >= 0){ + $silent_felcode=pop(@silent_felcodes); + } $def_felcode=$silent_felcode; + if(!($def_felcode eq 'HDB3' || $def_felcode eq 'AMI')){ + $def_felcode='HDB3'; + } + + if($#silent_feframes >= 0){ + $silent_feframe=pop(@silent_feframes); + } + $def_feframe=$silent_feframe; + if(!($def_feframe eq 'CRC4' || $def_feframe eq 'NCRC4' || $def_feframe eq 'UNFRAMED')){ + $def_feframe='CRC4'; + } } @@ -1643,6 +2076,9 @@ sub config_t1e1{ printf ("Select clock for AFT-A%s on port %s [slot:%s bus:%s span:$devnum]\n", $card->card_model, $port, $card->pci_slot, $card->pci_bus); $def_feclock=&prompt_user_list(@options, $def_feclock); } else { + if($#silent_feclocks >= 0){ + $silent_feclock=pop(@silent_feclocks); + } $def_feclock=$silent_feclock; } @@ -1673,8 +2109,11 @@ sub config_t1e1{ $card->hw_dtmf("NO"); } } else { - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf("YES"); + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); } else { $card->hw_dtmf("NO"); } @@ -1698,6 +2137,9 @@ sub config_t1e1{ $def_signalling=&prompt_user_list(@options,$def_signalling); } } else { + if($#silent_signallings >= 0){ + $silent_signalling=pop(@silent_signallings); + } $def_signalling=$silent_signalling; } $a10x->signalling($def_signalling); @@ -1830,71 +2272,103 @@ ENDSS7CONFIG: if ( $a10x->signalling eq 'PRI CPE' | $a10x->signalling eq 'PRI NET' ){ if ($silent==$FALSE && $config_zapata==$TRUE){ printf ("Select switchtype for AFT-A%s on port %s \n", $card->card_model, $port); - $a10x->pri_switchtype(get_pri_switchtype()); - } else { - $a10x->pri_switchtype($silent_switchtype); - } + $a10x->pri_switchtype(get_pri_switchtype()); + } else { + if($#silent_pri_switchtypes >= 0){ + $silent_pri_switchtype=pop(@silent_pri_switchtypes); + } + $def_feframe=$silent_feframe; + $a10x->pri_switchtype($silent_pri_switchtype); } + } - if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ - $a10x->ss7_subinterface(1); + if( $a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' ){ + $a10x->ss7_subinterface(1); + $a10x->gen_wanpipe_ss7_subinterfaces(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(2); $a10x->gen_wanpipe_ss7_subinterfaces(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(2); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - my $ss7_element; - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(3); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - - $a10x->gen_wanpipe_conf(); - if ($ss7_tdmvoicechans ne ''){ - $a10x->ss7_subinterface(5); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - foreach $ss7_element (@ss7_sorted){ - $a10x->ss7_sigchan($ss7_element); - $a10x->ss7_subinterface(6); - $a10x->gen_wanpipe_ss7_subinterfaces(); - } - }else{ - $a10x->gen_wanpipe_conf(); } - - if ($is_smg==$TRUE && $config_zapata==$FALSE){ - if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' - | $a10x->signalling eq 'No Signaling (Voice Only)')){ - $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); - } - }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ - if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ - - $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); - $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); - $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); - $zapata_conf.=$a10x->gen_zapata_conf(); - } - }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + my $ss7_element; + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(3); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + + $a10x->gen_wanpipe_conf(); + if ($ss7_tdmvoicechans ne ''){ + $a10x->ss7_subinterface(5); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + foreach $ss7_element (@ss7_sorted){ + $a10x->ss7_sigchan($ss7_element); + $a10x->ss7_subinterface(6); + $a10x->gen_wanpipe_ss7_subinterfaces(); + } + }else{ + $a10x->gen_wanpipe_conf(); + } + + if ($is_smg==$TRUE && $config_zapata==$FALSE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway' + | $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } + }elsif ($is_smg==$TRUE && $config_zapata==$TRUE){ + if (!($a10x->signalling eq 'SS7 - Sangoma Signal Media Gateway'| $a10x->signalling eq 'No Signaling (Voice Only)')){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); $zapata_conf.=$a10x->gen_zapata_conf(); - }elsif ($is_tdm_api == $FALSE){ - $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); } + }elsif ($is_trixbox==$TRUE | $config_zapata==$TRUE){ + if($silent==$FALSE){ + printf ("Configuring port %s on %s as a full %s\n", $a10x->fe_line(), $a10x->card->card_model(),$a10x->fe_media()); + my $res=&prompt_user_list("YES - Use all channels", "NO - Configure for fractional","YES"); + if ($res =~ m/NO/){ + my $max_chan=0; + if($a10x->fe_media eq 'T1'){ + $max_chan=24; + } else { + $max_chan=31; + } + my $first_chan = &get_chan_no("first",1,$max_chan-1); + my $last_chan = &get_chan_no("last",$first_chan+1,$max_chan); + + $a10x->frac_chan_first($first_chan); + $a10x->frac_chan_last($last_chan); + } + } else { + if($#silent_first_chans >= 0){ + $silent_first_chan = pop(@silent_first_chans); + $silent_last_chan = pop(@silent_last_chans); + } + + if($silent_first_chan != 0){ + $a10x->frac_chan_first($silent_first_chan); + $a10x->frac_chan_last($silent_last_chan); + } + } + + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + $a10x->card->zap_context(&get_zapata_context($a10x->card->card_model,$port)); + $a10x->card->zap_group(&get_zapata_group($a10x->card->card_model,$port,$a10x->card->zap_context)); + $zapata_conf.=$a10x->gen_zapata_conf(); + }elsif ($is_tdm_api == $FALSE){ + $zaptel_conf.=$a10x->gen_zaptel_conf($dchan_str); + } $devnum++; $num_digital_devices++; - my $msg ="\n\nPort ".$port." on A".$card->card_model." configuration complete...\n"; + my $msg ="\nPort ".$port." on AFT-A".$card->card_model." configuration complete...\n"; print "$msg"; if($silent==$FALSE){ prompt_user("Press any key to continue"); } - + } - + } @@ -1915,12 +2389,11 @@ ENDSS7CONFIG: sub config_analog{ - if($is_tdm_api==$TRUE){ return; } my $a20x; - if (!$first_cfg) { + if (!$first_cfg && $silent==$FALSE) { system('clear'); } $first_cfg=0; @@ -1951,14 +2424,18 @@ sub config_analog{ } if ($card->card_model eq '200' | $card->card_model eq '400'){ $num_analog_devices_total++; - system('clear'); - print "\n-----------------------------------------------------------\n"; - print "A$1 detected on slot:$3 bus:$4\n"; - print "-----------------------------------------------------------\n"; + if($silent==$FALSE) { + system('clear'); + print "\n-----------------------------------------------------------\n"; + print "A$1 detected on slot:$3 bus:$4\n"; + print "-----------------------------------------------------------\n"; + } if($is_trixbox==$FALSE){ - print "\nWould you like to configure A$1 on slot:$3 bus:$4\n"; - if (&prompt_user_list(("YES","NO","")) eq 'NO'){ - $skip_card=$TRUE; + if ($silent==$FALSE){ + print "\nWould you like to configure AFT-A$1 on slot:$3 bus:$4\n"; + if (&prompt_user_list(("YES","NO","")) eq 'NO'){ + $skip_card=$TRUE; + } } } if ($skip_card==$FALSE){ @@ -1967,7 +2444,7 @@ sub config_analog{ $a20x->card($card); $card->first_chan($current_zap_channel); - if ( $device_has_hwec==$TRUE){ + if ( $device_has_hwec==$TRUE && $silent==$FALSE){ print "Will this AFT-A$1 synchronize with an existing Sangoma T1/E1 card?\n"; print "\n WARNING: for hardware and firmware requirements, check:\n"; print " http://wiki.sangoma.com/t1e1analogfaxing\n"; @@ -1985,21 +2462,35 @@ sub config_analog{ } else { $card->hw_dtmf("NO"); } + $a20x->tdm_law(&prompt_tdm_law()); } else { - if ($card->hwec_mode eq "YES"){ - $card->hw_dtmf("YES"); + if($#silent_hwdtmfs >= 0){ + $silent_hwdtmf=pop(@silent_hwdtmfs); + } + + if ($card->hwec_mode eq "YES" && $no_hwdtmf==$FALSE){ + $card->hw_dtmf($silent_hwdtmf); } else { $card->hw_dtmf("NO"); } + + if($#silent_tdm_laws >= 0){ + $silent_tdm_law=pop(@silent_tdm_laws); + } + + $a20x->tdm_law($silent_tdm_law); } print "A$1 configured on slot:$3 bus:$4 span:$current_zap_span\n"; - prompt_user("Press any key to continue"); $zaptel_conf.="#Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; $zapata_conf.=";Sangoma A$1 [slot:$3 bus:$4 span:$current_zap_span] card->device_no.">\n"; $startup_string.="wanpipe$devnum "; $cfg_string.="wanpipe$devnum "; + + if($silent==$FALSE){ + prompt_user("Press any key to continue"); + } $current_zap_channel+=24; my $i; @@ -2017,13 +2508,27 @@ sub config_analog{ } }elsif ( $dev =~ /(\d+):FXS/ & $skip_card==$FALSE){ my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-internal"); + if($silent==$TRUE & $silent_zapata_context_opt == $TRUE){ + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $a20x->card->zap_context($silent_zapata_context); + } else { + $a20x->card->zap_context("from-internal"); + } $a20x->card->zap_group("1"); $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxo"); $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxo"); }elsif ( $dev =~ /(\d+):FXO/ & $skip_card==$FALSE){ my $zap_pos = $1+$current_zap_channel-25; - $a20x->card->zap_context("from-zaptel"); + if($silent==$TRUE & $silent_zapata_context_opt == $TRUE){ + if($#silent_zapata_contexts >= 0){ + $silent_zapata_context=pop(@silent_zapata_contexts); + } + $a20x->card->zap_context($silent_zapata_context); + } else { + $a20x->card->zap_context("from-zaptel"); + } $a20x->card->zap_group("0"); $zaptel_conf.=$a20x->gen_zaptel_conf($zap_pos,"fxs"); $zapata_conf.=$a20x->gen_zapata_conf($zap_pos,"fxs"); @@ -2031,7 +2536,9 @@ sub config_analog{ } if($num_analog_devices_total!=0){ print("\nAnalog card configuration complete\n\n"); - prompt_user("Press any key to continue"); + if( $silent==$FALSE){ + prompt_user("Press any key to continue"); + } } } diff --git a/util/wanconfig/Makefile b/util/wanconfig/Makefile index 7cabe5f..c839841 100644 --- a/util/wanconfig/Makefile +++ b/util/wanconfig/Makefile @@ -17,7 +17,7 @@ endif WAN_VIRTUAL= # Tools options. -CFLAGS = -Wall -O2 -D$(OS_TYPE) -I$(SYSINC) -I../../patches/kdrivers/include -D_DEBUG_=$(DEBUG) +CFLAGS = -Wall -O2 -D$(OS_TYPE) -I$(SYSINC) -D_DEBUG_=$(DEBUG) -DCONFIG_PRODUCT_WANPIPE_AFT_BRI CFLAGS += -DWAN_HWEC diff --git a/util/wanconfig/diff b/util/wanconfig/diff new file mode 100644 index 0000000..6fc3260 --- /dev/null +++ b/util/wanconfig/diff @@ -0,0 +1,139 @@ +--- wanconfig.c 2007-04-13 19:12:32.000000000 -0400 ++++ /common/wantools/wanconfig/wanconfig.c 2007-04-18 14:57:19.000000000 -0400 +@@ -257,7 +257,7 @@ + + int show_status(void); + int show_config(void); +-int show_hwprobe(void); ++int show_hwprobe(int); + int debugging(void); + int debug_read(void); + +@@ -298,6 +298,7 @@ + void free_device_link(char *devname); + int device_syncup(char *devname); + void sig_func (int sigio); ++int start_chan (int dev, link_def_t *def); + int start_link (void); + int stop_link(void); + int exec_command(unsigned char *rx_data); +@@ -470,6 +471,7 @@ + DO_SHOW_STATUS, + DO_SHOW_CONFIG, + DO_SHOW_HWPROBE, ++ DO_SHOW_HWPROBE_VERBOSE, + DO_DEBUGGING, + DO_DEBUG_READ, + } action; /* what to do */ +@@ -573,6 +575,8 @@ + { "TDMV_OPERMODE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, opermode_name), DTYPE_STR }, + { "RM_BATTTHRESH", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, battthresh), DTYPE_UINT }, + { "RM_BATTDEBOUNCE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, battdebounce), DTYPE_UINT }, ++ { "RM_EXTERNAL_SYNC", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, external_sync), DTYPE_UINT }, ++ + + /* TDMV parameters */ + { "TDMV_SPAN", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_tdmv_conf_t, span_no), DTYPE_UINT}, +@@ -586,7 +590,7 @@ + { "MTU", smemof(wandev_conf_t, mtu), DTYPE_UINT }, + { "UDPPORT", smemof(wandev_conf_t, udp_port), DTYPE_UINT }, + { "TTL", smemof(wandev_conf_t, ttl), DTYPE_UCHAR }, +- { "INTERFACE", smemof(wandev_conf_t, interface), DTYPE_UCHAR }, ++ { "INTERFACE", smemof(wandev_conf_t, electrical_interface), DTYPE_UCHAR }, + { "CLOCKING", smemof(wandev_conf_t, clocking), DTYPE_UCHAR }, + { "LINECODING", smemof(wandev_conf_t, line_coding), DTYPE_UCHAR }, + { "CONNECTION", smemof(wandev_conf_t, connection), DTYPE_UCHAR }, +@@ -1212,7 +1216,6 @@ + { WANCONFIG_AFT_TE1, xilinx_conftab }, + { WANCONFIG_AFT_ANALOG, xilinx_conftab }, + { WANCONFIG_AFT_TE3, xilinx_conftab }, +- { WANCONFIG_AFT_56K, xilinx_conftab }, + { WANCONFIG_BITSTRM, bitstrm_conftab }, + { WANCONFIG_SDLC, sdlc_conftab }, + { 0, NULL } +@@ -1228,7 +1231,6 @@ + { WANCONFIG_AFT_TE1, xilinx_if_conftab }, + { WANCONFIG_AFT_TE3, xilinx_if_conftab }, + { WANCONFIG_AFT_ANALOG, xilinx_if_conftab }, +- { WANCONFIG_AFT_56K, xilinx_if_conftab }, + { WANCONFIG_ASYHDLC, chdlc_conftab }, + { 0, NULL } + }; +@@ -1278,7 +1280,6 @@ + { WANCONFIG_AFT_TE1, "WAN_AFT_TE1" }, + { WANCONFIG_AFT_ANALOG, "WAN_AFT_ANALOG" }, + { WANCONFIG_AFT_TE3, "WAN_AFT_TE3" }, +- { WANCONFIG_AFT_56K, "WAN_AFT_56K" }, + { WANCONFIG_AFT, "WAN_XILINX" }, + { WANCONFIG_MFR, "WAN_MFR" }, + { WANCONFIG_DEBUG, "WAN_DEBUG" }, +@@ -1722,9 +1723,14 @@ + } + + else if( strcmp( argv[optind], "hwprobe" ) == 0 ) { +- set_action(DO_SHOW_HWPROBE); ++ if ((optind + 1 < argc) && (strcmp( argv[optind+1], "verbose" ) == 0 )){ ++ set_action(DO_SHOW_HWPROBE_VERBOSE); ++ optind++; ++ }else{ ++ set_action(DO_SHOW_HWPROBE); ++ } + } +- ++ + else if( strcmp( argv[optind], "help" ) == 0 ) { + show_help(); + } +@@ -1799,7 +1805,8 @@ + break; + + case DO_SHOW_HWPROBE: +- return show_hwprobe(); ++ case DO_SHOW_HWPROBE_VERBOSE: ++ return show_hwprobe(action); + break; + + case DO_DEBUGGING: +@@ -4663,7 +4670,7 @@ + return err; + } + +-int show_hwprobe(void) ++int show_hwprobe(int action) + { + int err = 0; + +@@ -4680,7 +4687,8 @@ + memset(&procfs, 0, sizeof(wan_procfs_t)); + procfs.magic = ROUTER_MAGIC; + procfs.max_len = 2048; +- procfs.cmd = WANPIPE_PROCFS_HWPROBE; ++ procfs.cmd = (action == DO_SHOW_HWPROBE) ? ++ WANPIPE_PROCFS_HWPROBE : WANPIPE_PROCFS_HWPROBE_VERBOSE ; + procfs.data = malloc(2048); + if (procfs.data == NULL){ + show_error(ERR_SYSTEM); +@@ -4971,6 +4979,7 @@ + + #if defined(WAN_HWEC) + ++ + #define WAN_EC_PID "/etc/wanpipe/wan_ec/wan_ec_pid" + #define WAN_EC_DIR "/etc/wanpipe/wan_ec" + +@@ -4978,6 +4987,7 @@ + { + int status; + char cmd[100]; ++#if defined(__LINUX__) + DIR *dir; + + dir = opendir(WAN_EC_DIR); +@@ -4987,6 +4997,7 @@ + } + + closedir(dir); ++#endif + + /*HW_EC*/ + sprintf(cmd, "wan_ec_client %s config", devname); diff --git a/util/wanconfig/file b/util/wanconfig/file deleted file mode 100644 index 2fa97f9..0000000 --- a/util/wanconfig/file +++ /dev/null @@ -1,1697 +0,0 @@ -wanconfig.c:87:36: error: linux/wanpipe_version.h: No such file or directory -wanconfig.c:88:36: error: linux/wanpipe_defines.h: No such file or directory -wanconfig.c:89:32: error: linux/wanpipe_cfg.h: No such file or directory -wanconfig.c:90:28: error: linux/wanpipe.h: No such file or directory -wanconfig.c:183: error: ‘WAN_IFNAME_SZ’ undeclared here (not in a function) -wanconfig.c:194: error: expected specifier-qualifier-list before ‘wanif_conf_t’ -wanconfig.c:201: error: ‘WAN_DRVNAME_SZ’ undeclared here (not in a function) -wanconfig.c:208: error: expected specifier-qualifier-list before ‘wandev_conf_t’ -wanconfig.c:284: error: expected ‘)’ before ‘*’ token -wanconfig.c:285: error: expected ‘)’ before ‘*’ token -wanconfig.c:492: error: expected specifier-qualifier-list before ‘wandev_conf_t’ -wanconfig.c:522: error: expected specifier-qualifier-list before ‘wandev_conf_t’ -wanconfig.c:522: error: expected ‘}’ before ‘)’ token -wanconfig.c:522: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:522: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:523: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:524: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:525: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:526: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:527: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:528: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:529: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:530: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:531: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:532: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:540: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:541: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:542: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:543: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:544: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:545: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:548: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:549: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:550: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:552: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:553: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:554: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:555: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:556: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:557: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:558: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:560: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:561: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:562: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:564: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:565: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:566: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:567: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:568: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:569: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:570: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:571: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:572: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:573: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:574: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:575: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:576: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:579: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:580: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:581: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:583: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:584: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:586: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:588: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:589: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:590: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:591: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:592: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:593: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:594: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:595: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:596: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:597: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:598: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:599: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:600: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:601: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:602: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:603: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:604: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:605: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:606: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:607: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:608: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:609: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:611: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:612: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:628: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:632: error: expected specifier-qualifier-list before ‘wan_ppp_conf_t’ -wanconfig.c:632: error: initializer element is not constant -wanconfig.c:632: error: (near initialization for ‘ppp_conftab[0].offset’) -wanconfig.c:632: error: expected ‘}’ before ‘)’ token -wanconfig.c:632: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:632: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:633: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:634: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:636: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:637: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:638: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:639: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:640: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:641: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:642: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:643: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:645: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:652: error: expected specifier-qualifier-list before ‘wan_chdlc_conf_t’ -wanconfig.c:652: error: initializer element is not constant -wanconfig.c:652: error: (near initialization for ‘chdlc_conftab[0].offset’) -wanconfig.c:652: error: expected ‘}’ before ‘)’ token -wanconfig.c:652: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:652: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:653: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:654: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:655: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:656: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:657: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:658: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:659: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:660: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:661: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:663: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:668: error: expected specifier-qualifier-list before ‘wan_sppp_if_conf_t’ -wanconfig.c:668: error: initializer element is not constant -wanconfig.c:668: error: (near initialization for ‘sppp_conftab[0].offset’) -wanconfig.c:668: error: expected ‘}’ before ‘)’ token -wanconfig.c:668: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:668: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:670: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:671: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:672: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:674: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:675: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:676: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:678: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:679: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:683: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:686: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:690: error: expected specifier-qualifier-list before ‘wan_fr_conf_t’ -wanconfig.c:690: error: initializer element is not constant -wanconfig.c:690: error: (near initialization for ‘fr_conftab[0].offset’) -wanconfig.c:690: error: expected ‘}’ before ‘)’ token -wanconfig.c:690: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:690: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:691: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:692: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:693: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:694: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:695: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:696: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:697: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:698: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:699: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:700: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:702: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:706: error: expected specifier-qualifier-list before ‘wan_xilinx_conf_t’ -wanconfig.c:706: error: initializer element is not constant -wanconfig.c:706: error: (near initialization for ‘xilinx_conftab[0].offset’) -wanconfig.c:706: error: expected ‘}’ before ‘)’ token -wanconfig.c:706: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:706: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:707: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:708: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:709: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:712: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:714: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:719: error: expected specifier-qualifier-list before ‘wan_bitstrm_conf_t’ -wanconfig.c:719: error: initializer element is not constant -wanconfig.c:719: error: (near initialization for ‘bitstrm_conftab[0].offset’) -wanconfig.c:719: error: expected ‘}’ before ‘)’ token -wanconfig.c:719: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:719: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:720: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:721: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:722: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:723: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:724: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:725: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:727: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:731: error: expected specifier-qualifier-list before ‘wan_sdlc_conf_t’ -wanconfig.c:731: error: initializer element is not constant -wanconfig.c:731: error: (near initialization for ‘sdlc_conftab[0].offset’) -wanconfig.c:731: error: expected ‘}’ before ‘)’ token -wanconfig.c:731: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:731: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:732: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:733: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:734: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:736: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:737: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:738: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:739: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:740: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:742: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:743: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:744: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:745: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:746: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:747: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:749: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:752: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:757: error: expected specifier-qualifier-list before ‘wan_xdlc_conf_t’ -wanconfig.c:757: error: initializer element is not constant -wanconfig.c:757: error: (near initialization for ‘xdlc_conftab[0].offset’) -wanconfig.c:757: error: expected ‘}’ before ‘)’ token -wanconfig.c:757: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:757: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:758: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:760: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:761: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:762: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:764: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:766: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:767: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:768: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:770: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:771: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:772: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:774: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:777: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:810: error: expected specifier-qualifier-list before ‘wan_atm_conf_t’ -wanconfig.c:810: error: initializer element is not constant -wanconfig.c:810: error: (near initialization for ‘atm_conftab[0].offset’) -wanconfig.c:810: error: expected ‘}’ before ‘)’ token -wanconfig.c:810: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:810: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:811: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:812: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:813: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:814: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:815: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:816: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:817: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:819: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:826: error: expected specifier-qualifier-list before ‘wan_atm_conf_if_t’ -wanconfig.c:826: error: initializer element is not constant -wanconfig.c:826: error: (near initialization for ‘atm_if_conftab[0].offset’) -wanconfig.c:826: error: expected ‘}’ before ‘)’ token -wanconfig.c:826: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:826: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:827: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:828: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:830: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:831: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:832: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:833: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:834: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:835: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:836: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:839: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:840: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:841: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:842: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:843: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:844: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:845: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:846: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:849: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:853: error: expected specifier-qualifier-list before ‘wan_xilinx_conf_if_t’ -wanconfig.c:853: error: initializer element is not constant -wanconfig.c:853: error: (near initialization for ‘xilinx_if_conftab[0].offset’) -wanconfig.c:853: error: expected ‘}’ before ‘)’ token -wanconfig.c:853: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:853: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:854: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:855: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:856: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:857: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:858: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:859: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:860: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:861: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:862: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:865: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:867: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:872: error: expected specifier-qualifier-list before ‘wan_bitstrm_conf_if_t’ -wanconfig.c:872: error: initializer element is not constant -wanconfig.c:872: error: (near initialization for ‘bitstrm_if_conftab[0].offset’) -wanconfig.c:872: error: expected ‘}’ before ‘)’ token -wanconfig.c:872: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:872: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:873: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:874: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:876: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:881: error: expected specifier-qualifier-list before ‘wan_adsl_conf_t’ -wanconfig.c:881: error: initializer element is not constant -wanconfig.c:881: error: (near initialization for ‘adsl_conftab[0].offset’) -wanconfig.c:881: error: expected ‘}’ before ‘)’ token -wanconfig.c:881: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:881: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:883: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:884: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:886: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:888: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:889: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:891: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:893: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:894: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:896: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:898: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:900: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:901: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:903: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:904: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:905: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:906: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:907: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:908: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:909: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:910: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:911: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:912: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:913: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:914: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:915: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:916: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:919: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:920: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:921: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:922: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:923: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:924: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:925: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:926: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:927: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:928: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:929: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:930: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:931: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:932: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:934: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:935: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:937: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:941: error: expected specifier-qualifier-list before ‘wan_bscstrm_conf_t’ -wanconfig.c:941: error: initializer element is not constant -wanconfig.c:941: error: (near initialization for ‘bscstrm_conftab[0].offset’) -wanconfig.c:941: error: expected ‘}’ before ‘)’ token -wanconfig.c:941: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:941: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:942: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:943: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:944: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:945: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:946: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:947: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:948: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:949: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:950: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:951: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:953: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:958: error: expected specifier-qualifier-list before ‘wan_ss7_conf_t’ -wanconfig.c:958: error: initializer element is not constant -wanconfig.c:958: error: (near initialization for ‘ss7_conftab[0].offset’) -wanconfig.c:958: error: expected ‘}’ before ‘)’ token -wanconfig.c:958: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:958: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:959: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:960: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:961: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:962: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:963: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:964: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:965: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:966: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:967: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:968: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:969: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:970: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:971: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:972: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:973: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:974: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:975: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:976: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:977: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:978: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:979: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:980: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:981: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:982: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:983: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:984: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:985: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:986: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:987: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:989: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:995: error: expected specifier-qualifier-list before ‘wan_x25_conf_t’ -wanconfig.c:995: error: initializer element is not constant -wanconfig.c:995: error: (near initialization for ‘x25_conftab[0].offset’) -wanconfig.c:995: error: expected ‘}’ before ‘)’ token -wanconfig.c:995: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:995: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:996: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:997: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:998: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:999: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1000: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1001: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1002: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1003: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1004: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1005: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1006: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1007: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1008: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1009: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1010: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1011: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1012: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1013: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1014: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1015: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1016: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1017: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1018: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1019: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1020: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1021: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1022: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1024: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:1029: error: expected specifier-qualifier-list before ‘wan_lapb_if_conf_t’ -wanconfig.c:1029: error: initializer element is not constant -wanconfig.c:1029: error: (near initialization for ‘lapb_annexg_conftab[0].offset’) -wanconfig.c:1029: error: expected ‘}’ before ‘)’ token -wanconfig.c:1029: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:1029: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1030: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1031: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1032: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1033: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1034: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1035: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1036: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1037: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1038: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1039: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1040: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1042: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1043: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1044: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1046: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1049: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:1054: error: expected specifier-qualifier-list before ‘wan_x25_if_conf_t’ -wanconfig.c:1054: error: initializer element is not constant -wanconfig.c:1054: error: (near initialization for ‘x25_annexg_conftab[0].offset’) -wanconfig.c:1054: error: expected ‘}’ before ‘)’ token -wanconfig.c:1054: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:1054: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1055: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1056: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1057: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1058: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1059: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1060: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1061: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1062: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1063: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1064: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1066: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1067: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1068: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1069: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1071: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1072: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1073: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1074: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1076: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1077: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1079: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1080: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1082: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1083: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1085: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1086: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1087: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1089: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1090: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1091: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1092: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1093: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1095: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1096: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1097: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1100: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:1105: error: expected specifier-qualifier-list before ‘wan_dsp_if_conf_t’ -wanconfig.c:1105: error: initializer element is not constant -wanconfig.c:1105: error: (near initialization for ‘dsp_annexg_conftab[0].offset’) -wanconfig.c:1105: error: expected ‘}’ before ‘)’ token -wanconfig.c:1105: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:1105: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1106: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1107: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1108: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1109: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1110: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1111: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1112: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1114: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:1118: error: expected specifier-qualifier-list before ‘wanif_conf_t’ -wanconfig.c:1118: error: initializer element is not constant -wanconfig.c:1118: error: (near initialization for ‘chan_conftab[0].offset’) -wanconfig.c:1118: error: expected ‘}’ before ‘)’ token -wanconfig.c:1118: error: expected ‘,’ or ‘;’ before ‘)’ token -wanconfig.c:1118: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1119: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1120: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1121: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1122: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1123: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1124: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1125: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1126: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1127: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1128: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1129: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1130: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1131: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1132: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1133: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1134: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1135: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1136: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1137: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1138: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1139: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1140: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1141: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1143: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1144: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1145: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1146: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1148: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1154: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1155: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1156: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1157: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1160: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1161: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1162: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1163: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1164: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1165: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1166: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1167: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1168: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1169: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1170: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1171: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1172: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1173: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1174: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1175: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1176: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1177: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1178: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1179: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1181: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1183: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1184: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1186: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1187: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1188: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1192: error: expected identifier or ‘(’ before ‘,’ token -wanconfig.c:1195: error: expected identifier or ‘(’ before ‘}’ token -wanconfig.c:1199: error: ‘WANCONFIG_PPP’ undeclared here (not in a function) -wanconfig.c:1199: error: initializer element is not constant -wanconfig.c:1199: error: (near initialization for ‘conf_def_tables[0].val’) -wanconfig.c:1200: error: ‘WANCONFIG_FR’ undeclared here (not in a function) -wanconfig.c:1200: error: initializer element is not constant -wanconfig.c:1200: error: (near initialization for ‘conf_def_tables[1].val’) -wanconfig.c:1201: error: ‘WANCONFIG_X25’ undeclared here (not in a function) -wanconfig.c:1201: error: initializer element is not constant -wanconfig.c:1201: error: (near initialization for ‘conf_def_tables[2].val’) -wanconfig.c:1202: error: ‘WANCONFIG_ADCCP’ undeclared here (not in a function) -wanconfig.c:1202: error: initializer element is not constant -wanconfig.c:1202: error: (near initialization for ‘conf_def_tables[3].val’) -wanconfig.c:1203: error: ‘WANCONFIG_CHDLC’ undeclared here (not in a function) -wanconfig.c:1203: error: initializer element is not constant -wanconfig.c:1203: error: (near initialization for ‘conf_def_tables[4].val’) -wanconfig.c:1204: error: ‘WANCONFIG_ASYHDLC’ undeclared here (not in a function) -wanconfig.c:1204: error: initializer element is not constant -wanconfig.c:1204: error: (near initialization for ‘conf_def_tables[5].val’) -wanconfig.c:1205: error: ‘WANCONFIG_MPPP’ undeclared here (not in a function) -wanconfig.c:1205: error: initializer element is not constant -wanconfig.c:1205: error: (near initialization for ‘conf_def_tables[6].val’) -wanconfig.c:1206: error: ‘WANCONFIG_LIP_ATM’ undeclared here (not in a function) -wanconfig.c:1206: error: initializer element is not constant -wanconfig.c:1206: error: (near initialization for ‘conf_def_tables[7].val’) -wanconfig.c:1207: error: ‘WANCONFIG_LIP_KATM’ undeclared here (not in a function) -wanconfig.c:1207: error: initializer element is not constant -wanconfig.c:1207: error: (near initialization for ‘conf_def_tables[8].val’) -wanconfig.c:1208: error: ‘WANCONFIG_MFR’ undeclared here (not in a function) -wanconfig.c:1208: error: initializer element is not constant -wanconfig.c:1208: error: (near initialization for ‘conf_def_tables[9].val’) -wanconfig.c:1209: error: ‘WANCONFIG_SS7’ undeclared here (not in a function) -wanconfig.c:1209: error: initializer element is not constant -wanconfig.c:1209: error: (near initialization for ‘conf_def_tables[10].val’) -wanconfig.c:1210: error: ‘WANCONFIG_ADSL’ undeclared here (not in a function) -wanconfig.c:1210: error: initializer element is not constant -wanconfig.c:1210: error: (near initialization for ‘conf_def_tables[11].val’) -wanconfig.c:1211: error: ‘WANCONFIG_BSCSTRM’ undeclared here (not in a function) -wanconfig.c:1211: error: initializer element is not constant -wanconfig.c:1211: error: (near initialization for ‘conf_def_tables[12].val’) -wanconfig.c:1212: error: ‘WANCONFIG_ATM’ undeclared here (not in a function) -wanconfig.c:1212: error: initializer element is not constant -wanconfig.c:1212: error: (near initialization for ‘conf_def_tables[13].val’) -wanconfig.c:1213: error: ‘WANCONFIG_MLINK_PPP’ undeclared here (not in a function) -wanconfig.c:1213: error: initializer element is not constant -wanconfig.c:1213: error: (near initialization for ‘conf_def_tables[14].val’) -wanconfig.c:1214: error: ‘WANCONFIG_AFT’ undeclared here (not in a function) -wanconfig.c:1214: error: initializer element is not constant -wanconfig.c:1214: error: (near initialization for ‘conf_def_tables[15].val’) -wanconfig.c:1215: error: ‘WANCONFIG_AFT_TE1’ undeclared here (not in a function) -wanconfig.c:1215: error: initializer element is not constant -wanconfig.c:1215: error: (near initialization for ‘conf_def_tables[16].val’) -wanconfig.c:1216: error: ‘WANCONFIG_AFT_ANALOG’ undeclared here (not in a function) -wanconfig.c:1216: error: initializer element is not constant -wanconfig.c:1216: error: (near initialization for ‘conf_def_tables[17].val’) -wanconfig.c:1217: error: ‘WANCONFIG_AFT_TE3’ undeclared here (not in a function) -wanconfig.c:1217: error: initializer element is not constant -wanconfig.c:1217: error: (near initialization for ‘conf_def_tables[18].val’) -wanconfig.c:1218: error: ‘WANCONFIG_AFT_56K’ undeclared here (not in a function) -wanconfig.c:1218: error: initializer element is not constant -wanconfig.c:1218: error: (near initialization for ‘conf_def_tables[19].val’) -wanconfig.c:1219: error: ‘WANCONFIG_BITSTRM’ undeclared here (not in a function) -wanconfig.c:1219: error: initializer element is not constant -wanconfig.c:1219: error: (near initialization for ‘conf_def_tables[20].val’) -wanconfig.c:1220: error: ‘WANCONFIG_SDLC’ undeclared here (not in a function) -wanconfig.c:1220: error: initializer element is not constant -wanconfig.c:1220: error: (near initialization for ‘conf_def_tables[21].val’) -wanconfig.c:1226: error: initializer element is not constant -wanconfig.c:1226: error: (near initialization for ‘conf_if_def_tables[0].val’) -wanconfig.c:1227: error: initializer element is not constant -wanconfig.c:1227: error: (near initialization for ‘conf_if_def_tables[1].val’) -wanconfig.c:1228: error: initializer element is not constant -wanconfig.c:1228: error: (near initialization for ‘conf_if_def_tables[2].val’) -wanconfig.c:1229: error: initializer element is not constant -wanconfig.c:1229: error: (near initialization for ‘conf_if_def_tables[3].val’) -wanconfig.c:1230: error: initializer element is not constant -wanconfig.c:1230: error: (near initialization for ‘conf_if_def_tables[4].val’) -wanconfig.c:1231: error: initializer element is not constant -wanconfig.c:1231: error: (near initialization for ‘conf_if_def_tables[5].val’) -wanconfig.c:1232: error: initializer element is not constant -wanconfig.c:1232: error: (near initialization for ‘conf_if_def_tables[6].val’) -wanconfig.c:1233: error: initializer element is not constant -wanconfig.c:1233: error: (near initialization for ‘conf_if_def_tables[7].val’) -wanconfig.c:1234: error: initializer element is not constant -wanconfig.c:1234: error: (near initialization for ‘conf_if_def_tables[8].val’) -wanconfig.c:1235: error: initializer element is not constant -wanconfig.c:1235: error: (near initialization for ‘conf_if_def_tables[9].val’) -wanconfig.c:1260: error: initializer element is not constant -wanconfig.c:1260: error: (near initialization for ‘config_id_str[0].val’) -wanconfig.c:1261: error: initializer element is not constant -wanconfig.c:1261: error: (near initialization for ‘config_id_str[1].val’) -wanconfig.c:1262: error: initializer element is not constant -wanconfig.c:1262: error: (near initialization for ‘config_id_str[2].val’) -wanconfig.c:1263: error: initializer element is not constant -wanconfig.c:1263: error: (near initialization for ‘config_id_str[3].val’) -wanconfig.c:1264: error: initializer element is not constant -wanconfig.c:1264: error: (near initialization for ‘config_id_str[4].val’) -wanconfig.c:1265: error: ‘WANCONFIG_BSC’ undeclared here (not in a function) -wanconfig.c:1265: error: initializer element is not constant -wanconfig.c:1265: error: (near initialization for ‘config_id_str[5].val’) -wanconfig.c:1266: error: ‘WANCONFIG_HDLC’ undeclared here (not in a function) -wanconfig.c:1266: error: initializer element is not constant -wanconfig.c:1266: error: (near initialization for ‘config_id_str[6].val’) -wanconfig.c:1267: error: initializer element is not constant -wanconfig.c:1267: error: (near initialization for ‘config_id_str[7].val’) -wanconfig.c:1268: error: ‘WANCONFIG_MPROT’ undeclared here (not in a function) -wanconfig.c:1268: error: initializer element is not constant -wanconfig.c:1268: error: (near initialization for ‘config_id_str[8].val’) -wanconfig.c:1269: error: initializer element is not constant -wanconfig.c:1269: error: (near initialization for ‘config_id_str[9].val’) -wanconfig.c:1270: error: initializer element is not constant -wanconfig.c:1270: error: (near initialization for ‘config_id_str[10].val’) -wanconfig.c:1271: error: initializer element is not constant -wanconfig.c:1271: error: (near initialization for ‘config_id_str[11].val’) -wanconfig.c:1272: error: ‘WANCONFIG_EDUKIT’ undeclared here (not in a function) -wanconfig.c:1272: error: initializer element is not constant -wanconfig.c:1272: error: (near initialization for ‘config_id_str[12].val’) -wanconfig.c:1273: error: initializer element is not constant -wanconfig.c:1273: error: (near initialization for ‘config_id_str[13].val’) -wanconfig.c:1274: error: initializer element is not constant -wanconfig.c:1274: error: (near initialization for ‘config_id_str[14].val’) -wanconfig.c:1275: error: initializer element is not constant -wanconfig.c:1275: error: (near initialization for ‘config_id_str[15].val’) -wanconfig.c:1276: error: initializer element is not constant -wanconfig.c:1276: error: (near initialization for ‘config_id_str[16].val’) -wanconfig.c:1277: error: initializer element is not constant -wanconfig.c:1277: error: (near initialization for ‘config_id_str[17].val’) -wanconfig.c:1278: error: initializer element is not constant -wanconfig.c:1278: error: (near initialization for ‘config_id_str[18].val’) -wanconfig.c:1279: error: ‘WANCONFIG_POS’ undeclared here (not in a function) -wanconfig.c:1279: error: initializer element is not constant -wanconfig.c:1279: error: (near initialization for ‘config_id_str[19].val’) -wanconfig.c:1280: error: initializer element is not constant -wanconfig.c:1280: error: (near initialization for ‘config_id_str[20].val’) -wanconfig.c:1281: error: initializer element is not constant -wanconfig.c:1281: error: (near initialization for ‘config_id_str[21].val’) -wanconfig.c:1282: error: initializer element is not constant -wanconfig.c:1282: error: (near initialization for ‘config_id_str[22].val’) -wanconfig.c:1283: error: initializer element is not constant -wanconfig.c:1283: error: (near initialization for ‘config_id_str[23].val’) -wanconfig.c:1284: error: initializer element is not constant -wanconfig.c:1284: error: (near initialization for ‘config_id_str[24].val’) -wanconfig.c:1285: error: initializer element is not constant -wanconfig.c:1285: error: (near initialization for ‘config_id_str[25].val’) -wanconfig.c:1286: error: initializer element is not constant -wanconfig.c:1286: error: (near initialization for ‘config_id_str[26].val’) -wanconfig.c:1287: error: ‘WANCONFIG_DEBUG’ undeclared here (not in a function) -wanconfig.c:1287: error: initializer element is not constant -wanconfig.c:1287: error: (near initialization for ‘config_id_str[27].val’) -wanconfig.c:1288: error: initializer element is not constant -wanconfig.c:1288: error: (near initialization for ‘config_id_str[28].val’) -wanconfig.c:1289: error: initializer element is not constant -wanconfig.c:1289: error: (near initialization for ‘config_id_str[29].val’) -wanconfig.c:1299: error: ‘WANOPT_OFF’ undeclared here (not in a function) -wanconfig.c:1299: error: initializer element is not constant -wanconfig.c:1299: error: (near initialization for ‘sym_table[0].val’) -wanconfig.c:1300: error: ‘WANOPT_ON’ undeclared here (not in a function) -wanconfig.c:1300: error: initializer element is not constant -wanconfig.c:1300: error: (near initialization for ‘sym_table[1].val’) -wanconfig.c:1301: error: ‘WANOPT_NO’ undeclared here (not in a function) -wanconfig.c:1301: error: initializer element is not constant -wanconfig.c:1301: error: (near initialization for ‘sym_table[2].val’) -wanconfig.c:1302: error: ‘WANOPT_YES’ undeclared here (not in a function) -wanconfig.c:1302: error: initializer element is not constant -wanconfig.c:1302: error: (near initialization for ‘sym_table[3].val’) -wanconfig.c:1304: error: ‘WANOPT_RS232’ undeclared here (not in a function) -wanconfig.c:1304: error: initializer element is not constant -wanconfig.c:1304: error: (near initialization for ‘sym_table[4].val’) -wanconfig.c:1305: error: ‘WANOPT_V35’ undeclared here (not in a function) -wanconfig.c:1305: error: initializer element is not constant -wanconfig.c:1305: error: (near initialization for ‘sym_table[5].val’) -wanconfig.c:1307: error: ‘WANOPT_NRZ’ undeclared here (not in a function) -wanconfig.c:1307: error: initializer element is not constant -wanconfig.c:1307: error: (near initialization for ‘sym_table[6].val’) -wanconfig.c:1308: error: ‘WANOPT_NRZI’ undeclared here (not in a function) -wanconfig.c:1308: error: initializer element is not constant -wanconfig.c:1308: error: (near initialization for ‘sym_table[7].val’) -wanconfig.c:1309: error: ‘WANOPT_FM0’ undeclared here (not in a function) -wanconfig.c:1309: error: initializer element is not constant -wanconfig.c:1309: error: (near initialization for ‘sym_table[8].val’) -wanconfig.c:1310: error: ‘WANOPT_FM1’ undeclared here (not in a function) -wanconfig.c:1310: error: initializer element is not constant -wanconfig.c:1310: error: (near initialization for ‘sym_table[9].val’) -wanconfig.c:1313: error: ‘WANOPT_IDLE_FLAG’ undeclared here (not in a function) -wanconfig.c:1313: error: initializer element is not constant -wanconfig.c:1313: error: (near initialization for ‘sym_table[10].val’) -wanconfig.c:1314: error: ‘WANOPT_IDLE_MARK’ undeclared here (not in a function) -wanconfig.c:1314: error: initializer element is not constant -wanconfig.c:1314: error: (near initialization for ‘sym_table[11].val’) -wanconfig.c:1317: error: ‘WANOPT_POINTTOPOINT’ undeclared here (not in a function) -wanconfig.c:1317: error: initializer element is not constant -wanconfig.c:1317: error: (near initialization for ‘sym_table[12].val’) -wanconfig.c:1318: error: ‘WANOPT_MULTIDROP’ undeclared here (not in a function) -wanconfig.c:1318: error: initializer element is not constant -wanconfig.c:1318: error: (near initialization for ‘sym_table[13].val’) -wanconfig.c:1320: error: ‘WANOPT_EXTERNAL’ undeclared here (not in a function) -wanconfig.c:1320: error: initializer element is not constant -wanconfig.c:1320: error: (near initialization for ‘sym_table[14].val’) -wanconfig.c:1321: error: ‘WANOPT_INTERNAL’ undeclared here (not in a function) -wanconfig.c:1321: error: initializer element is not constant -wanconfig.c:1321: error: (near initialization for ‘sym_table[15].val’) -wanconfig.c:1323: error: ‘WANOPT_DTE’ undeclared here (not in a function) -wanconfig.c:1323: error: initializer element is not constant -wanconfig.c:1323: error: (near initialization for ‘sym_table[16].val’) -wanconfig.c:1324: error: ‘WANOPT_DCE’ undeclared here (not in a function) -wanconfig.c:1324: error: initializer element is not constant -wanconfig.c:1324: error: (near initialization for ‘sym_table[17].val’) -wanconfig.c:1325: error: ‘WANOPT_CPE’ undeclared here (not in a function) -wanconfig.c:1325: error: initializer element is not constant -wanconfig.c:1325: error: (near initialization for ‘sym_table[18].val’) -wanconfig.c:1326: error: ‘WANOPT_NODE’ undeclared here (not in a function) -wanconfig.c:1326: error: initializer element is not constant -wanconfig.c:1326: error: (near initialization for ‘sym_table[19].val’) -wanconfig.c:1327: error: ‘WANOPT_SECONDARY’ undeclared here (not in a function) -wanconfig.c:1327: error: initializer element is not constant -wanconfig.c:1327: error: (near initialization for ‘sym_table[20].val’) -wanconfig.c:1328: error: ‘WANOPT_PRIMARY’ undeclared here (not in a function) -wanconfig.c:1328: error: initializer element is not constant -wanconfig.c:1328: error: (near initialization for ‘sym_table[21].val’) -wanconfig.c:1330: error: ‘WANOPT_PERMANENT’ undeclared here (not in a function) -wanconfig.c:1330: error: initializer element is not constant -wanconfig.c:1330: error: (near initialization for ‘sym_table[22].val’) -wanconfig.c:1331: error: ‘WANOPT_SWITCHED’ undeclared here (not in a function) -wanconfig.c:1331: error: initializer element is not constant -wanconfig.c:1331: error: (near initialization for ‘sym_table[23].val’) -wanconfig.c:1332: error: ‘WANOPT_ONDEMAND’ undeclared here (not in a function) -wanconfig.c:1332: error: initializer element is not constant -wanconfig.c:1332: error: (near initialization for ‘sym_table[24].val’) -wanconfig.c:1334: error: ‘WANOPT_FR_ANSI’ undeclared here (not in a function) -wanconfig.c:1334: error: initializer element is not constant -wanconfig.c:1334: error: (near initialization for ‘sym_table[25].val’) -wanconfig.c:1335: error: ‘WANOPT_FR_Q933’ undeclared here (not in a function) -wanconfig.c:1335: error: initializer element is not constant -wanconfig.c:1335: error: (near initialization for ‘sym_table[26].val’) -wanconfig.c:1336: error: ‘WANOPT_FR_LMI’ undeclared here (not in a function) -wanconfig.c:1336: error: initializer element is not constant -wanconfig.c:1336: error: (near initialization for ‘sym_table[27].val’) -wanconfig.c:1337: error: ‘WANOPT_FR_NO_LMI’ undeclared here (not in a function) -wanconfig.c:1337: error: initializer element is not constant -wanconfig.c:1337: error: (near initialization for ‘sym_table[28].val’) -wanconfig.c:1339: error: ‘WANOPT_PPP_STATIC’ undeclared here (not in a function) -wanconfig.c:1339: error: initializer element is not constant -wanconfig.c:1339: error: (near initialization for ‘sym_table[29].val’) -wanconfig.c:1340: error: ‘WANOPT_PPP_HOST’ undeclared here (not in a function) -wanconfig.c:1340: error: initializer element is not constant -wanconfig.c:1340: error: (near initialization for ‘sym_table[30].val’) -wanconfig.c:1341: error: ‘WANOPT_PPP_PEER’ undeclared here (not in a function) -wanconfig.c:1341: error: initializer element is not constant -wanconfig.c:1341: error: (near initialization for ‘sym_table[31].val’) -wanconfig.c:1347: error: ‘WANOPT_PRI’ undeclared here (not in a function) -wanconfig.c:1347: error: initializer element is not constant -wanconfig.c:1347: error: (near initialization for ‘sym_table[32].val’) -wanconfig.c:1348: error: ‘WANOPT_SEC’ undeclared here (not in a function) -wanconfig.c:1348: error: initializer element is not constant -wanconfig.c:1348: error: (near initialization for ‘sym_table[33].val’) -wanconfig.c:1351: error: ‘WANOPT_INTR’ undeclared here (not in a function) -wanconfig.c:1351: error: initializer element is not constant -wanconfig.c:1351: error: (near initialization for ‘sym_table[34].val’) -wanconfig.c:1352: error: ‘WANOPT_POLL’ undeclared here (not in a function) -wanconfig.c:1352: error: initializer element is not constant -wanconfig.c:1352: error: (near initialization for ‘sym_table[35].val’) -wanconfig.c:1354: error: ‘WANOPT_ONE’ undeclared here (not in a function) -wanconfig.c:1354: error: initializer element is not constant -wanconfig.c:1354: error: (near initialization for ‘sym_table[36].val’) -wanconfig.c:1355: error: ‘WANOPT_TWO’ undeclared here (not in a function) -wanconfig.c:1355: error: initializer element is not constant -wanconfig.c:1355: error: (near initialization for ‘sym_table[37].val’) -wanconfig.c:1356: error: ‘WANOPT_ONE_AND_HALF’ undeclared here (not in a function) -wanconfig.c:1356: error: initializer element is not constant -wanconfig.c:1356: error: (near initialization for ‘sym_table[38].val’) -wanconfig.c:1357: error: ‘WANOPT_NONE’ undeclared here (not in a function) -wanconfig.c:1357: error: initializer element is not constant -wanconfig.c:1357: error: (near initialization for ‘sym_table[39].val’) -wanconfig.c:1358: error: ‘WANOPT_EVEN’ undeclared here (not in a function) -wanconfig.c:1358: error: initializer element is not constant -wanconfig.c:1358: error: (near initialization for ‘sym_table[40].val’) -wanconfig.c:1359: error: ‘WANOPT_ODD’ undeclared here (not in a function) -wanconfig.c:1359: error: initializer element is not constant -wanconfig.c:1359: error: (near initialization for ‘sym_table[41].val’) -wanconfig.c:1361: error: ‘WANOPT_TTY_SYNC’ undeclared here (not in a function) -wanconfig.c:1361: error: initializer element is not constant -wanconfig.c:1361: error: (near initialization for ‘sym_table[42].val’) -wanconfig.c:1362: error: ‘WANOPT_TTY_ASYNC’ undeclared here (not in a function) -wanconfig.c:1362: error: initializer element is not constant -wanconfig.c:1362: error: (near initialization for ‘sym_table[43].val’) -wanconfig.c:1365: error: ‘WANOPT_FR_EEK_REQUEST’ undeclared here (not in a function) -wanconfig.c:1365: error: initializer element is not constant -wanconfig.c:1365: error: (near initialization for ‘sym_table[44].val’) -wanconfig.c:1366: error: ‘WANOPT_FR_EEK_REPLY’ undeclared here (not in a function) -wanconfig.c:1366: error: initializer element is not constant -wanconfig.c:1366: error: (near initialization for ‘sym_table[45].val’) -wanconfig.c:1372: error: ‘WAN_MEDIA_T1’ undeclared here (not in a function) -wanconfig.c:1372: error: initializer element is not constant -wanconfig.c:1372: error: (near initialization for ‘sym_table[46].val’) -wanconfig.c:1373: error: ‘WAN_MEDIA_E1’ undeclared here (not in a function) -wanconfig.c:1373: error: initializer element is not constant -wanconfig.c:1373: error: (near initialization for ‘sym_table[47].val’) -wanconfig.c:1374: error: ‘WAN_MEDIA_J1’ undeclared here (not in a function) -wanconfig.c:1374: error: initializer element is not constant -wanconfig.c:1374: error: (near initialization for ‘sym_table[48].val’) -wanconfig.c:1375: error: ‘WAN_MEDIA_56K’ undeclared here (not in a function) -wanconfig.c:1375: error: initializer element is not constant -wanconfig.c:1375: error: (near initialization for ‘sym_table[49].val’) -wanconfig.c:1376: error: ‘WAN_MEDIA_DS3’ undeclared here (not in a function) -wanconfig.c:1376: error: initializer element is not constant -wanconfig.c:1376: error: (near initialization for ‘sym_table[50].val’) -wanconfig.c:1377: error: ‘WAN_MEDIA_STS1’ undeclared here (not in a function) -wanconfig.c:1377: error: initializer element is not constant -wanconfig.c:1377: error: (near initialization for ‘sym_table[51].val’) -wanconfig.c:1378: error: ‘WAN_MEDIA_E3’ undeclared here (not in a function) -wanconfig.c:1378: error: initializer element is not constant -wanconfig.c:1378: error: (near initialization for ‘sym_table[52].val’) -wanconfig.c:1379: error: ‘WAN_MEDIA_FXOFXS’ undeclared here (not in a function) -wanconfig.c:1379: error: initializer element is not constant -wanconfig.c:1379: error: (near initialization for ‘sym_table[53].val’) -wanconfig.c:1380: error: ‘WAN_LCODE_AMI’ undeclared here (not in a function) -wanconfig.c:1380: error: initializer element is not constant -wanconfig.c:1380: error: (near initialization for ‘sym_table[54].val’) -wanconfig.c:1381: error: ‘WAN_LCODE_B8ZS’ undeclared here (not in a function) -wanconfig.c:1381: error: initializer element is not constant -wanconfig.c:1381: error: (near initialization for ‘sym_table[55].val’) -wanconfig.c:1382: error: ‘WAN_LCODE_HDB3’ undeclared here (not in a function) -wanconfig.c:1382: error: initializer element is not constant -wanconfig.c:1382: error: (near initialization for ‘sym_table[56].val’) -wanconfig.c:1383: error: ‘WAN_LCODE_B3ZS’ undeclared here (not in a function) -wanconfig.c:1383: error: initializer element is not constant -wanconfig.c:1383: error: (near initialization for ‘sym_table[57].val’) -wanconfig.c:1384: error: ‘WAN_FR_D4’ undeclared here (not in a function) -wanconfig.c:1384: error: initializer element is not constant -wanconfig.c:1384: error: (near initialization for ‘sym_table[58].val’) -wanconfig.c:1385: error: ‘WAN_FR_ESF’ undeclared here (not in a function) -wanconfig.c:1385: error: initializer element is not constant -wanconfig.c:1385: error: (near initialization for ‘sym_table[59].val’) -wanconfig.c:1386: error: ‘WAN_FR_NCRC4’ undeclared here (not in a function) -wanconfig.c:1386: error: initializer element is not constant -wanconfig.c:1386: error: (near initialization for ‘sym_table[60].val’) -wanconfig.c:1387: error: ‘WAN_FR_CRC4’ undeclared here (not in a function) -wanconfig.c:1387: error: initializer element is not constant -wanconfig.c:1387: error: (near initialization for ‘sym_table[61].val’) -wanconfig.c:1388: error: ‘WAN_FR_UNFRAMED’ undeclared here (not in a function) -wanconfig.c:1388: error: initializer element is not constant -wanconfig.c:1388: error: (near initialization for ‘sym_table[62].val’) -wanconfig.c:1389: error: ‘WAN_FR_E3_G751’ undeclared here (not in a function) -wanconfig.c:1389: error: initializer element is not constant -wanconfig.c:1389: error: (near initialization for ‘sym_table[63].val’) -wanconfig.c:1390: error: ‘WAN_FR_E3_G832’ undeclared here (not in a function) -wanconfig.c:1390: error: initializer element is not constant -wanconfig.c:1390: error: (near initialization for ‘sym_table[64].val’) -wanconfig.c:1391: error: ‘WAN_FR_DS3_Cbit’ undeclared here (not in a function) -wanconfig.c:1391: error: initializer element is not constant -wanconfig.c:1391: error: (near initialization for ‘sym_table[65].val’) -wanconfig.c:1392: error: ‘WAN_FR_DS3_M13’ undeclared here (not in a function) -wanconfig.c:1392: error: initializer element is not constant -wanconfig.c:1392: error: (near initialization for ‘sym_table[66].val’) -wanconfig.c:1393: error: ‘WAN_T1_LBO_0_DB’ undeclared here (not in a function) -wanconfig.c:1393: error: initializer element is not constant -wanconfig.c:1393: error: (near initialization for ‘sym_table[67].val’) -wanconfig.c:1394: error: ‘WAN_T1_LBO_75_DB’ undeclared here (not in a function) -wanconfig.c:1394: error: initializer element is not constant -wanconfig.c:1394: error: (near initialization for ‘sym_table[68].val’) -wanconfig.c:1395: error: ‘WAN_T1_LBO_15_DB’ undeclared here (not in a function) -wanconfig.c:1395: error: initializer element is not constant -wanconfig.c:1395: error: (near initialization for ‘sym_table[69].val’) -wanconfig.c:1396: error: ‘WAN_T1_LBO_225_DB’ undeclared here (not in a function) -wanconfig.c:1396: error: initializer element is not constant -wanconfig.c:1396: error: (near initialization for ‘sym_table[70].val’) -wanconfig.c:1397: error: ‘WAN_T1_0_110’ undeclared here (not in a function) -wanconfig.c:1397: error: initializer element is not constant -wanconfig.c:1397: error: (near initialization for ‘sym_table[71].val’) -wanconfig.c:1398: error: ‘WAN_T1_110_220’ undeclared here (not in a function) -wanconfig.c:1398: error: initializer element is not constant -wanconfig.c:1398: error: (near initialization for ‘sym_table[72].val’) -wanconfig.c:1399: error: ‘WAN_T1_220_330’ undeclared here (not in a function) -wanconfig.c:1399: error: initializer element is not constant -wanconfig.c:1399: error: (near initialization for ‘sym_table[73].val’) -wanconfig.c:1400: error: ‘WAN_T1_330_440’ undeclared here (not in a function) -wanconfig.c:1400: error: initializer element is not constant -wanconfig.c:1400: error: (near initialization for ‘sym_table[74].val’) -wanconfig.c:1401: error: ‘WAN_T1_440_550’ undeclared here (not in a function) -wanconfig.c:1401: error: initializer element is not constant -wanconfig.c:1401: error: (near initialization for ‘sym_table[75].val’) -wanconfig.c:1402: error: ‘WAN_T1_550_660’ undeclared here (not in a function) -wanconfig.c:1402: error: initializer element is not constant -wanconfig.c:1402: error: (near initialization for ‘sym_table[76].val’) -wanconfig.c:1403: error: ‘WAN_T1_0_133’ undeclared here (not in a function) -wanconfig.c:1403: error: initializer element is not constant -wanconfig.c:1403: error: (near initialization for ‘sym_table[77].val’) -wanconfig.c:1404: error: ‘WAN_T1_133_266’ undeclared here (not in a function) -wanconfig.c:1404: error: initializer element is not constant -wanconfig.c:1404: error: (near initialization for ‘sym_table[78].val’) -wanconfig.c:1405: error: ‘WAN_T1_266_399’ undeclared here (not in a function) -wanconfig.c:1405: error: initializer element is not constant -wanconfig.c:1405: error: (near initialization for ‘sym_table[79].val’) -wanconfig.c:1406: error: ‘WAN_T1_399_533’ undeclared here (not in a function) -wanconfig.c:1406: error: initializer element is not constant -wanconfig.c:1406: error: (near initialization for ‘sym_table[80].val’) -wanconfig.c:1407: error: ‘WAN_T1_533_655’ undeclared here (not in a function) -wanconfig.c:1407: error: initializer element is not constant -wanconfig.c:1407: error: (near initialization for ‘sym_table[81].val’) -wanconfig.c:1408: error: ‘WAN_E1_120’ undeclared here (not in a function) -wanconfig.c:1408: error: initializer element is not constant -wanconfig.c:1408: error: (near initialization for ‘sym_table[82].val’) -wanconfig.c:1409: error: ‘WAN_E1_75’ undeclared here (not in a function) -wanconfig.c:1409: error: initializer element is not constant -wanconfig.c:1409: error: (near initialization for ‘sym_table[83].val’) -wanconfig.c:1410: error: ‘WAN_NORMAL_CLK’ undeclared here (not in a function) -wanconfig.c:1410: error: initializer element is not constant -wanconfig.c:1410: error: (near initialization for ‘sym_table[84].val’) -wanconfig.c:1411: error: ‘WAN_MASTER_CLK’ undeclared here (not in a function) -wanconfig.c:1411: error: initializer element is not constant -wanconfig.c:1411: error: (near initialization for ‘sym_table[85].val’) -wanconfig.c:1412: error: ‘WANOPT_FE_OSC_CLOCK’ undeclared here (not in a function) -wanconfig.c:1412: error: initializer element is not constant -wanconfig.c:1412: error: (near initialization for ‘sym_table[86].val’) -wanconfig.c:1413: error: ‘WANOPT_FE_LINE_CLOCK’ undeclared here (not in a function) -wanconfig.c:1413: error: initializer element is not constant -wanconfig.c:1413: error: (near initialization for ‘sym_table[87].val’) -wanconfig.c:1414: error: ‘WAN_TE1_SIG_CAS’ undeclared here (not in a function) -wanconfig.c:1414: error: initializer element is not constant -wanconfig.c:1414: error: (near initialization for ‘sym_table[88].val’) -wanconfig.c:1415: error: ‘WAN_TE1_SIG_CCS’ undeclared here (not in a function) -wanconfig.c:1415: error: initializer element is not constant -wanconfig.c:1415: error: (near initialization for ‘sym_table[89].val’) -wanconfig.c:1418: error: ‘WAN_TE3_RDEVICE_ADTRAN’ undeclared here (not in a function) -wanconfig.c:1418: error: initializer element is not constant -wanconfig.c:1418: error: (near initialization for ‘sym_table[90].val’) -wanconfig.c:1419: error: ‘WAN_TE3_RDEVICE_DIGITALLINK’ undeclared here (not in a function) -wanconfig.c:1419: error: initializer element is not constant -wanconfig.c:1419: error: (near initialization for ‘sym_table[91].val’) -wanconfig.c:1420: error: ‘WAN_TE3_RDEVICE_KENTROX’ undeclared here (not in a function) -wanconfig.c:1420: error: initializer element is not constant -wanconfig.c:1420: error: (near initialization for ‘sym_table[92].val’) -wanconfig.c:1421: error: ‘WAN_TE3_RDEVICE_LARSCOM’ undeclared here (not in a function) -wanconfig.c:1421: error: initializer element is not constant -wanconfig.c:1421: error: (near initialization for ‘sym_table[93].val’) -wanconfig.c:1422: error: ‘WAN_TE3_RDEVICE_VERILINK’ undeclared here (not in a function) -wanconfig.c:1422: error: initializer element is not constant -wanconfig.c:1422: error: (near initialization for ‘sym_table[94].val’) -wanconfig.c:1423: error: ‘WAN_TE3_LIU_LB_NORMAL’ undeclared here (not in a function) -wanconfig.c:1423: error: initializer element is not constant -wanconfig.c:1423: error: (near initialization for ‘sym_table[95].val’) -wanconfig.c:1424: error: ‘WAN_TE3_LIU_LB_ANALOG’ undeclared here (not in a function) -wanconfig.c:1424: error: initializer element is not constant -wanconfig.c:1424: error: (near initialization for ‘sym_table[96].val’) -wanconfig.c:1425: error: ‘WAN_TE3_LIU_LB_REMOTE’ undeclared here (not in a function) -wanconfig.c:1425: error: initializer element is not constant -wanconfig.c:1425: error: (near initialization for ‘sym_table[97].val’) -wanconfig.c:1426: error: ‘WAN_TE3_LIU_LB_DIGITAL’ undeclared here (not in a function) -wanconfig.c:1426: error: initializer element is not constant -wanconfig.c:1426: error: (near initialization for ‘sym_table[98].val’) -wanconfig.c:1428: error: initializer element is not constant -wanconfig.c:1428: error: (near initialization for ‘sym_table[99].val’) -wanconfig.c:1429: error: initializer element is not constant -wanconfig.c:1429: error: (near initialization for ‘sym_table[100].val’) -wanconfig.c:1430: error: initializer element is not constant -wanconfig.c:1430: error: (near initialization for ‘sym_table[101].val’) -wanconfig.c:1431: error: ‘WANCONFIG_LAPB’ undeclared here (not in a function) -wanconfig.c:1431: error: initializer element is not constant -wanconfig.c:1431: error: (near initialization for ‘sym_table[102].val’) -wanconfig.c:1432: error: ‘WANCONFIG_XDLC’ undeclared here (not in a function) -wanconfig.c:1432: error: initializer element is not constant -wanconfig.c:1432: error: (near initialization for ‘sym_table[103].val’) -wanconfig.c:1433: error: ‘WANCONFIG_TTY’ undeclared here (not in a function) -wanconfig.c:1433: error: initializer element is not constant -wanconfig.c:1433: error: (near initialization for ‘sym_table[104].val’) -wanconfig.c:1434: error: initializer element is not constant -wanconfig.c:1434: error: (near initialization for ‘sym_table[105].val’) -wanconfig.c:1435: error: initializer element is not constant -wanconfig.c:1435: error: (near initialization for ‘sym_table[106].val’) -wanconfig.c:1436: error: initializer element is not constant -wanconfig.c:1436: error: (near initialization for ‘sym_table[107].val’) -wanconfig.c:1437: error: ‘WANCONFIG_XMTP2’ undeclared here (not in a function) -wanconfig.c:1437: error: initializer element is not constant -wanconfig.c:1437: error: (near initialization for ‘sym_table[108].val’) -wanconfig.c:1438: error: ‘WANCONFIG_LAPD’ undeclared here (not in a function) -wanconfig.c:1438: error: initializer element is not constant -wanconfig.c:1438: error: (near initialization for ‘sym_table[109].val’) -wanconfig.c:1439: error: initializer element is not constant -wanconfig.c:1439: error: (near initialization for ‘sym_table[110].val’) -wanconfig.c:1440: error: initializer element is not constant -wanconfig.c:1440: error: (near initialization for ‘sym_table[111].val’) -wanconfig.c:1441: error: initializer element is not constant -wanconfig.c:1441: error: (near initialization for ‘sym_table[112].val’) -wanconfig.c:1442: error: initializer element is not constant -wanconfig.c:1442: error: (near initialization for ‘sym_table[113].val’) -wanconfig.c:1443: error: initializer element is not constant -wanconfig.c:1443: error: (near initialization for ‘sym_table[114].val’) -wanconfig.c:1446: error: ‘WANOPT_SS7_ANSI’ undeclared here (not in a function) -wanconfig.c:1446: error: initializer element is not constant -wanconfig.c:1446: error: (near initialization for ‘sym_table[115].val’) -wanconfig.c:1447: error: ‘WANOPT_SS7_ITU’ undeclared here (not in a function) -wanconfig.c:1447: error: initializer element is not constant -wanconfig.c:1447: error: (near initialization for ‘sym_table[116].val’) -wanconfig.c:1448: error: ‘WANOPT_SS7_NTT’ undeclared here (not in a function) -wanconfig.c:1448: error: initializer element is not constant -wanconfig.c:1448: error: (near initialization for ‘sym_table[117].val’) -wanconfig.c:1450: error: ‘WANOPT_SS7_FISU’ undeclared here (not in a function) -wanconfig.c:1450: error: initializer element is not constant -wanconfig.c:1450: error: (near initialization for ‘sym_table[118].val’) -wanconfig.c:1451: error: ‘WANOPT_SS7_LSSU’ undeclared here (not in a function) -wanconfig.c:1451: error: initializer element is not constant -wanconfig.c:1451: error: (near initialization for ‘sym_table[119].val’) -wanconfig.c:1453: error: ‘WANOPT_SS7_MODE_128’ undeclared here (not in a function) -wanconfig.c:1453: error: initializer element is not constant -wanconfig.c:1453: error: (near initialization for ‘sym_table[120].val’) -wanconfig.c:1454: error: ‘WANOPT_SS7_MODE_4096’ undeclared here (not in a function) -wanconfig.c:1454: error: initializer element is not constant -wanconfig.c:1454: error: (near initialization for ‘sym_table[121].val’) -wanconfig.c:1456: error: ‘WANOPT_S50X’ undeclared here (not in a function) -wanconfig.c:1456: error: initializer element is not constant -wanconfig.c:1456: error: (near initialization for ‘sym_table[122].val’) -wanconfig.c:1457: error: ‘WANOPT_S51X’ undeclared here (not in a function) -wanconfig.c:1457: error: initializer element is not constant -wanconfig.c:1457: error: (near initialization for ‘sym_table[123].val’) -wanconfig.c:1458: error: ‘WANOPT_ADSL’ undeclared here (not in a function) -wanconfig.c:1458: error: initializer element is not constant -wanconfig.c:1458: error: (near initialization for ‘sym_table[124].val’) -wanconfig.c:1459: error: initializer element is not constant -wanconfig.c:1459: error: (near initialization for ‘sym_table[125].val’) -wanconfig.c:1460: error: ‘WANOPT_AFT’ undeclared here (not in a function) -wanconfig.c:1460: error: initializer element is not constant -wanconfig.c:1460: error: (near initialization for ‘sym_table[126].val’) -wanconfig.c:1463: error: ‘RFC_MODE_BRIDGED_ETH_LLC’ undeclared here (not in a function) -wanconfig.c:1463: error: initializer element is not constant -wanconfig.c:1463: error: (near initialization for ‘sym_table[127].val’) -wanconfig.c:1464: error: ‘RFC_MODE_BRIDGED_ETH_VC’ undeclared here (not in a function) -wanconfig.c:1464: error: initializer element is not constant -wanconfig.c:1464: error: (near initialization for ‘sym_table[128].val’) -wanconfig.c:1465: error: ‘RFC_MODE_ROUTED_IP_LLC’ undeclared here (not in a function) -wanconfig.c:1465: error: initializer element is not constant -wanconfig.c:1465: error: (near initialization for ‘sym_table[129].val’) -wanconfig.c:1466: error: ‘RFC_MODE_ROUTED_IP_VC’ undeclared here (not in a function) -wanconfig.c:1466: error: initializer element is not constant -wanconfig.c:1466: error: (near initialization for ‘sym_table[130].val’) -wanconfig.c:1467: error: ‘RFC_MODE_PPP_LLC’ undeclared here (not in a function) -wanconfig.c:1467: error: initializer element is not constant -wanconfig.c:1467: error: (near initialization for ‘sym_table[131].val’) -wanconfig.c:1468: error: ‘RFC_MODE_PPP_VC’ undeclared here (not in a function) -wanconfig.c:1468: error: initializer element is not constant -wanconfig.c:1468: error: (near initialization for ‘sym_table[132].val’) -wanconfig.c:1469: error: ‘RFC_MODE_STACK_VC’ undeclared here (not in a function) -wanconfig.c:1469: error: initializer element is not constant -wanconfig.c:1469: error: (near initialization for ‘sym_table[133].val’) -wanconfig.c:1472: error: initializer element is not constant -wanconfig.c:1472: error: (near initialization for ‘sym_table[134].val’) -wanconfig.c:1473: error: initializer element is not constant -wanconfig.c:1473: error: (near initialization for ‘sym_table[135].val’) -wanconfig.c:1474: error: ‘LAN_INTERFACE’ undeclared here (not in a function) -wanconfig.c:1474: error: initializer element is not constant -wanconfig.c:1474: error: (near initialization for ‘sym_table[136].val’) -wanconfig.c:1475: error: ‘WAN_INTERFACE’ undeclared here (not in a function) -wanconfig.c:1475: error: initializer element is not constant -wanconfig.c:1475: error: (near initialization for ‘sym_table[137].val’) -wanconfig.c:1477: error: ‘WANOPT_ADSL_T1_413’ undeclared here (not in a function) -wanconfig.c:1477: error: initializer element is not constant -wanconfig.c:1477: error: (near initialization for ‘sym_table[138].val’) -wanconfig.c:1478: error: ‘WANOPT_ADSL_G_LITE’ undeclared here (not in a function) -wanconfig.c:1478: error: initializer element is not constant -wanconfig.c:1478: error: (near initialization for ‘sym_table[139].val’) -wanconfig.c:1479: error: ‘WANOPT_ADSL_G_DMT’ undeclared here (not in a function) -wanconfig.c:1479: error: initializer element is not constant -wanconfig.c:1479: error: (near initialization for ‘sym_table[140].val’) -wanconfig.c:1480: error: ‘WANOPT_ADSL_ALCATEL_1_4’ undeclared here (not in a function) -wanconfig.c:1480: error: initializer element is not constant -wanconfig.c:1480: error: (near initialization for ‘sym_table[141].val’) -wanconfig.c:1481: error: ‘WANOPT_ADSL_ALCATEL’ undeclared here (not in a function) -wanconfig.c:1481: error: initializer element is not constant -wanconfig.c:1481: error: (near initialization for ‘sym_table[142].val’) -wanconfig.c:1482: error: ‘WANOPT_ADSL_MULTIMODE’ undeclared here (not in a function) -wanconfig.c:1482: error: initializer element is not constant -wanconfig.c:1482: error: (near initialization for ‘sym_table[143].val’) -wanconfig.c:1483: error: ‘WANOPT_ADSL_T1_413_AUTO’ undeclared here (not in a function) -wanconfig.c:1483: error: initializer element is not constant -wanconfig.c:1483: error: (near initialization for ‘sym_table[144].val’) -wanconfig.c:1484: error: ‘WANOPT_ADSL_TRELLIS_ENABLE’ undeclared here (not in a function) -wanconfig.c:1484: error: initializer element is not constant -wanconfig.c:1484: error: (near initialization for ‘sym_table[145].val’) -wanconfig.c:1485: error: ‘WANOPT_ADSL_TRELLIS_DISABLE’ undeclared here (not in a function) -wanconfig.c:1485: error: initializer element is not constant -wanconfig.c:1485: error: (near initialization for ‘sym_table[146].val’) -wanconfig.c:1486: error: ‘WANOPT_ADSL_TRELLIS_LITE_ONLY_DISABLE’ undeclared here (not in a function) -wanconfig.c:1486: error: initializer element is not constant -wanconfig.c:1486: error: (near initialization for ‘sym_table[147].val’) -wanconfig.c:1487: error: ‘WANOPT_ADSL_0DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1487: error: initializer element is not constant -wanconfig.c:1487: error: (near initialization for ‘sym_table[148].val’) -wanconfig.c:1488: error: ‘WANOPT_ADSL_1DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1488: error: initializer element is not constant -wanconfig.c:1488: error: (near initialization for ‘sym_table[149].val’) -wanconfig.c:1489: error: ‘WANOPT_ADSL_2DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1489: error: initializer element is not constant -wanconfig.c:1489: error: (near initialization for ‘sym_table[150].val’) -wanconfig.c:1490: error: ‘WANOPT_ADSL_3DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1490: error: initializer element is not constant -wanconfig.c:1490: error: (near initialization for ‘sym_table[151].val’) -wanconfig.c:1491: error: ‘WANOPT_ADSL_4DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1491: error: initializer element is not constant -wanconfig.c:1491: error: (near initialization for ‘sym_table[152].val’) -wanconfig.c:1492: error: ‘WANOPT_ADSL_5DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1492: error: initializer element is not constant -wanconfig.c:1492: error: (near initialization for ‘sym_table[153].val’) -wanconfig.c:1493: error: ‘WANOPT_ADSL_6DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1493: error: initializer element is not constant -wanconfig.c:1493: error: (near initialization for ‘sym_table[154].val’) -wanconfig.c:1494: error: ‘WANOPT_ADSL_7DB_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1494: error: initializer element is not constant -wanconfig.c:1494: error: (near initialization for ‘sym_table[155].val’) -wanconfig.c:1495: error: ‘WANOPT_ADSL_AUTO_CODING_GAIN’ undeclared here (not in a function) -wanconfig.c:1495: error: initializer element is not constant -wanconfig.c:1495: error: (near initialization for ‘sym_table[156].val’) -wanconfig.c:1496: error: ‘WANOPT_ADSL_RX_BIN_DISABLE’ undeclared here (not in a function) -wanconfig.c:1496: error: initializer element is not constant -wanconfig.c:1496: error: (near initialization for ‘sym_table[157].val’) -wanconfig.c:1497: error: ‘WANOPT_ADSL_RX_BIN_ENABLE’ undeclared here (not in a function) -wanconfig.c:1497: error: initializer element is not constant -wanconfig.c:1497: error: (near initialization for ‘sym_table[158].val’) -wanconfig.c:1498: error: ‘WANOPT_ADSL_FRAMING_TYPE_0’ undeclared here (not in a function) -wanconfig.c:1498: error: initializer element is not constant -wanconfig.c:1498: error: (near initialization for ‘sym_table[159].val’) -wanconfig.c:1499: error: ‘WANOPT_ADSL_FRAMING_TYPE_1’ undeclared here (not in a function) -wanconfig.c:1499: error: initializer element is not constant -wanconfig.c:1499: error: (near initialization for ‘sym_table[160].val’) -wanconfig.c:1500: error: ‘WANOPT_ADSL_FRAMING_TYPE_2’ undeclared here (not in a function) -wanconfig.c:1500: error: initializer element is not constant -wanconfig.c:1500: error: (near initialization for ‘sym_table[161].val’) -wanconfig.c:1501: error: ‘WANOPT_ADSL_FRAMING_TYPE_3’ undeclared here (not in a function) -wanconfig.c:1501: error: initializer element is not constant -wanconfig.c:1501: error: (near initialization for ‘sym_table[162].val’) -wanconfig.c:1502: error: ‘WANOPT_ADSL_EXPANDED_EXCHANGE’ undeclared here (not in a function) -wanconfig.c:1502: error: initializer element is not constant -wanconfig.c:1502: error: (near initialization for ‘sym_table[163].val’) -wanconfig.c:1503: error: ‘WANOPT_ADSL_SHORT_EXCHANGE’ undeclared here (not in a function) -wanconfig.c:1503: error: initializer element is not constant -wanconfig.c:1503: error: (near initialization for ‘sym_table[164].val’) -wanconfig.c:1504: error: ‘WANOPT_ADSL_CLOCK_CRYSTAL’ undeclared here (not in a function) -wanconfig.c:1504: error: initializer element is not constant -wanconfig.c:1504: error: (near initialization for ‘sym_table[165].val’) -wanconfig.c:1505: error: ‘WANOPT_ADSL_CLOCK_OSCILLATOR’ undeclared here (not in a function) -wanconfig.c:1505: error: initializer element is not constant -wanconfig.c:1505: error: (near initialization for ‘sym_table[166].val’) -wanconfig.c:1507: error: ‘IBM4680’ undeclared here (not in a function) -wanconfig.c:1507: error: initializer element is not constant -wanconfig.c:1507: error: (near initialization for ‘sym_table[167].val’) -wanconfig.c:1508: error: initializer element is not constant -wanconfig.c:1508: error: (near initialization for ‘sym_table[168].val’) -wanconfig.c:1509: error: ‘NCR2126’ undeclared here (not in a function) -wanconfig.c:1509: error: initializer element is not constant -wanconfig.c:1509: error: (near initialization for ‘sym_table[169].val’) -wanconfig.c:1510: error: ‘NCR2127’ undeclared here (not in a function) -wanconfig.c:1510: error: initializer element is not constant -wanconfig.c:1510: error: (near initialization for ‘sym_table[170].val’) -wanconfig.c:1511: error: ‘NCR1255’ undeclared here (not in a function) -wanconfig.c:1511: error: initializer element is not constant -wanconfig.c:1511: error: (near initialization for ‘sym_table[171].val’) -wanconfig.c:1512: error: ‘NCR7000’ undeclared here (not in a function) -wanconfig.c:1512: error: initializer element is not constant -wanconfig.c:1512: error: (near initialization for ‘sym_table[172].val’) -wanconfig.c:1513: error: ‘ICL’ undeclared here (not in a function) -wanconfig.c:1513: error: initializer element is not constant -wanconfig.c:1513: error: (near initialization for ‘sym_table[173].val’) -wanconfig.c:1518: error: ‘WANOPT_DSP_HPAD’ undeclared here (not in a function) -wanconfig.c:1518: error: initializer element is not constant -wanconfig.c:1518: error: (near initialization for ‘sym_table[174].val’) -wanconfig.c:1519: error: ‘WANOPT_DSP_TPAD’ undeclared here (not in a function) -wanconfig.c:1519: error: initializer element is not constant -wanconfig.c:1519: error: (near initialization for ‘sym_table[175].val’) -wanconfig.c:1521: error: ‘WANOPT_AUTO’ undeclared here (not in a function) -wanconfig.c:1521: error: initializer element is not constant -wanconfig.c:1521: error: (near initialization for ‘sym_table[176].val’) -wanconfig.c:1522: error: ‘WANOPT_MANUAL’ undeclared here (not in a function) -wanconfig.c:1522: error: initializer element is not constant -wanconfig.c:1522: error: (near initialization for ‘sym_table[177].val’) -wanconfig.c:1525: error: ‘WANOPT_TWO_WAY_ALTERNATE’ undeclared here (not in a function) -wanconfig.c:1525: error: initializer element is not constant -wanconfig.c:1525: error: (near initialization for ‘sym_table[178].val’) -wanconfig.c:1526: error: ‘WANOPT_TWO_WAY_SIMULTANEOUS’ undeclared here (not in a function) -wanconfig.c:1526: error: initializer element is not constant -wanconfig.c:1526: error: (near initialization for ‘sym_table[179].val’) -wanconfig.c:1527: error: ‘WANOPT_PRI_DISC_ON_NO_RESP’ undeclared here (not in a function) -wanconfig.c:1527: error: initializer element is not constant -wanconfig.c:1527: error: (near initialization for ‘sym_table[180].val’) -wanconfig.c:1528: error: ‘WANOPT_PRI_SNRM_ON_NO_RESP’ undeclared here (not in a function) -wanconfig.c:1528: error: initializer element is not constant -wanconfig.c:1528: error: (near initialization for ‘sym_table[181].val’) -wanconfig.c:1530: error: ‘WP_NONE’ undeclared here (not in a function) -wanconfig.c:1530: error: initializer element is not constant -wanconfig.c:1530: error: (near initialization for ‘sym_table[182].val’) -wanconfig.c:1531: error: ‘WP_SLINEAR’ undeclared here (not in a function) -wanconfig.c:1531: error: initializer element is not constant -wanconfig.c:1531: error: (near initialization for ‘sym_table[183].val’) -wanconfig.c:1533: error: ‘WAN_TDMV_ALAW’ undeclared here (not in a function) -wanconfig.c:1533: error: initializer element is not constant -wanconfig.c:1533: error: (near initialization for ‘sym_table[184].val’) -wanconfig.c:1534: error: ‘WAN_TDMV_MULAW’ undeclared here (not in a function) -wanconfig.c:1534: error: initializer element is not constant -wanconfig.c:1534: error: (near initialization for ‘sym_table[185].val’) -wanconfig.c: In function ‘main’: -wanconfig.c:1556: error: ‘WANPIPE_VERSION_BETA’ undeclared (first use in this function) -wanconfig.c:1556: error: (Each undeclared identifier is reported only once -wanconfig.c:1556: error: for each function it appears in.) -wanconfig.c:1558: error: ‘WANPIPE_VERSION’ undeclared (first use in this function) -wanconfig.c:1558: error: ‘WANPIPE_SUB_VERSION’ undeclared (first use in this function) -wanconfig.c:1558: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ -wanconfig.c:1558: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:1561: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ -wanconfig.c:1561: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:1632: error: ‘WANPIPE_COPYRIGHT_DATES’ undeclared (first use in this function) -wanconfig.c:1632: error: ‘WANPIPE_COMPANY’ undeclared (first use in this function) -wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ -wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:1632: warning: format ‘%s’ expects type ‘char *’, but argument 5 has type ‘struct look_up_t *’ -wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ -wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:1636: warning: format ‘%s’ expects type ‘char *’, but argument 5 has type ‘struct look_up_t *’ -wanconfig.c:1743: warning: comparison between pointer and integer -wanconfig.c:1745: warning: format ‘%d’ expects type ‘int’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:1749: warning: comparison between pointer and integer -wanconfig.c:1751: warning: format ‘%d’ expects type ‘int’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c: In function ‘startup’: -wanconfig.c:1934: warning: comparison between pointer and integer -wanconfig.c: In function ‘wp_shutdown’: -wanconfig.c:2011: warning: comparison between pointer and integer -wanconfig.c: In function ‘router_down’: -wanconfig.c:2033: error: size of array ‘filename’ has non-integer type -wanconfig.c:2037: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2037: error: ‘wandev_conf_t’ undeclared (first use in this function) -wanconfig.c:2037: warning: passing argument 1 of ‘malloc’ makes integer from pointer without a cast -wanconfig.c:2037: warning: statement with no effect -wanconfig.c:2038: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2047: warning: comparison between pointer and integer -wanconfig.c:2071: error: ‘ROUTER_DOWN’ undeclared (first use in this function) -wanconfig.c:2071: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2071: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:2093: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2093: error: ‘look_up_t’ has no member named ‘config_id’ -wanconfig.c:2094: warning: implicit declaration of function ‘update_adsl_vci_vpi_list’ -wanconfig.c:2094: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2094: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2094: error: request for member ‘adsl’ in something not a structure or union -wanconfig.c:2094: error: request for member ‘vcivpi_list’ in something not a structure or union -wanconfig.c:2095: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2095: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2095: error: request for member ‘adsl’ in something not a structure or union -wanconfig.c:2095: error: request for member ‘vcivpi_num’ in something not a structure or union -wanconfig.c:2098: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2099: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2099: warning: statement with no effect -wanconfig.c: In function ‘router_ifdel’: -wanconfig.c:2111: error: size of array ‘filename’ has non-integer type -wanconfig.c:2112: error: size of array ‘devicename’ has non-integer type -wanconfig.c:2118: warning: comparison between pointer and integer -wanconfig.c:2128: warning: comparison between pointer and integer -wanconfig.c:2148: error: ‘ROUTER_IFDEL’ undeclared (first use in this function) -wanconfig.c:2148: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c: In function ‘configure’: -wanconfig.c:2201: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2201: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2201: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2207: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c: In function ‘build_linkdef_list’: -wanconfig.c:2292: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2292: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2297: warning: passing argument 2 of ‘read_conf_section’ from incompatible pointer type -wanconfig.c:2299: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:2299: warning: statement with no effect -wanconfig.c: In function ‘build_chandef_list’: -wanconfig.c:2357: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2357: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2383: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:2388: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:2433: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:2439: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:2474: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:2475: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:2475: warning: assignment from incompatible pointer type -wanconfig.c:2477: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:2477: warning: statement with no effect -wanconfig.c:2481: error: ‘chan_def_t’ has no member named ‘link’ -wanconfig.c:2481: warning: statement with no effect -wanconfig.c: In function ‘configure_link’: -wanconfig.c:2498: error: size of array ‘filename’ has non-integer type -wanconfig.c:2511: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2512: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2512: error: ‘look_up_t’ has no member named ‘data’ -wanconfig.c:2512: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2512: error: ‘look_up_t’ has no member named ‘data’ -wanconfig.c:2513: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2514: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2514: warning: statement with no effect -wanconfig.c:2517: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2517: error: ‘wandev_conf_t’ undeclared (first use in this function) -wanconfig.c:2517: warning: passing argument 1 of ‘malloc’ makes integer from pointer without a cast -wanconfig.c:2517: warning: statement with no effect -wanconfig.c:2518: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2522: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2522: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast -wanconfig.c:2523: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2523: error: ‘look_up_t’ has no member named ‘magic’ -wanconfig.c:2523: error: ‘ROUTER_MAGIC’ undeclared (first use in this function) -wanconfig.c:2523: warning: statement with no effect -wanconfig.c:2524: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2524: error: ‘look_up_t’ has no member named ‘config_id’ -wanconfig.c:2524: warning: statement with no effect -wanconfig.c:2542: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2545: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2545: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2562: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:2572: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2572: error: ‘look_up_t’ has no member named ‘config_id’ -wanconfig.c:2578: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:2578: warning: assignment from incompatible pointer type -wanconfig.c:2591: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2591: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2591: error: request for member ‘fr’ in something not a structure or union -wanconfig.c:2591: error: request for member ‘dlci’ in something not a structure or union -wanconfig.c:2591: error: incompatible types in assignment -wanconfig.c:2591: warning: statement with no effect -wanconfig.c:2592: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2592: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2592: error: request for member ‘fr’ in something not a structure or union -wanconfig.c:2592: error: request for member ‘dlci’ in something not a structure or union -wanconfig.c:2592: error: invalid operands to binary > -wanconfig.c:2593: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2593: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2593: error: request for member ‘fr’ in something not a structure or union -wanconfig.c:2593: error: request for member ‘dlci’ in something not a structure or union -wanconfig.c:2593: error: incompatible types in assignment -wanconfig.c:2593: warning: statement with no effect -wanconfig.c:2603: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2603: error: ‘look_up_t’ has no member named ‘config_id’ -wanconfig.c:2604: warning: implicit declaration of function ‘read_adsl_vci_vpi_list’ -wanconfig.c:2604: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2604: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2604: error: request for member ‘adsl’ in something not a structure or union -wanconfig.c:2604: error: request for member ‘vcivpi_list’ in something not a structure or union -wanconfig.c:2605: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2605: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2605: error: request for member ‘adsl’ in something not a structure or union -wanconfig.c:2605: error: request for member ‘vcivpi_num’ in something not a structure or union -wanconfig.c:2621: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2621: error: ‘look_up_t’ has no member named ‘ft1’ -wanconfig.c:2621: warning: statement with no effect -wanconfig.c:2623: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2623: error: ‘look_up_t’ has no member named ‘ft1’ -wanconfig.c:2623: warning: statement with no effect -wanconfig.c:2628: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2628: error: ‘look_up_t’ has no member named ‘data’ -wanconfig.c:2628: warning: statement with no effect -wanconfig.c:2634: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:2634: warning: assignment from incompatible pointer type -wanconfig.c:2638: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2638: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2638: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2639: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2639: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2639: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2642: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2642: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2642: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2645: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2645: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2645: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2650: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2650: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2650: warning: passing argument 2 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:2658: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:2660: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2661: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2662: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2662: warning: statement with no effect -wanconfig.c:2664: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2664: error: ‘wanif_conf_t’ undeclared (first use in this function) -wanconfig.c:2664: warning: passing argument 1 of ‘malloc’ makes integer from pointer without a cast -wanconfig.c:2664: warning: statement with no effect -wanconfig.c:2665: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2670: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2670: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast -wanconfig.c:2671: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2671: error: ‘look_up_t’ has no member named ‘magic’ -wanconfig.c:2671: warning: statement with no effect -wanconfig.c:2672: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2672: error: ‘look_up_t’ has no member named ‘config_id’ -wanconfig.c:2672: warning: statement with no effect -wanconfig.c:2679: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2679: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2679: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c: In function ‘exec_link_cmd’: -wanconfig.c:2690: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2692: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ -wanconfig.c:2704: error: ‘ROUTER_VER’ undeclared (first use in this function) -wanconfig.c:2704: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:2708: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:2710: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:2756: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:2774: error: ‘ROUTER_SETUP’ undeclared (first use in this function) -wanconfig.c:2774: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:2774: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:2777: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:2779: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c: In function ‘configure_chan’: -wanconfig.c:2809: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2814: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2814: error: ‘look_up_t’ has no member named ‘name’ -wanconfig.c:2814: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2814: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2814: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2816: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2816: error: ‘look_up_t’ has no member named ‘addr’ -wanconfig.c:2816: error: ‘WAN_ADDRESS_SZ’ undeclared (first use in this function) -wanconfig.c:2816: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2816: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2819: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2819: error: ‘look_up_t’ has no member named ‘usedby’ -wanconfig.c:2819: error: ‘USED_BY_FIELD’ undeclared (first use in this function) -wanconfig.c:2819: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2819: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2823: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2823: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2825: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2825: error: ‘look_up_t’ has no member named ‘label’ -wanconfig.c:2825: error: ‘WAN_IF_LABEL_SZ’ undeclared (first use in this function) -wanconfig.c:2825: warning: passing argument 3 of ‘memcpy’ makes integer from pointer without a cast -wanconfig.c:2832: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2832: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2839: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2839: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2858: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2864: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2864: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2872: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2872: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2915: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2915: error: ‘look_up_t’ has no member named ‘u’ -wanconfig.c:2916: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c: In function ‘exec_chan_cmd’: -wanconfig.c:2938: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2940: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ -wanconfig.c:2953: error: ‘ROUTER_IFNEW’ undeclared (first use in this function) -wanconfig.c:2953: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2953: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:2955: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:2957: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:2970: error: ‘chan_def_t’ has no member named ‘link’ -wanconfig.c:2970: warning: initialization from incompatible pointer type -wanconfig.c:2973: warning: comparison between pointer and integer -wanconfig.c:2974: warning: comparison between pointer and integer -wanconfig.c:2975: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2975: error: ‘look_up_t’ has no member named ‘hwec’ -wanconfig.c:2975: error: request for member ‘enable’ in something not a structure or union -wanconfig.c:2977: warning: passing argument 1 of ‘config_hwec’ from incompatible pointer type -wanconfig.c:2984: warning: passing argument 1 of ‘enable_hwec’ from incompatible pointer type -wanconfig.c:2984: warning: passing argument 2 of ‘enable_hwec’ from incompatible pointer type -wanconfig.c:2986: warning: passing argument 1 of ‘release_hwec’ from incompatible pointer type -wanconfig.c:2996: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2996: error: ‘look_up_t’ has no member named ‘master’ -wanconfig.c:2996: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:2996: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:2998: error: ‘ROUTER_IFNEW_LAPB’ undeclared (first use in this function) -wanconfig.c:2998: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:2998: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:2999: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:3001: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:3014: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3014: error: ‘look_up_t’ has no member named ‘master’ -wanconfig.c:3014: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:3014: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:3016: error: ‘ROUTER_IFNEW_X25’ undeclared (first use in this function) -wanconfig.c:3016: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3016: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:3017: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:3019: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:3033: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3033: error: ‘look_up_t’ has no member named ‘master’ -wanconfig.c:3033: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:3033: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:3034: error: ‘ROUTER_IFNEW_DSP’ undeclared (first use in this function) -wanconfig.c:3034: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3034: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:3035: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:3037: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:3061: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3061: error: ‘look_up_t’ has no member named ‘master’ -wanconfig.c:3061: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:3061: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:3067: error: ‘ROUTER_IFNEW_LIP’ undeclared (first use in this function) -wanconfig.c:3067: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3067: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:3069: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:3071: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c: In function ‘conf_file_down’: -wanconfig.c:3820: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:3820: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:3822: warning: passing argument 1 of ‘router_down’ from incompatible pointer type -wanconfig.c:3795: warning: unused variable ‘devname’ -wanconfig.c: In function ‘has_config_changed’: -wanconfig.c:3909: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:3909: warning: assignment from incompatible pointer type -wanconfig.c:3910: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:3910: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:3910: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c: In function ‘free_device_link’: -wanconfig.c:3941: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:3941: warning: assignment from incompatible pointer type -wanconfig.c:3942: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:3942: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:3942: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:3955: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:3955: warning: assignment from incompatible pointer type -wanconfig.c:3957: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3958: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:3966: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:3966: warning: assignment from incompatible pointer type -wanconfig.c:3968: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:3968: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:3968: warning: statement with no effect -wanconfig.c:3970: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘struct look_up_t *’ -wanconfig.c:3971: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:3972: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c: In function ‘free_linkdefs’: -wanconfig.c:3999: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:3999: warning: assignment from incompatible pointer type -wanconfig.c:4001: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:4002: error: ‘chan_def_t’ has no member named ‘chanconf’ -wanconfig.c:4010: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:4011: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:4014: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:4014: warning: assignment from incompatible pointer type -wanconfig.c: In function ‘device_syncup’: -wanconfig.c:4034: warning: passing argument 2 of ‘has_config_changed’ from incompatible pointer type -wanconfig.c: In function ‘start_chan’: -wanconfig.c:4083: error: ‘chan_def_t’ has no member named ‘next’ -wanconfig.c:4083: warning: assignment from incompatible pointer type -wanconfig.c:4087: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4087: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4087: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:4088: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4088: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4088: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:4091: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4091: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4091: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:4094: warning: passing argument 1 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4094: warning: passing argument 2 of ‘__builtin_strncpy’ from incompatible pointer type -wanconfig.c:4094: warning: passing argument 3 of ‘__builtin_strncpy’ makes integer from pointer without a cast -wanconfig.c:4098: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4098: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4098: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4105: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c: In function ‘start_link’: -wanconfig.c:4150: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:4150: warning: assignment from incompatible pointer type -wanconfig.c:4151: warning: passing argument 2 of ‘has_config_changed’ from incompatible pointer type -wanconfig.c:4152: warning: passing argument 1 of ‘device_syncup’ from incompatible pointer type -wanconfig.c:4164: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:4164: warning: assignment from incompatible pointer type -wanconfig.c:4166: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4166: warning: passing argument 1 of ‘strlen’ from incompatible pointer type -wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4166: warning: passing argument 1 of ‘__builtin_strcmp’ from incompatible pointer type -wanconfig.c:4171: warning: pointer type mismatch in conditional expression -wanconfig.c:4171: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:4171: warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘void *’ -wanconfig.c:4175: warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘struct look_up_t *’ -wanconfig.c:4182: error: ‘link_def_t’ has no member named ‘linkconf’ -wanconfig.c:4182: error: ‘look_up_t’ has no member named ‘ft1’ -wanconfig.c:4182: warning: statement with no effect -wanconfig.c: In function ‘stop_link’: -wanconfig.c:4227: error: ‘link_def_t’ has no member named ‘next’ -wanconfig.c:4227: warning: assignment from incompatible pointer type -wanconfig.c:4232: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘struct look_up_t *’ -wanconfig.c:4234: warning: passing argument 1 of ‘router_down’ from incompatible pointer type -wanconfig.c: In function ‘debugging’: -wanconfig.c:4717: error: size of array ‘filename’ has non-integer type -wanconfig.c:4738: error: ‘union ’ has no member named ‘linkconf’ -wanconfig.c:4738: error: ‘wandev_conf_t’ undeclared (first use in this function) -wanconfig.c:4738: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast -wanconfig.c:4739: error: ‘union ’ has no member named ‘linkconf’ -wanconfig.c:4739: error: request for member ‘magic’ in something not a structure or union -wanconfig.c:4739: error: ‘ROUTER_MAGIC’ undeclared (first use in this function) -wanconfig.c:4739: warning: statement with no effect -wanconfig.c: In function ‘debug_read’: -wanconfig.c:4765: error: size of array ‘filename’ has non-integer type -wanconfig.c:4766: error: ‘wan_kernel_msg_t’ undeclared (first use in this function) -wanconfig.c:4766: warning: statement with no effect -wanconfig.c:4766: error: expected ‘;’ before ‘wan_kernel_msg’ -wanconfig.c:4787: error: ‘union ’ has no member named ‘linkconf’ -wanconfig.c:4787: error: ‘wandev_conf_t’ undeclared (first use in this function) -wanconfig.c:4787: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast -wanconfig.c:4788: error: ‘union ’ has no member named ‘linkconf’ -wanconfig.c:4788: error: request for member ‘magic’ in something not a structure or union -wanconfig.c:4788: error: ‘ROUTER_MAGIC’ undeclared (first use in this function) -wanconfig.c:4788: warning: statement with no effect -wanconfig.c:4794: error: ‘wan_kernel_msg’ undeclared (first use in this function) -wanconfig.c:4794: warning: passing argument 3 of ‘memset’ makes integer from pointer without a cast -wanconfig.c:4795: error: request for member ‘magic’ in something not a structure or union -wanconfig.c:4795: warning: statement with no effect -wanconfig.c:4796: error: request for member ‘max_len’ in something not a structure or union -wanconfig.c:4796: warning: statement with no effect -wanconfig.c:4797: error: request for member ‘data’ in something not a structure or union -wanconfig.c:4797: warning: statement with no effect -wanconfig.c:4798: error: request for member ‘data’ in something not a structure or union -wanconfig.c:4806: error: ‘ROUTER_DEBUG_READ’ undeclared (first use in this function) -wanconfig.c:4806: warning: passing argument 2 of ‘ioctl’ makes integer from pointer without a cast -wanconfig.c:4813: error: request for member ‘len’ in something not a structure or union -wanconfig.c:4815: error: request for member ‘len’ in something not a structure or union -wanconfig.c:4815: warning: comparison between pointer and integer -wanconfig.c:4816: error: request for member ‘data’ in something not a structure or union -wanconfig.c:4819: error: request for member ‘is_more’ in something not a structure or union -wanconfig.c:4828: error: request for member ‘data’ in something not a structure or union -wanconfig.c: At top level: -wanconfig.c:4834: error: expected ‘)’ before ‘*’ token -wanconfig.c:4870: error: expected ‘)’ before ‘*’ token -wanconfig.c: In function ‘parse_active_channel’: -wanconfig.c:4918: error: ‘ENABLE_ALL_CHANNELS’ undeclared (first use in this function) -wanconfig.c:4918: warning: return makes integer from pointer without a cast -make: *** [wanconfig] Error 1 diff --git a/util/wanconfig/wanconfig.c b/util/wanconfig/wanconfig.c index ef0e8d6..1007d3f 100644 --- a/util/wanconfig/wanconfig.c +++ b/util/wanconfig/wanconfig.c @@ -11,6 +11,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ---------------------------------------------------------------------------- +* Sep 25, 2007 Alex Feldman Verify return code from wanec client. +* Jun 25, 2007 David Rokhvarg Added support for AFT-ISDN BRI (A500) card. * Mar 29, 2007 David Rokhvarg Added support for AFT-56K card. * May 11, 2001 Alex Feldman Added T1/E1 support (TE1). * Apr 16, 2001 David Rokhvarg Added X25_SRC_ADDR and ACCEPT_CALLS_FROM to 'chan_conftab' @@ -68,10 +70,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -145,17 +147,19 @@ typedef struct data_buf /* General data buffer */ /* * Data types for configuration structure description tables. */ -#define DTYPE_INT 1 -#define DTYPE_UINT 2 -#define DTYPE_LONG 3 -#define DTYPE_ULONG 4 -#define DTYPE_SHORT 5 -#define DTYPE_USHORT 6 -#define DTYPE_CHAR 7 -#define DTYPE_UCHAR 8 -#define DTYPE_PTR 9 -#define DTYPE_STR 10 -#define DTYPE_FILENAME 11 +#define DTYPE_INT 1 +#define DTYPE_UINT 2 +#define DTYPE_LONG 3 +#define DTYPE_ULONG 4 +#define DTYPE_SHORT 5 +#define DTYPE_USHORT 6 +#define DTYPE_CHAR 7 +#define DTYPE_UCHAR 8 +#define DTYPE_PTR 9 +#define DTYPE_STR 10 +#define DTYPE_FILENAME 11 +#define DTYPE_OCT_FILENAME 12 +#define DTYPE_OCT_CHAN_CONF 13 #define NO_ANNEXG 0 #define ANNEXG_LAPB 1 @@ -236,10 +240,10 @@ int parse_conf_file (char* fname); int build_linkdef_list (FILE* file); int build_chandef_list (FILE* file); char* read_conf_section (FILE* file, char* section); -int read_conf_record (FILE* file, char* key); +int read_conf_record (FILE* file, char* key, int max_len); int configure_link (link_def_t* def, char init); int configure_chan (int dev, chan_def_t* def, char init, int id); -int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf); +int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf, int max_len); void init_first_time_tokens(char **token); void init_tokens(char **token); int tokenize (char* str, char **tokens); @@ -248,6 +252,7 @@ char* strupcase (char* str); void* lookup (int val, look_up_t* table); int name2val (char* name, look_up_t* table); int read_data_file (char* name, data_buf_t* databuf); +int read_oct_chan_config(char*, char*, wan_custom_conf_t *conf); unsigned long filesize (FILE* file); unsigned int dec_to_uint (char* str, int len); unsigned int get_config_data (int, char**); @@ -258,7 +263,7 @@ int gencat (char *filename); int show_status(void); int show_config(void); -int show_hwprobe(void); +int show_hwprobe(int); int debugging(void); int debug_read(void); @@ -288,9 +293,12 @@ void update_adsl_vci_vpi_list(wan_adsl_vcivpi_t* vcivpi_list, unsigned short vci void wakeup_java_ui(void); #if defined(WAN_HWEC) -static int config_hwec(char *devname); -static int enable_hwec(char *devname, char *ifname, char *); -static int release_hwec(char *devname); +static int wanconfig_hwec(chan_def_t *def); +static int wanconfig_hwec_config(char *devname); +static int wanconfig_hwec_release(char *devname); +static int wanconfig_hwec_enable(char *devname, char *ifname, char *); +static int wanconfig_hwec_modify(char *devname, chan_def_t *def); +static int wanconfig_hwec_dtmf_enable(char *devname, char *ifname, char *); #endif extern int close (int); @@ -299,6 +307,7 @@ int has_config_changed(link_def_t *linkdef, char *name); void free_device_link(char *devname); int device_syncup(char *devname); void sig_func (int sigio); +int start_chan (int dev, link_def_t *def); int start_link (void); int stop_link(void); int exec_command(char *rx_data); @@ -471,6 +480,7 @@ enum /* modes */ DO_SHOW_STATUS, DO_SHOW_CONFIG, DO_SHOW_HWPROBE, + DO_SHOW_HWPROBE_VERBOSE, DO_DEBUGGING, DO_DEBUG_READ, } action; /* what to do */ @@ -525,7 +535,7 @@ key_word_t common_conftab[] = /* Common configuration parameters */ { "MEMSIZE", smemof(wandev_conf_t, msize), DTYPE_UINT }, { "IRQ", smemof(wandev_conf_t, irq), DTYPE_UINT }, { "DMA", smemof(wandev_conf_t, dma), DTYPE_UINT }, - { "CARD_TYPE", smemof(wandev_conf_t, card_type), DTYPE_UCHAR }, + { "CARD_TYPE", smemof(wandev_conf_t, card_type), DTYPE_UINT }, { "S514CPU", smemof(wandev_conf_t, S514_CPU_no), DTYPE_STR }, { "PCISLOT", smemof(wandev_conf_t, PCI_slot_no), DTYPE_UINT }, { "PCIBUS", smemof(wandev_conf_t, pci_bus_no), DTYPE_UINT }, @@ -543,8 +553,8 @@ key_word_t common_conftab[] = /* Common configuration parameters */ { "FE_LCODE", offsetof(wandev_conf_t, fe_cfg)+smemof(sdla_fe_cfg_t, lcode), DTYPE_UCHAR }, { "FE_FRAME", offsetof(wandev_conf_t, fe_cfg)+smemof(sdla_fe_cfg_t, frame), DTYPE_UCHAR }, { "FE_LINE", offsetof(wandev_conf_t, fe_cfg)+smemof(sdla_fe_cfg_t, line_no), DTYPE_UINT }, - { "FE_TXTRISTATE", offsetof(wandev_conf_t, fe_cfg)+smemof(sdla_fe_cfg_t, tx_tristate_mode), DTYPE_UCHAR }, { "FE_POLL", offsetof(wandev_conf_t, fe_cfg)+smemof(sdla_fe_cfg_t, poll_mode), DTYPE_UCHAR }, + { "FE_TXTRISTATE", offsetof(wandev_conf_t, fe_cfg)+smemof(sdla_fe_cfg_t, tx_tristate_mode), DTYPE_UCHAR }, /* Front-End parameters (old style) */ /* Front-End parameters (old style) */ { "MEDIA", offsetof(wandev_conf_t, fe_cfg)+smemof(sdla_fe_cfg_t, media), DTYPE_UCHAR }, @@ -556,9 +566,10 @@ key_word_t common_conftab[] = /* Common configuration parameters */ { "TE_ACTIVE_CH", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, active_ch), DTYPE_UINT }, { "TE_RBS_CH", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, te_rbs_ch), DTYPE_UINT }, { "TE_HIGHIMPEDANCE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, high_impedance_mode), DTYPE_UCHAR }, - { "TE_RX_SLEVEL", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, rx_slevel), DTYPE_INT }, + { "TE_RX_SLEVEL", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, rx_slevel), DTYPE_INT }, { "TE_REF_CLOCK", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, te_ref_clock), DTYPE_UCHAR }, { "TE_SIG_MODE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, sig_mode), DTYPE_UCHAR }, + { "TE_IGNORE_YEL", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, ignore_yel_alarm), DTYPE_UCHAR }, /* T1/E1 Front-End parameters (old style) */ { "LBO", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, lbo), DTYPE_UCHAR }, { "ACTIVE_CH", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_te_cfg_t, active_ch), DTYPE_UINT }, @@ -576,7 +587,19 @@ key_word_t common_conftab[] = /* Common configuration parameters */ { "TDMV_OPERMODE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, opermode_name), DTYPE_STR }, { "RM_BATTTHRESH", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, battthresh), DTYPE_UINT }, { "RM_BATTDEBOUNCE", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, battdebounce), DTYPE_UINT }, + + { "RM_BRI_CLOCK_MASTER", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_bri_cfg_t, clock_mode), DTYPE_UCHAR }, + { "RM_BRI_CLOCK", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_bri_cfg_t, clock_mode), DTYPE_UCHAR }, { "RM_NETWORK_SYNC", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, network_sync), DTYPE_UINT }, + { "RM_FASTRINGER", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxs_fastringer), DTYPE_UCHAR }, + { "RM_LOWPOWER", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxs_lowpower), DTYPE_UCHAR }, + { "RM_FXSTXGAIN", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxs_txgain), DTYPE_INT }, + { "RM_FXSRXGAIN", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxs_rxgain), DTYPE_INT }, + { "RM_FXOTXGAIN", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxo_txgain), DTYPE_INT }, + { "RM_FXORXGAIN", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxo_rxgain), DTYPE_INT }, + { "RM_PULSEDIALING", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxs_pulsedialing), DTYPE_UCHAR }, + { "RM_RINGAMPL", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxs_ringampl), DTYPE_INT }, + //{ "RM_RELAXCFG", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, relaxcfg), DTYPE_UCHAR }, /* TDMV parameters */ { "TDMV_SPAN", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_tdmv_conf_t, span_no), DTYPE_UINT}, @@ -587,20 +610,22 @@ key_word_t common_conftab[] = /* Common configuration parameters */ { "RTP_TAP_PORT", offsetof(wandev_conf_t, rtp_conf)+smemof(wan_rtp_conf_t, rtp_port), DTYPE_USHORT}, { "RTP_TAP_SAMPLE", offsetof(wandev_conf_t, rtp_conf)+smemof(wan_rtp_conf_t, rtp_sample), DTYPE_USHORT}, { "RTP_TAP_DEV", offsetof(wandev_conf_t, rtp_conf)+smemof(wan_rtp_conf_t, rtp_devname), DTYPE_STR}, - { "RTP_TAP_MAC", offsetof(wandev_conf_t, rtp_conf)+smemof(wan_rtp_conf_t, rtp_mac), DTYPE_STR}, - + { "RTP_TAP_MAC", offsetof(wandev_conf_t, rtp_conf)+smemof(wan_rtp_conf_t, rtp_mac), DTYPE_UINT}, { "HWEC_CLKSRC", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, clk_src), DTYPE_UINT}, - { "HWEC_PERSIST_DISABLE", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, persist_disable), DTYPE_UINT}, - /* Keep backward compatibility */ + { "HWEC_PERSIST", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, persist_disable), DTYPE_UINT}, + /* Keep backward compatibility */ { "TDMV_HWEC_PERSIST_DISABLE", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, persist_disable), DTYPE_UINT}, { "HWEC_NOISE_REDUCTION", offsetof(wandev_conf_t, hwec_conf)+smemof(wan_hwec_conf_t, noise_reduction), DTYPE_UINT}, + { "OCT_CHIP_CONF", smemof(wandev_conf_t, oct_conf), DTYPE_OCT_FILENAME }, + { "OCT_ECHOOPERATIONMODE", smemof(wandev_conf_t, oct_conf), DTYPE_OCT_CHAN_CONF}, + { "BAUDRATE", smemof(wandev_conf_t, bps), DTYPE_UINT }, { "MTU", smemof(wandev_conf_t, mtu), DTYPE_UINT }, { "UDPPORT", smemof(wandev_conf_t, udp_port), DTYPE_UINT }, { "TTL", smemof(wandev_conf_t, ttl), DTYPE_UCHAR }, - { "INTERFACE", smemof(wandev_conf_t, interface), DTYPE_UCHAR }, + { "INTERFACE", smemof(wandev_conf_t, electrical_interface), DTYPE_UCHAR }, { "CLOCKING", smemof(wandev_conf_t, clocking), DTYPE_UCHAR }, { "LINECODING", smemof(wandev_conf_t, line_coding), DTYPE_UCHAR }, { "CONNECTION", smemof(wandev_conf_t, connection), DTYPE_UCHAR }, @@ -718,13 +743,8 @@ key_word_t xilinx_conftab[] = /* Xilinx specific configuration */ { "DMA_PER_CH", smemof(wan_xilinx_conf_t, dma_per_ch), DTYPE_USHORT }, { "RBS", smemof(wan_xilinx_conf_t, rbs), DTYPE_UCHAR }, { "DATA_MUX_MAP", smemof(wan_xilinx_conf_t, data_mux_map), DTYPE_UINT }, -// { "HWEC_CLKSRC", smemof(wan_xilinx_conf_t, ec_clk_src), DTYPE_UINT}, -// { "TDMV_HWEC", smemof(wan_xilinx_conf_t, tdmv_hwec), DTYPE_UCHAR}, { "RX_CRC_BYTES", smemof(wan_xilinx_conf_t, rx_crc_bytes), DTYPE_UINT}, - - { "ERR_CHECK_PERIOD", smemof(wan_xilinx_conf_t, err_throttle_period), DTYPE_UINT}, - { "ERR_TIMEOUT", smemof(wan_xilinx_conf_t, err_throttle_timeout), DTYPE_UINT}, - + { NULL, 0, 0 } }; @@ -875,9 +895,8 @@ key_word_t xilinx_if_conftab[] = { "SS7_ENABLE", smemof(wan_xilinx_conf_if_t, ss7_enable), DTYPE_UCHAR}, { "SS7_MODE", smemof(wan_xilinx_conf_if_t, ss7_mode), DTYPE_UCHAR}, { "SS7_LSSU_SZ", smemof(wan_xilinx_conf_if_t, ss7_lssu_size), DTYPE_UCHAR}, -// { "TDMV_HWEC_MAP", smemof(wan_xilinx_conf_if_t, tdmv_hwec_map), DTYPE_STR}, -// { "TDMV_HWEC", smemof(wan_xilinx_conf_if_t, tdmv_hwec), DTYPE_UCHAR}, { "RBS_CAS_IDLE", smemof(wan_xilinx_conf_if_t, rbs_cas_idle), DTYPE_UCHAR }, + { "HDLC_REPEAT", smemof(wan_xilinx_conf_if_t, hdlc_repeat), DTYPE_UCHAR }, { NULL, 0, 0 } }; @@ -1204,6 +1223,8 @@ key_word_t chan_conftab[] = /* Channel configuration parameters */ // { "TDMV_ECHO_OFF", smemof(wanif_conf_t, tdmv_echo_off), DTYPE_UCHAR}, // { "TDMV_CODEC", smemof(wanif_conf_t, tdmv_codec), DTYPE_UCHAR}, + { "OCT_ECHOOPERATIONMODE", smemof(wanif_conf_t, ec_conf), DTYPE_OCT_CHAN_CONF}, + { "SINGLE_TX_BUF", smemof(wanif_conf_t, single_tx_buf), DTYPE_UCHAR}, { NULL, 0, 0, 0 } @@ -1229,8 +1250,10 @@ look_up_t conf_def_tables[] = { WANCONFIG_AFT, xilinx_conftab }, { WANCONFIG_AFT_TE1, xilinx_conftab }, { WANCONFIG_AFT_ANALOG, xilinx_conftab }, - { WANCONFIG_AFT_TE3, xilinx_conftab }, + { WANCONFIG_AFT_ISDN_BRI, xilinx_conftab }, + { WANCONFIG_AFT_SERIAL, xilinx_conftab }, { WANCONFIG_AFT_56K, xilinx_conftab }, + { WANCONFIG_AFT_TE3, xilinx_conftab }, { WANCONFIG_BITSTRM, bitstrm_conftab }, { WANCONFIG_SDLC, sdlc_conftab }, { 0, NULL } @@ -1246,7 +1269,9 @@ look_up_t conf_if_def_tables[] = { WANCONFIG_AFT_TE1, xilinx_if_conftab }, { WANCONFIG_AFT_TE3, xilinx_if_conftab }, { WANCONFIG_AFT_ANALOG, xilinx_if_conftab }, - { WANCONFIG_AFT_56K, xilinx_if_conftab }, + { WANCONFIG_AFT_ISDN_BRI, xilinx_if_conftab }, + { WANCONFIG_AFT_SERIAL, xilinx_if_conftab }, + { WANCONFIG_AFT_56K, xilinx_if_conftab }, { WANCONFIG_ASYHDLC, chdlc_conftab }, { 0, NULL } }; @@ -1295,13 +1320,16 @@ look_up_t config_id_str[] = { WANCONFIG_AFT, "WAN_AFT" }, { WANCONFIG_AFT_TE1, "WAN_AFT_TE1" }, { WANCONFIG_AFT_ANALOG, "WAN_AFT_ANALOG" }, + { WANCONFIG_AFT_ISDN_BRI, "WAN_AFT_ISDN_BRI" }, + { WANCONFIG_AFT_SERIAL, "WAN_AFT_SERIAL" }, + { WANCONFIG_AFT_56K, "WAN_AFT_56K" }, { WANCONFIG_AFT_TE3, "WAN_AFT_TE3" }, - { WANCONFIG_AFT_56K, "WAN_AFT_56K" }, { WANCONFIG_AFT, "WAN_XILINX" }, { WANCONFIG_MFR, "WAN_MFR" }, { WANCONFIG_DEBUG, "WAN_DEBUG" }, { WANCONFIG_ADCCP, "WAN_ADCCP" }, { WANCONFIG_MLINK_PPP, "WAN_MLINK_PPP" }, +// { WANCONFIG_USB, "WAN_USB" }, { 0, NULL, } }; @@ -1392,12 +1420,14 @@ look_up_t sym_table[] = { WAN_MEDIA_STS1, "STS-1" }, { WAN_MEDIA_E3, "E3" }, { WAN_MEDIA_FXOFXS, "FXO/FXS" }, + { WAN_MEDIA_BRI, "BRI" }, { WAN_LCODE_AMI, "AMI" }, { WAN_LCODE_B8ZS, "B8ZS" }, { WAN_LCODE_HDB3, "HDB3" }, { WAN_LCODE_B3ZS, "B3ZS" }, { WAN_FR_D4, "D4" }, { WAN_FR_ESF, "ESF" }, + { WAN_FR_SLC96, "SLC-96" }, { WAN_FR_NCRC4, "NCRC4" }, { WAN_FR_CRC4, "CRC4" }, { WAN_FR_UNFRAMED, "UNFRAMED" }, @@ -1426,6 +1456,8 @@ look_up_t sym_table[] = { WAN_MASTER_CLK, "MASTER" }, { WANOPT_FE_OSC_CLOCK, "OSC" }, { WANOPT_FE_LINE_CLOCK, "LINE" }, + { WANOPT_NETWORK_SYNC_IN, "IN" }, + { WANOPT_NETWORK_SYNC_OUT, "OUT" }, { WAN_TE1_SIG_CAS, "CAS" }, { WAN_TE1_SIG_CCS, "CCS" }, @@ -1473,6 +1505,7 @@ look_up_t sym_table[] = { WANOPT_ADSL, "ADSL" }, { WANOPT_ADSL, "S518" }, { WANOPT_AFT, "AFT" }, + { WANOPT_AFT, "USB" }, /*-------------ADSL options--------------*/ { RFC_MODE_BRIDGED_ETH_LLC, "ETH_LLC_OA" }, @@ -1519,6 +1552,15 @@ look_up_t sym_table[] = { WANOPT_ADSL_CLOCK_CRYSTAL, "ADSL_CLOCK_CRYSTAL" }, { WANOPT_ADSL_CLOCK_OSCILLATOR, "ADSL_CLOCK_OSCILLATOR" }, +#if 0 + { WANOPT_OCT_CHAN_OPERMODE_NORMAL, "OCT_OP_MODE_NORMAL" }, + { WANOPT_OCT_CHAN_OPERMODE_POWERDOWN, "OCT_OP_MODE_POWERDOWN" }, + { WANOPT_OCT_CHAN_OPERMODE_NO_ECHO, "OCT_OP_MODE_NO_ECHO" }, + + { WANOPT_OCT_CHAN_OPERMODE_NORMAL, "OCT_OP_MODE_NORMAL" }, + { WANOPT_OCT_CHAN_OPERMODE_NORMAL, "OCT_OP_MODE_NORMAL" }, + +#endif { IBM4680, "IBM4680" }, { IBM4680, "IBM4680" }, { NCR2126, "NCR2126" }, @@ -1548,6 +1590,8 @@ look_up_t sym_table[] = { WAN_TDMV_ALAW, "ALAW" }, { WAN_TDMV_MULAW, "MULAW" }, + { WANOPT_SIM, "SIMULATE" }, + /*----- End ---------------------------*/ { 0, NULL }, }; @@ -1569,10 +1613,10 @@ int main (int argc, char *argv[]) int c; if (WANPIPE_VERSION_BETA){ - sprintf(wan_version,"Beta %s.%s", + snprintf(wan_version, 100, "Beta %s.%s", WANPIPE_VERSION, WANPIPE_SUB_VERSION); }else{ - sprintf(wan_version,"Stable %s.%s", + snprintf(wan_version, 100, "Stable %s.%s", WANPIPE_VERSION, WANPIPE_SUB_VERSION); } @@ -1740,9 +1784,14 @@ int main (int argc, char *argv[]) } else if( strcmp( argv[optind], "hwprobe" ) == 0 ) { - set_action(DO_SHOW_HWPROBE); + if ((optind + 1 < argc) && (strcmp( argv[optind+1], "verbose" ) == 0 )){ + set_action(DO_SHOW_HWPROBE_VERBOSE); + optind++; + }else{ + set_action(DO_SHOW_HWPROBE); + } } - + else if( strcmp( argv[optind], "help" ) == 0 ) { show_help(); } @@ -1817,7 +1866,8 @@ int main (int argc, char *argv[]) break; case DO_SHOW_HWPROBE: - return show_hwprobe(); + case DO_SHOW_HWPROBE_VERBOSE: + return show_hwprobe(action); break; case DO_DEBUGGING: @@ -2065,8 +2115,8 @@ int router_down (char *devname, int ignore_error) } #if defined(WAN_HWEC) - //ADBG : We don't know if wanpipe has HWEC enabled or not.... - //release_hwec(devname, NULL); + // FIXME: We don't know if wanpipe has HWEC enabled or not.... + //wanconfig_hwec_release(devname, NULL); #endif #if defined(__LINUX__) @@ -2077,7 +2127,7 @@ int router_down (char *devname, int ignore_error) dev = open(filename, O_RDONLY); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - strcpy(config.devname, &devname[0]); + strlcpy(config.devname, &devname[0], WAN_DRVNAME_SZ); def.linkconf->magic = ROUTER_MAGIC; config.arg = (void*)def.linkconf; if ((dev < 0) || (ioctl(dev, ROUTER_DOWN, &config) < 0 @@ -2146,14 +2196,14 @@ int router_ifdel (char *card_name, char *dev_name) } #if defined(WAN_HWEC) - //ADBG : We don't know if wanpipe has HWEC enabled or not.... - //release_hwec(card_name, dev_name); + //FIXME : We don't know if wanpipe has HWEC enabled or not.... + //wanconfig_hwec_release(card_name, dev_name); #endif #if defined(__LINUX__) snprintf(devicename, sizeof(devicename), "%s", dev_name); #else - strcpy(config.devname, dev_name); + strlcpy(config.devname, dev_name, WAN_DRVNAME_SZ); config.arg = NULL; #endif @@ -2424,6 +2474,8 @@ int build_chandef_list (FILE* file) chandef->annexg = ANNEXG_LIP_XDLC; chandef->protocol = strdup("MP_TTY"); }else{ + if (verbose) printf(" * %s defined with invalid protocol %s\n", + chandef->name, token[4]); return ERR_CONFIG; } @@ -2435,7 +2487,8 @@ int build_chandef_list (FILE* file) ( strcmp(chandef->usedby, "SWITCH") != 0 ) && ( strcmp(chandef->usedby, "PPPoE") != 0 ) && ( strcmp(chandef->usedby, "STACK") != 0 ) && - ( strcmp(chandef->usedby, "TTY") != 0 ) && + ( strcmp(chandef->usedby, "NETGRAPH") != 0 ) && + ( strcmp(chandef->usedby, "TTY") != 0 ) && ( strcmp(chandef->usedby, "BRIDGE_NODE") != 0 ) && ( strcmp(chandef->usedby, "TDM_VOICE") != 0 ) && ( strcmp(chandef->usedby, "TDM_VOICE_API") != 0 ) && @@ -2506,11 +2559,10 @@ int build_chandef_list (FILE* file) */ int configure_link (link_def_t* def, char init) { - int err = 0; - int len = 0; - int i; key_word_t* conf_table = lookup(def->config_id, conf_def_tables); - char filename[sizeof(router_dir) + WAN_DRVNAME_SZ + 2]; + int err = 0; + int len = 0, i, max_len = sizeof(router_dir) + WAN_DRVNAME_SZ; + char filename[max_len + 2]; chan_def_t* chandef; char* conf_rec; int dev=-1; @@ -2554,10 +2606,12 @@ int configure_link (link_def_t* def, char init) */ strupcase(token[0]); err = set_conf_param( - token[0], token[1], common_conftab, def->linkconf); + token[0], token[1], common_conftab, + def->linkconf, sizeof(wandev_conf_t)); if ((err < 0) && (conf_table != NULL)) err = set_conf_param( - token[0], token[1], conf_table, &def->linkconf->u); + token[0], token[1], conf_table, + &def->linkconf->u, sizeof(def->linkconf->u)); if (err < 0) { printf(" * Unknown parameter %s\n", token[0]); fprintf(stderr, "\n\n\tERROR in %s !!\n",conf_file); @@ -2574,7 +2628,7 @@ int configure_link (link_def_t* def, char init) } /* Open SDLA device and perform link configuration */ - sprintf(filename, "%s/%s", router_dir, def->name); + snprintf(filename, max_len, "%s/%s", router_dir, def->name); /* prepare a list of DLCI(s) and place it in the wandev_conf_t structure * This is done so that we have a list of DLCI(s) available when we @@ -2628,7 +2682,7 @@ int configure_link (link_def_t* def, char init) #endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - strcpy(config.devname, def->name); + strlcpy(config.devname, def->name, WAN_DRVNAME_SZ); config.arg = NULL; #endif @@ -2743,6 +2797,18 @@ int exec_link_cmd(int dev, link_def_t *def) break; default: +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + fprintf(stderr, "\n\t%s: Wanpipe Module Installation Failure!\n", + progname_sp); + fprintf(stderr, "\n\t%s: 1. New Wanpipe modules failed to install\n", + progname_sp); + fprintf(stderr, "\n\t%s: during wanpipe installation.\n", + progname_sp); + fprintf(stderr, "\n\t%s: 2. Wanpipe device doesn't exists in a list.\n", + progname_sp); + fprintf(stderr, "\n\t%s: 3. Wanpipe data structure is corrupted.\n", + progname_sp); +#else fprintf(stderr, "\n\t%s: Wanpipe Module Installation Failure!\n", progname_sp); fprintf(stderr, "\n\t%s: New Wanpipe modules failed to install during\n", @@ -2757,6 +2823,7 @@ int exec_link_cmd(int dev, link_def_t *def) progname_sp); fprintf(stderr, "\n\t%s: Then proceed to install Wanpipe again!\n", progname_sp); +#endif break; } @@ -2821,7 +2888,9 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) if (def->annexg && def->protocol){ conf_annexg_table=lookup(def->annexg, conf_annexg_def_tables); if (conf_annexg_table){ - set_conf_param("PROTOCOL", def->protocol, chan_conftab, def->chanconf); + set_conf_param( + "PROTOCOL", def->protocol, chan_conftab, + def->chanconf, sizeof(wanif_conf_t)); } } @@ -2835,7 +2904,9 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) if (def->label){ if (conf_annexg_table){ - set_conf_param("LABEL", def->label, conf_annexg_table, &def->chanconf->u); + set_conf_param( + "LABEL", def->label, conf_annexg_table, + &def->chanconf->u, sizeof(def->chanconf->u)); }else{ memcpy(def->chanconf->label,def->label,WAN_IF_LABEL_SZ); } @@ -2843,15 +2914,17 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) if (def->virtual_addr){ if (conf_annexg_table){ - set_conf_param("VIRTUAL_ADDR",def->virtual_addr, - conf_annexg_table, &def->chanconf->u); + set_conf_param( + "VIRTUAL_ADDR",def->virtual_addr, conf_annexg_table, + &def->chanconf->u, sizeof(def->chanconf->u)); } } if (def->real_addr){ if (def->annexg){ if (conf_annexg_table){ - set_conf_param("REAL_ADDR",def->real_addr, - conf_annexg_table, &def->chanconf->u); + set_conf_param( + "REAL_ADDR",def->real_addr, conf_annexg_table, + &def->chanconf->u,sizeof(def->chanconf->u)); } } } @@ -2870,13 +2943,12 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) * configuration definition tables. */ strupcase(token[0]); - if (set_conf_param(token[0], token[1], chan_conftab, def->chanconf)) { + if (set_conf_param(token[0], token[1], chan_conftab, def->chanconf,sizeof(wanif_conf_t))) { if (def->annexg && conf_annexg_table){ if (!conf_annexg_table || - set_conf_param(token[0], token[1], - conf_annexg_table, &def->chanconf->u)) { + set_conf_param(token[0], token[1], conf_annexg_table, &def->chanconf->u, sizeof(def->chanconf->u))) { printf("Invalid Annexg/Lip parameter %s\n", token[0]); show_error(ERR_CONFIG); @@ -2884,7 +2956,7 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) } }else if (conf_table){ - if (set_conf_param(token[0], token[1], conf_table, &def->chanconf->u)) { + if (set_conf_param(token[0], token[1], conf_table, &def->chanconf->u, sizeof(def->chanconf->u))) { printf("Invalid Iface parameter %s\n", token[0]); show_error(ERR_CONFIG); return ERR_CONFIG; @@ -2900,7 +2972,7 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) }else{ if (strcmp(token[0], "ACTIVE_CH") == 0){ - strcpy(def->active_ch, token[1]); + strlcpy(def->active_ch, token[1], 50); } } } @@ -2927,8 +2999,8 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) strupcase(token[0]); if (!conf_annexg_table || - set_conf_param(token[0], token[1], conf_annexg_table, &def->chanconf->u)) { - if (set_conf_param(token[0], token[1], chan_conftab, def->chanconf)) { + set_conf_param(token[0], token[1], conf_annexg_table, &def->chanconf->u, sizeof(def->chanconf->u))) { + if (set_conf_param(token[0], token[1], chan_conftab, def->chanconf, sizeof(wanif_conf_t))) { printf("Invalid parameter %s\n", token[0]); show_error(ERR_CONFIG); return ERR_CONFIG; @@ -2950,6 +3022,10 @@ int configure_chan (int dev, chan_def_t* def, char init, int id) int exec_chan_cmd(int dev, chan_def_t *def) { +#if defined(WAN_HWEC) + int err; +#endif + if (!def->chanconf){ printf("%s: Error: Device %s has no config structure\n", prognamed,def->name); @@ -2965,6 +3041,7 @@ int exec_chan_cmd(int dev, chan_def_t *def) config.arg = (void*)def->chanconf; if (ioctl(dev, ROUTER_IFNEW, &config) < 0) { #else + if (ioctl(dev, ROUTER_IFNEW, def->chanconf) < 0) { #endif fprintf(stderr, "\n\n\t%s: Interface %s setup failed\n", prognamed, def->name); @@ -2981,34 +3058,19 @@ int exec_chan_cmd(int dev, chan_def_t *def) } #if defined(WAN_HWEC) - { /* ALEX */ - struct link_def *linkdef = def->link; - int err; - - if ((linkdef->config_id == WANCONFIG_AFT_TE1 || - linkdef->config_id == WANCONFIG_AFT_ANALOG) && - def->chanconf->hwec.enable){ - - err = config_hwec(linkdef->name); - if (err){ - return err; - } - - err = enable_hwec(linkdef->name, - def->name, - def->active_ch); - if (err){ - release_hwec(linkdef->name); - return err; - } - } + if ((err = wanconfig_hwec(def))){ + fprintf(stderr, "\n\n\t%s: HWEC configuration failed on %s\n", prognamed, def->name); + fprintf(stderr, "\n\tPlease check %s and\n", verbose_log); + fprintf(stderr, "\t%s for errors.\n", krnl_log_file); + fprintf(stderr, "\n"); + return err; } #endif break; #if defined(__LINUX__) case ANNEXG_LAPB: - strncpy((char*)def->chanconf->master,master_lapb_dev, WAN_IFNAME_SZ); + strncpy((char*)def->chanconf->master,(char*)master_lapb_dev, WAN_IFNAME_SZ); if (ioctl(dev, ROUTER_IFNEW_LAPB, def->chanconf) < 0) { fprintf(stderr, "\n\n\t%s: Interface %s setup failed\n", prognamed, def->name); @@ -3026,7 +3088,7 @@ int exec_chan_cmd(int dev, chan_def_t *def) break; case ANNEXG_X25: - strncpy((char*)def->chanconf->master, master_x25_dev, WAN_IFNAME_SZ); + strncpy((char*)def->chanconf->master, (char*)master_x25_dev, WAN_IFNAME_SZ); if (ioctl(dev, ROUTER_IFNEW_X25, def->chanconf) < 0) { fprintf(stderr, "\n\n\t%s: Interface %s setup failed\n", prognamed, def->name); @@ -3045,7 +3107,7 @@ int exec_chan_cmd(int dev, chan_def_t *def) // DSP_20 case ANNEXG_DSP: - strncpy((char*)def->chanconf->master, master_dsp_dev, WAN_IFNAME_SZ); + strncpy((char*)def->chanconf->master, (char*)master_dsp_dev, WAN_IFNAME_SZ); if (ioctl(dev, ROUTER_IFNEW_DSP, def->chanconf) < 0) { fprintf(stderr, "\n\n\t%s: Interface %s setup failed\n", prognamed, def->name); fprintf(stderr, "\t%s: ioctl(ROUTER_IFNEW_DSP,%s) failed:\n", @@ -3073,7 +3135,7 @@ int exec_chan_cmd(int dev, chan_def_t *def) case ANNEXG_LIP_X25: case ANNEXG_LIP_ATM: case ANNEXG_LIP_KATM: - strncpy((char*)def->chanconf->master, master_lip_dev, WAN_IFNAME_SZ); + strncpy((char*)def->chanconf->master, (char*)master_lip_dev, WAN_IFNAME_SZ); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) config.arg = (void*)def->chanconf; @@ -3213,7 +3275,7 @@ int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf) * 1 - error * -1 - not found */ -int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf) +int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf, int max_len) { unsigned int tmp = 0; @@ -3228,10 +3290,18 @@ int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf) return read_data_file( val, (void*)((char*)conf + dtab->offset)); } + + /* FIXME: Add code that will parse Octasic Chip configuration file */ + if (dtab->dtype == DTYPE_OCT_FILENAME) { + return 0; + } + if (dtab->dtype == DTYPE_OCT_CHAN_CONF) { + return read_oct_chan_config( + key, val, (void*)((char*)conf + dtab->offset)); + } if (verbose) printf(" * Setting %s to %s\n", key, val); - if (strcmp(key, "RTP_TAP_IP") == 0) { int err; struct hostent *result = NULL; @@ -3287,11 +3357,11 @@ int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf) } if (dtab->dtype == DTYPE_STR) { - strcpy((char*)conf + dtab->offset, val); + strlcpy((char*)conf + dtab->offset, val, max_len-dtab->offset); return 0; } - if (!isdigit(*val) || + if (!(isdigit(*val) || (*val=='-' && isdigit(*(val+1)))) || strcmp(key, "TE_ACTIVE_CH") == 0 || strcmp(key, "ACTIVE_CH") == 0 || strcmp(key, "TE_LBO") == 0 || strcmp(key, "LBO") == 0 || strcmp(key, "FE_MEDIA") == 0 || strcmp(key, "MEDIA") == 0 || @@ -3303,8 +3373,8 @@ int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf) strupcase(val); for (sym = sym_table; sym->ptr && strcmp(sym->ptr, val); - ++sym) - ; + ++sym); + if (sym->ptr == NULL) { int ok_zero=0; @@ -3328,11 +3398,12 @@ int set_conf_param (char* key, char* val, key_word_t* dtab, void* conf) return -1; } tmp = (unsigned int)tmp_ch; + } else { + tmp = sym->val; } - else tmp = sym->val; + } else { + tmp = strtoul(val, NULL, 0); } - else tmp = strtoul(val, NULL, 0); - /* SANITY CHECK */ switch (dtab->dtype) { @@ -3397,20 +3468,25 @@ char* read_conf_section (FILE* file, char* section) { char key[MAX_CFGLINE]; /* key buffer */ char* buf = NULL; - int found = 0, offs = 0, len; + int found = 0, offs = 0, len, max_len = 0; rewind(file); - while ((len = read_conf_record(file, key)) > 0) { + while ((len = read_conf_record(file, key, MAX_CFGLINE)) > 0) { char* tmp; if (found) { if (*key == '[') break; /* end of section */ - if (buf) tmp = realloc(buf, offs + len + 1); - else tmp = malloc(len + 1); + max_len = len; + if (buf){ + max_len += offs; + tmp = realloc(buf, max_len + 1); + }else{ + tmp = malloc(max_len + 1); + } if (tmp) { buf = tmp; - strcpy(&buf[offs], key); + strlcpy(&buf[offs], key, max_len-offs); offs += len; buf[offs] = '\0'; } @@ -3445,7 +3521,7 @@ char* read_conf_section (FILE* file, char* section) * Return string length (incl. terminating zero) or 0 if end of file has been * reached. */ -int read_conf_record (FILE* file, char* key) +int read_conf_record (FILE* file, char* key, int max_len) { char buf[MAX_CFGLINE]; /* line buffer */ @@ -3458,7 +3534,7 @@ int read_conf_record (FILE* file, char* key) len = strcspn(str, "#;\n\r"); if (len) { str[len] = '\0'; - strcpy(key, str); + strlcpy(key, str, max_len); return len + 1; } } @@ -3617,6 +3693,39 @@ done: return err; } +int read_oct_chan_config (char *key, char *val, wan_custom_conf_t *conf) +{ + + if ((!conf->param_no && conf->params) || (conf->param_no && conf->params == NULL)){ + if (verbose) + printf(" * INTERNAL ERROR [%s:%d]: Reading OCT6100 config param %s:%s!\n", + __FUNCTION__,__LINE__, key,val); + fprintf(stderr, "%s: INTERNAL ERROR [%s:%d]: Reading OCT6100 config param %s:%s!\n", + prognamed, + __FUNCTION__,__LINE__, + key,val); + show_error(ERR_SYSTEM); + return ERR_SYSTEM; + } + + if (conf->param_no == 0){ + conf->params = malloc(sizeof(wan_custom_param_t)); + if (conf->params == NULL){ + if (verbose) printf(" * Can't allocate memory for OCT6100 config (%s:%s)!\n", + key,val); + fprintf(stderr, "%s: Can't allocate memory for OCT6100 config (%s:%s)!\n", + prognamed, key, val); + show_error(ERR_SYSTEM); + return ERR_SYSTEM; + } + memset(conf->params, 0, sizeof(wan_custom_param_t)); + } + strncpy(conf->params[conf->param_no].name, key, MAX_PARAM_LEN); + strncpy(conf->params[conf->param_no].sValue, val, MAX_VALUE_LEN); + conf->param_no++; + return 0; +} + /*============================================================================ * Get file size * Return file length or 0 if error. @@ -3642,7 +3751,7 @@ unsigned int dec_to_uint (char* str, int len) { unsigned val; - if (!len) len = strlen(str); + if (!len) len = strlen((char*)str); for (val = 0; len && is_digit(*str); ++str, --len) val = (val * 10) + (*str - (unsigned)'0') ; @@ -3959,7 +4068,7 @@ int has_config_changed(link_def_t *linkdef, char *name) struct stat statbuf; char timeBuf[TIME_STRING_BUF]; - sprintf(filename,"/etc/wanpipe/%s.conf",name); + snprintf(filename,50,"/etc/wanpipe/%s.conf",name); if (lstat(filename,&statbuf)){ return -1; @@ -4093,7 +4202,7 @@ int device_syncup(char *devname) free_device_link(devname); - sprintf(filename,"%s/%s.conf",conf_dir,devname); + snprintf(filename,100,"%s/%s.conf",conf_dir,devname); printf("%s: Parsing configuration file %s\n",prognamed,filename); err = parse_conf_file(filename); @@ -4174,7 +4283,7 @@ int start_chan (int dev, link_def_t *def) "no description", chandef->addr ? chandef->addr : "not specified"); } - + err=exec_chan_cmd(dev,chandef); if (err){ return err; @@ -4242,7 +4351,7 @@ start_cfg_chk: } fflush(stdout); - sprintf(filename, "%s/%s", router_dir, linkdef->name); + snprintf(filename, 100,"%s/%s", router_dir, linkdef->name); dev = open(filename, O_RDONLY); if (dev<0){ printf("%s: Failed to open file %s\n",prognamed,filename); @@ -4328,7 +4437,7 @@ int exec_command(char *rx_data) int err=-ENOEXEC; char *token[MAX_TOKENS]; - toknum = tokenize(rx_data, token); + toknum = tokenize((char*)rx_data, token); if (toknum < 2){ printf("%s: Invalid client cmd = %s\n",prognamed,rx_data); return -ENOEXEC; @@ -4463,7 +4572,7 @@ int start_daemon(void) setuid(0); /* set real UID = root */ setgid(getegid()); - sprintf(prognamed,"wanconfigd[%i]",getpid()); + snprintf(prognamed,20,"wanconfigd[%i]",getpid()); memset(&rx_data[0],0,100); memset(&address,0,sizeof(struct sockaddr_un)); @@ -4485,7 +4594,7 @@ int start_daemon(void) } address.sun_family=AF_UNIX; - strcpy(address.sun_path, WANCONFIG_SOCKET); + strlcpy(address.sun_path, WANCONFIG_SOCKET, sizeof(address.sun_path)); addrLength = sizeof(address.sun_family) + strlen(address.sun_path); @@ -4502,7 +4611,7 @@ int start_daemon(void) fp=open(WANCONFIG_PID,(O_CREAT|O_WRONLY),0644); if (fp){ char pid_str[10]; - sprintf(pid_str,"%i",getpid()); + snprintf(pid_str,10,"%i",getpid()); write(fp,&pid_str,strlen(pid_str)); close(fp); } @@ -4512,7 +4621,7 @@ int start_daemon(void) if (err<0){ printf("\n\nWarning: Failed pid write: rc=%i\n\n",err); }else{ - sprintf(rx_data,"echo %i > %s",getpid(),WANCONFIG_PID_FILE); + snprintf(rx_data,100,"echo %i > %s",getpid(),WANCONFIG_PID_FILE); if ((err=system(rx_data)) != 0){ printf("\n\nWarning: Failed pid write: rc=%i\n\n",err); } @@ -4736,7 +4845,7 @@ show_status_end: return err; } -int show_hwprobe(void) +int show_hwprobe(int action) { int err = 0; @@ -4753,7 +4862,8 @@ int show_hwprobe(void) memset(&procfs, 0, sizeof(wan_procfs_t)); procfs.magic = ROUTER_MAGIC; procfs.max_len = 2048; - procfs.cmd = WANPIPE_PROCFS_HWPROBE; + procfs.cmd = (action == DO_SHOW_HWPROBE) ? + WANPIPE_PROCFS_HWPROBE : WANPIPE_PROCFS_HWPROBE_VERBOSE ; procfs.data = malloc(2048); if (procfs.data == NULL){ show_error(ERR_SYSTEM); @@ -4783,8 +4893,8 @@ show_probe_end: int debugging(void) { int dev; - int err = 0; - char filename[sizeof(router_dir) + WAN_DRVNAME_SZ + 2]; + int err = 0, max_len = sizeof(router_dir) + WAN_DRVNAME_SZ; + char filename[max_len + 2]; if (dev_name == NULL){ fprintf(stderr, "\n\n\tPlease specify device name!\n"); @@ -4792,9 +4902,9 @@ int debugging(void) return -EINVAL; } #if defined(__LINUX__) - sprintf(filename, "%s/%s", router_dir, dev_name); + snprintf(filename, max_len, "%s/%s", router_dir, dev_name); #else - sprintf(filename, "%s", WANDEV_NAME); + snprintf(filename, max_len, "%s", WANDEV_NAME); #endif dev = open(filename, O_RDONLY); @@ -4808,7 +4918,7 @@ int debugging(void) memset(&u.linkconf, 0, sizeof(wandev_conf_t)); u.linkconf.magic = ROUTER_MAGIC; #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - strcpy(config.devname, dev_name); + strlcpy(config.devname, dev_name, WAN_DRVNAME_SZ); config.arg = NULL; if (ioctl(dev, ROUTER_DEBUGGING, &config) < 0){ //if (ioctl(dev, ROUTER_DEBUGGING, NULL) < 0){ @@ -4831,8 +4941,8 @@ int debugging(void) int debug_read(void) { int dev; - int err = 0; - char filename[sizeof(router_dir) + WAN_DRVNAME_SZ + 2]; + int err = 0, max_len = sizeof(router_dir) + WAN_DRVNAME_SZ; + char filename[max_len + 2]; wan_kernel_msg_t wan_kernel_msg; if (dev_name == NULL){ @@ -4841,9 +4951,9 @@ int debug_read(void) return -EINVAL; } #if defined(__LINUX__) - sprintf(filename, "%s/%s", router_dir, dev_name); + snprintf(filename, max_len, "%s/%s", router_dir, dev_name); #else - sprintf(filename, "%s", WANDEV_NAME); + snprintf(filename, max_len, "%s", WANDEV_NAME); #endif dev = open(filename, O_RDONLY); @@ -4857,7 +4967,7 @@ int debug_read(void) memset(&u.linkconf, 0, sizeof(wandev_conf_t)); u.linkconf.magic = ROUTER_MAGIC; #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - strcpy(config.devname, dev_name); + strlcpy(config.devname, dev_name, WAN_DRVNAME_SZ); config.arg = &wan_kernel_msg; #endif debug_read_again: @@ -4910,12 +5020,18 @@ void update_adsl_vci_vpi_list(wan_adsl_vcivpi_t* vcivpi_list, unsigned short vci file = fopen(adsl_file, "r"); tmp_file = fopen(tmp_adsl_file, "w"); if (file == NULL || tmp_file == NULL){ + printf(" * ADSL VCI/VPI list file doens't exists (skip)\n"); + if (file) fclose(file); + if (tmp_file) fclose(tmp_file); + return; +#if 0 fprintf( stderr, "%s: cannot open %s or %s\n", prognamed, adsl_file, tmp_adsl_file); if (file) fclose(file); if (tmp_file) fclose(tmp_file); show_error(ERR_SYSTEM); exit(ERR_SYSTEM); +#endif } while(fgets(buf, sizeof(buf) -1, file)){ @@ -4946,10 +5062,15 @@ void read_adsl_vci_vpi_list(wan_adsl_vcivpi_t* vcivpi_list, unsigned short* vciv file = fopen(adsl_file, "r"); if (file == NULL){ + printf(" * ADSL VCI/VPI list file doens't exists (skip)\n"); + *vcivpi_num = 0; + return; +#if 0 fprintf( stderr, "%s: cannot open %s\n", prognamed, adsl_file); show_error(ERR_SYSTEM); exit(ERR_SYSTEM); +#endif } while(fgets(buf, sizeof(buf) -1, file)){ @@ -5044,13 +5165,52 @@ unsigned int get_active_channels(int channel_flag, int start_channel, int stop_c #if defined(WAN_HWEC) + #define WAN_EC_PID "/etc/wanpipe/wan_ec/wan_ec_pid" #define WAN_EC_DIR "/etc/wanpipe/wan_ec" -static int config_hwec(char *devname) +static int wanconfig_hwec(chan_def_t *def) +{ + struct link_def *linkdef = def->link; + int err; + + + if ((linkdef->config_id != WANCONFIG_AFT_TE1 && + linkdef->config_id != WANCONFIG_AFT_ANALOG && + linkdef->config_id != WANCONFIG_AFT_ISDN_BRI) || + def->chanconf->hwec.enable != WANOPT_YES){ + return 0; + } + + if ((err = wanconfig_hwec_config(linkdef->name))){ + return err; + } + + if ((err = wanconfig_hwec_enable(linkdef->name, def->name, def->active_ch))){ + wanconfig_hwec_release(linkdef->name); + return err; + } + + if ((err = wanconfig_hwec_modify(linkdef->name, def))){ + wanconfig_hwec_release(linkdef->name); + return err; + } + + if (linkdef->linkconf->tdmv_conf.hw_dtmf == WANOPT_YES){ + err = wanconfig_hwec_dtmf_enable(linkdef->name, def->name, def->active_ch); + if (err){ + wanconfig_hwec_release(linkdef->name); + return err; + } + } + return 0; +} + +static int wanconfig_hwec_config(char *devname) { int status; char cmd[100]; +#if defined(__LINUX__) DIR *dir; dir = opendir(WAN_EC_DIR); @@ -5060,9 +5220,10 @@ static int config_hwec(char *devname) } closedir(dir); +#endif /*HW_EC*/ - sprintf(cmd, "wan_ec_client %s config", devname); + snprintf(cmd, 100, "wan_ec_client %s config", devname); status = system(cmd); if (WEXITSTATUS(status) != 0){ @@ -5075,35 +5236,109 @@ static int config_hwec(char *devname) return 0; } -static int enable_hwec(char *devname, char *ifname, char *channel_list) +static int wanconfig_hwec_release(char *devname) { int status; char cmd[100]; + + snprintf(cmd, 100, "wan_ec_client %s release", + devname); + status = system(cmd); + if (WEXITSTATUS(status) != 0){ + fprintf(stderr, + "wanconfig: Failed to release EC device %s (err=%d)!\n", + devname,WEXITSTATUS(status)); + return -EINVAL; + } + return 0; +} + + +static int wanconfig_hwec_modify(char *devname, chan_def_t *def) +{ + int status, len, i; + char cmd[100], *conf_string; + +#if defined(__LINUX__) DIR *dir; -return 0; - + dir = opendir(WAN_EC_DIR); + + if(dir == NULL) { + return 0; + } + + closedir(dir); +#endif + + len = 0; + for(i = 0; i < def->chanconf->ec_conf.param_no; i++){ + len += (strlen(def->chanconf->ec_conf.params[i].name) + + strlen(def->chanconf->ec_conf.params[i].sValue) + 5); + } + conf_string = malloc(len+1); + if (conf_string == NULL){ + fprintf(stderr, + "wanconfig: %s: Failed to allocate memory for EC custom config (len=%d)!\n", + devname, len+5); + return -EINVAL; + } + memset(conf_string, 0, len+1); + for(i = 0; i < def->chanconf->ec_conf.param_no; i++){ + sprintf(&conf_string[strlen(conf_string)], "--%s=%s", + def->chanconf->ec_conf.params[i].name, + def->chanconf->ec_conf.params[i].sValue); + } + if (strcasecmp(def->active_ch, "all") == 0){ + snprintf(cmd, 100, "wan_ec_client %s modify all %s", + devname, conf_string); + }else{ + snprintf(cmd, 100, "wan_ec_client %s modify %s %s", + devname, def->active_ch, conf_string); + } + status = system(cmd); + if (WEXITSTATUS(status) != 0){ + fprintf(stderr, + "wanconfig: Failed to modify EC device %s (err=%d)!\n", + devname,WEXITSTATUS(status)); + if (conf_string) free(conf_string); + return -EINVAL; + } + if (conf_string) free(conf_string); + return 0; +} + +static int +wanconfig_hwec_enable(char *devname, char *ifname, char *channel_list) +{ + int status; + char cmd[100]; +#if defined(__LINUX__) + DIR *dir; dir = opendir(WAN_EC_DIR); if(dir == NULL) { return 0; } closedir(dir); +#endif + + return 0; #if 1 if (strcasecmp(channel_list, "all") == 0){ - sprintf(cmd, "wan_ec_client %s mn all", + snprintf(cmd, 100, "wan_ec_client %s mn all", devname); }else{ - sprintf(cmd, "wan_ec_client %s mn %s", + snprintf(cmd, 100, "wan_ec_client %s mn %s", devname,channel_list); } #else if (strcasecmp(channel_list, "all") == 0){ - sprintf(cmd, "wan_ec_client %s enable all", + snprintf(cmd, 100, "wan_ec_client %s enable all", devname); }else{ - sprintf(cmd, "wan_ec_client %s enable %s", + snprintf(cmd, 100, "wan_ec_client %s enable %s", devname,channel_list); } #endif @@ -5119,18 +5354,33 @@ return 0; return 0; } -static int release_hwec(char *devname) +static int +wanconfig_hwec_dtmf_enable(char *devname, char *ifname, char *channel_list) { int status; char cmd[100]; +#if defined(__LINUX__) + DIR *dir; + dir = opendir(WAN_EC_DIR); + + if(dir == NULL) { + return 0; + } + closedir(dir); +#endif - sprintf(cmd, "wan_ec_client %s release", - devname); + if (strcasecmp(channel_list, "all") == 0){ + snprintf(cmd, 100, "wan_ec_client %s de all sout", + devname); + }else{ + snprintf(cmd, 100, "wan_ec_client %s de %s sout", + devname,channel_list); + } status = system(cmd); if (WEXITSTATUS(status) != 0){ fprintf(stderr, - "wanconfig: Failed to release EC device %s (err=%d)!\n", - devname,WEXITSTATUS(status)); + "wanconfig: %s: Failed to enable HWEC DTMF (channels %s, err=%d)!\n", + devname, channel_list,WEXITSTATUS(status)); return -EINVAL; } return 0; diff --git a/util/wanec_apilib/wanec_api.c b/util/wanec_apilib/wanec_api.c index b44287f..79f0458 100644 --- a/util/wanec_apilib/wanec_api.c +++ b/util/wanec_apilib/wanec_api.c @@ -41,18 +41,20 @@ #if defined(__LINUX__) # include # include -# include +# include #elif defined(__WINDOWS__) # include +# include # include +# include +# include # include # include -# include "wan_ecmain.h" -# include +# include #else # include # include -# include +# include #endif #include "wanec_api.h" @@ -68,13 +70,13 @@ /****************************************************************************** ** GLOBAL VARIABLES ******************************************************************************/ -wan_ec_api_t ec_api; +wan_ec_api_t ec_api; /****************************************************************************** ** FUNCTION PROTOTYPES ******************************************************************************/ extern int wanec_api_lib_config(wan_ec_api_t *ec_api, int verbose); -extern int wanec_api_lib_toneload(wan_ec_api_t *ec_api); +extern int wanec_api_lib_bufferload(wan_ec_api_t *ec_api); extern int wanec_api_lib_monitor(wan_ec_api_t *ec_api); extern int wanec_api_lib_cmd(wan_ec_api_t *ec_api); @@ -268,15 +270,16 @@ static int wanec_api_print_full_chip_stats(wan_ec_api_t *ec_api) } -static int wanec_api_print_chan_stats(wan_ec_api_t *ec_api, int channel) +static int wanec_api_print_chan_stats(wan_ec_api_t *ec_api, int fe_chan) { tPOCT6100_CHANNEL_STATS pChannelStats; + tPOCT6100_CHANNEL_STATS_TDM pChannelStatsTdm; tPOCT6100_CHANNEL_STATS_VQE pChannelStatsVqe; pChannelStats = (tPOCT6100_CHANNEL_STATS)&ec_api->u_chan_stats.f_ChannelStats; printf("%10s:%2d: Echo Channel Operation Mode\t\t\t: %s\n", ec_api->devname, - channel, + fe_chan, (pChannelStats->ulEchoOperationMode==cOCT6100_ECHO_OP_MODE_NORMAL)? "NORMAL": (pChannelStats->ulEchoOperationMode==cOCT6100_ECHO_OP_MODE_HT_FREEZE)? @@ -291,10 +294,10 @@ static int wanec_api_print_chan_stats(wan_ec_api_t *ec_api, int channel) "SPEECH RECOGNITION": "Unknown"); printf("%10s:%2d: Enable Tone Disabler\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fEnableToneDisabler==TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: Mute Ports\t\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->ulMutePortsMask==cOCT6100_CHANNEL_MUTE_PORT_RIN) ? "RIN" : (pChannelStats->ulMutePortsMask==cOCT6100_CHANNEL_MUTE_PORT_ROUT) ? @@ -306,85 +309,126 @@ static int wanec_api_print_chan_stats(wan_ec_api_t *ec_api, int channel) (pChannelStats->ulMutePortsMask==cOCT6100_CHANNEL_MUTE_PORT_NONE) ? "NONE" : "Unknown"); printf("%10s:%2d: Enable Extended Tone Detection\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fEnableExtToneDetection==TRUE) ? "TRUE" : "FALSE"); if (pChannelStats->ulToneDisablerStatus == cOCT6100_INVALID_STAT){ printf("%10s:%2d: Tone Disabler Status\t\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Tone Disabler Status\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->ulToneDisablerStatus==cOCT6100_TONE_DISABLER_EC_DISABLED)? "Disabled":"Enabled"); } printf("%10s:%2d: Voice activity is detected on SIN port\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fSinVoiceDetected==TRUE)? "TRUE": (pChannelStats->fSinVoiceDetected==FALSE)? "FALSE": "Unknown"); printf("%10s:%2d: Echo canceller has detected and converged\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fEchoCancellerConverged==TRUE)? "TRUE": (pChannelStats->fEchoCancellerConverged==FALSE)? "FALSE": "Unknown"); if (pChannelStats->lRinLevel == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Average power of signal level on RIN\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Average power of signal level on RIN\t\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lRinLevel); } if (pChannelStats->lSinLevel == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Average power of signal level on SIN\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Average power of signal level on SIN\t\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lSinLevel); } if (pChannelStats->lRinAppliedGain == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Current gain applied to signal level on RIN\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Current gain applied to signal level on RIN\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lRinAppliedGain); } if (pChannelStats->lSoutAppliedGain == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Current gain applied to signal level on SOUT\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Current gain applied to signal level on SOUT\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lSoutAppliedGain); } if (pChannelStats->lComfortNoiseLevel == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Average power of the comfort noise injected\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Average power of the comfort noise injected\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lComfortNoiseLevel); } + pChannelStatsTdm = &pChannelStats->TdmConfig; + printf("%10s:%2d: (TDM) PCM Law type on SIN\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulSinPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on SIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSinTimeslot); + printf("%10s:%2d: (TDM) TDM stream on SIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSinStream); + printf("%10s:%2d: (TDM) PCM Law type on RIN\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulRinPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on RIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRinTimeslot); + printf("%10s:%2d: (TDM) TDM stream on RIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRinStream); + printf("%10s:%2d: (TDM) PCM Law type on SOUT\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulSoutPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on SOUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSoutTimeslot); + printf("%10s:%2d: (TDM) TDM stream on SOUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSoutStream); + printf("%10s:%2d: (TDM) PCM Law type on ROUT\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulRoutPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on ROUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRoutTimeslot); + printf("%10s:%2d: (TDM) TDM stream on ROUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRoutStream); + pChannelStatsVqe = &pChannelStats->VqeConfig; printf("%10s:%2d: (VQE) NLP status\t\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fEnableNlp == TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: (VQE) Enable Tail Displacement\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fEnableTailDisplacement == TRUE) ? "TRUE" : "FALSE"); - printf("%10s:%2d: (VQE) Echo Cancellation offset windowd (ms)\t: %d\n", - ec_api->devname, channel, + printf("%10s:%2d: (VQE) Offset of the Echo Cancellation window (ms)\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsVqe->ulTailDisplacement); + printf("%10s:%2d: (VQE) Echo Cancellation offset window (ms)\t: %d\n", + ec_api->devname, fe_chan, pChannelStatsVqe->ulTailDisplacement); printf("%10s:%2d: (VQE) Comfort noise mode\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_NORMAL) ? "NORMAL" : (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_FAST_LATCH) ? "FAST LATCH" : (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_EXTENDED) ? "EXTENDED" : (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF) ? "OFF" : "UNKNOWN"); printf("%10s:%2d: (VQE) Acoustic Echo\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fAcousticEcho == TRUE) ? "TRUE" : "FALSE"); printf("\n"); @@ -392,16 +436,17 @@ static int wanec_api_print_chan_stats(wan_ec_api_t *ec_api, int channel) return 0; } -static int wanec_api_print_full_chan_stats(wan_ec_api_t *ec_api, int channel) +static int wanec_api_print_full_chan_stats(wan_ec_api_t *ec_api, int fe_chan) { tPOCT6100_CHANNEL_STATS pChannelStats; + tPOCT6100_CHANNEL_STATS_TDM pChannelStatsTdm; tPOCT6100_CHANNEL_STATS_VQE pChannelStatsVqe; tPOCT6100_CHANNEL_STATS_CODEC pChannelStatsCodec; pChannelStats = (tPOCT6100_CHANNEL_STATS)&ec_api->u_chan_stats.f_ChannelStats; printf("%10s:%2d: Echo Channel Operation Mode\t\t\t: %s\n", ec_api->devname, - channel, + fe_chan, (pChannelStats->ulEchoOperationMode==cOCT6100_ECHO_OP_MODE_NORMAL)? "NORMAL": (pChannelStats->ulEchoOperationMode==cOCT6100_ECHO_OP_MODE_HT_FREEZE)? @@ -416,10 +461,10 @@ static int wanec_api_print_full_chan_stats(wan_ec_api_t *ec_api, int channel) "SPEECH RECOGNITION": "Unknown"); printf("%10s:%2d: Enable Tone Disabler\t\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fEnableToneDisabler==TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: Mute Ports\t\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->ulMutePortsMask==cOCT6100_CHANNEL_MUTE_PORT_RIN) ? "RIN" : (pChannelStats->ulMutePortsMask==cOCT6100_CHANNEL_MUTE_PORT_ROUT) ? @@ -431,193 +476,240 @@ static int wanec_api_print_full_chan_stats(wan_ec_api_t *ec_api, int channel) (pChannelStats->ulMutePortsMask==cOCT6100_CHANNEL_MUTE_PORT_NONE) ? "NONE" : "Unknown"); printf("%10s:%2d: Enable Extended Tone Detection\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fEnableExtToneDetection==TRUE) ? "TRUE" : "FALSE"); if (pChannelStats->lCurrentERL == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Current Echo Return Loss\t\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Current Echo Return Loss\t\t\t\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lCurrentERL); } if (pChannelStats->lCurrentERLE == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Current Echo Return Loss Enhancement\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Current Echo Return Loss Enhancement\t\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lCurrentERLE); } if (pChannelStats->lMaxERL == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Maximum value of the ERL\t\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Maximum value of the ERL\t\t\t\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lMaxERL); } if (pChannelStats->lMaxERLE == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Maximum value of the ERLE\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Maximum value of the ERLE\t\t\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lMaxERLE); } if (pChannelStats->ulNumEchoPathChanges == cOCT6100_INVALID_STAT){ printf("%10s:%2d: Number of Echo Path changes\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Number of Echo Path changes\t\t\t: %d\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->ulNumEchoPathChanges); } if (pChannelStats->ulCurrentEchoDelay == cOCT6100_INVALID_STAT){ printf("%10s:%2d: Current Echo Delay\t\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Current Echo Delay\t\t\t\t: %d\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->ulCurrentEchoDelay); } if (pChannelStats->ulMaxEchoDelay == cOCT6100_INVALID_STAT){ printf("%10s:%2d: Maximum Echo Delay\t\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Maximum Echo Delay\t\t\t\t: %d\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->ulMaxEchoDelay); } if (pChannelStats->ulToneDisablerStatus == cOCT6100_INVALID_STAT){ printf("%10s:%2d: Tone Disabler Status\t\t\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Tone Disabler Status\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->ulToneDisablerStatus==cOCT6100_TONE_DISABLER_EC_DISABLED)? "Disabled":"Enabled"); } printf("%10s:%2d: Voice activity is detected on SIN port\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fSinVoiceDetected==TRUE)? "TRUE": (pChannelStats->fSinVoiceDetected==FALSE)? "FALSE": "Unknown"); printf("%10s:%2d: Echo canceller has detected and converged\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStats->fEchoCancellerConverged==TRUE)? "TRUE": (pChannelStats->fEchoCancellerConverged==FALSE)? "FALSE": "Unknown"); if (pChannelStats->lRinLevel == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Average power of signal level on RIN\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Average power of signal level on RIN\t\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lRinLevel); } if (pChannelStats->lSinLevel == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Average power of signal level on SIN\t\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Average power of signal level on SIN\t\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lSinLevel); } if (pChannelStats->lRinAppliedGain == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Current gain applied to signal level on RIN\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Current gain applied to signal level on RIN\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lRinAppliedGain); } if (pChannelStats->lSoutAppliedGain == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Current gain applied to signal level on SOUT\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Current gain applied to signal level on SOUT\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lSoutAppliedGain); } if (pChannelStats->lComfortNoiseLevel == cOCT6100_INVALID_SIGNED_STAT){ printf("%10s:%2d: Average power of the comfort noise injected\t: Invalid\n", - ec_api->devname, channel); + ec_api->devname, fe_chan); }else{ printf("%10s:%2d: Average power of the comfort noise injected\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStats->lComfortNoiseLevel); } + pChannelStatsTdm = &pChannelStats->TdmConfig; + printf("%10s:%2d: (TDM) PCM Law type on SIN\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulSinPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on SIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSinTimeslot); + printf("%10s:%2d: (TDM) TDM stream on SIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSinStream); + printf("%10s:%2d: (TDM) PCM Law type on RIN\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulRinPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on RIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRinTimeslot); + printf("%10s:%2d: (TDM) TDM stream on RIN port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRinStream); + printf("%10s:%2d: (TDM) PCM Law type on SOUT\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulSoutPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on SOUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSoutTimeslot); + printf("%10s:%2d: (TDM) TDM stream on SOUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulSoutStream); + printf("%10s:%2d: (TDM) PCM Law type on ROUT\t\t\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsTdm->ulRoutPcmLaw == cOCT6100_PCM_U_LAW) ? "ULAW" : "ALAW"); + printf("%10s:%2d: (TDM) TDM timeslot on ROUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRoutTimeslot); + printf("%10s:%2d: (TDM) TDM stream on ROUT port\t\t\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsTdm->ulRoutStream); + pChannelStatsVqe = &pChannelStats->VqeConfig; printf("%10s:%2d: (VQE) NLP status\t\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fEnableNlp == TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: (VQE) Enable Tail Displacement\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fEnableTailDisplacement == TRUE) ? "TRUE" : "FALSE"); + printf("%10s:%2d: (VQE) Offset of the Echo Cancellation window (ms)\t: %d\n", + ec_api->devname, fe_chan, + pChannelStatsVqe->ulTailDisplacement); printf("%10s:%2d: (VQE) Maximum tail length\t\t\t: %d ms\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->ulTailLength); printf("%10s:%2d: (VQE) Rin Level control mode\t\t\t: %s\n", - ec_api->devname, channel, - (pChannelStatsVqe->fRinLevelControl == TRUE) ? "Enable" : "BYPASSED"); + ec_api->devname, fe_chan, + (pChannelStatsVqe->fRinLevelControl == TRUE) ? "Enable" : "TRUE"); printf("%10s:%2d: (VQE) Rin Control Signal gain\t\t\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->lRinLevelControlGainDb); printf("%10s:%2d: (VQE) Sout Level control mode\t\t\t: %s\n", - ec_api->devname, channel, - (pChannelStatsVqe->fSoutLevelControl == TRUE) ? "Enable" : "BYPASSED"); + ec_api->devname, fe_chan, + (pChannelStatsVqe->fSoutLevelControl == TRUE) ? "Enable" : "TRUE"); printf("%10s:%2d: (VQE) Sout Control Signal gain\t\t\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->lSoutLevelControlGainDb); printf("%10s:%2d: (VQE) RIN Automatic Level Control\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fRinAutomaticLevelControl == TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: (VQE) RIN Target Level Control\t\t\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->lRinAutomaticLevelControlTargetDb); printf("%10s:%2d: (VQE) SOUT Automatic Level Control\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fSoutAutomaticLevelControl == TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: (VQE) SOUT Target Level Control\t\t\t: %d dBm0\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->lSoutAutomaticLevelControlTargetDb); printf("%10s:%2d: (VQE) Comfort noise mode\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_NORMAL) ? "NORMAL" : (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_FAST_LATCH) ? "FAST LATCH" : (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_EXTENDED) ? "EXTENDED" : (pChannelStatsVqe->ulComfortNoiseMode == cOCT6100_COMFORT_NOISE_OFF) ? "OFF" : "UNKNOWN"); + printf("%10s:%2d: (VQE) Remove any DTMF tone detection on SIN port\t: %s\n", + ec_api->devname, fe_chan, + (pChannelStatsVqe->fDtmfToneRemoval == TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: (VQE) Acoustic Echo\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->fAcousticEcho == TRUE) ? "TRUE" : "FALSE"); printf("%10s:%2d: (VQE) Non Linearity Behavior A\t\t\t: %d\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->ulNonLinearityBehaviorA); printf("%10s:%2d: (VQE) Non Linearity Behavior B\t\t\t: %d\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->ulNonLinearityBehaviorB); printf("%10s:%2d: (VQE) Double Talk algorithm\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsVqe->ulDoubleTalkBehavior==cOCT6100_DOUBLE_TALK_BEH_NORMAL)?"NORMAL": "LESS AGGRESSIVE"); printf("%10s:%2d: (VQE) Default ERL (not converged)\t\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->lDefaultErlDb); printf("%10s:%2d: (VQE) Acoustic Echo Cancellation default ERL\t: %d dB\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->lAecDefaultErlDb); printf("%10s:%2d: (VQE) Maximum Acoustic Echo tail length\t\t: %d ms\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, pChannelStatsVqe->ulAecTailLength); + printf("%10s:%2d: (VQE) Attenuation Level applied to the noise signal\t: %d dB\n", + ec_api->devname, fe_chan, + pChannelStatsVqe->lAnrSnrEnhancementDb); pChannelStatsCodec = &pChannelStats->CodecConfig; printf("%10s:%2d: (CODEC) Encoder channel port\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsCodec->ulEncoderPort == cOCT6100_CHANNEL_PORT_ROUT) ? "ROUT": (pChannelStatsCodec->ulEncoderPort == cOCT6100_CHANNEL_PORT_SOUT) ? "SOUT":"NO ENCODING"); printf("%10s:%2d: (CODEC) Encoder rate\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsCodec->ulEncodingRate == cOCT6100_G711_64KBPS) ? "G.711 64 kBps": (pChannelStatsCodec->ulEncodingRate == cOCT6100_G726_40KBPS) ? "G.726 40 kBps": (pChannelStatsCodec->ulEncodingRate == cOCT6100_G726_32KBPS) ? "G.726 32 kBps": @@ -634,11 +726,11 @@ static int wanec_api_print_full_chan_stats(wan_ec_api_t *ec_api, int channel) (pChannelStatsCodec->ulEncodingRate == cOCT6100_G727_16KBPS_2_0) ? "G.727 16 kBps (2:0)": "UNKNOWN"); printf("%10s:%2d: (CODEC) Decoder channel port\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsCodec->ulDecoderPort == cOCT6100_CHANNEL_PORT_RIN) ? "RIN": (pChannelStatsCodec->ulDecoderPort == cOCT6100_CHANNEL_PORT_SIN) ? "SIN":"NO DECODING"); printf("%10s:%2d: (CODEC) Decoder rate\t\t\t\t: %s\n", - ec_api->devname, channel, + ec_api->devname, fe_chan, (pChannelStatsCodec->ulDecodingRate == cOCT6100_G711_64KBPS) ? "G.711 64 kBps": (pChannelStatsCodec->ulDecodingRate == cOCT6100_G726_40KBPS) ? "G.726 40 kBps": (pChannelStatsCodec->ulDecodingRate == cOCT6100_G726_32KBPS) ? "G.726 32 kBps": @@ -673,128 +765,166 @@ int wanec_api_init(void) return 0; } -int wanec_api_config( char* devname, - int verbose) +int wanec_api_config( char *devname, + int verbose, + wanec_api_config_t *conf) { - memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = WAN_EC_CMD_CONFIG; ec_api.verbose = wanec_api_verbose(verbose); - return wanec_api_lib_config(&ec_api, 1); + ec_api.cmd = WAN_EC_API_CMD_CONFIG; + if (conf->conf.param_no){ + memcpy( &ec_api.custom_conf, + &conf->conf, + sizeof(wan_custom_conf_t)); + } + return wanec_api_lib_cmd(&ec_api); //return wanec_api_lib_config(&ec_api, 1); } -int wanec_api_release( char* devname, - int verbose) +int wanec_api_release( char *devname, + int verbose, + wanec_api_release_t *release) { - + memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = WAN_EC_CMD_RELEASE; ec_api.verbose = wanec_api_verbose(verbose); + ec_api.cmd = WAN_EC_API_CMD_RELEASE; return wanec_api_lib_cmd(&ec_api); } -int wanec_api_enable( char* devname, - unsigned long channel_map, - int verbose) +int wanec_api_mode( char *devname, + int verbose, + wanec_api_mode_t *mode) { memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = WAN_EC_CMD_ENABLE; ec_api.verbose = wanec_api_verbose(verbose); - ec_api.channel_map = channel_map; + ec_api.cmd = (mode->enable) ? + WAN_EC_API_CMD_ENABLE : + WAN_EC_API_CMD_DISABLE; + ec_api.fe_chan_map = mode->fe_chan_map; return wanec_api_lib_cmd(&ec_api); } -int wanec_api_disable( char* devname, - unsigned long channel_map, - int verbose) +int wanec_api_bypass( char *devname, + int verbose, + wanec_api_bypass_t *bypass) { memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = WAN_EC_CMD_DISABLE; - ec_api.verbose = wanec_api_verbose(verbose); - ec_api.channel_map = channel_map; - return wanec_api_lib_cmd(&ec_api); -} - -int wanec_api_bypass( char* devname, - int enable, - unsigned long channel_map, - int verbose) -{ - - memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = (enable) ? - WAN_EC_CMD_BYPASS_ENABLE : - WAN_EC_CMD_BYPASS_DISABLE; ec_api.verbose = wanec_api_verbose(verbose); - ec_api.channel_map = channel_map; + ec_api.cmd = (bypass->enable) ? + WAN_EC_API_CMD_BYPASS_ENABLE : + WAN_EC_API_CMD_BYPASS_DISABLE; + ec_api.fe_chan_map = bypass->fe_chan_map; return wanec_api_lib_cmd(&ec_api); } -int wanec_api_mode( char* devname, - int mode, - unsigned long channel_map, - int verbose) +int wanec_api_opmode( char *devname, + int verbose, + wanec_api_opmode_t *opmode) { memcpy(ec_api.devname, devname, strlen(devname)); - switch(mode){ - case 0: - ec_api.cmd = WAN_EC_CMD_MODE_POWERDOWN; + ec_api.verbose = wanec_api_verbose(verbose); + ec_api.cmd = WAN_EC_API_CMD_OPMODE; + ec_api.fe_chan_map = opmode->fe_chan_map; + switch(opmode->mode){ + case WANEC_API_OPMODE_NORMAL: + ec_api.u_chan_opmode.opmode = cOCT6100_ECHO_OP_MODE_NORMAL; break; - case 1: - ec_api.cmd = WAN_EC_CMD_MODE_NORMAL; + case WANEC_API_OPMODE_HT_FREEZE: + ec_api.u_chan_opmode.opmode = cOCT6100_ECHO_OP_MODE_HT_FREEZE; break; - case 2: - ec_api.cmd = WAN_EC_CMD_MODIFY_CHANNEL; + case WANEC_API_OPMODE_HT_RESET: + ec_api.u_chan_opmode.opmode = cOCT6100_ECHO_OP_MODE_HT_RESET; + break; + case WANEC_API_OPMODE_POWER_DOWN: + ec_api.u_chan_opmode.opmode = cOCT6100_ECHO_OP_MODE_POWER_DOWN; + break; + case WANEC_API_OPMODE_NO_ECHO: + ec_api.u_chan_opmode.opmode = cOCT6100_ECHO_OP_MODE_NO_ECHO; + break; + case WANEC_API_OPMODE_SPEECH_RECOGNITION: + ec_api.u_chan_opmode.opmode = cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION; break; default: return -EINVAL; } - ec_api.verbose = wanec_api_verbose(verbose); - ec_api.channel_map = channel_map; return wanec_api_lib_cmd(&ec_api); } -int wanec_api_dtmf( char* devname, - int enable, - unsigned long channel_map, - unsigned char port, - unsigned char type, - int verbose) +int wanec_api_modify( char *devname, + int verbose, + wanec_api_modify_t *modify) { memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = (enable) ? - WAN_EC_CMD_DTMF_ENABLE : - WAN_EC_CMD_DTMF_DISABLE; - ec_api.verbose = wanec_api_verbose(verbose); - ec_api.channel_map = channel_map; - ec_api.u_dtmf_config.port = port; //WAN_EC_CHANNEL_PORT_SOUT; - ec_api.u_dtmf_config.type = type; //WAN_EC_TONE_PRESENT; + ec_api.verbose = wanec_api_verbose(verbose); + ec_api.cmd = WAN_EC_API_CMD_MODIFY_CHANNEL; + ec_api.fe_chan_map = modify->fe_chan_map; + if (modify->conf.param_no){ + memcpy( &ec_api.custom_conf, + &modify->conf, + sizeof(wan_custom_conf_t)); + } return wanec_api_lib_cmd(&ec_api); } -int wanec_api_stats( char* devname, - int full, - int channel, - int reset, - int verbose) +int wanec_api_mute( char *devname, + int verbose, + wanec_api_mute_t *mute) +{ + + memcpy(ec_api.devname, devname, strlen(devname)); + ec_api.verbose = wanec_api_verbose(verbose); + switch(mute->mode){ + case 1: + ec_api.cmd = WAN_EC_API_CMD_CHANNEL_MUTE; + break; + case 2: + ec_api.cmd = WAN_EC_API_CMD_CHANNEL_UNMUTE; + break; + default: + return -EINVAL; + } + ec_api.fe_chan_map = mute->fe_chan_map; + ec_api.u_chan_mute.port_map = mute->port_map; + return wanec_api_lib_cmd(&ec_api); +} + +int wanec_api_dtmf( char *devname, + int verbose, + wanec_api_dtmf_t *dtmf) +{ + + memcpy(ec_api.devname, devname, strlen(devname)); + ec_api.verbose = wanec_api_verbose(verbose); + ec_api.cmd = (dtmf->enable) ? + WAN_EC_API_CMD_DTMF_ENABLE : + WAN_EC_API_CMD_DTMF_DISABLE; + ec_api.fe_chan_map = dtmf->fe_chan_map; + ec_api.u_dtmf_config.port_map = dtmf->port_map; + ec_api.u_dtmf_config.type = dtmf->type_map; + return wanec_api_lib_cmd(&ec_api); +} + +int wanec_api_stats( char *devname, + int verbose, + wanec_api_stats_t *stats) { int err; memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = (full) ? - WAN_EC_CMD_STATS_FULL : - WAN_EC_CMD_STATS; - ec_api.verbose = wanec_api_verbose(verbose); - if (channel){ - ec_api.channel_map = (1 << channel); - ec_api.u_chan_stats.reset = reset; + ec_api.verbose = wanec_api_verbose(verbose); + ec_api.cmd = (stats->full) ? + WAN_EC_API_CMD_STATS_FULL : + WAN_EC_API_CMD_STATS; + if (stats->fe_chan){ + ec_api.fe_chan_map = (1 << stats->fe_chan); + ec_api.u_chan_stats.reset = stats->reset; }else{ - ec_api.channel_map = 0; - ec_api.u_chip_stats.reset = reset; + ec_api.fe_chan_map = 0; + ec_api.u_chip_stats.reset = stats->reset; #if 0 if (full){ ec_api.u_chip_stats.f_ChipImageInfo = @@ -808,103 +938,101 @@ int wanec_api_stats( char* devname, if (err) return err; if (ec_api.err) return 0; - if (channel){ - if (ec_api.cmd == WAN_EC_CMD_STATS){ - err = wanec_api_print_chan_stats(&ec_api, channel); + if (!stats->silent){ + if (stats->fe_chan){ + if (ec_api.cmd == WAN_EC_API_CMD_STATS){ + err = wanec_api_print_chan_stats( + &ec_api, stats->fe_chan); + }else{ + err = wanec_api_print_full_chan_stats( + &ec_api, stats->fe_chan); + } }else{ - err = wanec_api_print_full_chan_stats(&ec_api, channel); - } - }else{ - if (ec_api.cmd == WAN_EC_CMD_STATS){ - err = wanec_api_print_chip_stats(&ec_api); - }else{ - err = wanec_api_print_full_chip_stats(&ec_api); + if (ec_api.cmd == WAN_EC_API_CMD_STATS){ + err = wanec_api_print_chip_stats(&ec_api); + }else{ + err = wanec_api_print_full_chip_stats(&ec_api); + } } } return err; } -int wanec_api_tone_load(char* devname, - char* tone, - int verbose) +int wanec_api_buffer_load(char *devname, + int verbose, + wanec_api_bufferload_t *bufferload) { int err; memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = WAN_EC_CMD_TONE_LOAD; ec_api.verbose = wanec_api_verbose(verbose); - memcpy(ec_api.u_tone_config.tone, tone, strlen(tone)); - - err = wanec_api_lib_toneload(&ec_api); + ec_api.cmd = WAN_EC_API_CMD_BUFFER_LOAD; + memcpy(ec_api.u_buffer_config.buffer, bufferload->buffer, strlen(bufferload->buffer)); + ec_api.u_buffer_config.pcmlaw = (UINT32)bufferload->pcmlaw; + err = wanec_api_lib_bufferload(&ec_api); if (err) return err; - if (ec_api.err) return 0; + if (ec_api.err) return -EINVAL; + bufferload->buffer_id = ec_api.u_buffer_config.buffer_index; return 0; } -int wanec_api_tone_unload( char* devname, - unsigned int tone_id, - int verbose) +int wanec_api_buffer_unload( char *devname, + int verbose, + wanec_api_bufferunload_t *bufferunload) { int err; memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = WAN_EC_CMD_TONE_LOAD; ec_api.verbose = wanec_api_verbose(verbose); - ec_api.u_tone_config.buffer_index = (UINT32)tone_id; + ec_api.cmd = WAN_EC_API_CMD_BUFFER_UNLOAD; + ec_api.u_buffer_config.buffer_index = (UINT32)bufferunload->buffer_id; err = wanec_api_lib_cmd(&ec_api); if (err) return err; if (ec_api.err) return 0; return 0; } -int wanec_api_playout( char* devname, - int start, - int channel, - unsigned int tone_id, - int verbose) +int wanec_api_playout( char *devname, + int verbose, + wanec_api_playout_t *playout) { int err; memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = (start) ? - WAN_EC_CMD_PLAYOUT_START : - WAN_EC_CMD_PLAYOUT_STOP; ec_api.verbose = wanec_api_verbose(verbose); - ec_api.channel = channel; - ec_api.channel_map = (1 << channel); - ec_api.u_playout.index = (UINT32)tone_id; - ec_api.u_playout.duration = 5000; + ec_api.cmd = (playout->start) ? + WAN_EC_API_CMD_PLAYOUT_START : + WAN_EC_API_CMD_PLAYOUT_STOP; + ec_api.fe_chan = playout->fe_chan; + ec_api.fe_chan_map = (1 << playout->fe_chan); + ec_api.u_playout.index = (UINT32)playout->buffer_id; + ec_api.u_playout.port = playout->port; + ec_api.u_playout.repeat_cnt = playout->repeat_cnt; + ec_api.u_playout.duration = playout->duration; + ec_api.u_playout.notifyonstop = playout->notifyonstop; + ec_api.u_playout.user_event_id = playout->user_event_id; err = wanec_api_lib_cmd(&ec_api); if (err) return err; if (ec_api.err) return 0; return 0; } -int wanec_api_monitor( char* devname, - int channel, - int verbose) +int wanec_api_monitor( char *devname, + int verbose, + wanec_api_monitor_t *monitor) { int err; memcpy(ec_api.devname, devname, strlen(devname)); - ec_api.cmd = WAN_EC_CMD_MONITOR; ec_api.verbose = wanec_api_verbose(verbose); - ec_api.channel = channel; - ec_api.channel_map = (1 << channel); + ec_api.cmd = WAN_EC_API_CMD_MONITOR; + ec_api.fe_chan = monitor->fe_chan; + ec_api.fe_chan_map = (1 << monitor->fe_chan); - err = wanec_api_lib_monitor(&ec_api); + err = wanec_api_lib_cmd(&ec_api); //err = wanec_api_lib_monitor(&ec_api); if (err) return err; if (ec_api.err) return 0; return 0; } -int wanec_api_param(char *key, char *value) -{ - strlcpy(ec_api.param[ec_api.param_no].key, - key, MAX_PARAM_LEN); - strlcpy(ec_api.param[ec_api.param_no].value, - value, MAX_VALUE_LEN); - ec_api.param_no++; - return 0; -} diff --git a/util/wanec_apilib/wanec_api.h b/util/wanec_apilib/wanec_api.h index bc8e937..c923115 100644 --- a/util/wanec_apilib/wanec_api.h +++ b/util/wanec_apilib/wanec_api.h @@ -4,19 +4,90 @@ #if !defined(__WANEC_API_H__) # define __WANEC_API_H__ +/* Echo Cancellatio OP MOde defines */ +#define WANEC_API_OPMODE_NORMAL 0 +#define WANEC_API_OPMODE_HT_FREEZE 1 +#define WANEC_API_OPMODE_HT_RESET 2 +#define WANEC_API_OPMODE_POWER_DOWN 3 +#define WANEC_API_OPMODE_NO_ECHO 4 +#define WANEC_API_OPMODE_SPEECH_RECOGNITION 5 + +typedef struct { + wan_custom_conf_t conf; +} wanec_api_config_t; +typedef struct { + int notused; +} wanec_api_release_t; +typedef struct { + int enable; + unsigned long fe_chan_map; +} wanec_api_mode_t; +typedef struct { + int enable; + unsigned long fe_chan_map; +} wanec_api_bypass_t; +typedef struct { + int mode; + unsigned long fe_chan_map; +} wanec_api_opmode_t; +typedef struct { + unsigned long fe_chan_map; + wan_custom_conf_t conf; +} wanec_api_modify_t; +typedef struct { + int mode; + unsigned long fe_chan_map; + unsigned char port_map; +} wanec_api_mute_t; +typedef struct { + int enable; + unsigned long fe_chan_map; + unsigned char port_map; + unsigned char type_map; +} wanec_api_dtmf_t; +typedef struct { + int full; + int fe_chan; + int reset; + int silent; +} wanec_api_stats_t; +typedef struct { + char *buffer; + unsigned char pcmlaw; + unsigned int buffer_id; +} wanec_api_bufferload_t; +typedef struct { + unsigned int buffer_id; +} wanec_api_bufferunload_t; +typedef struct { + int start; + unsigned int buffer_id; + int fe_chan; + unsigned char port; + unsigned int repeat_cnt; + unsigned int duration; + int notifyonstop; + unsigned int user_event_id; +} wanec_api_playout_t; +typedef struct { + int fe_chan; +} wanec_api_monitor_t; + extern int wanec_api_init(void); -extern int wanec_api_param(char *key, char *value); -extern int wanec_api_config(char*,int); -extern int wanec_api_release(char*,int); -extern int wanec_api_enable(char*,unsigned long,int); -extern int wanec_api_disable(char*,unsigned long,int); -extern int wanec_api_bypass(char*,int,unsigned long,int); -extern int wanec_api_mode(char*,int,unsigned long,int); -extern int wanec_api_dtmf(char*,int,unsigned long,unsigned char,unsigned char,int); -extern int wanec_api_stats(char*,int,int,int,int); -extern int wanec_api_tone_load(char*,char*,int); -extern int wanec_api_tone_unload(char*,unsigned int,int); -extern int wanec_api_playout(char*,int,int,unsigned int,int); -extern int wanec_api_monitor(char*,int,int); +extern int wanec_api_param_name(char *key); +extern int wanec_api_param_value(char *value); +extern int wanec_api_config(char*,int,wanec_api_config_t*); +extern int wanec_api_release(char*,int,wanec_api_release_t*); +extern int wanec_api_mode(char*,int,wanec_api_mode_t*); +extern int wanec_api_bypass(char*,int,wanec_api_bypass_t*); +extern int wanec_api_opmode(char*,int,wanec_api_opmode_t*); +extern int wanec_api_modify(char*,int,wanec_api_modify_t*); +extern int wanec_api_mute(char*,int,wanec_api_mute_t*); +extern int wanec_api_dtmf(char*,int,wanec_api_dtmf_t*); +extern int wanec_api_stats(char*,int,wanec_api_stats_t*); +extern int wanec_api_buffer_load(char*,int,wanec_api_bufferload_t*); +extern int wanec_api_buffer_unload(char*,int,wanec_api_bufferunload_t*); +extern int wanec_api_playout(char*,int,wanec_api_playout_t*); +extern int wanec_api_monitor(char*,int,wanec_api_monitor_t*); #endif /* __WANEC_API_H__ */ diff --git a/util/wanec_apilib/wanec_api_lib.c b/util/wanec_apilib/wanec_api_lib.c index a93cc90..935aadd 100644 --- a/util/wanec_apilib/wanec_api_lib.c +++ b/util/wanec_apilib/wanec_api_lib.c @@ -48,8 +48,10 @@ # include # include # include //for offsetof() - +# include +# include # include +# include # include # include # include @@ -68,7 +70,7 @@ wan_udp_hdr_t wan_udp; # include #endif -#include +#include /****************************************************************************** ** DEFINES AND MACROS @@ -76,19 +78,22 @@ wan_udp_hdr_t wan_udp; #define OCT6116_32S_IMAGE_NAME "OCT6116-32S.ima" #define OCT6116_64S_IMAGE_NAME "OCT6116-64S.ima" -#define OCT6126_128S_IMAGE_NAME "OCT6126-128S.ima" +#define OCT6116_128S_IMAGE_NAME "OCT6116-128S.ima" #define OCT6116_256S_IMAGE_NAME "OCT6116-256S.ima" #if !defined(__WINDOWS__) -#define WAN_EC_DIR "/etc/wanpipe/wan_ec" +#define WAN_EC_NAME "wan_ec" +#if defined(__LINUX__) +# define WAN_EC_DIR "/etc/wanpipe/" WAN_EC_NAME +#else +# define WAN_EC_DIR "/usr/local/etc/wanpipe/" WAN_EC_NAME +#endif #define WAN_EC_BUFFERS WAN_EC_DIR "/buffers" -#define WAN_EC_DEBUG "wan_ec_sangoma" - #define OCT6116_32S_IMAGE_PATH WAN_EC_DIR "/" OCT6116_32S_IMAGE_NAME #define OCT6116_64S_IMAGE_PATH WAN_EC_DIR "/" OCT6116_64S_IMAGE_NAME -#define OCT6126_128S_IMAGE_PATH WAN_EC_DIR "/" OCT6126_128S_IMAGE_NAME +#define OCT6116_128S_IMAGE_PATH WAN_EC_DIR "/" OCT6116_128S_IMAGE_NAME #define OCT6116_256S_IMAGE_PATH WAN_EC_DIR "/" OCT6116_256S_IMAGE_NAME #else @@ -99,7 +104,7 @@ char windows_dir[MAX_PATH]; char OCT6116_32S_IMAGE_PATH[MAX_PATH]; char OCT6116_64S_IMAGE_PATH[MAX_PATH]; -char OCT6126_128S_IMAGE_PATH[MAX_PATH]; +char OCT6116_128S_IMAGE_PATH[MAX_PATH]; char OCT6116_256S_IMAGE_PATH[MAX_PATH]; #endif @@ -125,30 +130,30 @@ typedef struct { wanec_image_info_t wanec_image_32 = { 32, cOCT6100_MEMORY_CHIP_SIZE_8MB, - cOCT6100_DEBUG_GET_DATA_MODE_16S, + cOCT6100_DEBUG_GET_DATA_MODE_120S, OCT6116_32S_IMAGE_NAME, OCT6116_32S_IMAGE_PATH }; wanec_image_info_t wanec_image_64 = { 64, cOCT6100_MEMORY_CHIP_SIZE_8MB, - cOCT6100_DEBUG_GET_DATA_MODE_16S, + cOCT6100_DEBUG_GET_DATA_MODE_120S, OCT6116_64S_IMAGE_NAME, OCT6116_64S_IMAGE_PATH }; wanec_image_info_t wanec_image_128 = { 128, cOCT6100_MEMORY_CHIP_SIZE_16MB, cOCT6100_DEBUG_GET_DATA_MODE_120S, - OCT6126_128S_IMAGE_NAME, OCT6126_128S_IMAGE_PATH, + OCT6116_128S_IMAGE_NAME, OCT6116_128S_IMAGE_PATH, }; wanec_image_info_t wanec_image_256 = { 256, cOCT6100_MEMORY_CHIP_SIZE_16MB, - cOCT6100_DEBUG_GET_DATA_MODE_16S, + cOCT6100_DEBUG_GET_DATA_MODE_120S, OCT6116_256S_IMAGE_NAME, OCT6116_256S_IMAGE_PATH }; typedef struct { - int hwec_chan_no; + u_int16_t hwec_chan_no; int images_no; wanec_image_info_t *image_info[5]; } wanec_image_list_t; @@ -194,7 +199,7 @@ struct wan_ec_image { 128, 128, cOCT6100_MEMORY_CHIP_SIZE_16MB, cOCT6100_DEBUG_GET_DATA_MODE_120S, - OCT6126_128S_IMAGE_NAME, OCT6126_128S_IMAGE_PATH, + OCT6116_128S_IMAGE_NAME, OCT6116_128S_IMAGE_PATH, 1, { 256 } }, { 256, @@ -235,12 +240,20 @@ CHAR *ToneBufferPaths[WAN_NUM_PLAYOUT_TONES] = HANDLE wanec_api_lib_open(wan_ec_api_t *ec_api); int wanec_api_lib_close(wan_ec_api_t *ec_api, HANDLE dev); int wanec_api_lib_ioctl(HANDLE dev, wan_ec_api_t *ec_api, int verbose); +int wanec_api_lib_chip_load(HANDLE dev, wan_ec_api_t *ec_api, u_int16_t, int verbose); #else static int wanec_api_lib_open(wan_ec_api_t *ec_api); static int wanec_api_lib_close(wan_ec_api_t *ec_api, int dev); static int wanec_api_lib_ioctl(int dev, wan_ec_api_t *ec_api, int verbose); +int wanec_api_lib_chip_load(int dev, wan_ec_api_t *ec_api, u_int16_t, int verbose); #endif +int wanec_api_lib_config(wan_ec_api_t *ec_api, int verbose); +int wanec_api_lib_bufferload(wan_ec_api_t *ec_api); +int wanec_api_lib_monitor(wan_ec_api_t *ec_api); +int wanec_api_lib_cmd(wan_ec_api_t *ec_api); + + /****************************************************************************** ** FUNCTION DEFINITIONS ******************************************************************************/ @@ -293,12 +306,14 @@ static int wanec_api_lib_ioctl(int dev, wan_ec_api_t *ec_api, int verbose) switch(ec_api->err){ case WAN_EC_API_RC_INVALID_STATE: printf("Failed (Invalid State:%s)!\n", - WAN_OCT6100_STATE_DECODE(ec_api->state)); + WAN_EC_STATE_DECODE(ec_api->state)); break; case WAN_EC_API_RC_FAILED: case WAN_EC_API_RC_INVALID_CMD: case WAN_EC_API_RC_INVALID_DEV: case WAN_EC_API_RC_BUSY: + case WAN_EC_API_RC_INVALID_CHANNELS: + case WAN_EC_API_RC_INVALID_PORT: default: printf("Failed (%s)!\n", WAN_EC_API_RC_DECODE(ec_api->err)); @@ -390,7 +405,7 @@ int wanec_api_lib_ioctl(HANDLE dev, wan_ec_api_t *ec_api, int verbose) switch(ec_api->err){ case WAN_EC_API_RC_INVALID_STATE: printf("Failed (Invalid State:%s)!\n", - WAN_OCT6100_STATE_DECODE(ec_api->state)); + WAN_EC_STATE_DECODE(ec_api->state)); break; case WAN_EC_API_RC_FAILED: case WAN_EC_API_RC_INVALID_CMD: @@ -437,7 +452,7 @@ wanec_api_lib_loadImageFile( wan_ec_api_t *ec_api, pFile = fopen(path, "rb" ); if ( pFile == NULL ){ - printf("ERROR: %s: Failed to open image file %s!\n", + printf("ERROR: %s: Failed to open file (%s)!\n", ec_api->devname, path); return -EINVAL; } @@ -490,8 +505,7 @@ wanec_api_lib_loadImageFile( wan_ec_api_t *ec_api, } /* Oct6100 image path */ -#if 1 -static wanec_image_list_t *wanec_api_lib_image_search(int hwec_chan_no) +static wanec_image_list_t *wanec_api_lib_image_search(u_int16_t hwec_chan_no) { wanec_image_list_t *image_list = &wanec_image_list[0]; @@ -503,54 +517,37 @@ static wanec_image_list_t *wanec_api_lib_image_search(int hwec_chan_no) } return NULL; } -#else -static struct wan_ec_image *wanec_api_lib_image_search(int hwec_chan_no) -{ - struct wan_ec_image *image_info = &wan_ec_image_list[0]; - while(image_info && image_info->hwec_chan_no){ - if (image_info->hwec_chan_no == hwec_chan_no){ - return image_info; - } - image_info++; - } - return NULL; -} -#endif - -int wanec_api_lib_chip_load( #if defined(__WINDOWS__) - HANDLE dev, +int wanec_api_lib_chip_load(HANDLE dev, wan_ec_api_t *ec_api, u_int16_t max_channels,int verbose) #else - int dev, +int wanec_api_lib_chip_load(int dev, wan_ec_api_t *ec_api, u_int16_t max_channels, int verbose) #endif - wan_ec_api_t *ec_api, int verbose) { - static wanec_image_list_t *image_list; - static wanec_image_info_t *image_info; - int err, cnt = 0,image_no = 0; + static wanec_image_list_t *image_list; + static wanec_image_info_t *image_info; + int err, image_no = 0; #if defined(__WINDOWS__) ////////////////////////////////////////////////////////////////////////////////////////// //initialize globals - GetWindowsDirectory(windows_dir, MAX_PATH); + GetSystemWindowsDirectory(windows_dir, MAX_PATH); _snprintf(WAN_EC_DIR, MAX_PATH, "%s\\%s", windows_dir, "sang_ec_files"); _snprintf(OCT6116_32S_IMAGE_PATH, MAX_PATH, "%s\\%s", WAN_EC_DIR, OCT6116_32S_IMAGE_NAME); _snprintf(OCT6116_64S_IMAGE_PATH, MAX_PATH, "%s\\%s", WAN_EC_DIR, OCT6116_64S_IMAGE_NAME); - _snprintf(OCT6126_128S_IMAGE_PATH, MAX_PATH, "%s\\%s", WAN_EC_DIR, OCT6126_128S_IMAGE_NAME); + _snprintf(OCT6116_128S_IMAGE_PATH, MAX_PATH, "%s\\%s", WAN_EC_DIR, OCT6116_128S_IMAGE_NAME); _snprintf(OCT6116_256S_IMAGE_PATH, MAX_PATH, "%s\\%s", WAN_EC_DIR, OCT6116_256S_IMAGE_NAME); #endif - if(ec_api->u_info.max_channels == 0){ + if (max_channels == 0){ printf("ERROR: %s: this card does NOT have Echo Canceller chip!\n", ec_api->devname); return -EINVAL; } - printf("Searching image for %d channels...\n", ec_api->u_info.max_channels); + printf("Searching image for %d channels...\n", max_channels); -#if 1 - image_list = wanec_api_lib_image_search(ec_api->u_info.max_channels); + image_list = wanec_api_lib_image_search(max_channels); while(image_no < image_list->images_no){ image_info = image_list->image_info[image_no]; if (image_info == NULL){ @@ -558,7 +555,7 @@ int wanec_api_lib_chip_load( printf( "ERROR: %s: Failed to find image file to EC chip (max=%d)!\n", ec_api->devname, - ec_api->u_info.max_channels); + max_channels); return -EINVAL; } @@ -569,13 +566,12 @@ int wanec_api_lib_chip_load( printf("Found Image path: %s\n", image_info->image_path); #endif - ec_api->u_config.max_channels = ec_api->u_info.max_channels; + ec_api->u_config.max_channels = max_channels; ec_api->u_config.memory_chip_size = image_info->memory_chip_size; ec_api->u_config.debug_data_mode = image_info->debug_data_mode; if (image_no+1 == image_list->images_no){ ec_api->u_config.imageLast = WANOPT_YES; } - /* Load the image file */ err = wanec_api_lib_loadImageFile( ec_api, image_info->image_path, @@ -584,35 +580,37 @@ int wanec_api_lib_chip_load( if (err){ return -EINVAL; } - ec_api->cmd = WAN_EC_CMD_CONFIG; + ec_api->cmd = WAN_EC_API_CMD_CONFIG; err = wanec_api_lib_ioctl(dev, ec_api, verbose); if (err || ec_api->err){ free(ec_api->u_config.imageData); return (err) ? -EINVAL : 0; } free(ec_api->u_config.imageData); - cnt = 0; + ec_api->u_config_poll.cnt = 0; config_poll: - ec_api->cmd = WAN_EC_CMD_GETINFO; + ec_api->cmd = WAN_EC_API_CMD_CONFIG_POLL; err = wanec_api_lib_ioctl(dev, ec_api, verbose); if (err || ec_api->err){ wanec_api_lib_close(ec_api, dev); return (err) ? -EINVAL : 0; } - if (ec_api->state == WAN_OCT6100_STATE_CHIP_OPEN_PENDING){ + if (ec_api->state == WAN_EC_STATE_CHIP_OPEN_PENDING){ sleep(5); printf("."); - if (cnt++ < 10) goto config_poll; + if (ec_api->u_config_poll.cnt++ < WANEC_API_MAX_CONFIG_POLL){ + goto config_poll; + } } - if (ec_api->state != WAN_OCT6100_STATE_CHIP_OPEN && - ec_api->state != WAN_OCT6100_STATE_CHIP_READY){ + if (ec_api->state != WAN_EC_STATE_CHIP_OPEN && + ec_api->state != WAN_EC_STATE_CHIP_READY){ image_no ++; continue; } break; } - if (ec_api->state != WAN_OCT6100_STATE_CHIP_OPEN && - ec_api->state != WAN_OCT6100_STATE_CHIP_READY){ + if (ec_api->state != WAN_EC_STATE_CHIP_OPEN && + ec_api->state != WAN_EC_STATE_CHIP_READY){ printf("Timeout!\n"); return -EINVAL; } @@ -625,9 +623,10 @@ int wanec_api_lib_config(wan_ec_api_t *ec_api, int verbose) #if !defined(__WINDOWS__) int dev; #else - HANDLE dev; + HANDLE dev; #endif - int err; + u_int16_t hwec_max_channels = 0; + int err; printf("%s: Configuring Echo Canceller device...\t", ec_api->devname); @@ -642,118 +641,48 @@ int wanec_api_lib_config(wan_ec_api_t *ec_api, int verbose) return -ENXIO; } - ec_api->cmd = WAN_EC_CMD_GETINFO; + ec_api->cmd = WAN_EC_API_CMD_GETINFO; err = wanec_api_lib_ioctl(dev, ec_api, verbose); if (err || ec_api->err){ wanec_api_lib_close(ec_api, dev); return (err) ? -EINVAL : 0; } + hwec_max_channels = ec_api->u_info.max_channels; - if (ec_api->state == WAN_OCT6100_STATE_RESET){ - if (wanec_api_lib_chip_load(dev, ec_api, verbose)){ + if (ec_api->state == WAN_EC_STATE_RESET){ + if (wanec_api_lib_chip_load(dev, ec_api, hwec_max_channels, verbose)){ wanec_api_lib_close(ec_api, dev); return -EINVAL; } } - if (ec_api->state != WAN_OCT6100_STATE_CHIP_OPEN && - ec_api->state != WAN_OCT6100_STATE_CHIP_READY){ + if (ec_api->state != WAN_EC_STATE_CHIP_OPEN && + ec_api->state != WAN_EC_STATE_CHIP_READY){ printf("%s: WARNING: Incorrect Echo Canceller state (%s)!\n", ec_api->devname, - WAN_OCT6100_STATE_DECODE(ec_api->state)); + WAN_EC_STATE_DECODE(ec_api->state)); return -EINVAL; } /* Open all channels */ - ec_api->cmd = WAN_EC_CMD_CHANNEL_OPEN; + ec_api->cmd = WAN_EC_API_CMD_CHANNEL_OPEN; err = wanec_api_lib_ioctl(dev, ec_api, verbose); if (err || ec_api->err){ wanec_api_lib_close(ec_api, dev); return (err) ? -EINVAL : 0; } -#else - - image_info = wanec_api_lib_image_search(ec_api->u_info.max_channels); -try_another_image: - if (image_info == NULL){ - printf("Failed!\n\n"); - printf( - "ERROR: %s: Failed to find image file to EC chip (max=%d)!\n", - ec_api->devname, - ec_api->u_info.max_channels); - wanec_api_lib_close(ec_api, dev); - return -EINVAL; - } - -#if defined(__WINDOWS__) - printf("Found Image path: %s\n", image_info->image_path); -#endif - - ec_api->u_config.max_channels = ec_api->u_info.max_channels; - ec_api->u_config.memory_chip_size = image_info->memory_chip_size; - ec_api->u_config.debug_data_mode = image_info->debug_data_mode; - - /* Load the image file */ - err = wanec_api_lib_loadImageFile( ec_api, - image_info->image_path, - &ec_api->u_config.imageData, - &ec_api->u_config.imageSize); - if (err){ - wanec_api_lib_close(ec_api, dev); - return -EINVAL; - } - ec_api->cmd = WAN_EC_CMD_CONFIG; - err = wanec_api_lib_ioctl(dev, ec_api, verbose); - if (err || ec_api->err){ - free(ec_api->u_config.imageData); - wanec_api_lib_close(ec_api, dev); - return (err) ? -EINVAL : 0; - } - free(ec_api->u_config.imageData); -config_poll: - ec_api->cmd = WAN_EC_CMD_GETINFO; - err = wanec_api_lib_ioctl(dev, ec_api, verbose); - if (err || ec_api->err){ - wanec_api_lib_close(ec_api, dev); - return (err) ? -EINVAL : 0; - } - if (ec_api->state == WAN_OCT6100_STATE_CHIP_OPEN_PENDING){ - sleep(5); - printf("."); - if (cnt++ < 10) goto config_poll; - } - if (ec_api->state != WAN_OCT6100_STATE_CHIP_OPEN && - ec_api->state != WAN_OCT6100_STATE_CHIP_READY){ - if (image_info->hwec_opt_no > opt_no){ - ec_api->u_info.max_channels = image_info->hwec_opt[opt_no]; - opt_no++; - goto try_another_image; - } - printf("Timeout!\n"); - wanec_api_lib_close(ec_api, dev); - return -EINVAL; - } - - /* Open all channels */ - ec_api->cmd = WAN_EC_CMD_CHANNEL_OPEN; - err = wanec_api_lib_ioctl(dev, ec_api, verbose); - if (err || ec_api->err){ - wanec_api_lib_close(ec_api, dev); - return (err) ? -EINVAL : 0; - } -#endif printf("Done!\n"); wanec_api_lib_close(ec_api, dev); return err; } -int wanec_api_lib_toneload(wan_ec_api_t *ec_api) +int wanec_api_lib_bufferload(wan_ec_api_t *ec_api) { - char tone_path[100]; - int err = 0; + char buffer_path[100]; + int err = 0; #if !defined(__WINDOWS__) - int dev; + int dev; #else HANDLE dev; #endif @@ -769,27 +698,32 @@ int wanec_api_lib_toneload(wan_ec_api_t *ec_api) printf("Failed (Device open)!\n"); return -ENXIO; } - - sprintf(tone_path, "%s/%s.pcm", WAN_EC_BUFFERS, ec_api->u_tone_config.tone); +#if !defined(__WINDOWS__) + sprintf(buffer_path, "%s/%s.pcm", WAN_EC_BUFFERS, ec_api->u_buffer_config.buffer); +#else + GetSystemWindowsDirectory(windows_dir, MAX_PATH); + _snprintf(WAN_EC_BUFFERS, MAX_PATH, "%s\\%s", windows_dir, "sang_ec_files"); + sprintf(buffer_path, "%s\\%s.pcm", WAN_EC_BUFFERS, ec_api->u_buffer_config.buffer); +#endif err = wanec_api_lib_loadImageFile( ec_api, - tone_path, - &ec_api->u_tone_config.data, - &ec_api->u_tone_config.size); + buffer_path, + &ec_api->u_buffer_config.data, + &ec_api->u_buffer_config.size); if (err){ printf("Failed!\n"); - goto tone_load_done; + goto buffer_load_done; } err = wanec_api_lib_ioctl(dev, ec_api, ec_api->verbose); if (err || ec_api->err){ - goto tone_load_done; + goto buffer_load_done; } - printf("Done (Index=%d)!\n", ec_api->u_tone_config.buffer_index); + printf("Done!\n"); -tone_load_done: +buffer_load_done: wanec_api_lib_close(ec_api, dev); - if (ec_api->u_tone_config.data){ - free(ec_api->u_tone_config.data); + if (ec_api->u_buffer_config.data){ + free(ec_api->u_buffer_config.data); } return err; @@ -799,7 +733,7 @@ int wanec_api_lib_monitor(wan_ec_api_t *ec_api) { int dev, err=0; #if !defined(__WINDOWS__) - if (ec_api->channel){ + if (ec_api->fe_chan){ dev = wanec_api_lib_open(ec_api); if (dev < 0){ @@ -808,7 +742,7 @@ int wanec_api_lib_monitor(wan_ec_api_t *ec_api) printf("%s: Start monitorting the channel %d ...", ec_api->devname, - ec_api->channel); + ec_api->fe_chan); err = wanec_api_lib_ioctl(dev, ec_api, 1); if (err || ec_api->err){ wanec_api_lib_close(ec_api, dev); @@ -821,7 +755,7 @@ int wanec_api_lib_monitor(wan_ec_api_t *ec_api) FILE *output = NULL; size_t len; int cnt = 0; - char filename[MAXPATHLEN]; + char filename[MAXPATHLEN]; printf("%s: Reading Monitor Data ..", ec_api->devname); @@ -830,7 +764,7 @@ int wanec_api_lib_monitor(wan_ec_api_t *ec_api) if (dev < 0){ return ENXIO; } - ec_api->channel = 0; + ec_api->fe_chan = 0; ec_api->u_chan_monitor.remain_len = 0; ec_api->u_chan_monitor.remain_len = 0; ec_api->u_chan_monitor.data_len = 0; @@ -848,9 +782,9 @@ int wanec_api_lib_monitor(wan_ec_api_t *ec_api) gettimeofday(&tv, NULL); localtime_r((time_t*)&tv.tv_sec, &t); snprintf(filename, MAXPATHLEN, - "%s_chan%d_%d.%d.%d_%d.%d.%d.bin", - WAN_EC_DEBUG, - ec_api->channel, + "%s_%s_chan%d_%d.%d.%d_%d.%d.%d.bin", + WAN_EC_NAME, + ec_api->devname, ec_api->fe_chan, t.tm_mon,t.tm_mday,1900+t.tm_year, t.tm_hour,t.tm_min,t.tm_sec); output = fopen(filename, "wb"); @@ -894,24 +828,33 @@ int wanec_api_lib_cmd(wan_ec_api_t *ec_api) HANDLE dev; #endif - dev = wanec_api_lib_open(ec_api); + switch(ec_api->cmd){ + case WAN_EC_API_CMD_CONFIG: + return wanec_api_lib_config(ec_api, 1); + case WAN_EC_API_CMD_MONITOR: + return wanec_api_lib_monitor(ec_api); + default: + dev = wanec_api_lib_open(ec_api); #if !defined(__WINDOWS__) - if (dev < 0){ + if (dev < 0){ #else - if (dev == INVALID_HANDLE_VALUE){ + if (dev == INVALID_HANDLE_VALUE){ #endif - printf("Failed (Device open)!\n"); - return -ENXIO; - } - printf("%s: Running %s command to Echo Canceller device...\t", - ec_api->devname, - WAN_EC_CMD_DECODE(ec_api->cmd)); - err = wanec_api_lib_ioctl(dev, ec_api, 1); - if (err || ec_api->err){ + printf("Failed (Device open)!\n"); + return -ENXIO; + } + printf("%s: Running %s command to Echo Canceller device...\t", + ec_api->devname, + WAN_EC_API_CMD_DECODE(ec_api->cmd)); + err = wanec_api_lib_ioctl(dev, ec_api, 1); + if (err || ec_api->err){ + wanec_api_lib_close(ec_api, dev); + return (err) ? -EINVAL : 0; + } + printf("Done!\n\n"); wanec_api_lib_close(ec_api, dev); - return (err) ? -EINVAL : 0; + break; } - printf("Done!\n"); - wanec_api_lib_close(ec_api, dev); return 0; } + diff --git a/util/wanec_client/.#Makefile.Linux.1.15 b/util/wanec_client/.#Makefile.Linux.1.15 new file mode 100755 index 0000000..727fbaf --- /dev/null +++ b/util/wanec_client/.#Makefile.Linux.1.15 @@ -0,0 +1,62 @@ +# ============================================================================ +# Makefile WAN Echo Canceler Chip configurator. Make Script. +# +# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved. +# ---------------------------------------------------------------------------- +# Augc 25, 2005 Alex Feldman Initial version. +# ============================================================================ + +####### DEFINES ############################################################## + +# Build Options. +PROD = wan_ec_setup +VERSION = 1.0 +DEBUG = 2 +YACC = yacc + +# Project File Paths. +TMPDIR = tmp +OUTDIR = mod/ +SYSINC = /lib/modules/$(shell uname -r)/build/include +VPATH = $(LOCINC):$(TMPDIR) +ARCH = $(shell uname -m) +DIR_EC_APILIB = ../wanec_apilib + +PRODS=wan_ec_client +SRC_CLIENT=wan_ecmain.c y.tab.c wan_ec_argl.c + +SRC_EC_APILIB=$(DIR_EC_APILIB)/wanec_api.c $(DIR_EC_APILIB)/wanec_api_lib.c +INC_EC_APILIB=-I/usr/include/wanpipe/oct6100_api -I$(DIR_EC_APILIB) + +CFLAGS = -Wall -O2 -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_TDMV_EC -D_DEBUG_=$(DEBUG) -D_GNUC_ +CFLAGS += -I$(SYSINC) -I/usr/include/wanpipe $(INC_EC_APILIB) $(EXTRA_FLAGS) -DCONFIG_PRODUCT_WANPIPE_AFT_BRI + +#$(WANEC_DIR) -I$(WANEC_DIR)/oct6100_api/include -I$(WANEC_DIR)/oct6100_api/octdeviceapi/oct6100api/ + +####### RULES ################################################################ + +all: $(PRODS) + @echo "Ok." + +wan_ec_client: $(SRC_CLIENT) $(SRC_EC_APILIB) + $(CC) $(CFLAGS) -o $@ $^ + +y.tab.c: + $(YACC) -d wan_ec_arg.y + +wan_ec_argl.c: + $(LEX) -owan_ec_argl.c wan_ec_arg.l + +install: + @echo "Installing Wanpipe EC API in $(WAN_VIRTUAL)/usr/sbin" + install $(PRODS) $(WAN_VIRTUAL)/usr/sbin/ + +uninstall: + @echo "Un-installing Wanpipe EC API from $(WAN_VIRTUAL)/usr/sbin" + rm -f $(WAN_VIRTUAL)/usr/sbin/$(PRODS) + +clean: + rm -f $(PRODS) + rm -f y.tab.c + rm -f y.tab.h + rm -f wan_ec_argl.c diff --git a/util/wanec_client/Makefile b/util/wanec_client/Makefile deleted file mode 100755 index 6c9dd59..0000000 --- a/util/wanec_client/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# ============================================================================ -# Makefile WAN Echo Canceler Chip configurator. Make Script. -# -# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved. -# ---------------------------------------------------------------------------- -# Augc 25, 2005 Alex Feldman Initial version. -# ============================================================================ - -####### DEFINES ############################################################## - -# Build Options. -PWD = $(shell pwd) -PROD = wan_ec_setup -VERSION = 1.0 -DEBUG = 2 -YACC = bison - -# Project File Paths. -TMPDIR = tmp -OUTDIR = mod/ -SYSINC = /lib/modules/$(shell uname -r)/build/include -VPATH = $(LOCINC):$(TMPDIR) -ARCH = $(shell uname -m) -DIR_EC_APILIB = ../wanec_apilib - -PRODS=wan_ec_client -SRC_CLIENT=wan_ecmain.c y.tab.c wan_ec_argl.c - -SRC_EC_APILIB = $(DIR_EC_APILIB)/wanec_api.c $(DIR_EC_APILIB)/wanec_api_lib.c -INC_EC_APILIB = -I../../patches/kdrivers/wanec -I../../patches/kdrivers/include -INC_EC_APILIB += -I../../patches/kdrivers/wanec/oct6100_api/include -INC_EC_APILIB += -I$(DIR_EC_APILIB) - -CFLAGS = -Wall -O2 -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_TDMV_EC -D_DEBUG_=$(DEBUG) -D_GNUC_ -CFLAGS += -I$(SYSINC) $(INC_EC_APILIB) $(EXTRA_FLAGS) - -#$(WANEC_DIR) -I$(WANEC_DIR)/oct6100_api/include -I$(WANEC_DIR)/oct6100_api/octdeviceapi/oct6100api/ - -####### RULES ################################################################ - -all: $(PRODS) - @echo "Ok." - -wan_ec_client: $(SRC_CLIENT) $(SRC_EC_APILIB) - $(CC) $(CFLAGS) -o $@ $^ - -y.tab.c: - $(YACC) -d -o y.tab.c wan_ec_arg.y - -wan_ec_argl.c: - $(LEX) -owan_ec_argl.c wan_ec_arg.l - -install: - @echo "Installing Wanpipe EC API in $(WAN_VIRTUAL)/usr/sbin" - install $(PRODS) $(WAN_VIRTUAL)/usr/sbin/ - -uninstall: - @echo "Un-installing Wanpipe EC API from $(WAN_VIRTUAL)/usr/sbin" - rm -f $(WAN_VIRTUAL)/usr/sbin/$(PRODS) - -clean: - rm -f $(PRODS) - rm -f y.tab.c - rm -f y.tab.h - rm -f wan_ec_argl.c diff --git a/util/wanec_client/Makefile b/util/wanec_client/Makefile new file mode 120000 index 0000000..b00583b --- /dev/null +++ b/util/wanec_client/Makefile @@ -0,0 +1 @@ +Makefile.Linux \ No newline at end of file diff --git a/util/wanec_client/Makefile.FreeBSD b/util/wanec_client/Makefile.FreeBSD new file mode 100755 index 0000000..228cf09 --- /dev/null +++ b/util/wanec_client/Makefile.FreeBSD @@ -0,0 +1,33 @@ +# ============================================================================ +# Makefile WAN Echo Canceler Chip configurator. Make Script. +# +# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved. +# ---------------------------------------------------------------------------- +# Augc 25, 2005 Alex Feldman Initial version. +# ============================================================================ +.PATH: /usr/include/net ../wanec_apilib + +####### DEFINES ############################################################## +YACC = yacc +LEX = lex + +# Build Options. +PROG = wan_ec_client +BINDIR = /usr/local/sbin +SRCS = wan_ecmain.c y.tab.c wan_ec_argl.c wanec_api.c wanec_api_lib.c +CFLAGS += -Wall -Wmissing-prototypes -I. -I/usr/include/wanpipe -O2 -I../wanec_apilib + +CLEANFILES += y.tab.c wan_ec_argl.c +.OBJDIR = /usr/obj${.CURDIR} +NOMAN = + +####### RULES ################################################################ + + +y.tab.c: + $(YACC) -d wan_ec_arg.y + +wan_ec_argl.c: + $(LEX) -owan_ec_argl.c wan_ec_arg.l + +.include diff --git a/util/wanec_client/Makefile.Linux b/util/wanec_client/Makefile.Linux new file mode 100755 index 0000000..6e77816 --- /dev/null +++ b/util/wanec_client/Makefile.Linux @@ -0,0 +1,69 @@ +# ============================================================================ +# Makefile WAN Echo Canceler Chip configurator. Make Script. +# +# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved. +# ---------------------------------------------------------------------------- +# Augc 25, 2005 Alex Feldman Initial version. +# ============================================================================ + +####### DEFINES ############################################################## + +# Build Options. +PROD = wan_ec_setup +VERSION = 1.0 +DEBUG = 2 +YACC = bison + +# Project File Paths. +TMPDIR = tmp +OUTDIR = mod/ +SYSINC = /lib/modules/$(shell uname -r)/build/include +VPATH = $(LOCINC):$(TMPDIR) +ARCH = $(shell uname -m) +DIR_EC_APILIB = ../wanec_apilib + +WANECDIR=../../patches/kdrivers/wanec +ifeq (,$(wildcard $(WANECDIR))) +WANECDIR=/common/wanec +endif + +PRODS=wan_ec_client +SRC_CLIENT=wan_ecmain.c wan_ec_argy.c wan_ec_argl.c + +SRC_EC_APILIB=$(DIR_EC_APILIB)/wanec_api.c $(DIR_EC_APILIB)/wanec_api_lib.c +INC_EC_APILIB = -I$(WANECDIR) -I../../patches/kdrivers/include +INC_EC_APILIB += -I$(WANECDIR)/oct6100_api/include -I/usr/include/wanpipe +INC_EC_APILIB +=-I$(WANECDIR)/oct6100_api -I$(DIR_EC_APILIB) + +CFLAGS = -Wall -O2 -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_TDMV_EC -D_DEBUG_=$(DEBUG) -D_GNUC_ +CFLAGS += $(INC_EC_APILIB) -I$(SYSINC) $(EXTRA_FLAGS) + +#$(WANEC_DIR) -I$(WANEC_DIR)/oct6100_api/include -I$(WANEC_DIR)/oct6100_api/octdeviceapi/oct6100api/ + +####### RULES ################################################################ + +all: $(PRODS) + @echo "Ok." + +wan_ec_client: $(SRC_CLIENT) $(SRC_EC_APILIB) + $(CC) $(CFLAGS) -o $@ $^ + +wan_ec_argy.c: + $(YACC) -d -o wan_ec_argy.c wan_ec_arg.y + +wan_ec_argl.c: + $(LEX) -owan_ec_argl.c wan_ec_arg.l + +install: + @echo "Installing Wanpipe EC API in $(WAN_VIRTUAL)/usr/sbin" + install $(PRODS) $(WAN_VIRTUAL)/usr/sbin/ + +uninstall: + @echo "Un-installing Wanpipe EC API from $(WAN_VIRTUAL)/usr/sbin" + rm -f $(WAN_VIRTUAL)/usr/sbin/$(PRODS) + +clean: + rm -f $(PRODS) + rm -f wan_ec_argy.c + rm -f wan_ec_argy.h + rm -f wan_ec_argl.c diff --git a/util/wanec_client/Makefile.OpenBSD b/util/wanec_client/Makefile.OpenBSD new file mode 100755 index 0000000..6749874 --- /dev/null +++ b/util/wanec_client/Makefile.OpenBSD @@ -0,0 +1,76 @@ +# ============================================================================ +# Makefile WAN Echo Canceler Chip configurator. Make Script. +# +# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved. +# ---------------------------------------------------------------------------- +# Augc 25, 2005 Alex Feldman Initial version. +# ============================================================================ + +####### DEFINES ############################################################## + +# Build Options. +PROD = wan_ec_setup +VERSION = 1.0 + +# Project File Paths. +ARCH = $(shell uname -m) +WAN_EC_LIB = oct6100api +#WAN_EC_LIB = wan_oct6100_lib +WAN_EC_LIB_DIR = . +WAN_EC_DAEMON = YES +LOCINC = . +WANINC = /sys + +SRC_DAEMON=wan_oct6100.c wan_oct6100api.c wan_oct6100u.c +SRC_CLIENT=wan_ecmain.c y.tab.c wan_ec_argl.c wan_ec_cmd.c + +CFLAGS = -Wall -O2 -DCONFIG_PRODUCT_WANPIPE_TDMV_EC -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(LOCINC) -I$(WANINC) -I/usr/include -Ioct6100_api/include -Ioct6100_api/octdeviceapi/oct6100api/ + +LDFLAGS=-L$(WAN_EC_LIB_DIR) -l$(WAN_EC_LIB) -lc +#LDFLAGS=-L$(WAN_OCT6100_LIB_DIR) -loct6100api + +PRODS=wan_ec_client wan_ecd +CFLAGS+=-DWAN_OCT6100_DAEMON +#PRODS=wan_ec_setup + +####### RULES ################################################################ + +all: $(WAN_EC_LIB) $(PRODS) + @echo "Ok." + +oct6100api: + @$(MAKE) -r -C oct6100_api/octdeviceapiw/oct6100_apiw_openbsd/ -f oct6100api.mak + +wan_ec_setup: $(SRC_DAEMON) $(SRC_CLIENT) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +wan_ecd: $(SRC_DAEMON) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +wan_ec_client: $(SRC_CLIENT) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +y.tab.c: + $(YACC) -d wan_ec_arg.y + +wan_ec_argl.c: + $(LEX) -owan_ec_argl.c wan_ec_arg.l + +install: + @echo "Installing Wanpipe EC API in $(WAN_VIRTUAL)/usr/sbin" + \cp -f image/OCT6116-32S.ima /etc/wanpipe/wan_ec/ + \cp -f image/OCT6126-128S.ima /etc/wanpipe/wan_ec/ + \cp -f image/OCT6116-256S.ima /etc/wanpipe/wan_ec/ + install $(PRODS) $(WAN_VIRTUAL)/usr/local/sbin/ + \cp -rf buffers /etc/wanpipe/wan_ec/ + +uninstall: + @echo "Un-installing Wanpipe EC API from $(WAN_VIRTUAL)/usr/sbin" + rm -f $(WAN_VIRTUAL)/usr/sbin/$(PRODS) + +clean: + rm -f $(PRODS) + rm -f y.tab.c + rm -f y.tab.h + rm -f wan_ec_argl.c + @$(MAKE) -r -C oct6100_api/octdeviceapiw/oct6100_apiw_openbsd/ -f oct6100api.mak clean diff --git a/util/wanec_client/Makefile.org b/util/wanec_client/Makefile.org new file mode 100755 index 0000000..4d1c4d7 --- /dev/null +++ b/util/wanec_client/Makefile.org @@ -0,0 +1,60 @@ +# ============================================================================ +# Makefile WAN Echo Canceler Chip configurator. Make Script. +# +# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved. +# ---------------------------------------------------------------------------- +# Augc 25, 2005 Alex Feldman Initial version. +# ============================================================================ + +####### DEFINES ############################################################## + +# Build Options. +PROD = wan_oct6100_setup +VERSION = 1.0 +DEBUG = 2 +YACC = byacc + +# Project File Paths. +TMPDIR = tmp +OUTDIR = mod/ +LOCINC = /usr/src/linux/include +VPATH = $(LOCINC):$(TMPDIR) +ARCH = $(shell uname -m) +WAN_OCT6100_LIB_DIR = . +WAN_OCT6100_DAEMON = YES + +CFLAGS = -Wall -O2 -D__LINUX__ -DCONFIG_PRODUCT_WANPIPE_TDMV_EC -D_DEBUG_=$(DEBUG) -D_GNUC_ -I$(LOCINC) -Ioct6100_api/include + +LDFLAGS=-L$(WAN_OCT6100_LIB_DIR) -loct6100api + +ifeq "${WAN_OCT6100_DAEMON}" "YES" +PRODS=wan_oct6100_lib wan_oct6100_client wan_oct6100d +CFLAGS+=-DWAN_OCT6100_DAEMON +else +PRODS=wan_oct6100_lib wan_oct6100_setup +endif + + +####### RULES ################################################################ + +all: wan_oct6100_lib wan_oct6100_setup + @echo "Ok." + +wan_oct6100_lib: + @$(MAKE) -r -C oct6100_api/octdeviceapiw/oct6100_apiw_linux/ -f oct6100api.mak + +wan_oct6100_setup: wan_ecmain.c wan_oct6100.c wan_oct6100api.c + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +install: + @echo "Installing Wanpipe OCT6100 API in $(WAN_VIRTUAL)/usr/sbin" + \cp -f image/OCT6126-128S.ima /etc/wanpipe/oct6100/ + install -D $(PROD) $(WAN_VIRTUAL)/usr/sbin/$(PROD) + +uninstall: + @echo "Un-installing Wanpipe OCT6100 API from $(WAN_VIRTUAL)/usr/sbin" + rm -f $(WAN_VIRTUAL)/usr/sbin/$(PROD) + +clean: + rm -f $(PROD) + @$(MAKE) -r -C oct6100_api/octdeviceapiw/oct6100_apiw_linux/ -f oct6100api.mak clean diff --git a/util/wanec_client/Makefile6.FreeBSD b/util/wanec_client/Makefile6.FreeBSD new file mode 100755 index 0000000..f28e62e --- /dev/null +++ b/util/wanec_client/Makefile6.FreeBSD @@ -0,0 +1,34 @@ +# ============================================================================ +# Makefile WAN Echo Canceler Chip configurator. Make Script. +# +# Copyright (c) 1995-1997 Sangoma Technologies Inc. All Rights Reserved. +# ---------------------------------------------------------------------------- +# Augc 25, 2005 Alex Feldman Initial version. +# ============================================================================ +.PATH: /usr/include/net ../wanec_apilib + +####### DEFINES ############################################################## +YACC = yacc +LEX = lex + +# Build Options. +PROG = wan_ec_client +BINDIR = /usr/local/sbin +SRCS = wan_ecmain.c y.tab.c wan_ec_argl.c wanec_api.c wanec_api_lib.c +CFLAGS += -Wall -Wmissing-prototypes -O2 +CFLAGS += -I. -I/wanpipe/code/include -I/common/include -I../wanec_apilib -I/common/wanec -I/common/wanec/oct6100_api/include + +CLEANFILES += y.tab.c wan_ec_argl.c +.OBJDIR = /usr/obj${.CURDIR} +NO_MAN = + +####### RULES ################################################################ + + +y.tab.c: + $(YACC) -d wan_ec_arg.y + +wan_ec_argl.c: + $(LEX) -owan_ec_argl.c wan_ec_arg.l + +.include diff --git a/util/wanec_client/Makefile_test b/util/wanec_client/Makefile_test new file mode 100755 index 0000000..056ec9e --- /dev/null +++ b/util/wanec_client/Makefile_test @@ -0,0 +1,30 @@ +# ============================================================================ +# 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) + +####### RULES ################################################################ + +all: xilinx_test + @echo "Ok." + +xilinx_test: xilinx_test.c xilinx_pmc.c xilinx_cpld.c + $(CC) $(CFLAGS) -o $@ $^ + + +clean: + rm -f xilinx_test diff --git a/util/wanec_client/wan_ec_arg.l b/util/wanec_client/wan_ec_arg.l index 8b2c4d3..282d9d7 100644 --- a/util/wanec_client/wan_ec_arg.l +++ b/util/wanec_client/wan_ec_arg.l @@ -4,18 +4,22 @@ #include #include #include +#include #include #include #include -#include "y.tab.h" +#include "wan_ec_argy.h" #include "wan_ecmain.h" #include "wanec_api.h" #define WAN_EC_VERSION "1.3" +#if !defined(YYLMAX) #define YYLMAX 512 +#endif #define token(x) x #define END(v) (v-1+sizeof(v)/sizeof(v[0])) +#define YY_NO_UNPUT #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ { \ @@ -42,11 +46,12 @@ char **targv; static char **arglim; unsigned offset = 0; -wanec_client_t *gl_ec_client; -int action = WAN_EC_ACT_CMD; -char idstr[YYLMAX]; -int gl_err = 0; +extern wanec_client_t ec_client; +int action = WAN_EC_ACT_CMD; +char idstr[YYLMAX]; +int gl_err = 0; +int wan_ec_args_parse_and_run(int argc, char* argv[]); extern unsigned long convert_str(char* str, int type); extern void yyerror(char*); extern int yyparse(); @@ -54,13 +59,12 @@ void yy_reset(void); static void s_lookup(int); static int lookup_name(void); -static int wan_ec_read_param(void); -static int help(void); -static int help1(void); - +int help(int); +static int help1(int); %} +sign [-] letter [a-zA-Z_] exp_letter [a-zA-Z_\x80-\xFF] digit [0-9] @@ -74,12 +78,12 @@ blank [ \t] %% -"-v" { gl_ec_client->verbose = 1; } -"-vv" { gl_ec_client->verbose = 2; } -"--h" { help(); exit(0); } -"--h1" { help(); help1(); exit(0); } +"-v" { ec_client.verbose = 1; } +"-vv" { ec_client.verbose = 2; } +"--h" { help(0); exit(0); } +"--h1" { help(1); help1(1); exit(0); } -{digit}{digit}*{integer_suffix}? { /* decimal */ +{sign}*{digit}{digit}*{integer_suffix}? { /* decimal */ s_lookup(token(DEC_CONSTANT)); return token(DEC_CONSTANT); } @@ -93,8 +97,9 @@ blank [ \t] "-" { return token('-'); } "." { return token('.'); } +"=" { return token('='); } -"--" { wan_ec_read_param(); } +"--" { return token(CUSTOM_PARAM_TOKEN); } . { //return token(yytext[0]); @@ -109,32 +114,46 @@ static struct table_args_t { int value; char* descr; } table_args[] = { - {"all", token(ALL_TOKEN), "1" }, - {"bd", token(BYPASS_DISABLE_TOKEN), "2" }, - {"be", token(BYPASS_ENABLE_TOKEN), "3" }, - {"config", token(CONFIG_TOKEN), "4" }, - {"dd", token(DTMF_DISABLE_TOKEN), "5" }, - {"de", token(DTMF_ENABLE_TOKEN), "5" }, - {"disable", token(DISABLE_TOKEN), "5" }, - {"duration", token(DURATION_TOKEN), "5" }, - {"enable", token(ENABLE_TOKEN), "6" }, - {"help", token(HELP_TOKEN), "7" }, - {"help1", token(HELP1_TOKEN), "8" }, - {"kill", token(KILL_TOKEN), "10"}, - {"load", token(LOAD_TOKEN), "11"}, - {"mn", token(MODE_NORMAL_TOKEN), "12"}, - {"modify", token(MODIFY_TOKEN), "14"}, - {"monitor", token(MONITOR_TOKEN), "15"}, - {"mpd", token(MODE_POWERDOWN_TOKEN), "16"}, - {"playout_start",token(PLAYOUT_START_TOKEN), "17"}, - {"playout_stop",token(PLAYOUT_STOP_TOKEN), "17"}, - {"release", token(RELEASE_TOKEN), "18"}, - {"stats", token(STATS_TOKEN), "19"}, - {"stats_full", token(STATS_FULL_TOKEN), "20"}, - {"test", token(TEST_TOKEN), "21"}, - {"tone_load", token(TONE_LOAD_TOKEN), "17"}, - {"tone_unload", token(TONE_UNLOAD_TOKEN), "17"}, - {"unload", token(UNLOAD_TOKEN), "22"} + {"alaw", token(PCM_ALAW_TOKEN), "Description" }, + {"all", token(ALL_TOKEN), "Description" }, + {"all_ports", token(ALL_PORT_TOKEN), "Description" }, + {"bd", token(BYPASS_DISABLE_TOKEN), "Description" }, + {"be", token(BYPASS_ENABLE_TOKEN), "Description" }, + {"buffer_load", token(BUFFER_LOAD_TOKEN), "Description" }, + {"buffer_unload", token(BUFFER_UNLOAD_TOKEN), "Description" }, + {"config", token(CONFIG_TOKEN), "Description" }, + {"dd", token(DTMF_DISABLE_TOKEN), "Description" }, + {"de", token(DTMF_ENABLE_TOKEN), "Description" }, + {"disable", token(DISABLE_TOKEN), "Description" }, + {"duration", token(DURATION_TOKEN), "Description" }, + {"enable", token(ENABLE_TOKEN), "Description" }, + {"help", token(HELP_TOKEN), "Description" }, + {"help1", token(HELP1_TOKEN), "Description" }, + {"kill", token(KILL_TOKEN), "Description" }, + {"load", token(LOAD_TOKEN), "Description" }, + {"mhtf", token(MODE_HT_FREEZE_TOKEN), "Description" }, + {"mhtr", token(MODE_HT_RESET_TOKEN), "Description" }, + {"mn", token(MODE_NORMAL_TOKEN), "Description" }, + {"mne", token(MODE_NO_ECHO_TOKEN), "Description" }, + {"modify", token(MODIFY_TOKEN), "Description" }, + {"monitor", token(MONITOR_TOKEN), "Description" }, + {"mpd", token(MODE_POWERDOWN_TOKEN), "Description" }, + {"msr", token(MODE_SPEECH_RECOGNITION_TOKEN), "Description" }, + {"mute", token(MUTE_TOKEN), "Description" }, + {"playout_start", token(PLAYOUT_START_TOKEN), "Description" }, + {"playout_stop", token(PLAYOUT_STOP_TOKEN), "Description" }, + {"release", token(RELEASE_TOKEN), "Description" }, + {"repeat", token(REPEAT_TOKEN), "Description" }, + {"rin", token(RIN_PORT_TOKEN), "Description" }, + {"rout", token(ROUT_PORT_TOKEN), "Description" }, + {"sin", token(SIN_PORT_TOKEN), "Description" }, + {"sout", token(SOUT_PORT_TOKEN), "Description" }, + {"stats", token(STATS_TOKEN), "Description" }, + {"stats_full", token(STATS_FULL_TOKEN), "Description" }, + {"test", token(TEST_TOKEN), "Description" }, + {"ulaw", token(PCM_ULAW_TOKEN), "Description" }, + {"unload", token(UNLOAD_TOKEN), "Description" }, + {"unmute", token(UNMUTE_TOKEN), "Description" } }; static int lookup_name() @@ -142,14 +161,16 @@ static int lookup_name() struct table_args_t *first_arg = table_args, *last_arg = END(table_args), *mid_arg; - int cmp = 0; + int res = 0; while(first_arg <= last_arg){ mid_arg = first_arg + (last_arg - first_arg) / 2; - //printf("ADBG: %s (%s)\n", mid_arg->name, yytext); - if ((cmp = strcmp(mid_arg->name, yytext)) == 0){ - return mid_arg->value; - }else if (cmp < 0){ + res = strcmp(mid_arg->name, yytext); + if (res == 0){ + res = strlen(mid_arg->name) - strlen(yytext); + if (res == 0) return mid_arg->value; + } + if (res < 0){ first_arg = mid_arg + 1; }else{ last_arg = mid_arg - 1; @@ -211,7 +232,22 @@ void yy_reset() int yywrap(void) { return 1; } -static int help(void) +static void help_extra(int verbose) +{ + printf(" where:\n"); + printf(" fe_chan values:\n"); + printf(" 1,2,..,24 - for T1 line\n"); + printf(" 1,2,..,31 - for E1 line\n"); + printf(" all - all channels\n"); + printf("\n"); + printf(" port values:\n"); + printf(" sin|sout|rin|rout - EC port\n"); + printf(" all_ports - all EC ports\n"); + printf("\n"); + return; +} + +int help(int verbose) { printf("\nWanpipe Echo Canceller setup utility (ver. %s)\n\n", WAN_EC_VERSION); @@ -219,84 +255,54 @@ static int help(void) printf(" wan_ec_client \n"); printf("\n"); printf(" Commands are:\n"); - printf("\tconfig\t\t\t- Configure all Echo Canceller channels\n"); - printf("\t\t\t\t in Power Down mode!\n"); - printf("\trelease\t\t\t- Close/Release all Echo Canceller channels\n"); - printf("\tenable \t- Enable Echo canceller on specified channel(s)\n"); - printf("\tdisable \t- Disable Echo canceller on specified channel(s)\n"); - printf("\tde \t\t- Enable DTMF detection on specified channel(s)\n"); - printf("\tdd \t\t- Disable DTMF detection on specified channel(s)\n"); - printf("\tstats\t\t\t- Read Echo Canceller Chip/Image statistis\n"); - printf("\tstats \t- Read Echo Canceller channel statistis\n"); - printf("\tmonitor \t- Enable Debug monitoring for specified channel\n"); - printf("\tmonitor\t\t\t- Get debug data for previously specified channel\n"); - printf("\n"); - printf(" where:\n"); - printf("\t FE_channel values:\n"); - printf("\t\t1,2,..,24\t- for T1 line\n"); - printf("\t\t1,2,..,31\t- for E1 line\n"); - printf("\t\tall\t\t- all channels\n"); + printf(" config - Configure all Echo Canceller channels\n"); + printf(" in Normal mode!\n"); + printf(" release - Close/Release all Echo Canceller channels\n"); + printf(" enable - Enable Echo canceller on specified channel(s)\n"); + printf(" disable - Disable Echo canceller on specified channel(s)\n"); + printf(" de [sout|rout] - Enable DTMF detection on specified channel(s)\n"); + printf(" dd [sout|rout] - Disable DTMF detection on specified channel(s)\n"); + printf(" stats - Read Echo Canceller Chip/Image statistis\n"); + printf(" stats - Read Echo Canceller channel statistis\n"); + printf(" monitor - Enable Debug monitoring for specified channel\n"); + printf(" monitor - Get debug data for previously specified channel\n"); printf("\n"); + if (!verbose) help_extra(verbose); return 0; -} +} -static int help1(void) +static int help1(int verbose) { printf(" Special commands are:\n"); - printf("\tbe \t- Enable Echo canceller bypass mode\n"); - printf("\tbd \t- Disable Echo canceller bypass mode\n"); - printf("\tmn \t- Set Echo canceller in Normal mode\n"); - printf("\tmpd \t- set Echo canceller int Power-Down mode\n"); - printf("\ttone_load \t- Load specific tone (tone_name.pcm)\n"); - printf("\ttone_unload \t- Unload specific tone (tone_id \n"); - printf("\t\t\t\t returns by tone_load command)\n"); - printf("\tplayout_start \t- Start playout specific tone\n"); - printf("\tplayout_stop \t- Stop playout specific tone\n"); - printf("\tstats_full \t- Read full Echo Canceller channel statistis\n"); - printf("\tmodify \t- Modify channel configuration parameters\n"); + printf(" be - Enable Echo canceller bypass mode\n"); + printf(" bd - Disable Echo canceller bypass mode\n"); + printf(" mn - Set Echo canceller in Normal mode\n"); + printf(" mpd - set Echo canceller in Power-Down mode\n"); + printf(" mhtf - set Echo canceller in HT Freeze mode\n"); + printf(" mhtr - set Echo canceller in HT Reset mode\n"); + printf(" mne - set Echo canceller in No Echo mode\n"); + printf(" msr - set Echo canceller in Speech Recognition mode\n"); + printf(" buffer_load - Load specific buffer (name.pcm)\n"); + printf(" buffer_unload - Unload specific buffer (index \n"); + printf(" returns by buffer_load command)\n"); + printf(" playout_start [duration | repeat ]\n"); + printf(" - Start playout specific bufer\n"); + printf(" playout_stop [port] - Stop playout specific buffer\n"); + printf(" stats_full - Read full Echo Canceller channel statistis\n"); + printf(" modify - Modify channel configuration parameters\n"); + printf(" mute [ports] - Mute specified channels on ports\n"); + printf(" unmute [ports] - Un-Mute specified channels on ports\n"); printf("\n"); + if (verbose) help_extra(verbose); return 0; } -static int wan_ec_read_param() -{ - char str[MAX_EC_CLIENT_PARAM_LEN], *ptr; - - int i = 0; - - while((str[i] = input()) == '-'); - while(str[i] != EOF && str[i] != ' ' && str[i] != '\n' && str[i] != '\0'){ - str[++i] = input(); - } - if (i == 0){ - return 0; - } - str[i] = '\0'; - ptr = strchr(str, '='); - if (ptr == NULL){ - printf("Error: Invalid parameter format (%s)!\n", str); - return 0; - } - *ptr = '\0'; ptr++; - - wanec_api_param(str, ptr); -#if 0 - strlcpy(gl_ec_client->param[gl_ec_client->param_no].key, - str, MAX_EC_CLIENT_PARAM_LEN); - strlcpy(gl_ec_client->param[gl_ec_client->param_no].value, - ptr, MAX_EC_CLIENT_VALUE_LEN); - gl_ec_client->param_no++; -#endif - return 0; -} - -int wan_ec_args_parse_and_run(wanec_client_t *ec_client, int argc, char* argv[]) +int wan_ec_args_parse_and_run(int argc, char* argv[]) { if (argc == 1){ - help(); + help(0); return 0; } - gl_ec_client = ec_client; targv = argv+1; arglim = argv+argc; yyparse(); diff --git a/util/wanec_client/wan_ec_arg.y b/util/wanec_client/wan_ec_arg.y index 9a447f4..3b84a24 100644 --- a/util/wanec_client/wan_ec_arg.y +++ b/util/wanec_client/wan_ec_arg.y @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include #include #include @@ -12,26 +14,46 @@ #include #include "wanec_api.h" -extern wanec_client_t *gl_ec_client; -extern int action; -extern char yytext[]; -extern char **targv; -extern unsigned offset; -static int start_channel = 0, range = 0; -extern int gl_err; +extern wanec_client_t ec_client; +extern wan_custom_conf_t *custom_conf; +extern int action; +extern char yytext[]; +extern char **targv; +extern unsigned offset; +static int start_channel = 0, range = 0; +extern int gl_err; extern int yylex(void); +extern int help(int); -unsigned long convert_str(char* str, int type); +long convert_str(char* str, int type); static int is_channel(unsigned long); void yyerror(char* msg); +static int wanec_client_param_name(char *key); +static int wanec_client_param_sValue(char*); +static int wanec_client_param_dValue(unsigned int); + +extern int wanec_client_config(void); +extern int wanec_client_release(void); +extern int wanec_client_mode(int enable); +extern int wanec_client_bypass(int enable); +extern int wanec_client_opmode(int mode); +extern int wanec_client_modify(void); +extern int wanec_client_mute(int mode); +extern int wanec_client_dtmf(int enable); +extern int wanec_client_stats(int full); +extern int wanec_client_bufferload(void); +extern int wanec_client_bufferunload(unsigned long buffer_id); +extern int wanec_client_playout(int start); +extern int wanec_client_monitor(void); + %} %union { #define YYSTYPE YYSTYPE - char* str; - unsigned long val; + char* str; + long val; } @@ -45,7 +67,11 @@ void yyerror(char* msg); %token BYPASS_ENABLE_TOKEN %token BYPASS_DISABLE_TOKEN %token MODE_NORMAL_TOKEN +%token MODE_HT_FREEZE_TOKEN +%token MODE_HT_RESET_TOKEN %token MODE_POWERDOWN_TOKEN +%token MODE_NO_ECHO_TOKEN +%token MODE_SPEECH_RECOGNITION_TOKEN %token DTMF_ENABLE_TOKEN %token DTMF_DISABLE_TOKEN %token STATS_TOKEN @@ -55,12 +81,23 @@ void yyerror(char* msg); %token HELP1_TOKEN %token MONITOR_TOKEN %token MODIFY_TOKEN -%token TONE_LOAD_TOKEN -%token TONE_UNLOAD_TOKEN +%token BUFFER_LOAD_TOKEN +%token BUFFER_UNLOAD_TOKEN %token PLAYOUT_START_TOKEN %token PLAYOUT_STOP_TOKEN +%token PCM_ULAW_TOKEN +%token PCM_ALAW_TOKEN %token DURATION_TOKEN +%token REPEAT_TOKEN %token TEST_TOKEN +%token CUSTOM_PARAM_TOKEN +%token MUTE_TOKEN +%token UNMUTE_TOKEN +%token RIN_PORT_TOKEN +%token ROUT_PORT_TOKEN +%token SIN_PORT_TOKEN +%token SOUT_PORT_TOKEN +%token ALL_PORT_TOKEN %token CHAR_STRING %token DEC_CONSTANT @@ -72,135 +109,111 @@ void yyerror(char* msg); start_args : TEST_TOKEN { action = WAN_EC_ACT_TEST; } | CHAR_STRING - { memcpy(gl_ec_client->devname, $1, strlen($1)); + { memcpy(ec_client.devname, $1, strlen($1)); wanec_api_init(); } command ; -command : CONFIG_TOKEN - { gl_err = wanec_api_config( gl_ec_client->devname, - gl_ec_client->verbose); } +command : CONFIG_TOKEN custom_param_list + { gl_err = wanec_client_config(); } | RELEASE_TOKEN - { wanec_api_release( gl_ec_client->devname, - gl_ec_client->verbose); } + { gl_err = wanec_client_release(); } | KILL_TOKEN - { wanec_api_release( gl_ec_client->devname, - gl_ec_client->verbose); } + { gl_err = wanec_client_release(); } | ENABLE_TOKEN channel_map - { wanec_api_enable( gl_ec_client->devname, - gl_ec_client->channel_map, - gl_ec_client->verbose); } + { gl_err = wanec_client_mode(1); } | DISABLE_TOKEN channel_map - { wanec_api_disable( gl_ec_client->devname, - gl_ec_client->channel_map, - gl_ec_client->verbose); } + { gl_err = wanec_client_mode(0); } | BYPASS_ENABLE_TOKEN channel_map - { wanec_api_bypass( gl_ec_client->devname, - 1, - gl_ec_client->channel_map, - gl_ec_client->verbose); } + { gl_err = wanec_client_bypass(1); } | BYPASS_DISABLE_TOKEN channel_map - { wanec_api_bypass( gl_ec_client->devname, - 0, - gl_ec_client->channel_map, - gl_ec_client->verbose); } + { gl_err = wanec_client_bypass(0); } | MODE_NORMAL_TOKEN channel_map - { wanec_api_mode( gl_ec_client->devname, - 1, - gl_ec_client->channel_map, - gl_ec_client->verbose); } + { gl_err = wanec_client_opmode(WANEC_API_OPMODE_NORMAL); } + | MODE_HT_FREEZE_TOKEN channel_map + { gl_err = wanec_client_opmode(WANEC_API_OPMODE_HT_FREEZE); } + | MODE_HT_RESET_TOKEN channel_map + { gl_err = wanec_client_opmode(WANEC_API_OPMODE_HT_RESET); } | MODE_POWERDOWN_TOKEN channel_map - { wanec_api_mode( gl_ec_client->devname, - 0, - gl_ec_client->channel_map, - gl_ec_client->verbose); } - | DTMF_ENABLE_TOKEN channel_map - { wanec_api_dtmf( gl_ec_client->devname, - 1, - gl_ec_client->channel_map, - WAN_EC_CHANNEL_PORT_SOUT, - WAN_EC_TONE_PRESENT, - gl_ec_client->verbose); } - | DTMF_DISABLE_TOKEN channel_map - { wanec_api_dtmf( gl_ec_client->devname, - 0, - gl_ec_client->channel_map, - WAN_EC_CHANNEL_PORT_SOUT, - WAN_EC_TONE_PRESENT, - gl_ec_client->verbose); } + { gl_err = wanec_client_opmode(WANEC_API_OPMODE_POWER_DOWN); } + | MODE_NO_ECHO_TOKEN channel_map + { gl_err = wanec_client_opmode(WANEC_API_OPMODE_NO_ECHO); } + | MODE_SPEECH_RECOGNITION_TOKEN channel_map + { gl_err = wanec_client_opmode(WANEC_API_OPMODE_SPEECH_RECOGNITION); } + | MODIFY_TOKEN channel_map custom_param_list + { gl_err = wanec_client_modify(); } + | MUTE_TOKEN channel_map port_list + { gl_err = wanec_client_mute(1); } + | UNMUTE_TOKEN channel_map port_list + { gl_err = wanec_client_mute(2); } + | DTMF_ENABLE_TOKEN channel_map port_list + { gl_err = wanec_client_dtmf(1); } + | DTMF_DISABLE_TOKEN channel_map port_list + { gl_err = wanec_client_dtmf(0); } | STATS_TOKEN stats_debug_args - { wanec_api_stats( gl_ec_client->devname, - 0, - gl_ec_client->channel, - 0, - gl_ec_client->verbose); } + { gl_err = wanec_client_stats(0); } | STATS_FULL_TOKEN stats_debug_args - { wanec_api_stats( gl_ec_client->devname, - 1, - gl_ec_client->channel, - 0, - gl_ec_client->verbose); } - | TONE_LOAD_TOKEN CHAR_STRING - { wanec_api_tone_load( gl_ec_client->devname, - $2, - gl_ec_client->verbose); } - | TONE_UNLOAD_TOKEN DEC_CONSTANT - { wanec_api_tone_unload( gl_ec_client->devname, - $2, - gl_ec_client->verbose); } + { gl_err = wanec_client_stats(1); } + | BUFFER_LOAD_TOKEN CHAR_STRING + { strcpy(ec_client.filename,$2); } + buffer_load_args + { gl_err = wanec_client_bufferload(); } + | BUFFER_UNLOAD_TOKEN DEC_CONSTANT + { gl_err = wanec_client_bufferunload($2); } | PLAYOUT_START_TOKEN DEC_CONSTANT - { gl_ec_client->channel = $2; } + { ec_client.fe_chan = $2; } DEC_CONSTANT - { wanec_api_playout( gl_ec_client->devname, - 1, - gl_ec_client->channel, - $4, - gl_ec_client->verbose); } - playout_args + { ec_client.buffer_id = $4; + ec_client.repeat_cnt = 1; } + playout_start_args + { gl_err = wanec_client_playout(1); } | PLAYOUT_STOP_TOKEN DEC_CONSTANT - { gl_ec_client->channel = $2; } + { ec_client.fe_chan = $2; } DEC_CONSTANT - { wanec_api_playout( gl_ec_client->devname, - 0, - gl_ec_client->channel, - $4, - gl_ec_client->verbose); } + { ec_client.buffer_id = $4; } + port + { ec_client.port = $6; gl_err = wanec_client_playout(0); } | MONITOR_TOKEN stats_debug_args - { wanec_api_monitor( gl_ec_client->devname, - gl_ec_client->channel, - gl_ec_client->verbose); } - | MODIFY_TOKEN channel_map - { wanec_api_mode( gl_ec_client->devname, - 2, - gl_ec_client->channel_map, - gl_ec_client->verbose); } + { gl_err = wanec_client_monitor(); } ; -playout_args : /* empty */ - | playout_args playout_arg - ; +buffer_load_args : + | PCM_ULAW_TOKEN + { ec_client.pcmlaw = WAN_EC_PCM_U_LAW; } + | PCM_ALAW_TOKEN + { ec_client.pcmlaw = WAN_EC_PCM_A_LAW; } + ; + +playout_start_args : /* empty */ + | playout_start_args playout_start_arg + ; -playout_arg : DURATION_TOKEN DEC_CONSTANT - ; +playout_start_arg : DURATION_TOKEN DEC_CONSTANT + { ec_client.duration = $2; } + | REPEAT_TOKEN DEC_CONSTANT + { ec_client.repeat_cnt = $2; } + | port + { ec_client.port = $1; } + ; channel_map : ALL_TOKEN - { gl_ec_client->channel_map = 0xFFFFFFFF; } + { ec_client.fe_chan_map = 0xFFFFFFFF; } | channel_list ; channel_list : /* empty */ - { gl_ec_client->channel_map = 0xFFFFFFFF; } + { ec_client.fe_chan_map = 0xFFFFFFFF; } | DEC_CONSTANT { is_channel($1); if (range){ int i=0; for(i=start_channel;i<=$1;i++){ - gl_ec_client->channel_map |= (1<channel_map |= (1 << $1); + ec_client.fe_chan_map |= (1 << $1); } } | DEC_CONSTANT '-' @@ -212,29 +225,75 @@ channel_list : /* empty */ if (range){ int i=0; for(i=start_channel;i<=$1;i++){ - gl_ec_client->channel_map |= (1<channel_map |= (1 << $1); + ec_client.fe_chan_map |= (1 << $1); } } channel_list ; stats_debug_args: - { gl_ec_client->channel = 0; gl_ec_client->channel_map = 0x00000000; } + { ec_client.fe_chan = 0; ec_client.fe_chan_map = 0x00000000; } | DEC_CONSTANT { is_channel($1); - gl_ec_client->channel = $1; gl_ec_client->channel_map = (1<<$1); } + ec_client.fe_chan = $1; ec_client.fe_chan_map = (1<<$1); } ; +port_list : ALL_PORT_TOKEN + { ec_client.port_map = + WAN_EC_CHANNEL_PORT_SIN|WAN_EC_CHANNEL_PORT_SOUT|WAN_EC_CHANNEL_PORT_RIN|WAN_EC_CHANNEL_PORT_ROUT; } + | ports + ; + +ports : port + { ec_client.port_map |= $1; } + | port + { ec_client.port_map |= $1; } + ports + ; + +port : SIN_PORT_TOKEN + { $$ = WAN_EC_CHANNEL_PORT_SIN; } + | SOUT_PORT_TOKEN + { $$ = WAN_EC_CHANNEL_PORT_SOUT; } + | RIN_PORT_TOKEN + { $$ = WAN_EC_CHANNEL_PORT_RIN; } + | ROUT_PORT_TOKEN + { $$ = WAN_EC_CHANNEL_PORT_ROUT; } + ; + +custom_param_list : + | CUSTOM_PARAM_TOKEN CHAR_STRING '=' + { wanec_client_param_name($2); } + custom_param_value custom_param_list + ; + +custom_param_value : CHAR_STRING + { wanec_client_param_sValue($1); } + | DEC_CONSTANT + { wanec_client_param_dValue($1); } + ; %% -unsigned long convert_str(char* str, int type) +#if 0 +custom_param_list: + | custom_param custom_param_list + ; + +custom_param : CUSTOM_PARAM_TOKEN CHAR_STRING '=' + { wanec_client_param_name($2); } + CHAR_STRING + { wanec_client_param_value($5); } + ; +#endif + +long convert_str(char* str, int type) { - unsigned long value = 0; + long value = 0; switch(type){ case DEC_CONSTANT: sscanf(str, "%lu", &value); @@ -258,7 +317,50 @@ static int is_channel(unsigned long channel) void yyerror(char* msg) { - printf("> %s (argv=%s,offset=%d)\n", msg, *targv, offset); + if (!ec_client.verbose){ + printf("> %s\n", msg); + help (0); + }else{ + printf("> %s (argv=%s,offset=%d)\n", msg, *targv, offset); + } exit(1); } + +static int wanec_client_param_name(char *key) +{ + if (ec_client.conf.param_no == 0){ + ec_client.conf.params = malloc(sizeof(wan_custom_param_t)); + if (ec_client.conf.params == NULL){ + printf("ERROR: Failed to allocate structure for custom configuration!\n"); + return -EINVAL; + } + memset(ec_client.conf.params, 0, sizeof(wan_custom_param_t)); + } + strlcpy(ec_client.conf.params[ec_client.conf.param_no].name, + key, MAX_PARAM_LEN); + return 0; +} + +static int wanec_client_param_sValue(char *sValue) +{ + if (ec_client.conf.params == NULL){ + printf("ERROR: Custom configuration structure is not allocated!\n"); + return -EINVAL; + } + strlcpy(ec_client.conf.params[ec_client.conf.param_no].sValue, + sValue, MAX_VALUE_LEN); + ec_client.conf.param_no++; + return 0; +} + +static int wanec_client_param_dValue(unsigned int dValue) +{ + if (ec_client.conf.params == NULL){ + printf("ERROR: Custom configuration structure is not allocated!\n"); + return -EINVAL; + } + ec_client.conf.params[ec_client.conf.param_no].dValue = dValue; + ec_client.conf.param_no++; + return 0; +} diff --git a/util/wanec_client/wan_ecmain.c b/util/wanec_client/wan_ecmain.c index 3764416..77628a2 100644 --- a/util/wanec_client/wan_ecmain.c +++ b/util/wanec_client/wan_ecmain.c @@ -13,7 +13,6 @@ ******************************************************************************/ #if !defined(__WINDOWS__) - #include #include #include @@ -36,20 +35,11 @@ # include # include #endif - -#else - -#include "windows_config.h" - -wanpipe_t wanpipes[MAX_NUM_OF_WANPIPES]; - -char WAN_EC_DIR[MAX_PATH]; -char WAN_EC_BUFFERS[MAX_PATH]; -char windows_dir[MAX_PATH]; - -#endif//__WINDOWS__ +#endif #include "wan_ecmain.h" +#include +#include "wanec_api.h" /****************************************************************************** ** DEFINES AND MACROS @@ -62,11 +52,25 @@ char windows_dir[MAX_PATH]; /****************************************************************************** ** GLOBAL VARIABLES ******************************************************************************/ +wanec_client_t ec_client; /****************************************************************************** ** FUNCTION PROTOTYPES ******************************************************************************/ -extern int wan_ec_args_parse_and_run( wanec_client_t*, int, char** ); +int wan_ec_args_parse_and_run(int argc, char* argv[]); +int wanec_client_config(void); +int wanec_client_release(void); +int wanec_client_mode(int enable); +int wanec_client_bypass(int enable); +int wanec_client_opmode(int mode); +int wanec_client_modify(void); +int wanec_client_mute(int mode); +int wanec_client_dtmf(int enable); +int wanec_client_stats(int full); +int wanec_client_bufferload(char *buffer); +int wanec_client_bufferunload(unsigned long buffer_id); +int wanec_client_playout(int start); +int wanec_client_monitor(void); /****************************************************************************** ** FUNCTION DEFINITIONS @@ -74,31 +78,226 @@ extern int wan_ec_args_parse_and_run( wanec_client_t*, int, char** ); int main(int argc, char *argv[]) { - wanec_client_t ec_client; - -#if defined(__WINDOWS__) - unsigned char win_parse = 0; - //////////////////////////////////////////////////////////////////////////// - //Get and parse command line arguments. - //////////////////////////////////////////////////////////////////////////// - if(argc == 3 && !strcmp(argv[1], "-f")){ - //If "-f is provided, parse the file. - win_parse = 1; - } - if(argc == 2 && !strcmp(argv[1], "-v")){ - //If "-v", print out version. - win_parse = 1; - } - - if(win_parse == 1){ - return parse_cmd_line_args(argc, argv); - } -#endif + int err; memset(&ec_client, 0, sizeof(wanec_client_t)); - if (wan_ec_args_parse_and_run(&ec_client, argc, argv)){ - return -EINVAL; + err = wan_ec_args_parse_and_run(argc, argv); + if (!err){ + printf("\n\n"); } - printf("\n\n"); - return 0; + if (ec_client.conf.param_no){ + free(ec_client.conf.params); + ec_client.conf.params = NULL; + } + return err; +} + +int wanec_client_config(void) +{ + wanec_api_config_t conf; + int err; + + memset(&conf, 0, sizeof(wanec_api_config_t)); + if (ec_client.conf.param_no){ + memcpy(&conf.conf, &ec_client.conf, sizeof(wan_custom_conf_t)); + } + err = wanec_api_config( + ec_client.devname, + ec_client.verbose, + &conf); + return err; +} + +int wanec_client_release(void) +{ + wanec_api_release_t release; + int err; + + memset(&release, 0, sizeof(wanec_api_release_t)); + err = wanec_api_release( + ec_client.devname, + ec_client.verbose, + &release); + return err; +} + +int wanec_client_mode(int enable) +{ + wanec_api_mode_t mode; + int err; + + memset(&mode, 0, sizeof(wanec_api_mode_t)); + mode.enable = enable; + mode.fe_chan_map= ec_client.fe_chan_map; + err = wanec_api_mode( + ec_client.devname, + ec_client.verbose, + &mode); + return err; +} + +int wanec_client_bypass(int enable) +{ + wanec_api_bypass_t bypass; + int err; + + memset(&bypass, 0, sizeof(wanec_api_bypass_t)); + bypass.enable = enable; + bypass.fe_chan_map = ec_client.fe_chan_map; + err = wanec_api_bypass( + ec_client.devname, + ec_client.verbose, + &bypass); + return err; +} + +int wanec_client_opmode(int mode) +{ + wanec_api_opmode_t opmode; + int err; + + memset(&opmode, 0, sizeof(wanec_api_opmode_t)); + opmode.mode = mode; + opmode.fe_chan_map = ec_client.fe_chan_map; + err = wanec_api_opmode( + ec_client.devname, + ec_client.verbose, + &opmode); + return err; +} + + +int wanec_client_modify() +{ + wanec_api_modify_t modify; + int err; + + memset(&modify, 0, sizeof(wanec_api_modify_t)); + modify.fe_chan_map = ec_client.fe_chan_map; + if (ec_client.conf.param_no){ + memcpy(&modify.conf, &ec_client.conf, sizeof(wan_custom_conf_t)); + } + err = wanec_api_modify( + ec_client.devname, + ec_client.verbose, + &modify); + return err; +} + +int wanec_client_mute(int mode) +{ + wanec_api_mute_t mute; + int err; + + memset(&mute, 0, sizeof(wanec_api_mute_t)); + mute.mode = mode; + mute.fe_chan_map = ec_client.fe_chan_map; + mute.port_map = ec_client.port_map; + err = wanec_api_mute( + ec_client.devname, + ec_client.verbose, + &mute); + return err; + +} + +int wanec_client_dtmf(int enable) +{ + wanec_api_dtmf_t dtmf; + int err; + + memset(&dtmf, 0, sizeof(wanec_api_dtmf_t)); + dtmf.enable = enable; + dtmf.fe_chan_map = ec_client.fe_chan_map; + dtmf.port_map = ec_client.port_map; + dtmf.type_map = WAN_EC_TONE_PRESENT; + err = wanec_api_dtmf( + ec_client.devname, + ec_client.verbose, + &dtmf); + return err; +} + +int wanec_client_stats(int full) +{ + wanec_api_stats_t stats; + int err; + + memset(&stats, 0, sizeof(wanec_api_stats_t)); + stats.full = full; + stats.fe_chan = ec_client.fe_chan; + stats.reset = 0; //reset + err = wanec_api_stats( + ec_client.devname, + ec_client.verbose, + &stats); + return err; +} + +int wanec_client_bufferload(char *buf) +{ + wanec_api_bufferload_t bufferload; + int err; + + printf("%s(): buf: %s\n", __FUNCTION__, buf); + + memset(&bufferload, 0, sizeof(wanec_api_bufferload_t)); + bufferload.buffer = buf; + err = wanec_api_buffer_load( + ec_client.devname, + ec_client.verbose, + &bufferload); + if (!err){ + printf("Buffer index is %d!\n", bufferload.buffer_id); + } + return err; +} + +int wanec_client_bufferunload(unsigned long buffer_id) +{ + wanec_api_bufferunload_t bufferunload; + int err; + + memset(&bufferunload, 0, sizeof(wanec_api_bufferunload_t)); + bufferunload.buffer_id = (unsigned int)buffer_id; + err = wanec_api_buffer_unload( + ec_client.devname, + ec_client.verbose, + &bufferunload); + return err; +} + +int wanec_client_playout(int start) +{ + wanec_api_playout_t playout; + int err; + + memset(&playout, 0, sizeof(wanec_api_playout_t)); + playout.start = start; + playout.fe_chan = ec_client.fe_chan; + playout.buffer_id = ec_client.buffer_id; + playout.port = ec_client.port; + playout.notifyonstop = 1; + playout.user_event_id = 0xA5; /* dummy value */ + playout.repeat_cnt = ec_client.repeat_cnt; + playout.duration = (ec_client.duration) ? ec_client.duration : 5000; // default 5s + err = wanec_api_playout( + ec_client.devname, + ec_client.verbose, + &playout); + return err; +} + +int wanec_client_monitor(void) +{ + wanec_api_monitor_t monitor; + int err; + + memset(&monitor, 0, sizeof(wanec_api_monitor_t)); + monitor.fe_chan = ec_client.fe_chan; + err = wanec_api_monitor( + ec_client.devname, + ec_client.verbose, + &monitor); + return err; } diff --git a/util/wanec_client/wan_ecmain.h b/util/wanec_client/wan_ecmain.h index 81e8b9c..8886823 100644 --- a/util/wanec_client/wan_ecmain.h +++ b/util/wanec_client/wan_ecmain.h @@ -12,6 +12,7 @@ # include # include # include +# include #else # include # include @@ -32,19 +33,25 @@ enum { }; typedef struct { - char devname[WAN_DRVNAME_SZ+1]; + char devname[WAN_DRVNAME_SZ+1]; // unsigned char if_name[WAN_IFNAME_SZ+1]; int verbose; - int channel; - unsigned long channel_map; + int fe_chan; + unsigned long fe_chan_map; // char channels[MAX_EC_CLIENT_CHANNELS_LEN]; - int param_no; - struct { - char key[MAX_EC_CLIENT_PARAM_LEN]; - char value[MAX_EC_CLIENT_VALUE_LEN]; - } param[10]; + char filename[MAX_FILENAME_LEN]; + unsigned char pcmlaw; + + unsigned int buffer_id; + unsigned int duration; + unsigned int repeat_cnt; + + unsigned char port; + unsigned char port_map; + + wan_custom_conf_t conf; } wanec_client_t; #endif /* __WAN_ECMAIN_H__ */ diff --git a/util/wanpipemon.old/Makefile b/util/wanpipemon.old/Makefile deleted file mode 100644 index 1eb25dd..0000000 --- a/util/wanpipemon.old/Makefile +++ /dev/null @@ -1,103 +0,0 @@ -# ============================================================================ -# Makefile Make script for building Linux WAN router utilities. -# ---------------------------------------------------------------------------- -# Copyright (c) 1995-2000 Sangoma Technologies Inc. All Rights Reserved. -# ============================================================================ - -####### MACROS ############################################################### - -# Build options. -OS_TYPE = __LINUX__ -DEBUG = 2 - -PROD=wanpipemon - -SYSINC=$(shell echo "/lib/modules/$(shell uname -r)/build/include") - -WAN_VIRTUAL= -LXDIR=../lxdialog -ENABLE_GUI=YES -ENABLE_HDLC=YES -ENABLE_WANPIPEMON_ZAP= -PROTOCOL_DEFS= -ASTBROOT=/usr -#-DCONFIG_PRODUCT_WANPIPE_ADSL - -CC = gcc -CPP = gcc -E -CFLAGS = -Wall -Wstrict-prototypes -CFLAGS += $(EXTRA_FLAGS) -CFLAGS += -I$(SYSINC) -D$(OS_TYPE) -I../ft1 -O2 -fomit-frame-pointer -DLOCALE -D_DEBUG_=$(DEBUG) -WAN_VIRTUAL= - - -# Tools options. - -ifeq "${ENABLE_GUI}" "NO" -LX_OBJ = -GUI_OBJ = -LDLIBS = -else -LX_OBJ = $(LXDIR)/checklist.o $(LXDIR)/menubox.o $(LXDIR)/inputbox.o $(LXDIR)/util.o -GUI_OBJ = wangui.o -LDLIBS = -lncurses - -CFLAGS += -DWANPIPEMON_GUI -DLOCALE - -ifeq "${ENABLE_WANPIPEMON_ZAP}" "YES" -CFLAGS += -DWANPIPEMON_ZAP -LDLIBS += -lstdc++ -endif - -CFLAGS += -DCURSES_LOC="" -endif - -OBJS= wanpipemon.o fpipemon.o cpipemon.o ppipemon.o xpipemon.o atmpipemon.o aftpipemon.o dslpipemon.o prot_trace.o ss7pipemon.o bpipemon.o fe_lib.o xml_lib.o ../ft1/unixio.o -OBJS+=$(GUI_OBJ) - -ifeq "${ENABLE_WANPIPEMON_ZAP}" "YES" -OBJS+=zapmon.o -endif - -ifeq "${ENABLE_HDLC}" "YES" -CFLAGS += -DWANPIPEMON_HDLC_TRACE -I../lib/hdlc -OBJS += ../lib/hdlc/wanpipe_hdlc.o -endif - -SRCS = $(OBJS:.o=.c) - -OBJS+=$(LX_OBJ) - - -####### RULES ################################################################ - -all: $(PROD) - @echo "Ok. Using INCLUDE $(SYSINC)" - -$(PROD): $(OBJS) - -ncurses: - @x=`find $(ASTBROOT)/lib/ /lib/ /usr/lib/ /usr/lib64/ /usr/local/lib/ -maxdepth 1 -name 'libncurses.*' 2> /dev/null` ;\ - if [ ! "$$x" ]; then \ - echo -e "\007" ;\ - echo ">> Unable to find the Ncurses libraries." ;\ - echo ">>" ;\ - echo ">> You must have Ncurses installed in order" ;\ - echo ">> to use 'make menuconfig'" ;\ - echo ;\ - exit 1 ;\ - fi - -nenad: - @echo "Ok. Using INCLUDE $(SYSINC)" - -install: - @echo "Installing Wanpipe utilites in $(WAN_VIRTUAL)/usr/sbin" - install -D $(PROD) $(WAN_VIRTUAL)/usr/sbin/$(PROD) - -uninstall: - @echo "Un-installing Wanpipe utilites from $(WAN_VIRTUAL)/usr/sbin" - rm -f $(WAN_VIRTUAL)/usr/sbin/$(PROD) -clean: - rm -f *.o - rm -f $(PROD) diff --git a/util/wanpipemon.old/aftpipemon.c b/util/wanpipemon.old/aftpipemon.c deleted file mode 100644 index 1708b4d..0000000 --- a/util/wanpipemon.old/aftpipemon.c +++ /dev/null @@ -1,1342 +0,0 @@ -/***************************************************************************** -* aftpipemon.c AFT Debugger/Monitor -* -* Author: Nenad Corbic -* -* 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. -* ---------------------------------------------------------------------------- -* Jan 06, 2004 Nenad Corbic Initial version based on aftpipemon -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include /* offsetof(), etc. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) - -#define BANNER(str) banner(str,0) -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ -/* Structures for data casting */ - - - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -/* The ft1_lib needs these global variables */ - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -/* Command routines */ -static void modem( void ); -#if 0 -static void global_stats( void ); -#endif -static void comm_err_stats( void ); -static void read_code_version( void ); -static void link_status( void ); -static void operational_stats( void ); -static void line_trace( int ); -static void aft_router_up_time( void ); -static void flush_operational_stats( void ); -static void flush_comm_err_stats( void ); -static void read_ft1_te1_56k_config( void ); - -static int aft_read_hwec_status(void); - -static int aft_remora_tones(int); -static int aft_remora_ring(int); -static int aft_remora_regdump(int); - -static wp_trace_output_iface_t trace_iface; - -static char *gui_main_menu[]={ -"aft_card_stats_menu","Card Status", -"aft_stats_menu", "Card Statistics", -"aft_trace_menu", "Trace Data", -"csudsu_menu", "CSU DSU Config/Stats", -"aft_flush_menu","Flush Statistics", -"." -}; - - -static char *aft_card_stats_menu[]={ -"xm","Modem Status", -"xl","Link Status", -"xcv","Read Code Version", -"xru","Display Router UP time", -"." -}; - -static char *aft_stats_menu[]={ -"sc","Communication Error Statistics", -"so","Operational Statistics", -"." -}; - -static char *aft_trace_menu[]={ -"tr","Raw Hex trace", -"ti","Interpreted trace", -"." -}; - -static char *aft_flush_menu[]={ -"fc","Flush Communication Error Statistics", -"fo","Flush Operational Statistics", -"fpm","Flush T1/E1 performance monitoring cnters", -"." -}; - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"aft_card_stats_menu",aft_card_stats_menu}, - {"aft_stats_menu",aft_stats_menu}, - {"aft_trace_menu",aft_trace_menu}, - {"csudsu_menu",csudsu_menu}, - {"aft_flush_menu",aft_flush_menu}, - {".",NULL} -}; - - -char ** AFTget_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** AFTget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=(char**)gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int AFTConfig(void) -{ - char codeversion[10]; - unsigned char x=0; - - protocol_cb_size = sizeof(wan_mgmt_t) + - sizeof(wan_cmd_t) + - sizeof(wan_trace_info_t) + 1; - wan_udp.wan_udphdr_command= READ_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - while (++x < 4) { - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - - if (wan_udp.wan_udphdr_return_code == 0xCC){ - return(WAN_FALSE); - } - wan_udp.wan_udphdr_return_code = 0xaa; - } - - if (x >= 4) return(WAN_FALSE); - - is_508 = WAN_FALSE; - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = READ_CODE_VERSION; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - return(WAN_TRUE); -}; - - -#if 0 -static void global_stats (void) -{ - GLOBAL_STATS_STRUCT* global_stats; - wan_udp.wan_udphdr_command= READ_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("GLOBAL STATISTICS"); - global_stats = (GLOBAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - printf("Times application did not respond to IRQ: %u", - global_stats->app_IRQ_timeout_count); - } else { - error(); - } -}; /* global stats */ -#endif - -static void modem( void ) -{ -#if 1 - unsigned char cts_dcd; - wan_udp.wan_udphdr_command= AFT_MODEM_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("MODEM STATUS"); - memcpy(&cts_dcd, &wan_udp.wan_udphdr_data[0],1); - printf("DCD: "); - (cts_dcd & 0x08) ? printf("High\n") : printf("Low\n"); - printf("CTS: "); - (cts_dcd & 0x20) ? printf("High\n") : printf("Low\n"); - } -#endif -}; /* modem */ - - -static void comm_err_stats (void) -{ -#if 1 - aft_comm_err_stats_t* comm_err_stats; - wan_udp.wan_udphdr_command= READ_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("AFT COMMUNICATION ERROR STATISTICS"); - - comm_err_stats = (aft_comm_err_stats_t *)&wan_udp.wan_udphdr_data[0]; - - printf("RX Stats:\n"); - printf(" Number of receiver overrun errors: %u\n", - comm_err_stats->Rx_overrun_err_count); - printf(" Number of receiver CRC errors: %u\n", - comm_err_stats->Rx_crc_err_count); - printf(" Number of receiver Abort errors: %u\n", - comm_err_stats->Rx_abort_count); - printf(" Number of receiver corruption errors: %u\n", - comm_err_stats->Rx_hdlc_corrupiton); - printf(" Number of receiver PCI errors: %u\n", - comm_err_stats->Rx_pci_errors); - printf(" Number of receiver DMA descriptor errors: %u\n", - comm_err_stats->Rx_dma_descr_err); - printf("TX Stats:\n"); - printf(" Number of transmitter PCI errors: %u\n", - comm_err_stats->Tx_pci_errors); - printf(" Number of transmitter PCI latency warnings: %u\n", - comm_err_stats->Tx_pci_latency); - printf(" Number of transmitter DMA descriptor errors: %u\n", - comm_err_stats->Tx_dma_errors); - printf(" Number of transmitter DMA descriptor length errors: %u\n", - comm_err_stats->Tx_dma_len_nonzero); - -#if 0 - printf(" Number of times DCD changed state: %u\n", - comm_err_stats->DCD_state_change_count); - printf(" Number of times CTS changed state: %u\n", - comm_err_stats->CTS_state_change_count); -#endif - } -#endif -}; /* comm_err_stats */ - - -static void flush_comm_err_stats( void ) -{ -#if 1 - wan_udp.wan_udphdr_command=FLUSH_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - -#endif -}; /* flush_comm_err_stats */ - - -static void read_code_version (void) -{ - wan_udp.wan_udphdr_command= READ_CODE_VERSION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("AFT CODE VERSION"); - printf("Code version: HDLC rev.%X\n", - wan_udp.wan_udphdr_data[0]); - }else{ - printf("Error: Rc=%x\n",wan_udp.wan_udphdr_return_code); - } -}; /* read code version */ - - -static void link_status (void) -{ - wan_udp.wan_udphdr_command= AFT_LINK_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - BANNER("AFT LINK STATUS"); - - if (wan_udp.wan_udphdr_return_code == 0){ - printf("Device Link Status: %s\n", - wan_udp.wan_udphdr_data[0] ? "Connected":"Disconnected"); - } - - return; -}; /* Link Status */ - - -static void operational_stats (void) -{ - aft_op_stats_t *stats; - wan_udp.wan_udphdr_command= READ_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("AFT OPERATIONAL STATISTICS"); - stats = (aft_op_stats_t *)&wan_udp.wan_udphdr_data[0]; - - printf( " Number of frames transmitted: %lu", - stats->Data_frames_Tx_count); - printf( "\n Number of bytes transmitted: %lu", - stats->Data_bytes_Tx_count); - printf( "\n Transmit Throughput: %lu", - stats->Data_Tx_throughput); - printf( "\n Transmit frames discarded (length error): %lu", - stats->Tx_Data_discard_lgth_err_count); - printf( "\n Transmit frames realigned: %lu", - stats->Data_frames_Tx_realign_count); - - - printf("\n\n Number of frames received: %lu", - stats->Data_frames_Rx_count); - printf( "\n Number of bytes received: %lu", - stats->Data_bytes_Rx_count); - printf( "\n Receive Throughput: %lu", - stats->Data_Rx_throughput); - printf( "\n Received frames discarded (too short): %lu", - stats->Rx_Data_discard_short_count); - printf( "\n Received frames discarded (too long): %lu", - stats->Rx_Data_discard_long_count); - printf( "\nReceived frames discarded (link inactive): %lu", - stats->Rx_Data_discard_inactive_count); - - - printf("\n\nHDLC link active/inactive and loopback statistics"); - printf( "\n Times that the link went active: %u", stats->link_active_count); - printf( "\n Times that the link went inactive (modem failure): %u", stats->link_inactive_modem_count); - printf( "\n Times that the link went inactive (keepalive failure): %u", stats->link_inactive_keepalive_count); - printf( "\n link looped count: %u", stats->link_looped_count); - - - } -}; /* Operational_stats */ - - -static void flush_operational_stats( void ) -{ -#if 1 - wan_udp.wan_udphdr_command= FLUSH_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); -#endif -}; /* flush_operational_stats */ - - -int AFTDisableTrace(void) -{ - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - return 0; -} - -static int print_local_time (char *date_string) -{ - - char tmp_time[50]; - time_t time_val; - struct tm *time_tm; - - date_string[0]='\0'; - - time_val=time(NULL); - - /* Parse time and date */ - time_tm=localtime(&time_val); - - strftime(tmp_time,sizeof(tmp_time),"%b",time_tm); - sprintf(date_string, " %s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); - sprintf(date_string+strlen(date_string), "%s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); - sprintf(date_string+strlen(date_string), "%s",tmp_time); - - return 0; -} - -static int loop_rx_data(int passnum) -{ - unsigned int num_frames; - unsigned short curr_pos = 0; - wan_trace_pkt_t *trace_pkt; - unsigned int i; - struct timeval to; - int timeout=0; - char date_string[100]; - - gettimeofday(&to, NULL); - to.tv_sec = 0; - to.tv_usec = 0; - - print_local_time(date_string); - - printf("%s | Test %04i | ", - date_string, passnum); - - for(;;) { - - select(1,NULL, NULL, NULL, &to); - - wan_udp.wan_udphdr_command = GET_TRACE_INFO; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len) { - - num_frames = wan_udp.wan_udphdr_aft_num_frames; - - for ( i = 0; i < num_frames; i++) { - trace_pkt= (wan_trace_pkt_t *)&wan_udp.wan_udphdr_data[curr_pos]; - - /* frame type */ - if (trace_pkt->status & 0x01) { - trace_iface.status |= WP_TRACE_OUTGOING; - }else{ - if (trace_pkt->status & 0x10) { - trace_iface.status |= WP_TRACE_ABORT; - } else if (trace_pkt->status & 0x20) { - trace_iface.status |= WP_TRACE_CRC; - } else if (trace_pkt->status & 0x40) { - trace_iface.status |= WP_TRACE_OVERRUN; - } - } - - trace_iface.len = trace_pkt->real_length; - trace_iface.timestamp=trace_pkt->time_stamp; - trace_iface.sec = trace_pkt->sec; - trace_iface.usec = trace_pkt->usec; - - curr_pos += sizeof(wan_trace_pkt_t); - - if (trace_pkt->real_length >= WAN_MAX_DATA_SIZE){ - printf("\t:the frame data is to big (%u)!", - trace_pkt->real_length); - fflush(stdout); - continue; - - }else if (trace_pkt->data_avail == 0) { - - printf("\t: the frame data is not available" ); - fflush(stdout); - continue; - } - - - /* update curr_pos again */ - curr_pos += trace_pkt->real_length; - - trace_iface.trace_all_data=trace_all_data; - trace_iface.data=(unsigned char*)&trace_pkt->data[0]; - - - if (trace_pkt->status & 0x01){ - continue; - } - - if (trace_iface.data[0] == (0xFF-0) && - trace_iface.data[1] == (0xFF-1) && - trace_iface.data[2] == (0xFF-2) && - trace_iface.data[3] == (0xFF-3)) { - printf("Successful (%s)!\n", - trace_iface.status & WP_TRACE_ABORT ? "Abort" : - trace_iface.status & WP_TRACE_CRC ? "Crc" : - trace_iface.status & WP_TRACE_OVERRUN ? "Overrun" : "Ok" - ); - return 0; - } - - - - } //for - } //if - curr_pos = 0; - - if (!wan_udp.wan_udphdr_chdlc_ismoredata){ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - timeout++; - if (timeout > 100) { - printf("Timeout!\n"); - break; - } - }else{ - to.tv_sec = 0; - to.tv_usec = 0; - } - } - return 0; -} - - -static int aft_digital_loop_test( void ) -{ - int passnum=0; - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - wan_udp.wan_udphdr_command= ENABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0]=0; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0 && - wan_udp.wan_udphdr_return_code != 1) { - printf("Error: Failed to start loop test: failed to start tracing!\n"); - return -1; - } - - printf("Starting Loop Test (press ctrl-c to exit)!\n\n"); - - while (1) { - - wan_udp.wan_udphdr_command= DIGITAL_LOOPTEST; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data[0] = 0xFF-0; - wan_udp.wan_udphdr_data[1] = 0xFF-1; - wan_udp.wan_udphdr_data[2] = 0xFF-2; - wan_udp.wan_udphdr_data[3] = 0xFF-3; - wan_udp.wan_udphdr_data_len = 100; - DO_COMMAND(wan_udp); - - switch (wan_udp.wan_udphdr_return_code) { - - case 0: - break; - case 1: - printf("Error: Failed to start loop test: dev not found\n"); - goto loop_rx_exit; - case 2: - printf("Error: Failed to start loop test: dev state not connected\n"); - goto loop_rx_exit; - case 3: - printf("Error: Failed to start loop test: memory error\n"); - goto loop_rx_exit; - case 4: - printf("Error: Failed to start loop test: invalid operation mode\n"); - goto loop_rx_exit; - - default: - printf("Error: Failed to start loop test: unknown error (%i)\n", - wan_udp.wan_udphdr_return_code); - goto loop_rx_exit; - } - - - loop_rx_data(++passnum); - usleep(500000); - fflush(stdout); - - if (passnum >= 10) { - break; - } - } - -loop_rx_exit: - - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - return 0; -} - -static void line_trace(int trace_mode) -{ - unsigned int num_frames; - unsigned short curr_pos = 0; - wan_trace_pkt_t *trace_pkt; - unsigned int i; - int recv_buff = sizeof(wan_udp_hdr_t)+ 100; - fd_set ready; - struct timeval to; - - setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recv_buff, sizeof(int) ); - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - wan_udp.wan_udphdr_command= ENABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0]=trace_mode; - - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - printf("Starting trace...(Press ENTER to exit)\n"); - fflush(stdout); - } else if(wan_udp.wan_udphdr_return_code == 0xCD ) { - printf("Cannot Enable Line Tracing from Underneath.\n"); - fflush(stdout); - return; - }else if (wan_udp.wan_udphdr_return_code == 0x01 ) { - printf("Starting trace...(although it's already enabled!)\n"); - printf("Press ENTER to exit.\n"); - fflush(stdout); - }else{ - printf("Failed to Enable Line Tracing. Return code: 0x%02X\n", - wan_udp.wan_udphdr_return_code ); - fflush(stdout); - return; - } - - to.tv_sec = 0; - to.tv_usec = 0; - for(;;) { - FD_ZERO(&ready); - FD_SET(0,&ready); - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - - wan_udp.wan_udphdr_command = GET_TRACE_INFO; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len) { - - num_frames = wan_udp.wan_udphdr_aft_num_frames; - - for ( i = 0; i < num_frames; i++) { - trace_pkt= (wan_trace_pkt_t *)&wan_udp.wan_udphdr_data[curr_pos]; - - /* frame type */ - if (trace_pkt->status & 0x01) { - trace_iface.status |= WP_TRACE_OUTGOING; - }else{ - if (trace_pkt->status & 0x10) { - trace_iface.status |= WP_TRACE_ABORT; - } else if (trace_pkt->status & 0x20) { - trace_iface.status |= WP_TRACE_CRC; - } else if (trace_pkt->status & 0x40) { - trace_iface.status |= WP_TRACE_OVERRUN; - } - } - - trace_iface.len = trace_pkt->real_length; - trace_iface.timestamp=trace_pkt->time_stamp; - trace_iface.sec = trace_pkt->sec; - trace_iface.usec = trace_pkt->usec; - - curr_pos += sizeof(wan_trace_pkt_t); - - if (trace_pkt->real_length >= WAN_MAX_DATA_SIZE){ - printf("\t:the frame data is to big (%u)!", - trace_pkt->real_length); - fflush(stdout); - continue; - - }else if (trace_pkt->data_avail == 0) { - - printf("\t: the frame data is not available" ); - fflush(stdout); - continue; - } - - - /* update curr_pos again */ - curr_pos += trace_pkt->real_length; - - trace_iface.trace_all_data=trace_all_data; - trace_iface.data=(unsigned char*)&trace_pkt->data[0]; - - /* - if (raw_data) { - trace_iface.type=WP_OUT_TRACE_RAW; - }else - */ - if (pcap_output){ - trace_iface.type=WP_OUT_TRACE_PCAP; - } - /* - else{ - trace_iface.type=WP_OUT_TRACE_INTERP; - } - */ - - trace_iface.link_type=wan_protocol; - - wp_trace_output(&trace_iface); - - fflush(stdout); - - } //for - } //if - curr_pos = 0; - - if (!wan_udp.wan_udphdr_chdlc_ismoredata){ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - }else{ - to.tv_sec = 0; - to.tv_usec = 0; - } - } - - - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); -}; /* line_trace */ - -static int aft_read_hwec_status() -{ - u_int32_t hwec_status; - int channel, found = 0; - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command = AFT_HWEC_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code) { - printf("Failed to get HW Echo Canceller status!\n"); - fflush(stdout); - return 0; - } - hwec_status = *(u_int32_t*)&wan_udp.wan_udphdr_data[0]; - for(channel = 0; channel < 32; channel++){ - if (hwec_status & (1 << channel)){ - printf( - "Sangoma HW Echo Canceller is enabled for channel %d\n", - channel); - found = 1; - } - } - if (!found){ - printf( - "Sangoma HW Echo Canceller is disabled for all channels!\n"); - } - fflush(stdout); - return 0; -} - -static int aft_remora_tones(int mod_no) -{ - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command = WAN_FE_TONES; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = mod_no; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code) { - printf("Failed to play the AFT Remora tones!\n"); - fflush(stdout); - return 0; - } - - fflush(stdout); - return 0; -} - -static int aft_remora_ring(int mod_no) -{ - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command = WAN_FE_RING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = mod_no; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code) { - printf("Failed to ring the module!\n"); - fflush(stdout); - return 0; - } - - fflush(stdout); - return 0; -} - -static int aft_remora_regdump(int mod_no) -{ - wan_remora_udp_t *rm_udp; - int reg; - - rm_udp = (wan_remora_udp_t *)&wan_udp.wan_udphdr_data[0]; - rm_udp->mod_no = mod_no; - wan_udp.wan_udphdr_command = WAN_FE_REGDUMP; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = sizeof(wan_remora_udp_t); - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code || !wan_udp.wan_udphdr_data_len) { - printf("Failed to get register dump!\n"); - fflush(stdout); - return 0; - } - rm_udp = (wan_remora_udp_t *)&wan_udp.wan_udphdr_data[0]; - printf("\t------- Direct registers (%s,port %d) -------\n", - WP_REMORA_DECODE_TYPE(rm_udp->type), - rm_udp->mod_no); - if (rm_udp->type == MOD_TYPE_FXS){ - - for(reg = 0; reg < WAN_FXS_NUM_REGS; reg++){ - if (reg % 8 == 0) printf("\n\t"); - printf("%3d. %02X ", reg, rm_udp->u.regs_fxs.direct[reg]); - } - printf("\n\t-----------------------------\n"); - printf("\n"); - printf("\t------- Indirect registers (port %d) -------\n", - rm_udp->mod_no); - for (reg=0; reg < WAN_FXS_NUM_INDIRECT_REGS; reg++){ - if (reg % 6 == 0) printf("\n\t"); - printf("%3d. %04X ", reg, rm_udp->u.regs_fxs.indirect[reg]); - } - printf("\n\t-----------------------------\n"); - printf("\n"); - printf("TIP\t: -%d Volts\n", (rm_udp->u.regs_fxs.direct[80]*376)/1000); - printf("RING\t: -%d Volts\n", (rm_udp->u.regs_fxs.direct[81]*376)/1000); - printf("VBAT\t: -%d Volts\n", (rm_udp->u.regs_fxs.direct[82]*376)/1000); - } else if (rm_udp->type == MOD_TYPE_FXO){ - - for(reg = 0; reg < WAN_FXO_NUM_REGS; reg++){ - if (reg % 8 == 0) printf("\n\t"); - printf("%3d. %02X ", reg, rm_udp->u.regs_fxo.direct[reg]); - } - printf("\n\t-----------------------------\n"); - printf("\n"); - } - - fflush(stdout); - return 0; -} - -static int aft_remora_stats(int mod_no) -{ - wan_remora_udp_t *rm_udp; - - rm_udp = (wan_remora_udp_t *)&wan_udp.wan_udphdr_data[0]; - rm_udp->mod_no = mod_no; - wan_udp.wan_udphdr_command = WAN_FE_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = sizeof(wan_remora_udp_t); - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code || !wan_udp.wan_udphdr_data_len) { - printf("Failed to get voltage stats!\n"); - fflush(stdout); - return 0; - } - rm_udp = (wan_remora_udp_t *)&wan_udp.wan_udphdr_data[0]; - printf("\t------- Voltage Status (%s,port %d) -------\n\n", - WP_REMORA_DECODE_TYPE(rm_udp->type), - rm_udp->mod_no); - if (rm_udp->type == MOD_TYPE_FXS){ - printf("TIP\t: -%7.4f Volts\n", (float)(rm_udp->u.stats.tip_volt*376)/1000); - printf("RING\t: -%7.4f Volts\n", (float)(rm_udp->u.stats.ring_volt*376)/1000); - printf("VBAT\t: -%7.4f Volts\n", (float)(rm_udp->u.stats.bat_volt*376)/1000); - }else if (rm_udp->type == MOD_TYPE_FXO){ - unsigned char volt = rm_udp->u.stats.volt; - if (volt & 0x80){ - volt = ~volt + 1; - } - printf("VOLTAGE\t: %d Volts\n", volt); - } - fflush(stdout); - return 0; -} - - -//CORBA -int AFTUsage(void) -{ - printf("wanpipemon: Wanpipe AFT Hardware Level Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("wanpipemon -i -u -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address must be supplied\n"); - printf("\t\t Wanpipe network interface name (ex: wp1_chdlc)\n"); - printf("\tOption -u: (Optional, default: 9000)\n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -full: (Optional, trace option)\n"); - printf("\t\tDisplay raw packets in full: default trace pkt len=25bytes\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t l Link Status\n"); - printf("\t cv Read Code Version\n"); - printf("\t ru Display Router UP time\n"); - printf("\tCard Statistics\n"); - printf("\t s c Communication Error Statistics\n"); - printf("\t o Operational Statistics\n"); - printf("\tTrace Data \n"); - printf("\t t i Trace and Interpret ALL frames\n"); - printf("\t r Trace ALL frames, in RAW format\n"); - printf("\tT1/E1 Configuration/Statistics\n"); - printf("\t T a Read T1/E1/56K alarms.\n"); - printf("\t lt Diagnostic Digital Loopback testing (T1/E1 card only)\n"); - printf("\t allb Active Line Loopback mode (T1/E1 card only)\n"); - printf("\t dllb Deactive Line Loopback mode (T1/E1 card only)\n"); - printf("\t aplb Active Payload Loopback mode (T1/E1 card only)\n"); - printf("\t dplb Deactive Payload Loopback mode (T1/E1 card only)\n"); - printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t salb Send Loopback Activate Code (T1/E1 card only)\n"); - printf("\t sdlb Send Loopback Deactive Code (T1/E1 card only)\n"); - printf("\t txe Enable TX (AFT card only)\n"); - printf("\t txd Disable TX (AFT card only)\n"); - printf("\tFlush Statistics\n"); - printf("\t f c Flush Communication Error Statistics\n"); - printf("\t o Flush Operational Statistics\n"); - printf("\t pm Flush T1/E1 performance monitoring counters\n"); - printf("\tEcho Canceller Statistics\n"); - printf("\t e hw Read HW Echo Canceller Status\n"); - printf("\tAFT Remora Statistics\n"); - printf("\t a tone Play a tones ( -m - Module number)\n"); - printf("\t a ring Rings phone ( -m - Module number)\n"); - printf("\t a regdump Dumps FXS/FXO registers ( -m - Module number)\n"); - printf("\t a stats Voltage status ( -m - Module number)\n"); - printf("\tAFT Debugging\n"); - printf("\t d err Eanble RX RBS debugging\n"); - printf("\t d drr Disable RX RBS debugging\n"); - printf("\t d ert Eanble TX RBS debugging\n"); - printf("\t d drt Disable TX RBS debugging\n"); - printf("\t d rr Read RX/TX RBS status\n"); - printf("\t d pr Print current RX/TX RBS status\n"); - printf("\t d sr Set TX RBS status\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: wanpipemon -i w1g1 -u 9000 -c xm :View Modem Status \n"); - printf("\tex: wanpipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n\n"); - return 0; - -} - -static void aft_router_up_time( void ) -{ - u_int32_t time; - - wan_udp.wan_udphdr_command= ROUTER_UP_TIME; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - time = *(u_int32_t*)&wan_udp.wan_udphdr_data[0]; - - BANNER("ROUTER UP TIME"); - - print_router_up_time(time); -} - -static void read_ft1_te1_56k_config (void) -{ - unsigned char adapter_type = 0x00; - - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } -#if 0 - printf("Adapter type %i\n",adapter_type); -#endif - switch(adapter_type){ - case WAN_MEDIA_NONE: - printf("CSU/DSU Read Configuration Failed"); - break; - - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - case WAN_MEDIA_DS3: - case WAN_MEDIA_56K: - read_te1_56k_config(); - break; - - default: - printf("Unknown Front End Adapter Type: 0x%X",adapter_type); - break; - - } - return; -} - -int AFTMain(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - int mod_no = 0, i, err; - sdla_fe_debug_t fe_debug; - - switch(command[0]){ - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt,"l")){ - link_status(); - }else if (!strcmp(opt, "cv")){ - read_code_version(); - }else if (!strcmp(opt,"ru")){ - aft_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type wanpipemon for help\n\n"); - } - break; - - case 's': - if (!strcmp(opt,"c")){ - comm_err_stats(); - }else if (!strcmp(opt,"o")){ - operational_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type wanpipemon for help\n\n"); - printf("command: %s\n", command); - } - break; - - case 't': - memset(&trace_iface,0,sizeof(wp_trace_output_iface_t)); - - if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - trace_iface.type=WP_OUT_TRACE_RAW; - line_trace(0); - }else if (!strcmp(opt, "rh")){ - raw_data = WAN_TRUE; - trace_iface.type=WP_OUT_TRACE_HDLC; - line_trace(0); - }else if (!strcmp(opt, "rd")){ - raw_data = WAN_TRUE; - trace_iface.type=WP_OUT_TRACE_RAW; - line_trace(1); - }else if (!strcmp(opt, "i")){ - raw_data = WAN_FALSE; - trace_iface.type=WP_OUT_TRACE_INTERP; - line_trace(0); - }else if (!strcmp(opt, "i4")){ - raw_data = WAN_FALSE; - trace_iface.type=WP_OUT_TRACE_INTERP; - trace_iface.sub_type = WP_OUT_TRACE_INTERP_IPV4; - line_trace(0); - }else{ - printf("ERROR: Invalid Trace Command 't', Type wanpipemon for help\n\n"); - } - break; - - case 'f': - if (!strcmp(opt, "o")){ - flush_operational_stats(); - printf("Operational statistics flushed\n"); - /*operational_stats();*/ - }else if (!strcmp(opt, "c")){ - flush_comm_err_stats(); - printf("Communication statistics flushed\n"); - /* comm_err_stats();*/ - }else if (!strcmp(opt, "pm")){ - flush_te1_pmon(); - printf("Performance monitoring counters flushed\n"); - } else{ - printf("ERROR: Invalid Flush Command 'f', Type wanpipemon for help\n\n"); - } - break; - - case 'T': - if (!strcmp(opt,"read")){ - read_ft1_te1_56k_config(); - }else if (!strcmp(opt,"lt")){ - aft_digital_loop_test(); - }else if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"a")){ - read_te1_56k_stat(0); - }else if (!strcmp(opt,"af")){ - read_te1_56k_stat(1); - }else if (!strcmp(opt,"txe")){ - set_fe_tx_mode(WAN_FE_TXMODE_ENABLE); - }else if (!strcmp(opt,"txd")){ - set_fe_tx_mode(WAN_FE_TXMODE_DISABLE); - }else{ - printf("ERROR: Invalid FT1 Command 'T', Type wanpipemon for help\n\n"); - } - break; - - case 'd': - if (!strcmp(opt,"err")){ - set_debug_mode(WAN_FE_DEBUG_RBS, WAN_FE_DEBUG_RBS_RX_ENABLE); - }else if (!strcmp(opt,"ert")){ - set_debug_mode(WAN_FE_DEBUG_RBS, WAN_FE_DEBUG_RBS_TX_ENABLE); - }else if (!strcmp(opt,"drr")){ - set_debug_mode(WAN_FE_DEBUG_RBS, WAN_FE_DEBUG_RBS_RX_DISABLE); - }else if (!strcmp(opt,"drt")){ - set_debug_mode(WAN_FE_DEBUG_RBS, WAN_FE_DEBUG_RBS_TX_DISABLE); - }else if (!strcmp(opt,"rr")){ - set_debug_mode(WAN_FE_DEBUG_RBS, WAN_FE_DEBUG_RBS_READ); - }else if (!strcmp(opt,"pr")){ - set_debug_mode(WAN_FE_DEBUG_RBS, WAN_FE_DEBUG_RBS_PRINT); - }else if (!strcmp(opt,"sr")){ - int i=0; - if (argc < 6){ - printf("ERROR: Invalid command argument!\n"); - break; - } - fe_debug.fe_debug_rbs.abcd = 0x00; - fe_debug.fe_debug_rbs.channel= atoi(argv[5]); - if (fe_debug.fe_debug_rbs.channel < 1 || fe_debug.fe_debug_rbs.channel > 31){ - printf("ERROR: T1/E1 channel number of out range (%d)!\n", - fe_debug.fe_debug_rbs.channel); - break; - } - if (argc > 6){ - for(i = 0; i < strlen(argv[6]); i++){ - switch(argv[6][i]){ - case 'A': case 'a': - fe_debug.fe_debug_rbs.abcd |= WAN_RBS_SIG_A; - break; - case 'B': case 'b': - fe_debug.fe_debug_rbs.abcd |= WAN_RBS_SIG_B; - break; - case 'C': case 'c': - fe_debug.fe_debug_rbs.abcd |= WAN_RBS_SIG_C; - break; - case 'D': case 'd': - fe_debug.fe_debug_rbs.abcd |= WAN_RBS_SIG_D; - break; - } - } - } - fe_debug.type = WAN_FE_DEBUG_RBS; - fe_debug.mode = WAN_FE_DEBUG_RBS_SET; - set_fe_debug_mode(&fe_debug); - }else if (!strcmp(opt,"eais")){ - set_debug_mode(WAN_FE_DEBUG_ALARM, WAN_FE_DEBUG_ALARM_AIS_ENABLE); - }else if (!strcmp(opt,"dais")){ - set_debug_mode(WAN_FE_DEBUG_ALARM, WAN_FE_DEBUG_ALARM_AIS_DISABLE); - }else if (!strcmp(opt,"cfg")){ - fe_debug.type = WAN_FE_DEBUG_RECONFIG; - set_fe_debug_mode(&fe_debug); - }else if (!strcmp(opt,"reg")){ - int value; - fe_debug.type = WAN_FE_DEBUG_REG; - if (argc < 6){ - printf("ERROR: Invalid command argument!\n"); - break; - } - value = strtol(argv[5],(char**)NULL, 16); - if (value == LONG_MIN || value == LONG_MAX){ - printf("ERROR: Invalid argument 5: %s!\n", - argv[5]); - break; - } - fe_debug.fe_debug_reg.reg = value; - fe_debug.fe_debug_reg.read = 1; - if (argc > 6){ - value = strtol(argv[6],(char**)NULL, 16); - if (value == LONG_MIN || value == LONG_MAX){ - printf("ERROR: Invalid argument 6: %s!\n", - argv[6]); - break; - } - fe_debug.fe_debug_reg.read = 0; - fe_debug.fe_debug_reg.value = value; - } - set_fe_debug_mode(&fe_debug); - }else{ - printf("ERROR: Invalid Status Command 'd', Type wanpipemon for help\n\n"); - } - break; - case 'e': - if (strcmp(opt,"hw") == 0){ - aft_read_hwec_status(); - }else{ - printf("ERROR: Invalid Status Command 'e', Type wanpipemon for help\n\n"); - } - break; - - case 'a': - err = 0; - for(i=0;i 16){ - printf("ERROR: Invalid Module number!\n\n"); - fflush(stdout); - return 0; - } - mod_no--; - }else{ - printf("ERROR: Invalid Module number!\n\n"); - fflush(stdout); - return 0; - } - break; - } - } - - if (strcmp(opt,"tone") == 0){ - aft_remora_tones(mod_no); - }else if (strcmp(opt,"ring") == 0){ - aft_remora_ring(mod_no); - }else if (strcmp(opt,"regdump") == 0){ - aft_remora_regdump(mod_no); - }else if (strcmp(opt,"stats") == 0){ - aft_remora_stats(mod_no); - }else{ - printf("ERROR: Invalid Status Command 'a', Type wanpipemon for help\n\n"); - } - break; - - default: - printf("ERROR: Invalid Command, Type wanpipemon for help\n\n"); - break; - }//switch - printf("\n"); - fflush(stdout); - return 0; -}; //main diff --git a/util/wanpipemon.old/aftpipemon.o b/util/wanpipemon.old/aftpipemon.o deleted file mode 100644 index e0f5cb6843fb5d368fd1b4bdaec6e798450b8564..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29172 zcmchA3wTu3x%Ns32oV`nRJ?CsqM#56cS1lQ;o5L%5`-!>4l|QvWRgke0zo|*n?#8* ziuF?4ss*)`gZ5}EMMSMp5b$!;f?B+5i%JYCEefb8=Y7}u_ROA10<{10{Nppc>;2ZZ zzV)s9W$%pFPA#04mX@aMPnznY5=<%g3==a_!$8$ronWhKoWJ1Wzc5go^G@BKp04#> znYig{x8+(tg!0A$clWklb(_+fM!r{oxQ6}F*-aVmO+v6S&yCoO-G>ezKHSg}dnf0G zwv3f^&!#o?x!JWoecbNYKG*swY2#ra*4nu3+1=+h_vzkL;CBD@+s58?n|n6yz4Wru zpKhWgXS-92 zpd∨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 -* -* 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. -* ---------------------------------------------------------------------------- -* Jul 05, 2004 David Rokhvarg Added i4, iphy, rphy options. -* Jan 06, 2003 Nenad Corbic Initial version based on cpipemon -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include /* offsetof(), etc. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) - -/* Link addresses */ -#define CISCO_ADDR_UNICAST 0x0F -#define CISCO_ADDR_BCAST 0x8F - -/* Packet Types */ -#define CISCO_PACKET_IP 0x0800 -#define CISCO_PACKET_SLARP 0x8035 -#define CISCO_PACKET_CDP 0x2000 - -/* Packet Codes */ -#define SLARP_REQUEST 0 -#define SLARP_REPLY 1 -#define SLARP_KEEPALIVE 2 - -#define BANNER(str) banner(str,0) -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ -/* Structures for data casting */ - -/* types of ATM cells */ -enum ATM_CELL_TYPE{ - ATM_UNKNOWN_CELL, - ATM_IDLE_CELL, - ATM_PHYSICAL_LAYER_OAM_CELL, - ATM_RESERVED_FOR_PHYSICAL_LAYER_CELL, - ATM_UNASSIGNED_CELL, - ATM_USER_DATA_CELL, - ATM_OAM_F5_CELL -}; - -#pragma pack(1) - -#define LENGTH_ATM_CELL 53 -#define LENGTH_PAYLOAD_ATM_CELL 48 - -typedef struct { - unsigned char GFC_VPI; - unsigned char VPI_VCI; - unsigned char VCI; - unsigned char VCI_PT_CLP; - unsigned char HEC; -} ATM_HEADER_STRUCT; - -#define byte0 GFC_VPI -#define byte1 VPI_VCI -#define byte2 VCI -#define byte3 VCI_PT_CLP -#define byte4 HEC - -typedef struct { - ATM_HEADER_STRUCT ATM_header; - unsigned char ATM_payload[LENGTH_PAYLOAD_ATM_CELL]; -} ATM_CELL_STRUCT; -#pragma pack() - -typedef struct{ - - unsigned char UU; - unsigned char CPI; - unsigned short length; - unsigned long CRC; - -}AAL5_CPCS_PDU_TRAILER; - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -/* The ft1_lib needs these global variables */ -static int gfail; - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -static void error( void ); - -/* Command routines */ -static void modem( void ); -static void global_stats( void ); -static void comm_stats( void ); -static void read_code_version( void ); -static void atm_configuration( void ); -static void link_status( void ); -static void operational_stats( void ); -static void line_trace( int trace_mode, int trace_sub_type); -static void atm_router_up_time( void ); -static void flush_operational_stats( void ); -static void flush_global_stats( void ); -static void flush_comm_stats( void ); -static void set_FT1_monitor_status( unsigned char); -static void read_ft1_te1_56k_config( void ); - -/* Other routines */ -static int get_cell_type(char* data, int len); -void decode_user_data_cell(char* data, int len); - -static char *gui_main_menu[]={ -"atm_card_stats_menu","Card Status", -"atm_card_config_menu","Card Configuration", -"atm_stats_menu", "Card Statistics", -"atm_trace_menu", "Trace Data", -"csudsu_menu", "CSU DSU Config/Stats", -"atm_flush_menu","Flush Statistics", -"." -}; - - -static char *atm_card_stats_menu[]={ -"xm","Modem Status", -"xl","Link Status", -"xcv","Read Code Version", -"xru","Display Router UP time", -"." -}; - -static char *atm_card_config_menu[]={ -"crc","Read Configuration\n", -"." -}; - -static char *atm_stats_menu[]={ -"sg","Global Statistics", -"sc","Communication Error Statistics", -"so","Operational Statistics", -"." -}; - -static char *atm_trace_menu[]={ -"ti4", "Interpreted IP Data frames", -"tr", "Raw Hex, Data packets", -"trl2","Raw Hex, ATM-PDU packets", -"trl1","Raw Hex, ATM Cells", -"." -}; - -static char *atm_flush_menu[]={ -"fg","Flush Global Statistics", -"fc","Flush Communication Error Statistics", -"fo","Flush Operational Statistics", -"." -}; - - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"atm_card_stats_menu",atm_card_stats_menu}, - {"atm_card_config_menu",atm_card_config_menu}, - {"atm_stats_menu",atm_stats_menu}, - {"atm_trace_menu",atm_trace_menu}, - {"csudsu_menu",csudsu_menu}, - {"atm_flush_menu",atm_flush_menu}, - {".",NULL} -}; - - -char ** ATMget_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** ATMget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int ATMConfig(void) -{ - char codeversion[10]; - unsigned char x=0; - - protocol_cb_size = sizeof(wan_mgmt_t) + - sizeof(wan_cmd_t) + - sizeof(wan_trace_info_t) + 1; - wan_udp.wan_udphdr_command= PHY_READ_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - while (++x < 4) { - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - - if (wan_udp.wan_udphdr_return_code == 0xCC){ - return(WAN_FALSE); - } - wan_udp.wan_udphdr_return_code = 0xaa; - } - - if (x >= 4) return(WAN_FALSE); - - if (wan_udp.wan_udphdr_data_len == sizeof(PHY_CONFIGURATION_STRUCT)) { - is_508 = WAN_TRUE; - } else { - is_508 = WAN_FALSE; - } - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = READ_CODE_VERSION; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - return(WAN_TRUE); -}; - -void ATM_set_FT1_mode( void ) -{ - for(;;){ - wan_udp.wan_udphdr_command= SET_FT1_MODE; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0){ - break; - } - } -} /* set_FT1_mode */ - -void ATM_read_FT1_status( void ) -{ - - wan_udp.wan_udphdr_command= FT1_READ_STATUS; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if(wan_udp.wan_udphdr_return_code == 0) { - par_port_A_byte = wan_udp.wan_udphdr_data[0]; - par_port_B_byte = wan_udp.wan_udphdr_data[1]; - - if(!(par_port_A_byte & PP_A_RT_NOT_RED)) { - FT1_LED.RT_red ++; - } - if(!(par_port_A_byte & PP_A_RT_NOT_GREEN)) { - FT1_LED.RT_green ++; - } - if((par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) - == (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - FT1_LED.RT_off ++; - } - if(!(par_port_A_byte & PP_A_LL_NOT_RED)) { - FT1_LED.LL_red ++; - } - else { - FT1_LED.LL_off ++; - } - if(!(par_port_A_byte & PP_A_DL_NOT_RED)) { - FT1_LED.DL_red ++; - } - else { - FT1_LED.DL_off ++; - } - if(!(par_port_B_byte & PP_B_RxD_NOT_GREEN)) { - FT1_LED.RxD_green ++; - } - if(!(par_port_B_byte & PP_B_TxD_NOT_GREEN)) { - FT1_LED.TxD_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_GREEN)) { - FT1_LED.ERR_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_red ++; - } - if((par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) - == (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_off ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_RED)) { - FT1_LED.INS_red ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_GREEN)) { - FT1_LED.INS_green ++; - } - if((par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) - == (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - FT1_LED.INS_off ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_GREEN)) { - FT1_LED.ST_green ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_RED)) { - FT1_LED.ST_red ++; - } - if((par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) - == (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - FT1_LED.ST_off ++; - } - } -} /* read_FT1_status */ - - - -static void error( void ) -{ - printf("Error: Command failed!\n"); - -}; /* error */ - - -static void global_stats (void) -{ - GLOBAL_STATS_STRUCT* global_stats; - wan_udp.wan_udphdr_command= READ_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("GLOBAL STATISTICS"); - global_stats = (GLOBAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - printf("Times application did not respond to IRQ: %u", - global_stats->app_IRQ_timeout_count); - } else { - error(); - } -}; /* global stats */ - -static void flush_global_stats (void) -{ - wan_udp.wan_udphdr_command= FLUSH_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) error(); -}; /* flush global stats */ - -static void modem( void ) -{ - unsigned char cts_dcd; - wan_udp.wan_udphdr_command= READ_MODEM_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("MODEM STATUS"); - memcpy(&cts_dcd, &wan_udp.wan_udphdr_data[0],1); - printf("DCD: "); - (cts_dcd & 0x08) ? printf("High\n") : printf("Low\n"); - printf("CTS: "); - (cts_dcd & 0x20) ? printf("High\n") : printf("Low\n"); - } else { - error(); - } -}; /* modem */ - - -static void comm_stats (void) -{ - COMMS_ERROR_STATS_STRUCT* comm_stats; - wan_udp.wan_udphdr_command= READ_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("COMMUNICATION ERROR STATISTICS"); - - comm_stats = (COMMS_ERROR_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf("Number of receiver overrun errors: %u\n", comm_stats->Rx_overrun_err_count); - printf("Number of times DCD changed state: %u\n", comm_stats->DCD_state_change_count); - printf("Number of times CTS changed state: %u\n", comm_stats->CTS_state_change_count); - } else { - error(); - } -}; /* comm_stats */ - - -static void flush_comm_stats( void ) -{ - wan_udp.wan_udphdr_command= FLUSH_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) error(); -}; /* flush_comm_stats */ - - -static void read_code_version (void) -{ - wan_udp.wan_udphdr_command= READ_CODE_VERSION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("CODE VERSION"); - printf("Code version: %s\n", - wan_udp.wan_udphdr_data); - }else{ - printf("Error: Rc=%x\n",wan_udp.wan_udphdr_return_code); - } -}; /* read code version */ - -static void atm_configuration (void) -{ - PHY_CONFIGURATION_STRUCT *cfg; - wan_udp.wan_udphdr_command = PHY_READ_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - cfg = (PHY_CONFIGURATION_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - BANNER("ATM CONFIGURATION"); - - if (wan_udp.wan_udphdr_return_code == 0) { - - printf("%-25s: %-8lu \t%-25s: %s\n", - "Baud rate",cfg->baud_rate, - "Line configuration", - (cfg->line_config_options==INTERFACE_LEVEL_V35)? - "V.35":"RS-232"); - - - printf("%-25s: 0x%-8X\t%-25s: %u\n", - "Modem config options",cfg->modem_config_options, - "Modem Status Timer",cfg->modem_status_timer); - - printf("%-25s: %-8u \t%-25s: 0x%-8X\n", - "Modem Status Timer",cfg->modem_status_timer, - "API Options",cfg->API_options); - - - printf("%-25s: 0x%-8X\t%-25s: 0x%-8X\n", - "Protocol Options",cfg->protocol_options, - "HEC Options",cfg->HEC_options); - - printf("%-25s: 0x%-8X\t%-25s: 0x%-8X\n", - "Custom RX COSET",cfg->custom_Rx_COSET, - "Custom TX COSET",cfg->custom_Tx_COSET); - - printf("%-25s: 0x%-8X\t%-25s: %u\n", - "Buffer Options",cfg->buffer_options, - "Max Cells in Tx Block", cfg->max_cells_in_Tx_block); - - printf("%-25s: %-8u \t%-25s: %-8u\n", - "Tx Underrun Cell GFC",cfg->Tx_underrun_cell_GFC, - "Tx Underrun Cell PT",cfg->Tx_underrun_cell_PT); - - - printf("%-25s: %-8u \t%-25s: %-8u\n", - "Tx Underrun Cell CLP",cfg->Tx_underrun_cell_CLP, - "Tx Underrun Cell Payload",cfg->Tx_underrun_cell_payload); - - printf("%-25s: %-8u \t%-25s: %-8u\n", - "Mac Cells in Rx Block",cfg->max_cells_in_Rx_block, - "Rx Hunt Timer",cfg->Rx_hunt_timer); - - printf("%-25s: 0x%-8X\t%-25s: %u\n", - "Rx Sync Bytes",cfg->Rx_sync_bytes, - "Rx Sync Offset",cfg->Rx_sync_offset); - - printf("%-25s: %-8u \t%-25s: %-8u\n", - "Cell Rx sync loss timer",cfg->cell_Rx_sync_loss_timer, - "Rx HEC Check Timer",cfg->Rx_HEC_check_timer); - - printf("%-25s: %-8u \t%-25s: %-8u\n", - "Rx Bad HEC Timer",cfg->Rx_bad_HEC_timer, - "Rx Max Bad HEC Count",cfg->Rx_max_bad_HEC_count); - - printf("%-25s: 0x%-8X", - "Statistics Options",cfg->statistics_options); - - } else { - error(); - } -}; /* atm_configuration */ - - -static void link_status (void) -{ - wan_udp.wan_udphdr_command= ATM_LINK_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - BANNER("LINK STATUS"); - - if (wan_udp.wan_udphdr_return_code == 0){ - printf("ATM PHY Status: %s\n", - wan_udp.wan_udphdr_data[0] ? "Connected":"Disconnected"); - printf("ATM SAR Status: %s\n", - (wan_udp.wan_udphdr_data[1]==ATM_CONNECTED)?"Connected": - (wan_udp.wan_udphdr_data[1]==ATM_DISCONNECTED)?"Disconnected": - (wan_udp.wan_udphdr_data[1]==ATM_AIS)?"Alarm AIS": - "Unknown"); - } - - return; -}; /* Link Status */ - - -static void operational_stats (void) -{ - PHY_OPERATIONAL_STATS_STRUCT *stats; - wan_udp.wan_udphdr_command= PHY_READ_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("OPERATIONAL STATISTICS"); - stats = (PHY_OPERATIONAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf( " Number of ATM Cell blocks transmitted: %lu",stats->blocks_Tx_count); - printf( "\n Number of ATM Cell bytes transmitted: %lu",stats->bytes_Tx_count); - printf( "\n Transmit (idle+data) Throughput(bps): %lu",stats->Tx_throughput); - printf( "\n Tx Underrun cell count: %lu",stats->Tx_underrun_cell_count); - - printf("\n\n Number of ATM Cell blocks received: %lu",stats->blocks_Rx_count); - printf( "\n Number of ATM Cell bytes received: %lu",stats->bytes_Rx_count); - printf( "\n Receive (idle+data) Throughput(bps): %lu",stats->Rx_throughput); - - printf("\n\n"); - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "TX cell frames discarded",stats->Tx_length_error_count, - "RX ATM Cell frames disc",stats->Rx_blocks_discard_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx Idle Cell discarded",stats->Rx_Idle_Cell_discard_count, - "Rx Unassigned Cell disc",stats->Rx_Unas_Cell_discard_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx Phys Lyr Cell disc",stats->Rx_Phys_Lyr_Cell_discard_count, - "Rx_bad_HEC_count",stats->Rx_bad_HEC_count); - - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx_sync_attempt_count",stats->Rx_sync_attempt_count, - "Rx_sync_achieved_count",stats->Rx_sync_achieved_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx_sync_failure_count",stats->Rx_sync_failure_count, - "Rx_hunt_attempt_count",stats->Rx_hunt_attempt_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx_hunt_char_sync_count",stats->Rx_hunt_char_sync_count, - "Rx_hunt_timeout_count",stats->Rx_hunt_timeout_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx_hunt_achieved_count",stats->Rx_hunt_achieved_count, - "Rx_hunt_failure_count",stats->Rx_hunt_failure_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx_presync_attempt_count",stats->Rx_presync_attempt_count, - "Rx_presync_achieved_count",stats->Rx_presync_achieved_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx_presync_failure_count",stats->Rx_presync_failure_count, - "Rx_resync_bad_HEC_count",stats->Rx_resync_bad_HEC_count); - - printf("%-25s: %-8lu \t%-25s: %-8lu\n", - "Rx_resync_rx_loss_count",stats->Rx_resync_reception_loss_count, - "Rx_resync_overrun_count",stats->Rx_resync_overrun_count); - - } else { - error(); - } -} /* Operational_stats */ - - -static void flush_operational_stats( void ) -{ - wan_udp.wan_udphdr_command= PHY_FLUSH_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } - -}; /* flush_operational_stats */ - - -int ATMDisableTrace(void) -{ - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - return 0; -} - - -static void line_trace( int trace_mode, int trace_sub_type) -{ - unsigned int num_frames, num_chars; - unsigned short curr_pos = 0; - wan_trace_pkt_t *trace_pkt; - unsigned int i, j; - int recv_buff = sizeof(wan_udp_hdr_t)+ 100; - fd_set ready; - struct timeval to; - int count; - wp_trace_output_iface_t trace_iface; - - memset(&trace_iface,0,sizeof(wp_trace_output_iface_t)); - - setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recv_buff, sizeof(int) ); - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - wan_udp.wan_udphdr_command= ENABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0]=trace_mode; - - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - printf("Starting trace...(Press ENTER to exit)\n"); - fflush(stdout); - } else if(wan_udp.wan_udphdr_return_code == 0xCD ) { - printf("Cannot Enable Line Tracing from Underneath.\n"); - fflush(stdout); - return; - }else if (wan_udp.wan_udphdr_return_code == 0x01 ) { - printf("Starting trace...(although it's already enabled!)\n"); - printf("Press ENTER to exit.\n"); - fflush(stdout); - }else{ - printf("Failed to Enable Line Tracing. Return code: 0x%02X\n", - wan_udp.wan_udphdr_return_code ); - fflush(stdout); - return; - } - - to.tv_sec = 0; - to.tv_usec = 0; - for(;;) { - FD_ZERO(&ready); - FD_SET(0,&ready); - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - - wan_udp.wan_udphdr_command = GET_TRACE_INFO; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len) { - - num_frames = wan_udp.wan_udphdr_atm_num_frames; - - for ( i = 0; i < num_frames; i++) { - trace_pkt= (wan_trace_pkt_t *)&wan_udp.wan_udphdr_data[curr_pos]; - - /* frame type */ - if (trace_pkt->status & 0x01) { - printf("\nOUTGOING\t"); - }else{ - if (trace_pkt->status & 0x10) { - printf("\nINCOMING - Aborted\t"); - } else if (trace_pkt->status & 0x20) { - printf("\nINCOMING - CRC Error\t"); - } else if (trace_pkt->status & 0x40) { - printf("\nINCOMING - Overrun Error\t"); - } else { - printf("\nINCOMING\t"); - } - } - - /* real length and time stamp */ - printf("Len=%-5u\tTimestamp=%-5u\t", - trace_pkt->real_length, trace_pkt->time_stamp); - - curr_pos += sizeof(wan_trace_pkt_t); - - if (trace_pkt->real_length >= WAN_MAX_DATA_SIZE){ - printf("\t:the frame data is to big (%u)!", - trace_pkt->real_length); - fflush(stdout); - continue; - - }else if (trace_pkt->data_avail == 0) { - - printf("\t: the frame data is not available" ); - fflush(stdout); - continue; - } - - /* update curr_pos again */ - curr_pos += trace_pkt->real_length; - - if (!trace_all_data){ - if (trace_mode != 2){ - num_chars = (unsigned char) - ((trace_pkt->real_length <= 53) - ? trace_pkt->real_length : 53); - }else{ - num_chars = trace_pkt->real_length; - } - }else{ - num_chars = trace_pkt->real_length; - } - - trace_iface.link_type = WANCONFIG_ATM; - trace_iface.type = WP_OUT_TRACE_INTERP; - trace_iface.sub_type = trace_sub_type; - - trace_iface.trace_all_data = trace_all_data; - trace_iface.data=trace_pkt->data; - - trace_iface.len = trace_pkt->real_length; - //trace_iface.len = num_chars;//trace_pkt->real_length; - - wp_trace_output(&trace_iface); - - count = 0; - //printf("\t"); - - //WP_OUT_TRACE_ATM_INTERPRETED_PHY - if(trace_mode == 2 || trace_mode == 3){ - - if(trace_sub_type == WP_OUT_TRACE_ATM_INTERPRETED_PHY){ - //printf("\n\t"); - //printf("\t"); - printf("\t\tHeader\t : "); - - j = 3; - printf("GFC=%d ", - (trace_pkt->data[j-3] & 0xF0) >> 4 ); - - printf("VPI=%d ", - trace_pkt->data[j-3]<<4 | - (trace_pkt->data[j-2]&0xF0)>>4); - - printf("VCI=%d ", - (trace_pkt->data[j-2]&0x0F)<<12 | - (trace_pkt->data[j-1]<<4)| - (trace_pkt->data[j-0]&0xF0)>>4); - - printf("PT=0x%X ", - (trace_pkt->data[j]&0x0F)>>1); - - printf("CLP=0x%X ", - trace_pkt->data[j] & 0x01); - - printf("HEC=0x%02X ", - trace_pkt->data[j+1]); - - - printf("Cell Type: "); - switch(get_cell_type((char*)trace_pkt->data, trace_pkt->real_length)) - { - case ATM_USER_DATA_CELL: - decode_user_data_cell((char*)trace_pkt->data, - trace_pkt->real_length); - break; - default: - ;//do nothting - } - } - //printf("\n\t\t"); - }//if() - - - printf("\n"); - fflush(stdout); - - }//for ( i = 0; i < num_frames; i++) - } - curr_pos = 0; - - if (!wan_udp.wan_udphdr_chdlc_ismoredata){ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - }else{ - to.tv_sec = 0; - to.tv_usec = 0; - } - } - - wan_udp.wan_udphdr_command= DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); -}; /* line_trace */ - - -static int get_cell_type(char* data, int len) -{ - ATM_HEADER_STRUCT * atm_hdr_ptr = (ATM_HEADER_STRUCT * )data; - ATM_CELL_STRUCT * ATM_cell_ptr = (ATM_CELL_STRUCT * )data; - - unsigned short gfc_vpi = ((ATM_cell_ptr->ATM_header.GFC_VPI << 4) & 0x0FF0) | - ((ATM_cell_ptr->ATM_header.VPI_VCI >> 4) & 0x000F); - - unsigned short vci = ((ATM_cell_ptr->ATM_header.VPI_VCI << 12) & 0xF000) | - ((ATM_cell_ptr->ATM_header.VCI << 4) & 0x0FF0) | - ((ATM_cell_ptr->ATM_header.VCI_PT_CLP >> 4) & 0x000F); - - unsigned char pti = ((ATM_cell_ptr->ATM_header.VCI_PT_CLP >> 1) & 0x07); - - unsigned char clp = ATM_cell_ptr->ATM_header.VCI_PT_CLP & 0x01; - - //unsigned char hec = ATM_cell_ptr->ATM_header.HEC; - - if(!(gfc_vpi & 0x00FF) && !vci){ - - if( !atm_hdr_ptr->byte0 && - !atm_hdr_ptr->byte1 && - !atm_hdr_ptr->byte2){ - - if(!(atm_hdr_ptr->byte3 & 0xFE) && (clp & 0x01) ){ - - printf("Idle"); - return ATM_IDLE_CELL; - } - - if(!(atm_hdr_ptr->byte3 & 0xFC) && (atm_hdr_ptr->byte3 & 0x03) ){ - - printf("PHY Layer"); - return ATM_PHYSICAL_LAYER_OAM_CELL; - } - } - - if( !(atm_hdr_ptr->byte0 & 0x0F) && - !atm_hdr_ptr->byte1 && - !atm_hdr_ptr->byte2 && - !(atm_hdr_ptr->byte3 & 0xF0)){ - - if(atm_hdr_ptr->byte3 & 0x01 ){ - - printf("PHY Layer"); - return ATM_RESERVED_FOR_PHYSICAL_LAYER_CELL; - }else{ - - printf("Unassigned"); - return ATM_UNASSIGNED_CELL; - } - } - }else{ - if(!(pti & 0x04)){ - - printf("User Data"); - return ATM_USER_DATA_CELL; - }else if(pti & 0x04){ - - printf("OAM"); - return ATM_OAM_F5_CELL; - } - } - - printf("Unknown"); - return ATM_UNKNOWN_CELL; -} - -void decode_user_data_cell(char* data, int len) -{ - int i; - unsigned char* puchar_tmp; - ATM_CELL_STRUCT * ATM_cell_ptr = (ATM_CELL_STRUCT * )data; - AAL5_CPCS_PDU_TRAILER * trailer_ptr = (AAL5_CPCS_PDU_TRAILER * )&data[45]; - unsigned char pti = ((ATM_cell_ptr->ATM_header.VCI_PT_CLP >> 1) & 0x07); - - if(pti & 0x01){ - - printf("\n\t\tPDU trailer: "); - printf("UU=0x%02X ", trailer_ptr->UU); - printf("CPI=0x%02X ", trailer_ptr->CPI); - printf("length=%u ", ntohs(trailer_ptr->length)); - - printf("CRC=0x"); - puchar_tmp = (unsigned char*)&trailer_ptr->CRC; - - for(i = 0; i < 4; i++){ - printf("%02X", *puchar_tmp); - puchar_tmp++; - } - } -} -/* -if(!strcmp(opt,"il3" )){ - line_trace(0, WP_OUT_TRACE_RAW); -}else if (!strcmp(opt, "rl2")){ - line_trace(1, WP_OUT_TRACE_RAW); -*/ - -//CORBA -int ATMUsage(void) -{ - printf("wanpipemon: Wanpipe ATM Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("wanpipemon -i -u -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address must be supplied\n"); - printf("\t\t Wanpipe network interface name (ex: wp1_chdlc)\n"); - printf("\tOption -u: (Optional, default: 9000)\n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -full: (Optional, trace option)\n"); - printf("\t\tDisplay raw packets in full: default trace pkt len=25bytes\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t l Link Status\n"); - printf("\t cv Read Code Version\n"); - printf("\t ru Display Router UP time\n"); - printf("\tCard Configuration\n"); - printf("\t c rc Read CHDLC Configuration\n"); - printf("\tCard Statistics\n"); - printf("\t s g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t o Operational Statistics\n"); - printf("\t s SLARP and CDP Statistics\n"); - printf("\tTrace Data \n"); - printf("\t t rl3 Trace DATA frames only (no header), in RAW format\n"); - printf("\t rl2 Trace DATA frames only (display header), in RAW format\n"); - printf("\t rl1 Trace PHY level cells, in RAW format (surpress idle)\n"); - printf("\t il1 Trace PHY level cells, in Interpreted format (surpress idle)\n"); - printf("\t rphy Trace PHY level cells, in RAW format\n"); - printf("\t iphy Trace PHY level cells, in Interpreted format.\n"); - printf("\t i4 Trace DATA frames only. Interpret data as IP V4 frames.\n"); - printf("\tFT1/T1/E1/56K Configuration/Statistics\n"); - printf("\t T v View Status \n"); - printf("\t s Self Test\n"); - printf("\t l Line Loop Test\n"); - printf("\t d Digital Loop Test\n"); - printf("\t r Remote Test\n"); - printf("\t o Operational Mode\n"); - printf("\t p FT1 CSU/DSU operational statistics\n"); - printf("\t f Flush FT1 CSU/DSU operational statistcs\n"); - printf("\t set Set CSU/DSU configuration\n"); - printf("\t read Read CSU/DSU configuration (FT1/T1/E1 card)\n"); - printf("\t allb Active Line Loopback mode (T1/E1 card only)\n"); - printf("\t dllb Deactive Line Loopback mode (T1/E1 card only)\n"); - printf("\t aplb Active Payload Loopback mode (T1/E1 card only)\n"); - printf("\t dplb Deactive Payload Loopback mode (T1/E1 card only)\n"); - printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t salb Send Loopback Activate Code (T1/E1 card only)\n"); - printf("\t sdlb Send Loopback Deactive Code (T1/E1 card only)\n"); - printf("\t a Read T1/E1/56K alarms.\n"); - printf("\tFlush Statistics\n"); - printf("\t f g Flush Global Statistics\n"); - printf("\t c Flush Communication Error Statistics\n"); - printf("\t o Flush Operational Statistics\n"); - printf("\t s Flush SLARP and CDP Statistics\n"); - printf("\t p Flush T1/E1 performance monitoring counters\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: wanpipemon -i wp1_atm -u 9000 -c xm :View Modem Status \n"); - printf("\tex: wanpipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n\n"); - return 0; -} - -static void atm_router_up_time( void ) -{ - unsigned long time; - - wan_udp.wan_udphdr_command= ROUTER_UP_TIME; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - time = *(unsigned long*)&wan_udp.wan_udphdr_data[0]; - - BANNER("ROUTER UP TIME"); - - print_router_up_time(time); -} - -static void set_FT1_monitor_status( unsigned char status) -{ - gfail = 0; - - - //cb.data[0] = status; - wan_udp.wan_udphdr_command= FT1_MONITOR_STATUS_CTRL; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = status; - DO_COMMAND(wan_udp); - //if( (cb.wan_udphdr_return_code != 0) && status){ - if ((wan_udp.wan_udphdr_return_code != 0) && status){ - gfail = 1; - printf("This command is only possible with S508/FT1 board!"); - } -} /* set_FT1_monitor_status */ - - -static void read_ft1_te1_56k_config (void) -{ - unsigned char adapter_type = 0x00; - - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } - - printf("Adapter type %i\n",adapter_type); - - switch(adapter_type){ - case WAN_MEDIA_NONE: - printf("CSU/DSU Read Configuration Failed"); - break; - - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - case WAN_MEDIA_56K: - read_te1_56k_config(); - break; - } - return; -} - - -int ATMMain(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - - switch(command[0]){ - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt, "cv")){ - read_code_version(); - }else if (!strcmp(opt,"l")){ - link_status(); - }else if (!strcmp(opt,"ru")){ - atm_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type wanpipemon for help\n\n"); - } - break; - case 's': - if (!strcmp(opt,"g")){ - global_stats(); - }else if (!strcmp(opt,"c")){ - comm_stats(); - }else if (!strcmp(opt,"o")){ - operational_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type wanpipemon for help\n\n"); - - } - break; - case 'c': - if (!strcmp(opt,"rc")){ - atm_configuration(); - }else{ - printf("ERROR: Invalid Configuration Command 'c', Type wanpipemon for help\n\n"); - } - break; - case 't': - if(!strcmp(opt, "rl3" )){ - line_trace(0, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "rl2")){ - line_trace(1, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "rl1")){ - line_trace(2, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "il1")){ - line_trace(2, WP_OUT_TRACE_ATM_INTERPRETED_PHY); - }else if (!strcmp(opt, "rphy")){ - line_trace(3, WP_OUT_TRACE_ATM_RAW_PHY); - }else if (!strcmp(opt, "iphy")){ - line_trace(3, WP_OUT_TRACE_ATM_INTERPRETED_PHY); - }else if (!strcmp(opt, "i4")){ - line_trace(0, WP_OUT_TRACE_INTERP_IPV4); - }else{ - printf("ERROR: Invalid Trace Command 't', Type wanpipemon for help\n\n"); - } - break; - case 'f': - if (!strcmp(opt, "o")){ - flush_operational_stats(); - operational_stats(); - }else if (!strcmp(opt, "g")){ - flush_global_stats(); - global_stats(); - }else if (!strcmp(opt, "c")){ - flush_comm_stats(); - comm_stats(); - }else if (!strcmp(opt, "p")){ - flush_te1_pmon(); - } else{ - printf("ERROR: Invalid Flush Command 'f', Type wanpipemon for help\n\n"); - } - break; - - case 'T': - if (!strcmp(opt, "v")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - view_FT1_status(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "s")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "l")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_local_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "d")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_digital_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "r")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_remote_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "o")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_operational_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "f")){ - set_FT1_monitor_status(0x04); - if(!gfail){ - printf("Flushed Operational Statistics\n"); - }else{ - printf("FT1 Flush Failed %i\n",gfail); - } - - }else if (!strcmp(opt,"read")){ - read_ft1_te1_56k_config(); - }else if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"a")){ - read_te1_56k_stat(0); - } else{ - printf("ERROR: Invalid FT1 Command 'T', Type wanpipemon for help\n\n"); - } - break; - - default: - printf("ERROR: Invalid Command, Type wanpipemon for help\n\n"); - break; - }//switch - printf("\n"); - fflush(stdout); - return 0; -}; //main diff --git a/util/wanpipemon.old/atmpipemon.o b/util/wanpipemon.old/atmpipemon.o deleted file mode 100644 index c5141733c853edabcc73b4b481635b83a616799f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26004 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 k!@n#le7o>Rgg+{Lr|`#w_X*!eT!D2%_%lS -* -* Copyright: (c) 1995-2002 Sangoma Technologies Inc. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* ---------------------------------------------------------------------------- -* Nov 07, 2001 Nenad Corbic Inital Version. -*****************************************************************************/ - -#if !defined(__LINUX__) -# error "BiSync Monitor not supported on FreeBSD/OpenBSD OS!" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "fe_lib.h" - -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN 2024 - -/* Structures for data casting */ -#pragma pack(1) -typedef struct { - unsigned char link_address; /* Broadcast or Unicast */ - unsigned char control; - unsigned short packet_type; /* IP/SLARP/CDP */ -} cisco_header_t; -#pragma pack() - -#pragma pack(1) -typedef struct { - wp_mgmt_t wp_mgmt PACKED; - cblock_t cblock PACKED; - trace_info_t trace_info PACKED; - unsigned char data[SIZEOF_MB_DATA_BFR] PACKED; -} udp_mgmt_pkt_t; -#pragma pack() - -#pragma pack(1) -typedef struct { - ip_pkt_t ip_pkt; - udp_pkt_t udp_pkt; - udp_mgmt_pkt_t cb; -}udp_packet; -#pragma pack() - -#define CB_SIZE sizeof(wp_mgmt_t)+sizeof(cblock_t)+sizeof(trace_info_t)+1 - -/* Link addresses */ -#define CISCO_ADDR_UNICAST 0x0F -#define CISCO_ADDR_BCAST 0x8F - -/* Packet Types */ -#define CISCO_PACKET_IP 0x0800 -#define CISCO_PACKET_SLARP 0x8035 -#define CISCO_PACKET_CDP 0x2000 - -#pragma pack(1) -typedef struct { - unsigned long code; /* Slarp Control Packet Code */ - union { - struct { - unsigned long address; /* IP address */ - unsigned long mask; /* IP mask */ - unsigned short reserved[3]; - } address; - struct { - unsigned long my_sequence; - unsigned long your_sequence; - unsigned short reliability; - unsigned short t1; /* time alive (upper) */ - unsigned short t2; /* time alive (lower) */ - } keepalive; - } un; -} cisco_slarp_t; -#pragma pack() -/* Packet Codes */ - -#define SLARP_REQUEST 0 -#define SLARP_REPLY 1 -#define SLARP_KEEPALIVE 2 - -/* storage for FT1 LEDs */ -FT1_LED_STATUS FT1_LED; - -/* Prototypes */ - -int main(int, char** ); -void init(int, char** ); -void usage( void ); -int MakeUdpConnection( void ); -#ifdef LINUX_2_1 -int MakeRawConnection( void ); -#endif -int ObtainConfiguration( void ); -unsigned char DoCommand( void ); -void error( void ); - -/* Command routines */ -void modem( void ); -void global_stats( void ); -void comm_stats( void ); -void read_code_version( void ); -void bstrm_configuration( void ); -void operational_stats( void ); -void slarp_stats( void ); -void line_trace( int ); -void bstrm_router_up_time( void ); -void flush_operational_stats( void ); -void flush_global_stats( void ); -void flush_comm_stats( void ); -void get_ip_addr(char *if_name); -void banner(char *); -void set_FT1_monitor_status( unsigned char); -void set_FT1_mode(int verbose); -void read_FT1_status( void ); -void read_ft1_op_stats( void ); - - -/* Global variables */ -int sock = 0; -struct sockaddr_in soin; -unsigned int loop_counter, frame_count; -int is_508, raw_data=WAN_FALSE, udp_port = 9000; -char ipaddress[16]; -char src_ip[16]; -char i_name[16]; -char cmd[5]; -char raw_sock=0; - -/* The ft1_lib needs these global variables */ -unsigned char par_port_A_byte; -unsigned char par_port_B_byte; -int gfail; -udp_mgmt_pkt_t cb; - - -int MakeUdpConnection( void ) -{ - sock = socket( PF_INET, SOCK_DGRAM, 0 ); - - if( sock < 0 ) { - printf("Error: Unable to open socket!\n"); - return( WAN_FALSE ); - } /* if */ - - soin.sin_family = AF_INET; - soin.sin_addr.s_addr = inet_addr(ipaddress); - - if(soin.sin_addr.s_addr < 0){ - printf("Error: Invalid IP address!\n"); - return( WAN_FALSE ); - } - - soin.sin_port = htons((u_short)udp_port); - - if( !connect( sock, (struct sockaddr *)&soin, sizeof(soin)) == 0 ) { - printf("Error: Cannot make connection!\nMake sure the IP address is correct\n"); - return( WAN_FALSE ); - } - - if( !ObtainConfiguration() ) { - printf("Error: Unable to obtain BSTRM information.\nMake sure the IP and UDP port are correct.\n"); - close( sock ); - return( WAN_FALSE ); - } - - return( WAN_TRUE ); -}; /* MakeConnection */ - - -#ifdef LINUX_2_1 -int MakeRawConnection( void ) -{ - struct ifreq ifr; - struct sockaddr_ll soin; - - raw_sock=1; - - sock = socket(PF_PACKET, SOCK_RAW, 0); - if (sock < 0){ - printf("Error: Unable to open socket!\n"); - return( WAN_FALSE ); - } /* if */ - - soin.sll_family = AF_PACKET; - soin.sll_protocol = htons(ETH_P_IP); - strcpy (ifr.ifr_name,i_name); - ioctl(sock,SIOCGIFINDEX,&ifr); - soin.sll_ifindex = ifr.ifr_ifindex; - - - if (bind(sock, (struct sockaddr *)&soin, sizeof(soin)) < 0) { - printf("Error: Cannot make connection!\nMake sure the IP address is correct\n"); - return( WAN_FALSE ); - } /* if */ - - if (!ObtainConfiguration()) { - printf("Error: Unable to obtain BSTRM information.\n"); - printf("Make sure the IP and UDP port are correct.\n"); - close( sock ); - return( WAN_FALSE ); - } /* if */ - - return( WAN_TRUE ); - -}; /* MakeRawConnection */ -#endif - -int ObtainConfiguration( void ) -{ - unsigned char codeversion[10]; - unsigned char x; - - x = 0; - cb.cblock.command= READ_BSTRM_CONFIGURATION; - cb.cblock.buffer_length = 0; - - while (DoCommand() != 0 && ++x < 4) { - if (cb.cblock.return_code == 0xaa) { - printf("Error: Command timeout occurred"); - return(WAN_FALSE); - } - - if (cb.cblock.return_code == 0xCC ) return(WAN_FALSE); - } - - if (x >= 4) return(WAN_FALSE); - - if( cb.cblock.buffer_length == sizeof(BSTRM_CONFIGURATION_STRUCT)) { - is_508 = WAN_TRUE; - } else { - is_508 = WAN_FALSE; - } - - strcpy(codeversion, "?.??"); - - cb.cblock.command= READ_BSTRM_CODE_VERSION; - cb.cblock.buffer_length = 0; - DoCommand(); - if (cb.cblock.return_code == 0) { - cb.data[cb.cblock.buffer_length] = 0; - strcpy(codeversion, cb.data); - } - - return(WAN_TRUE); -}; /* ObtainConfiguration */ - - -unsigned char DoCommand( void ) -{ - static unsigned char id = 0; - fd_set ready; - struct timeval to; - int x, err=0; - - if (raw_sock){ - udp_packet udp_pkt; - memset(&udp_pkt,0,sizeof(udp_pkt)); - - udp_pkt.ip_pkt.ver_inet_hdr_length = 0x45; - udp_pkt.ip_pkt.service_type = 0; - udp_pkt.ip_pkt.total_length = sizeof(ip_pkt_t)+ - sizeof(udp_pkt_t)+CB_SIZE+cb.cblock.buffer_length; - udp_pkt.ip_pkt.identifier = 0; - udp_pkt.ip_pkt.flags_frag_offset = 0; - udp_pkt.ip_pkt.ttl = 0x7F; - udp_pkt.ip_pkt.protocol = 0x11; - udp_pkt.ip_pkt.hdr_checksum = 0x1232; - udp_pkt.ip_pkt.ip_src_address = inet_addr("1.1.1.1"); - udp_pkt.ip_pkt.ip_dst_address = inet_addr("1.1.1.2"); - - udp_pkt.udp_pkt.udp_src_port = htons((u_short)udp_port); - udp_pkt.udp_pkt.udp_dst_port = htons((u_short)udp_port); - udp_pkt.udp_pkt.udp_length = sizeof(udp_pkt_t)+CB_SIZE+cb.cblock.buffer_length; - udp_pkt.udp_pkt.udp_checksum = 0x1234; - - memcpy(&udp_pkt.cb, &cb, CB_SIZE); - if (cb.cblock.buffer_length){ - memcpy(&udp_pkt.cb.data, &cb.data, cb.cblock.buffer_length); - } - - for( x = 0; x < 4; x += 1 ) { - udp_pkt.cb.cblock.opp_flag = 0; - udp_pkt.cb.wp_mgmt.request_reply = 0x01; - udp_pkt.cb.wp_mgmt.id=id; - udp_pkt.cb.cblock.return_code = 0xaa; - send(sock, &udp_pkt, udp_pkt.ip_pkt.total_length,0); - - if (err <0){ - perror("Send"); - continue; - } - - FD_ZERO(&ready); - FD_SET(sock,&ready); - to.tv_sec = 5; - to.tv_usec = 0; - - if((err = select(sock + 1,&ready, NULL, NULL, &to))) { - err = recv(sock, &udp_pkt, - (sizeof(ip_pkt_t)+sizeof(udp_pkt_t)+CB_SIZE+MDATALEN),0); - - if (err >= (CB_SIZE+udp_pkt.cb.cblock.buffer_length)){ - - memcpy(&cb,&udp_pkt.cb.wp_mgmt.signature, - (CB_SIZE+udp_pkt.cb.cblock.buffer_length)); - }else{ - printf("Error: No Data received from the connected socket.\n"); - } - break; - }else{ - printf("Error: No Data received from the connected socket.\n"); - } - } - - }else{ - - for( x = 0; x < 4; x += 1 ) { - cb.cblock.opp_flag = 0; - cb.wp_mgmt.request_reply = 0x01; - cb.wp_mgmt.id = id; - /* 0xAA is our special return code indicating packet timeout */ - cb.cblock.return_code = 0xaa; - err = send(sock, &cb, 35 + cb.cblock.buffer_length, 0); - if (err <0){ - perror("Send"); - continue; - } - - FD_ZERO(&ready); - FD_SET(sock,&ready); - to.tv_sec = 5; - to.tv_usec = 0; - - if((err = select(sock + 1,&ready, NULL, NULL, &to))) { - - err = recv(sock, &cb, 35+MDATALEN,0); - if( err < 0 ){ - perror("Recv"); - } - break; - }else{ - printf("Error: No Data received from the connected socket.\n"); - } - } - } - - /* make sure the id is correct (returning results from a previous - call may be disastrous if not recognized) - also make sure it is a reply - */ - - if (cb.wp_mgmt.id != id || cb.wp_mgmt.request_reply != 0x02){ - cb.cblock.return_code = 0xbb; - } - id++; - if (cb.cblock.return_code == 0xCC) { - printf("Error: Code is not running on the board!"); - exit(1); - } - - return(cb.cblock.return_code); - -}; /* DoCommand */ - - -void init( int argc, char *argv[]) -{ - int i, i_cnt=0, u_cnt=0, c_cnt=0, if_found=0; - struct in_addr *ip_str=NULL; - cb.wp_mgmt.id = 0; - - for (i=0;i argc-1){ - printf("ERROR: Invalid IP or Interface Name, Type cpipemon for help\n\n"); - exit(0); - } - - strcpy(ipaddress,argv[i+1]); - if (inet_aton(ipaddress,ip_str) != 0 ){ - }else{ - strcpy(i_name,ipaddress); - if_found=1; - } - i_cnt=1; - }else if (!strcmp(argv[i],"-u")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid UDP PORT, Type cpipemon for help\n\n"); - exit(0); - } - - if(isdigit(argv[i+1][0])){ - udp_port = atoi(argv[i+1]); - }else{ - printf("ERROR: Invalid UDP Port, Type cpipemon for help\n\n"); - exit(0); - } - u_cnt=1; - }else if (!strcmp(argv[i],"-c")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid Command, Type cpipemon for help\n\n"); - exit(0); - } - - strcpy(cmd,argv[i+1]); - c_cnt=1; - } - } - - if (!i_cnt){ - printf("ERROR: No IP address or Interface Name, Type cpipemon for help\n\n"); - exit(0); - } - if (!c_cnt){ - printf("ERROR: No Command, Type cpipemon for help\n\n"); - exit(0); - } - - if (if_found){ - get_ip_addr(ipaddress); - } - - /* signature for UDP Management */ - sprintf(cb.wp_mgmt.signature, "%s", "BTPIPEAB"); -}; - -void get_ip_addr(char *if_name){ - - int skfd; - struct sockaddr_in *sin; - struct ifreq ifr; - - if ((skfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) { - printf("SOCKET FAILED\n"); - perror("socket"); - exit(1); - } - - strncpy(ifr.ifr_ifrn.ifrn_name, if_name, sizeof(ifr.ifr_ifrn.ifrn_name)); - - if (ioctl(skfd, SIOCGIFFLAGS , &ifr) < 0) { - fprintf(stderr, "Error: Unknown interface: %s\n",if_name); - exit(0); - } - - if (ioctl(skfd, SIOCGIFDSTADDR , &ifr) < 0) { - - strcpy(ipaddress,"0.0.0.0"); - }else{ - sin = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_dstaddr; - strcpy(ipaddress,inet_ntoa(sin->sin_addr)); - } - - if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0) { - - strcpy(src_ip,"0.0.0.0"); - }else{ - sin = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_addr; - strcpy(src_ip,inet_ntoa(sin->sin_addr)); - } - - - close (skfd); - - return; - -} - - -void error( void ) -{ - - printf("Error: Command failed!\n"); - -}; /* error */ - - -void global_stats (void) -{ - GLOBAL_STATS_STRUCT* global_stats; - cb.cblock.command= READ_GLOBAL_STATISTICS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - banner("GLOBAL STATISTICS"); - global_stats = (GLOBAL_STATS_STRUCT *)&cb.data[0]; - printf("Times application did not respond to IRQ: %d", - global_stats->app_IRQ_timeout_count); - } else { - error(); - } -}; /* global stats */ - -void flush_global_stats (void) -{ - cb.cblock.command= FLUSH_GLOBAL_STATISTICS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code != 0 ) error(); -}; /* flush global stats */ - -void modem( void ) -{ - unsigned char cts_dcd; - - cb.cblock.command= READ_MODEM_STATUS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - banner("MODEM STATUS"); - memcpy(&cts_dcd,&cb.data[0],1); - printf("DCD: "); - (cts_dcd & 0x08) ? printf("High\n") : printf("Low\n"); - printf("CTS: "); - (cts_dcd & 0x20) ? printf("High\n") : printf("Low\n"); - } else { - error(); - } -}; /* modem */ - - -void comm_stats (void) -{ - COMMS_ERROR_STATS_STRUCT* comm_stats; - cb.cblock.command= READ_COMMS_ERROR_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - banner("COMMUNICATION ERROR STATISTICS"); - - comm_stats = (COMMS_ERROR_STATS_STRUCT *)&cb.data[0]; - - printf(" Number of receiver overrun errors: %d\n", comm_stats->Rx_overrun_err_count); - printf(" Primary port - missed Tx DMA interrupt count: %d\n", comm_stats->pri_missed_Tx_DMA_int_count); - printf(" Synchronization lost count: %d\n", comm_stats->sync_lost_count); - printf(" Synchronization achieved count: %d\n", comm_stats->sync_achieved_count); - printf(" Number of times receiver disabled: %d\n", comm_stats->Rx_dis_pri_bfrs_full_count); - printf(" Number of times DCD changed state: %d\n", comm_stats->DCD_state_change_count); - printf(" Number of times CTS changed state: %d\n", comm_stats->CTS_state_change_count); - } else { - error(); - } -}; /* comm_stats */ - - -void flush_comm_stats( void ) -{ - cb.cblock.command= FLUSH_COMMS_ERROR_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code != 0 ) error(); -}; /* flush_comm_stats */ - - -void read_code_version (void) -{ - cb.cblock.command= READ_BSTRM_CODE_VERSION; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - unsigned char version[10]; - banner("CODE VERSION"); - memcpy(version,&cb.data,cb.cblock.buffer_length); - version[cb.cblock.buffer_length] = '\0'; - printf("Bit Streaming Code version: %s\n", version); - } -}; /* read code version */ - -void bstrm_configuration (void) -{ - return; -#if 0 - BSTRM_CONFIGURATION_STRUCT *bstrm_cfg; - cb.cblock.command = READ_BSTRM_CONFIGURATION; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - bstrm_cfg = (BSTRM_CONFIGURATION_STRUCT *)&cb.data[0]; - banner("BSTRM CONFIGURATION"); - - printf("Baud rate: %ld", bstrm_cfg->baud_rate); - - printf("\nLine configuration: "); - switch (bstrm_cfg->line_config_options) { - case INTERFACE_LEVEL_V35: - printf("V.35"); - break; - case INTERFACE_LEVEL_RS232: - printf("RS-232"); - break; - } - - printf("\n\nLink State depends on:"); - if (bstrm_cfg->BSTRM_protocol_options & IGNORE_DCD_FOR_LINK_STAT) - printf ("\n\t\t\tDCD: NO"); - else - printf ("\n\t\t\tDCD: YES"); - - if (bstrm_cfg->BSTRM_protocol_options & IGNORE_CTS_FOR_LINK_STAT) - printf ("\n\t\t\tCTS: NO\n"); - else - printf ("\n\t\t\tCTS: YES\n"); - - if (bstrm_cfg->BSTRM_protocol_options & IGNORE_KPALV_FOR_LINK_STAT) - printf ("\tKeepalive Reception: NO\n"); - else - printf ("\tKeepalive Reception: YES\n"); - - printf("\n\n Maximum data field length: %d", - bstrm_cfg->max_BSTRM_data_field_length); - - printf( "\n Keepalive transmit interval (ms): %d", - bstrm_cfg->transmit_keepalive_timer); - - printf( "\nExpected keepalive reception interval (ms): %d", - bstrm_cfg->receive_keepalive_timer); - - printf( "\n Keepalive reception error tolerance: %d", - bstrm_cfg->keepalive_error_tolerance); - - printf( "\n SLARP request transmit interval (ms): %d", - bstrm_cfg->SLARP_request_timer); - - } else { - error(); - } -#endif -}; /* bstrm_configuration */ - - -void operational_stats (void) -{ - BSTRM_OPERATIONAL_STATS_STRUCT *stats; - cb.cblock.command= READ_BSTRM_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - banner("OPERATIONAL STATISTICS"); - stats = (BSTRM_OPERATIONAL_STATS_STRUCT *)&cb.data[0]; - - printf( " Number of blocks transmitted: %ld",stats->blocks_Tx_count); - printf( "\n Number of bytes transmitted: %ld",stats->bytes_Tx_count); - printf( "\n Transmit Throughput: %ld",stats->Tx_throughput); - printf( "\n Transmit blocks discarded (length error): %ld",stats->Tx_discard_lgth_err_count); - printf( "\n Tx blocks transmitted after an idle line: %ld",stats->Tx_blocks_after_idle_count); - printf("\n\n Number of blocks received: %ld",stats->blocks_Rx_count); - printf( "\n Number of bytes received: %ld",stats->bytes_Rx_count); - printf( "\n Receive Throughput: %ld",stats->Rx_throughput); - } else { - error(); - } -} /* Operational_stats */ - - -void flush_operational_stats( void ) -{ - cb.cblock.command= FLUSH_BSTRM_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code != 0 ) { - error(); - } - -}; /* flush_operational_stats */ - -void slarp_stats (void) -{ -#if 0 - BSTRM_OPERATIONAL_STATS_STRUCT *stats; - cb.cblock.command= READ_BSTRM_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - banner("SLARP STATISTICS"); - stats = (BSTRM_OPERATIONAL_STATS_STRUCT *)&cb.data[0]; - - printf("\n SLARP frame transmission/reception statistics"); - printf( "\n SLARP request packets transmitted: %ld", - stats->BSTRM_SLARP_REQ_Tx_count); - printf( "\n SLARP request packets received: %ld", - stats->BSTRM_SLARP_REQ_Rx_count); - printf("\n\n SLARP Reply packets transmitted: %ld", - stats->BSTRM_SLARP_REPLY_Tx_count); - printf( "\n SLARP Reply packets received: %ld", - stats->BSTRM_SLARP_REPLY_Rx_count); - printf("\n\n SLARP keepalive packets transmitted: %ld", - stats->BSTRM_SLARP_KPALV_Tx_count); - printf( "\n SLARP keepalive packets received: %ld", - stats->BSTRM_SLARP_KPALV_Rx_count); - - printf( "\n\nIncoming SLARP Packets with format errors"); - printf( "\n Invalid SLARP Code: %d", stats->Rx_SLARP_invalid_code_count); - printf( "\n Replies with bad IP addr: %d", stats->Rx_SLARP_Reply_bad_IP_addr); - printf( "\n Replies with bad netmask: %d",stats->Rx_SLARP_Reply_bad_netmask); - printf( "\n\nSLARP timeout/retry statistics"); - printf( "\n SLARP Request timeouts: %d",stats->SLARP_Request_TO_count); - printf( "\n keepalive reception timeouts: %d",stats->SLARP_Rx_keepalive_TO_count); - - printf("\n\nCisco Discovery Protocol frames"); - printf( "\n Transmitted: %ld", stats->BSTRM_CDP_Tx_count); - printf( "\n Received: %ld", stats->BSTRM_CDP_Rx_count); - - } else { - error(); - } -#endif -} /* slarp_stats */ - - - -void line_trace(int trace_mode) -{ -#if 0 - unsigned char num_frames, num_chars; - unsigned short curr_pos = 0; - trace_pkt_t *trace_pkt; - unsigned int i, j; - unsigned char outstr[2000]; - int recv_buff = sizeof(udp_mgmt_pkt_t ) + MDATALEN + 100; - fd_set ready; - struct timeval to; - cisco_header_t *cisco_header; - - setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recv_buff, sizeof(int) ); - - /* Disable trace to ensure that the buffers are flushed */ - cb.cblock.command= CPIPE_DISABLE_TRACING; - cb.cblock.buffer_length = 0; - DoCommand(); - - cb.cblock.command= CPIPE_ENABLE_TRACING; - cb.cblock.buffer_length = 0; - cb.data[0]=0; - if(trace_mode == TRACE_PROT){ - cb.cblock.buffer_length = 1; - cb.data[0] |= TRACE_SLARP_FRAMES | TRACE_CDP_FRAMES; - printf("Tracing Protocol only %X\n",cb.data[0]); - }else if(trace_mode == TRACE_DATA){ - cb.cblock.buffer_length = 1; - cb.data[0] = TRACE_DATA_FRAMES; - }else{ - cb.cblock.buffer_length = 1; - cb.data[0] |= TRACE_SLARP_FRAMES | - TRACE_DATA_FRAMES | - TRACE_CDP_FRAMES; - } - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - printf("Starting trace...(Press ENTER to exit)\n"); - fflush(stdout); - } else if( cb.cblock.return_code == 0xCD ) { - printf("Cannot Enable Line Tracing from Underneath.\n"); - fflush(stdout); - return; - } else if( cb.cblock.return_code == 0x01 ) { - printf("Starting trace...(although it's already enabled!)\n"); - printf("Press ENTER to exit.\n"); - fflush(stdout); - } else { - printf("Failed to Enable Line Tracing. Return code: 0x%02X\n", - cb.cblock.return_code ); - fflush(stdout); - return; - } - - for(;;) { - FD_ZERO(&ready); - FD_SET(0,&ready); - to.tv_sec = 1; - to.tv_usec = 0; - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - - cb.cblock.command = CPIPE_GET_TRACE_INFO; - cb.cblock.buffer_length = 0; - DoCommand(); - if (cb.cblock.return_code == 0 && cb.cblock.buffer_length) { - num_frames = cb.trace_info.num_frames; - for ( i = 0; i < num_frames; i++) { - trace_pkt= (trace_pkt_t *)(&cb.data[0] + curr_pos); - - /* frame type */ - if (trace_pkt->status & 0x01) { - sprintf(outstr,"OUTGOING\t"); - } else { - if (trace_pkt->status & 0x10) { - sprintf(outstr,"INCOMING - Aborted\t"); - } else if (trace_pkt->status & 0x20) { - sprintf(outstr,"INCOMING - CRC Error\t"); - } else if (trace_pkt->status & 0x40) { - sprintf(outstr,"INCOMING - Overrun Error\t"); - } else { - sprintf(outstr,"INCOMING\t"); - } - } - - /* real length and time stamp */ - sprintf(outstr+strlen(outstr), "%d\t%d\t", - trace_pkt->real_length, trace_pkt->time_stamp); - - /* first update curr_pos */ - curr_pos += sizeof(trace_pkt_t); - if (trace_pkt->data_avail == 0) { - sprintf( outstr+strlen(outstr), "the frame data is not available" ); - } else { - /* update curr_pos again */ - curr_pos += trace_pkt->real_length - 1; - num_chars = (unsigned char) - ((trace_pkt->real_length <= 25) - ? trace_pkt->real_length : 25); - - if (raw_data) { /* show raw data */ - for( j=0; jdata[j]); - } - outstr[strlen(outstr)-1] = '\0'; - } else { /* show int data */ - cisco_header = (cisco_header_t *) - &trace_pkt->data[0]; - switch(ntohs(cisco_header->packet_type)) { - - case CISCO_PACKET_IP: - sprintf(outstr+strlen(outstr), - "IP packet from %ld.%ld.%ld.%ld to %ld.%ld.%ld.%ld", - ((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0x000000FF, - (((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0x0000FF00) >> 8, - (((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0x00FF0000) >>16, - (((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0xFF000000) >>24, - - ((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0x000000FF, - (((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0x0000FF00) >> 8, - (((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0x00FF0000) >>16, - (((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0xFF000000) >>24 -); - break; - - case CISCO_PACKET_SLARP: { - cisco_slarp_t *cisco_slarp = - (cisco_slarp_t*)(cisco_header+1); - - switch(ntohl(cisco_slarp->code)) { - case SLARP_REQUEST: - sprintf(outstr+strlen(outstr), - "SLARP Request packet"); - break; - - case SLARP_REPLY: - sprintf(outstr+strlen(outstr), - "SLARP Reply packet"); - break; - - case SLARP_KEEPALIVE: - sprintf(outstr+strlen(outstr), - "SLARP Keepalive packet"); - break; - - default: - sprintf(outstr+strlen(outstr), - "Unrecognized SLARP packet"); - break; - } /* Slarp code switch */ - break; - } /* slarp case */ - - case CISCO_PACKET_CDP: - sprintf(outstr+strlen(outstr), - "Cisco Discover Protocol packet"); - break; - - default: - sprintf(outstr+strlen(outstr),"Unknown type"); - } /* Switch packet type */ - } //if - } //if - - printf("%s\n",outstr); - fflush(stdout); - } //for - } //if - curr_pos = 0; - - if (!cb.trace_info.ismoredata) sleep(TIMEOUT); - } - - cb.cblock.command= CPIPE_DISABLE_TRACING; - cb.cblock.buffer_length = 0; - DoCommand(); -#endif -}; /* line_trace */ - -void usage(void) -{ - printf("bpipemon: Wanpipe Bisync Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("bpipemon -i -u -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address must be supplied\n"); - printf("\t\t Wanpipe network interface name (ex: wp1_bstrm)\n"); - printf("\tOption -u: (Optional, default: 9000)\n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t cv Read Code Version\n"); - printf("\tCard Statistics\n"); - printf("\t s g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t o Operational Statistics\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: bpipemon -i wp1_bstrm0 -u 9000 -c xm :View Modem Status \n"); -} - -void bstrm_router_up_time( void ) -{ - unsigned long time; - cb.cblock.command= CPIPE_ROUTER_UP_TIME; - cb.cblock.buffer_length = 0; - cb.data[0] = 0; - DoCommand(); - - time = *(unsigned long*)&cb.data[0]; - - if (time < 3600) { - if (time<60) - printf(" Router UP Time: %ld seconds\n", time); - else - printf(" Router UP Time: %ld minute(s)\n", (time/60)); - }else - printf(" Router UP Time: %ld hour(s)\n", (time/3600)); - -} - -void banner (char *title){ - - int len,i; - - len = strlen(title); - printf("\n\t"); - for (i=0;i<(len+16);i++) - printf("-"); - printf("\n\t\t%s",title); - printf("\n\t"); - for (i=0;i<(len+16);i++) - printf("-"); - printf("\n\n"); - -} - -void set_FT1_monitor_status( unsigned char status) -{ -#if 0 - gfail = 0; - cb.cblock.command= FT1_MONITOR_STATUS_CTRL; - cb.cblock.buffer_length = 1; - cb.data[0] = status; - DoCommand(); - if( (cb.cblock.return_code != 0) && status){ - gfail = 1; - printf("This command is only possible with S508/FT1 board!"); - } -#endif -} /* set_FT1_monitor_status */ - - -/* Subroutine for changing modes on a FT1 boards */ - -void set_FT1_mode(int verbose) -{ -#if 0 - int cnt=0; - - for(;;) { - cb.cblock.command= SET_FT1_MODE; - cb.cblock.buffer_length = 0; - DoCommand(); - if(cb.cblock.return_code == 0) { - if(verbose) { - printf("."); - fflush(stdout); - } - break; - } - if (++cnt == MAX_FT1_RETRY){ - break; - } - } -#endif -} /* set_FT1_mode */ - -/* Read the data for status of all the lights */ - -void read_FT1_status( void ) -{ -#if 0 - cb.cblock.command= CPIPE_FT1_READ_STATUS; - cb.cblock.buffer_length = 0; - DoCommand(); - if(cb.cblock.return_code == 0) { - par_port_A_byte = cb.data[0]; - par_port_B_byte = cb.data[1]; - - if(!(par_port_A_byte & PP_A_RT_NOT_RED)) { - FT1_LED.RT_red ++; - } - if(!(par_port_A_byte & PP_A_RT_NOT_GREEN)) { - FT1_LED.RT_green ++; - } - if((par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) - == (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - FT1_LED.RT_off ++; - } - if(!(par_port_A_byte & PP_A_LL_NOT_RED)) { - FT1_LED.LL_red ++; - } - else { - FT1_LED.LL_off ++; - } - if(!(par_port_A_byte & PP_A_DL_NOT_RED)) { - FT1_LED.DL_red ++; - } - else { - FT1_LED.DL_off ++; - } - if(!(par_port_B_byte & PP_B_RxD_NOT_GREEN)) { - FT1_LED.RxD_green ++; - } - if(!(par_port_B_byte & PP_B_TxD_NOT_GREEN)) { - FT1_LED.TxD_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_GREEN)) { - FT1_LED.ERR_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_red ++; - } - if((par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) - == (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_off ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_RED)) { - FT1_LED.INS_red ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_GREEN)) { - FT1_LED.INS_green ++; - } - if((par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) - == (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - FT1_LED.INS_off ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_GREEN)) { - FT1_LED.ST_green ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_RED)) { - FT1_LED.ST_red ++; - } - if((par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) - == (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - FT1_LED.ST_off ++; - } - } -#endif -} /* read_FT1_status */ - -void read_ft1_op_stats( void ) -{ -#if 0 - fd_set ready; - struct timeval to; - unsigned short length; - - - printf("TIME: Time in seconds since the FT1 op stats were last reset\n"); - printf(" ES: Errored Second\n"); - printf(" BSE: Bursty Errored Second\n"); - printf(" SES: Severly Errored Second\n"); - printf(" UAS: Unavailable Second\n"); - printf("LOFC: Loss of Frame Count\n"); - printf(" ESF: ESF Error Count\n"); - - printf("\nFT1 CSU/DSU Operational Stats...(Press ENTER to exit)\n"); - for(;;){ - - cb.cblock.command= READ_FT1_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - FD_ZERO(&ready); - FD_SET(0,&ready); - to.tv_sec = 0; - to.tv_usec = 50000; - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - if( cb.cblock.buffer_length ){ - int i=0; - printf(" TIME ES BES SES UAS LOFC ESF\n"); - length = cb.cblock.buffer_length; - while(length){ - - printf("%c", cb.data[i]); - length--; - i++; - } - printf("\n"); - } - } -#endif -} - - -void set_ft1_config(int argc, char ** argv) -{ -#if 0 - ft1_config_t *ft1_config = (ft1_config_t *)&cb.data[0]; - int i=0,found=0; - - cb.cblock.command = SET_FT1_CONFIGURATION; - cb.cblock.buffer_length = sizeof(ft1_config_t); - - for (i=0;iframing_mode = atoi(argv[i++]); - ft1_config->encoding_mode = atoi(argv[i++]); - ft1_config->line_build_out = atoi(argv[i++]); - ft1_config->channel_base = atoi(argv[i++]); - ft1_config->baud_rate_kbps = atoi(argv[i++]); - ft1_config->clock_mode = atoi(argv[i]); - - - if (ft1_config->framing_mode > 1){ - printf("Error: Invalid Framing Mode (0=ESF 1=D4)\n"); - return; - } - if (ft1_config->encoding_mode > 1){ - printf("Error: Invalid Encoding Mode (0=B8ZS 1=AMI)\n"); - return; - } - if (ft1_config->line_build_out > 7){ - printf("Error: Invalid Line Build Mode (0-7) Default:0\n"); - return; - } - if (ft1_config->channel_base > 24){ - printf("Error: Invalid Channel Base (1-24) Default:1 \n"); - return; - } - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps > 1536)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps > 1344)){ - printf("Error: Invalid Baud Rate: B8ZS Max=1536KBps; AMI Max=1344KBps\n"); - return; - } - - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps < 64)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps < 56)){ - printf("Error: Invalid Baud Rate: B8ZS Min=64KBps; AMI Max=56KBps\n"); - return; - } - - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps%64 != 0)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps%56 != 0)){ - printf("Error: Invalid Baud Rate: \n"); - printf(" For B8ZS: Baud rate must be a multiple of 64KBps.\n"); - printf(" For AMI: Baud rate must be a multiple of 56KBps.\n"); - return; - } - - if (ft1_config->clock_mode > 1){ - printf("Error: Invalid Clock Mode: (0=Normal, 1=Master) Default:0\n"); - return; - } - - DoCommand(); - if (cb.cblock.return_code == 0){ - printf("CSU/DSU Configuration Successfull!\n"); - - }else if (cb.cblock.return_code == 0xaa){ - printf("Sangoma Adaptor is not equiped with an onboard CSU/DSU!\n"); - printf("\tCSU/DSU Configuration Failed!\n"); - - }else{ - printf("CSU/DSU Configuration Failed: rc %x",cb.cblock.return_code); - } -#endif -} - - -void read_ft1_config (void) -{ -#if 0 - cb.cblock.command = READ_FT1_CONFIGURATION; - cb.cblock.buffer_length = 0; - - DoCommand(); - if (cb.cblock.return_code != 0){ - printf("CSU/DSU Read Configuration Failed"); - }else{ - ft1_config_t *ft1_config = (ft1_config_t *)&cb.data[0]; - printf("CSU/DSU Conriguration:\n"); - printf("\tFraming\t\t%s\n",ft1_config->framing_mode ? "D4" : "ESF"); - printf("\tEncoding\t%s\n",ft1_config->encoding_mode ? "AMI" : "B8ZS"); - printf("\tLine Build\t%i\n",ft1_config->line_build_out); - printf("\tChannel Base\t%i\n",ft1_config->channel_base); - printf("\tBaud Rate\t%i\n",ft1_config->baud_rate_kbps); - printf("\tClock Mode\t%s\n",ft1_config->clock_mode ? "MASTER":"NORMAL"); - } -#endif -} - - - - -int main(int argc, char* argv[]) -{ - int proceed; - char command; - char *opt; - - memset(&cb,0,sizeof(udp_mgmt_pkt_t)); - - printf("\n"); - if( argc > 2 ) { - - init( argc, argv); - command = cmd[0]; - opt = (char *) &cmd[1]; - - if (!strcmp(ipaddress,"0.0.0.0")){ - #ifdef LINUX_2_1 - proceed = MakeRawConnection(); - #else - printf("ERROR: Raw API is not supported for kernels lower than 2.2.X\n"); - printf(" Upgrate to 2.2.X kernel for Raw API support\n"); - exit(1); - #endif - }else{ - proceed = MakeUdpConnection(); - } - - if(proceed == WAN_TRUE){ - switch(command){ - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt, "cv")){ - read_code_version(); - }else if (!strcmp(opt,"ru")){ - bstrm_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type cpipemon for help\n\n"); - } - break; - case 's': - if (!strcmp(opt,"g")){ - global_stats(); - }else if (!strcmp(opt,"c")){ - comm_stats(); - }else if (!strcmp(opt,"o")){ - operational_stats(); - }else if (!strcmp(opt,"s")){ - slarp_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type cpipemon for help\n\n"); - - } - break; - case 'c': - if (!strcmp(opt,"rc")){ - bstrm_configuration(); - }else{ - printf("ERROR: Invalid Configuration Command 'c', Type cpipemon for help\n\n"); - } - break; - case 't': - if(!strcmp(opt,"i" )){ - raw_data = WAN_FALSE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "ip")){ - raw_data = WAN_FALSE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "id")){ - raw_data = WAN_FALSE; - line_trace(TRACE_DATA); - }else if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "rp")){ - raw_data = WAN_TRUE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "rd")){ - raw_data = WAN_TRUE; - line_trace(TRACE_DATA); - }else{ - printf("ERROR: Invalid Trace Command 't', Type cpipemon for help\n\n"); - } - break; - case 'f': - if (!strcmp(opt, "o")){ - flush_operational_stats(); - operational_stats(); - }else if (!strcmp(opt, "s")){ - flush_operational_stats(); - slarp_stats(); - }else if (!strcmp(opt, "g")){ - flush_global_stats(); - global_stats(); - }else if (!strcmp(opt, "c")){ - flush_comm_stats(); - comm_stats(); - } else{ - printf("ERROR: Invalid Flush Command 'f', Type cpipemon for help\n\n"); - } - break; -#if 0 - case 'T': - if (!strcmp(opt, "v")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - //view_FT1_status(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "s")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - //FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "l")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - //FT1_local_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "d")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - //FT1_digital_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "r")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_remote_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "o")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_operational_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "p")){ - set_FT1_monitor_status(0x02); - if(!gfail) - read_ft1_op_stats(); - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "f")){ - set_FT1_monitor_status(0x04); - if(!gfail){ - printf("Flushed Operational Statistics\n"); - }else{ - printf("FT1 Flush Failed %i\n",gfail); - } - }else if (!strcmp(opt, "set")){ - set_ft1_config(argc, argv); - - }else if (!strcmp(opt,"read")){ - read_ft1_config(); - - } else{ - printf("ERROR: Invalid FT1 Command 'T', Type cpipemon for help\n\n"); - } - break; -#endif - default: - printf("ERROR: Invalid Command, Type cpipemon for help\n\n"); - break; - }//switch - } - close( sock ); - } else { - usage(); - } //if - printf("\n"); - fflush(stdout); - return 0; -}; //main diff --git a/util/wanpipemon.old/bpipemon.c b/util/wanpipemon.old/bpipemon.c deleted file mode 100644 index 727f9a1..0000000 --- a/util/wanpipemon.old/bpipemon.c +++ /dev/null @@ -1,574 +0,0 @@ -/***************************************************************************** -* bpipemon.c Bitstream Monitor -* Author: Nenad Corbic -* -* 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. -* ---------------------------------------------------------------------------- -* Dec 18, 2003 Nenad Corbic Initial version based on ppipemon -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include /* offsetof(), etc. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# error "Bitstrm is not supported on Non-Linux platforms" -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) - -#define BANNER(str) banner(str,0) -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ -/* Structures for data casting */ - - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -static void error( void ); - -/* Command routines */ -static void modem( void ); -static void global_stats( void ); -static void comm_stats( void ); -static void read_code_version( void ); -static void operational_stats( void ); -static void bitstrm_router_up_time( void ); -static void flush_operational_stats( void ); -static void flush_global_stats( void ); -static void flush_comm_stats( void ); -static void read_ft1_te1_56k_config( void ); - - -static char *gui_main_menu[]={ -"bitstrm_card_stats_menu","Card Status", -"bitstrm_stats_menu", "Card Statistics", -"csudsu_menu", "CSU DSU Config/Stats", -"bitstrm_flush_menu","Flush Statistics", -"." -}; - - -static char *bitstrm_card_stats_menu[]={ -"xm","Modem Status", -"xl","Link Status", -"xcv","Read Code Version", -"xru","Display Router UP time", -"." -}; - -static char *bitstrm_stats_menu[]={ -"sg","Global Statistics", -"sc","Communication Error Statistics", -"so","Operational Statistics", -"." -}; - -static char *bitstrm_flush_menu[]={ -"fg","Flush Global Statistics", -"fc","Flush Communication Error Statistics", -"fo","Flush Operational Statistics", -"fp","Flush T1/E1 performance monitoring counters", -"." -}; - - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"bitstrm_card_stats_menu",bitstrm_card_stats_menu}, - {"bitstrm_stats_menu",bitstrm_stats_menu}, - {"csudsu_menu",csudsu_menu}, - {"bitstrm_flush_menu",bitstrm_flush_menu}, - {".",NULL} -}; - - -char ** BITSTRMget_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** BITSTRMget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int BITSTRMConfig(void) -{ - char codeversion[10]; - unsigned char x=0; - - protocol_cb_size = sizeof(wan_mgmt_t) + - sizeof(wan_cmd_t) + - sizeof(wan_trace_info_t) + 1; - wan_udp.wan_udphdr_command= READ_BSTRM_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - while (++x < 4) { - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - - if (wan_udp.wan_udphdr_return_code == 0xCC){ - return(WAN_FALSE); - } - wan_udp.wan_udphdr_return_code = 0xaa; - } - - if (x >= 4) return(WAN_FALSE); - - if (wan_udp.wan_udphdr_data_len == sizeof(READ_BSTRM_CONFIGURATION)) { - is_508 = WAN_TRUE; - } else { - is_508 = WAN_FALSE; - } - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = READ_BSTRM_CODE_VERSION; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - return(WAN_TRUE); -}; - -static void error( void ) -{ - printf("Error: Command failed!\n"); - -}; /* error */ - - -static void global_stats (void) -{ - GLOBAL_STATS_STRUCT* global_stats; - wan_udp.wan_udphdr_command= READ_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("GLOBAL STATISTICS"); - global_stats = (GLOBAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - printf("Times application did not respond to IRQ: %u", - global_stats->app_IRQ_timeout_count); - } else { - error(); - } -}; /* global stats */ - -static void flush_global_stats (void) -{ - wan_udp.wan_udphdr_command= FLUSH_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) error(); -}; /* flush global stats */ - -static void modem( void ) -{ - unsigned char cts_dcd; - wan_udp.wan_udphdr_command= READ_MODEM_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("MODEM STATUS"); - memcpy(&cts_dcd, &wan_udp.wan_udphdr_data[0],1); - printf("DCD: "); - (cts_dcd & 0x08) ? printf("High\n") : printf("Low\n"); - printf("CTS: "); - (cts_dcd & 0x20) ? printf("High\n") : printf("Low\n"); - } else { - error(); - } -}; /* modem */ - - -static void comm_stats (void) -{ - COMMS_ERROR_STATS_STRUCT* comm_stats; - wan_udp.wan_udphdr_command= READ_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("COMMUNICATION ERROR STATISTICS"); - - comm_stats = (COMMS_ERROR_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf(" Number of receiver overrun errors: %d\n", comm_stats->Rx_overrun_err_count); - printf(" Primary port - missed Tx DMA interrupt count: %d\n", comm_stats->pri_missed_Tx_DMA_int_count); - printf(" Synchronization lost count: %d\n", comm_stats->sync_lost_count); - printf(" Synchronization achieved count: %d\n", comm_stats->sync_achieved_count); - printf(" Number of times receiver disabled: %d\n", comm_stats->Rx_dis_pri_bfrs_full_count); - printf(" Number of times DCD changed state: %d\n", comm_stats->DCD_state_change_count); - printf(" Number of times CTS changed state: %d\n", comm_stats->CTS_state_change_count); - - } else { - error(); - } -}; /* comm_stats */ - - -static void flush_comm_stats( void ) -{ - wan_udp.wan_udphdr_command= FLUSH_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) error(); -}; /* flush_comm_stats */ - - -static void read_code_version (void) -{ - wan_udp.wan_udphdr_command= READ_BSTRM_CODE_VERSION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - unsigned char version[10]; - BANNER("CODE VERSION"); - memcpy(version,&wan_udp.wan_udphdr_data,wan_udp.wan_udphdr_data_len); - version[wan_udp.wan_udphdr_data_len] = '\0'; - printf("Bit Streaming Code version: %s\n", version); - } -}; /* read code version */ - -static void link_status (void) -{ - READ_BSTRM_STATUS_STRUCT *status; - wan_udp.wan_udphdr_command= READ_BSTRM_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("LINK STATUS"); - - status = (READ_BSTRM_STATUS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf(" Link status: "); - switch (status->sync_status) { - case SYNC_ACHIEVED: - printf("Active\n"); - break; - default: - printf("Inactive (0x%X)\n",status->sync_status); - } - - printf("Available data frames for application: %u\n", - status->no_Rx_data_blocks_avail); - - printf(" Receiver status: "); - if (status->receiver_status & 0x01) - printf("Disabled due to flow control restrictions\n"); - else printf("Enabled\n"); - - printf(" Exception Conditions: 0x%X", - status->BSTRM_excep_conditions); - - } else { - error(); - } -}; /* Link Status */ - - -static void operational_stats (void) -{ - BSTRM_OPERATIONAL_STATS_STRUCT *stats; - wan_udp.wan_udphdr_command= READ_BSTRM_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("OPERATIONAL STATISTICS"); - stats = (BSTRM_OPERATIONAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - - printf( " Number of blocks transmitted: %ld",stats->blocks_Tx_count); - printf( "\n Number of bytes transmitted: %ld",stats->bytes_Tx_count); - printf( "\n Transmit Throughput: %ld",stats->Tx_throughput); - printf( "\n Tx idle count: %ld",stats->Tx_idle_count); - printf( "\n Tx blocks discarded (length error) count: %ld",stats->Tx_discard_lgth_err_count); - printf("\n\n Number of blocks received: %ld",stats->blocks_Rx_count); - printf( "\n Number of bytes received: %ld",stats->bytes_Rx_count); - printf( "\n Receive Throughput: %ld",stats->Rx_throughput); - printf( "\n Receive discard count: %ld",stats->Rx_discard_count); - - } else { - error(); - } -} /* Operational_stats */ - - -static void flush_operational_stats( void ) -{ - wan_udp.wan_udphdr_command= FLUSH_BSTRM_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } - -}; /* flush_operational_stats */ - - -int BITSTMRDisableTrace(void) -{ - wan_udp.wan_udphdr_command= BPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - return 0; -} - -int BITSTRMUsage(void) -{ - - printf("bpipemon: Wanpipe Bisync Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("bpipemon -i -u -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address must be supplied\n"); - printf("\t\t Wanpipe network interface name (ex: wp1_bstrm)\n"); - printf("\tOption -u: (Optional, default: 9000)\n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t cv Read Code Version\n"); - printf("\tCard Statistics\n"); - printf("\t s g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t o Operational Statistics\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: bpipemon -i wp1_bstrm0 -u 9000 -c xm :View Modem Status \n"); - - return 0; -} - - - - -static void bitstrm_router_up_time( void ) -{ - u_int32_t time; - - wan_udp.wan_udphdr_command= BPIPE_ROUTER_UP_TIME; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - time = *(u_int32_t*)&wan_udp.wan_udphdr_data[0]; - - BANNER("ROUTER UP TIME"); - print_router_up_time(time); -} - -static void read_ft1_te1_56k_config (void) -{ - unsigned char adapter_type = 0x00; - - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } - - switch(adapter_type){ - case WAN_MEDIA_NONE: - printf("Unsuported Media : adapter_type=0x%X\n",adapter_type); - break; - - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - case WAN_MEDIA_56K: - read_te1_56k_config(); - break; - } - return; -} - - -int BITSTRMMain(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - - switch(command[0]){ - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt, "cv")){ - read_code_version(); - }else if (!strcmp(opt,"l")){ - link_status(); - }else if (!strcmp(opt,"ru")){ - bitstrm_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type wanpipemon for help\n\n"); - } - break; - case 's': - if (!strcmp(opt,"g")){ - global_stats(); - }else if (!strcmp(opt,"c")){ - comm_stats(); - }else if (!strcmp(opt,"o")){ - operational_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type wanpipemon for help\n\n"); - - } - break; - case 'f': - if (!strcmp(opt, "o")){ - flush_operational_stats(); - operational_stats(); - }else if (!strcmp(opt, "g")){ - flush_global_stats(); - global_stats(); - }else if (!strcmp(opt, "c")){ - flush_comm_stats(); - comm_stats(); - }else if (!strcmp(opt, "p")){ - flush_te1_pmon(); - } else{ - printf("ERROR: Invalid Flush Command 'f', Type wanpipemon for help\n\n"); - } - break; - - case 'T': - if (!strcmp(opt,"read")){ - read_ft1_te1_56k_config(); - }else if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"a")){ - read_te1_56k_stat(0); - } else{ - printf("ERROR: Invalid FT1 Command 'T', Type wanpipemon for help\n\n"); - } - break; - - default: - printf("ERROR: Invalid Command, Type wanpipemon for help\n\n"); - break; - }//switch - printf("\n"); - fflush(stdout); - return 0; -}; //main diff --git a/util/wanpipemon.old/bpipemon.o b/util/wanpipemon.old/bpipemon.o deleted file mode 100644 index 8d02fa73238c1509c0d0d86558bc510d1b572f1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12172 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 -* -* Copyright: (c) 1995-1999 Sangoma Technologies Inc. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* ---------------------------------------------------------------------------- -* -* Jan 11, 2005 David Rokhvarg Added code to run above AFT card with protocol -* in the LIP layer. -* Dec 05, 2001 Alex Feldman Added T1/E1 Statistics. -* Nov 07, 2000 Nenad Corbic Added Keyboard Led Debugging Commands. -* Mar 14, 2000 Nenad Corbic Added API support. No IP addresses needed. -* Sep 21, 1999 Nenad Corbic Changed the input parameters, hearders -* data types. More user friendly. -* Aug 06, 1998 David Fong Initial version based on ppipemon -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include /* offsetof(), etc. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) - - -#define BANNER(str) banner(str,0) -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -/* The ft1_lib needs these global variables */ -static int gfail; -extern char* progname; - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -static void error( void ); - -/* Command routines */ -static void line_trace_S514( int trace_mode, int trace_sub_type); -static void modem_S514( void ); -static void comm_err_S514(void); -static void flush_comm_err_S514( void ); -static void operational_stats_S514( void ); -static void flush_operational_stats_S514( void ); -static void read_code_version_S514(void); -static void link_status_S514(void); - -static void flush_slarp_cdp_stats(void); - -static void comm_err( void ); -static void flush_comm_err( void ); - -static void operational_stats( void ); -static void flush_operational_stats( void ); - -static void chdlc_router_up_time( void ); - -/* -static void global_stats (void); -static void flush_global_stats( void ); -*/ - -static void read_code_version( void ); -static void chdlc_configuration( void ); - -static void link_status( void ); -static void slarp_stats( void ); - -static void set_FT1_monitor_status( unsigned char); -static void read_ft1_op_stats( void ); -static void read_ft1_te1_56k_config( void ); -static void ft1_usage (void); - -static wp_trace_output_iface_t trace_iface; - -static char *gui_main_menu[]={ -"chdlc_card_stats_menu","Card Status", -//"chdlc_card_config_menu","Card Configuration", -"chdlc_stats_menu", "Card Statistics", -"chdlc_trace_menu", "Trace Data", -"csudsu_menu", "CSU DSU Config/Stats", -"chdlc_flush_menu","Flush Statistics", -"." -}; - - -static char *chdlc_card_stats_menu[]={ -"xm","Modem Status", -"xl","Link Status", -"xcv","Read Code Version", -"xru","Display Router UP time", -"." -}; - -static char *chdlc_card_config_menu[]={ -"crc","Read Configuration\n", -"." -}; - -static char *chdlc_stats_menu[]={ -//"sg","Global Statistics", -"sc","Communication Error Statistics", -"so","Operational Statistics", -"ss","SLARP and CDP Statistics", -"." -}; - -static char *chdlc_trace_menu[]={ -"ti","Trace and Interpret ALL frames", -//"tip","Trace and Interpret PROTOCOL frames only", -//"tid","Trace and Interpret DATA frames only", -"tr","Trace ALL frames, in RAW format", -//"trp","Trace PROTOCOL frames only, in RAW format", -//"trd","Trace DATA frames only, in RAW format", -"." -}; - -#if 0 -static char *chdlc_csudsu_menu[]={ -"Tv","View Status", -"Ts","Self Test", -"Tl","Line Loop Test", -"Td","Digital Loop Test", -"Tr","Remote Test", -"To","Operational Mode", -"Tp","Operational stats (FT1)", -"Tf", "Flush operational stats (FT1)", -"Tset", "Set FT1 configuration", -"Tread","Read CSU/DSU config (FT1/T1/E1)", -"Tallb","E Line Loopback (T1/E1)", -"Tdllb","D Line Loopback (T1/E1)", -"Taplb","E Payload Loopback (T1/E1)", -"Tdplb","D Payload Loopback (T1/E1)", -"Tadlb","E Diag Digital Loopback (T1/E1)", -"Tddlb","D Diag Digital Loopback (T1/E1)", -"Tsalb","Send Loopback Activate Code (T1/E1)", -"Tsdlb","Send Loopback Deactive Code (T1/E1)", -"Ta","Read T1/E1/56K alrams", -"." -}; -#endif - -static char *chdlc_flush_menu[]={ -//"fg","Flush Global Statistics", -"fc","Flush Communication Error Statistics", -"fo","Flush Operational Statistics", -"fs","Flush SLARP and CDP Statistics", -"fpm","Flush T1/E1 performance monitoring counters", -"." -}; - - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"chdlc_card_stats_menu",chdlc_card_stats_menu}, - {"chdlc_card_config_menu",chdlc_card_config_menu}, - {"chdlc_stats_menu",chdlc_stats_menu}, - {"chdlc_trace_menu",chdlc_trace_menu}, - {"csudsu_menu",csudsu_menu}, - {"chdlc_flush_menu",chdlc_flush_menu}, - {".",NULL} -}; - - -char ** CHDLCget_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** CHDLCget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int CHDLCConfig(void) -{ - char codeversion[10]; - unsigned char x=0; - - protocol_cb_size = sizeof(wan_mgmt_t) + - sizeof(wan_cmd_t) + - sizeof(wan_trace_info_t) + 1; - wan_udp.wan_udphdr_command= READ_CHDLC_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - while (++x < 4) { - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - - if (wan_udp.wan_udphdr_return_code == 0xCC){ - return(WAN_FALSE); - } - wan_udp.wan_udphdr_return_code = 0xaa; - } - - if (x >= 4) return(WAN_FALSE); - - if (wan_udp.wan_udphdr_data_len == sizeof(CHDLC_CONFIGURATION_STRUCT)) { - is_508 = WAN_TRUE; - } else { - is_508 = WAN_FALSE; - } - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = READ_CHDLC_CODE_VERSION; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - return(WAN_TRUE); -}; - -void CHDLC_set_FT1_mode( void ) -{ - for(;;){ - wan_udp.wan_udphdr_command= SET_FT1_MODE; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0){ - break; - } - } -} /* set_FT1_mode */ - -void CHDLC_read_FT1_status( void ) -{ - - wan_udp.wan_udphdr_command= CPIPE_FT1_READ_STATUS; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if(wan_udp.wan_udphdr_return_code == 0) { - par_port_A_byte = wan_udp.wan_udphdr_data[0]; - par_port_B_byte = wan_udp.wan_udphdr_data[1]; - - if(!(par_port_A_byte & PP_A_RT_NOT_RED)) { - FT1_LED.RT_red ++; - } - if(!(par_port_A_byte & PP_A_RT_NOT_GREEN)) { - FT1_LED.RT_green ++; - } - if((par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) - == (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - FT1_LED.RT_off ++; - } - if(!(par_port_A_byte & PP_A_LL_NOT_RED)) { - FT1_LED.LL_red ++; - } - else { - FT1_LED.LL_off ++; - } - if(!(par_port_A_byte & PP_A_DL_NOT_RED)) { - FT1_LED.DL_red ++; - } - else { - FT1_LED.DL_off ++; - } - if(!(par_port_B_byte & PP_B_RxD_NOT_GREEN)) { - FT1_LED.RxD_green ++; - } - if(!(par_port_B_byte & PP_B_TxD_NOT_GREEN)) { - FT1_LED.TxD_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_GREEN)) { - FT1_LED.ERR_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_red ++; - } - if((par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) - == (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_off ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_RED)) { - FT1_LED.INS_red ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_GREEN)) { - FT1_LED.INS_green ++; - } - if((par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) - == (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - FT1_LED.INS_off ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_GREEN)) { - FT1_LED.ST_green ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_RED)) { - FT1_LED.ST_red ++; - } - if((par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) - == (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - FT1_LED.ST_off ++; - } - } -} /* read_FT1_status */ - -static void error( void ) -{ - printf("Error: Command failed!\n"); -} - -#if 0 -static void global_stats (void) -{ - GLOBAL_STATS_STRUCT* global_stats; - wan_udp.wan_udphdr_command= READ_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("GLOBAL STATISTICS"); - global_stats = (GLOBAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - printf("Times application did not respond to IRQ: %u", - global_stats->app_IRQ_timeout_count); - } else { - error(); - } -}; /* global stats */ - -static void flush_global_stats (void) -{ - wan_udp.wan_udphdr_command= FLUSH_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) error(); -}; /* flush global stats */ -#endif - -static void modem( void ) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - modem_S514(); - }else{ - hw_modem(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void modem_S514( void ) -{ - unsigned char cts_dcd; - wan_udp.wan_udphdr_command= READ_MODEM_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("MODEM STATUS"); - memcpy(&cts_dcd, &wan_udp.wan_udphdr_data[0],1); - printf("DCD: "); - (cts_dcd & 0x08) ? printf("High\n") : printf("Low\n"); - printf("CTS: "); - (cts_dcd & 0x20) ? printf("High\n") : printf("Low\n"); - } else { - error(); - } -}; /* modem */ - -static void comm_err(void) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - comm_err_S514(); - }else{ - hw_comm_err(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void comm_err_S514(void) -{ - COMMS_ERROR_STATS_STRUCT* comm_err_stats; - wan_udp.wan_udphdr_command= READ_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("COMMUNICATION ERROR STATISTICS"); - - comm_err_stats = (COMMS_ERROR_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf(" Number of receiver overrun errors: %u\n", - comm_err_stats->Rx_overrun_err_count); - printf(" Number of receiver CRC errors: %u\n", - comm_err_stats->CRC_err_count); - printf(" Number of abort frames received: %u\n", - comm_err_stats->Rx_abort_count); - printf(" Number of times receiver disabled: %u\n", - comm_err_stats->Rx_dis_pri_bfrs_full_count); - printf(" Number of transmitted abort frames (missed Tx interrupt): %u\n", - comm_err_stats->sec_Tx_abort_msd_Tx_int_count); - printf(" Number of transmit underruns: %u\n", - comm_err_stats->missed_Tx_und_int_count); - printf(" Number of abort frames transmitted: %u\n", - comm_err_stats->sec_Tx_abort_count); - printf(" Number of times DCD changed state: %u\n", - comm_err_stats->DCD_state_change_count); - printf(" Number of times CTS changed state: %u\n", - comm_err_stats->CTS_state_change_count); - } else { - error(); - } -}; /* comm_stats */ - -static void flush_comm_err( void ) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - flush_comm_err_S514(); - }else{ - hw_flush_comm_err(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void flush_comm_err_S514( void ) -{ - wan_udp.wan_udphdr_command= FLUSH_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) error(); -}; /* flush_comm_stats */ - -static void read_code_version (void) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - read_code_version_S514(); - }else{ - hw_read_code_version(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void read_code_version_S514(void) -{ - wan_udp.wan_udphdr_command= READ_CHDLC_CODE_VERSION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - unsigned char version[10]; - BANNER("CODE VERSION"); - memcpy(version,&wan_udp.wan_udphdr_data,wan_udp.wan_udphdr_data_len); - version[wan_udp.wan_udphdr_data_len] = '\0'; - printf("Cisco HDLC Code version: %s\n", version); - } -}; /* read code version */ - -static void chdlc_configuration (void) -{ - wan_sppp_if_conf_t *chdlc_cfg; - wan_udp.wan_udphdr_command = READ_CHDLC_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - chdlc_cfg = (wan_sppp_if_conf_t*)&wan_udp.wan_udphdr_u.data[0]; - BANNER("CHDLC CONFIGURATION"); - - printf("Ignore Keepalive\t: %s\n", - (chdlc_cfg->sppp_keepalive_timer == 0 ? "Yes" : "No")); - - if(chdlc_cfg->sppp_keepalive_timer){ - printf("Keepalive interval (s)\t: %u\n", - chdlc_cfg->sppp_keepalive_timer); - printf("Keepalive reception error tolerance: %u", - chdlc_cfg->keepalive_err_margin); - } - - } else { - error(); - } -}; /* chdlc_configuration */ - - -static void link_status (void) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - link_status_S514(); - }else{ - hw_link_status(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void link_status_S514(void) -{ - CHDLC_LINK_STATUS_STRUCT *status; - wan_udp.wan_udphdr_command= READ_CHDLC_LINK_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("LINK STATUS"); - - status = (CHDLC_LINK_STATUS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf(" Link status: "); - switch (status->CHDLC_link_status) { - case CHDLC_LINK_INACTIVE: - printf("Inactive\n"); - break; - case CHDLC_LINK_ACTIVE: - printf("Active\n"); - break; - } - - printf("Available data frames for application: %u\n", - status->no_Data_frms_for_app); - - printf(" Receiver status: "); - if (status->receiver_status & 0x01) - printf("Disabled due to flow control restrictions\n"); - else printf("Enabled\n"); - } else { - error(); - } -}; /* Link Status */ - -static void operational_stats (void) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - operational_stats_S514(); - }else{ - hw_general_stats(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void operational_stats_S514(void) -{ - CHDLC_OPERATIONAL_STATS_STRUCT *stats; - wan_udp.wan_udphdr_command= READ_CHDLC_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("OPERATIONAL STATISTICS"); - stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf( " Number of frames transmitted: %u",stats->Data_frames_Tx_count); - printf( "\n Number of bytes transmitted: %u",stats->Data_bytes_Tx_count); - printf( "\n Transmit Throughput: %u",stats->Data_Tx_throughput); - printf( "\n Transmit frames discarded (length error): %u",stats->Tx_Data_discard_lgth_err_count); - - printf("\n\n Number of frames received: %u",stats->Data_frames_Rx_count); - printf( "\n Number of bytes received: %u",stats->Data_bytes_Rx_count); - printf( "\n Receive Throughput: %u",stats->Data_Rx_throughput); - printf( "\n Received frames discarded (too short): %u",stats->Rx_Data_discard_short_count); - printf( "\n Received frames discarded (too long): %u",stats->Rx_Data_discard_long_count); - printf( "\nReceived frames discarded (link inactive): %u",stats->Rx_Data_discard_inactive_count); - - - printf("\n\nIncoming frames with format errors"); - printf( "\n Frames of excessive length: %u", stats->Rx_frms_too_long_count); - printf( "\n Incomplete Cisco Header: %u", stats->Rx_frm_incomp_CHDLC_hdr_count); - printf( "\n Invalid Cisco HDLC link address: %u", stats->Rx_invalid_CHDLC_addr_count); - printf( "\n Invalid Cisco HDLC control: %u", stats->Rx_invalid_CHDLC_ctrl_count); - printf( "\n Invalid Cisco HDLC frame type: %u", stats->Rx_invalid_CHDLC_type_count); - - printf("\n\nCisco HDLC link active/inactive and loopback statistics"); - printf( "\n Times that the link went active: %u", stats->link_active_count); - printf( "\n Times that the link went inactive (modem failure): %u", stats->link_inactive_modem_count); - printf( "\n Times that the link went inactive (keepalive failure): %u", stats->link_inactive_keepalive_count); - printf( "\n link looped count: %u", stats->link_looped_count); - } else { - error(); - } -} /* Operational_stats */ - -static void flush_operational_stats( void ) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - flush_operational_stats_S514(); - }else{ - hw_flush_general_stats(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void flush_operational_stats_S514( void ) -{ - wan_udp.wan_udphdr_command= FLUSH_CHDLC_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -} - -static void flush_slarp_cdp_stats(void) -{ - wan_udp.wan_udphdr_command= FLUSH_CHDLC_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -} - -static void slarp_stats (void) -{ - CHDLC_OPERATIONAL_STATS_STRUCT *stats; - wan_udp.wan_udphdr_command= READ_CHDLC_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("SLARP STATISTICS"); - /*stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0];*/ /* WRONG OFFSET!!! */ - stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)&wan_udp.wan_udphdr_u.data[0]; - - printf("\n SLARP frame transmission/reception statistics"); - printf( "\n SLARP request packets transmitted: %u", - stats->CHDLC_SLARP_REQ_Tx_count); - printf( "\n SLARP request packets received: %u", - stats->CHDLC_SLARP_REQ_Rx_count); - printf("\n\n SLARP Reply packets transmitted: %u", - stats->CHDLC_SLARP_REPLY_Tx_count); - printf( "\n SLARP Reply packets received: %u", - stats->CHDLC_SLARP_REPLY_Rx_count); - printf("\n\n SLARP keepalive packets transmitted: %u", - stats->CHDLC_SLARP_KPALV_Tx_count); - printf( "\n SLARP keepalive packets received: %u", - stats->CHDLC_SLARP_KPALV_Rx_count); - - printf( "\n\nIncoming SLARP Packets with format errors"); - printf( "\n Invalid SLARP Code: %u", stats->Rx_SLARP_invalid_code_count); - printf( "\n Replies with bad IP addr: %u", stats->Rx_SLARP_Reply_bad_IP_addr); - printf( "\n Replies with bad netmask: %u",stats->Rx_SLARP_Reply_bad_netmask); - printf( "\n\nSLARP timeout/retry statistics"); - printf( "\n SLARP Request timeouts: %u",stats->SLARP_Request_TO_count); - printf( "\n keepalive reception timeouts: %u",stats->SLARP_Rx_keepalive_TO_count); - - printf("\n\nCisco Discovery Protocol frames"); - printf( "\n Transmitted: %u", stats->CHDLC_CDP_Tx_count); - printf( "\n Received: %u", stats->CHDLC_CDP_Rx_count); - - } else { - error(); - } - -} /* slarp_stats */ - - -int CHDLCDisableTrace(void) -{ - wan_udp.wan_udphdr_command= CPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - return 0; -} - -static int print_local_time (char *date_string) -{ - - char tmp_time[50]; - time_t time_val; - struct tm *time_tm; - - date_string[0]='\0'; - - time_val=time(NULL); - - /* Parse time and date */ - time_tm=localtime(&time_val); - - strftime(tmp_time,sizeof(tmp_time),"%b",time_tm); - sprintf(date_string, " %s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); - sprintf(date_string+strlen(date_string), "%s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); - sprintf(date_string+strlen(date_string), "%s",tmp_time); - - return 0; -} - -static int loop_rx_data(int passnum) -{ - unsigned int num_frames; - unsigned short curr_pos = 0; - wan_trace_pkt_t *trace_pkt; - unsigned int i; - struct timeval to; - int timeout=0; - char date_string[100]; - - gettimeofday(&to, NULL); - to.tv_sec = 0; - to.tv_usec = 0; - - print_local_time(date_string); - - printf("%s | Test %04i | ", - date_string, passnum); - - for(;;) { - - select(1,NULL, NULL, NULL, &to); - - wan_udp.wan_udphdr_command = CPIPE_GET_TRACE_INFO; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len) { - - num_frames = wan_udp.wan_udphdr_aft_num_frames; - - for ( i = 0; i < num_frames; i++) { - trace_pkt= (wan_trace_pkt_t *)&wan_udp.wan_udphdr_data[curr_pos]; - - /* frame type */ - if (trace_pkt->status & 0x01) { - trace_iface.status |= WP_TRACE_OUTGOING; - }else{ - if (trace_pkt->status & 0x10) { - trace_iface.status |= WP_TRACE_ABORT; - } else if (trace_pkt->status & 0x20) { - trace_iface.status |= WP_TRACE_CRC; - } else if (trace_pkt->status & 0x40) { - trace_iface.status |= WP_TRACE_OVERRUN; - } - } - - trace_iface.len = trace_pkt->real_length; - trace_iface.timestamp=trace_pkt->time_stamp; - trace_iface.sec = trace_pkt->sec; - trace_iface.usec = trace_pkt->usec; - - curr_pos += sizeof(wan_trace_pkt_t); - - if (trace_pkt->real_length >= WAN_MAX_DATA_SIZE){ - printf("\t:the frame data is to big (%u)!", - trace_pkt->real_length); - fflush(stdout); - continue; - - }else if (trace_pkt->data_avail == 0) { - - printf("\t: the frame data is not available" ); - fflush(stdout); - continue; - } - - - /* update curr_pos again */ - curr_pos += trace_pkt->real_length; - - trace_iface.trace_all_data=trace_all_data; - trace_iface.data=(unsigned char*)&trace_pkt->data[0]; - - - if (trace_pkt->status & 0x01){ - continue; - } - - if (trace_iface.data[0] == (0x0F) && - trace_iface.data[1] == (0x0F) && - trace_iface.data[2] == (0x0F) && - trace_iface.data[3] == (0x0F)) { - printf("Successful (%s)!\n", - trace_iface.status & WP_TRACE_ABORT ? "Abort" : - trace_iface.status & WP_TRACE_CRC ? "Crc" : - trace_iface.status & WP_TRACE_OVERRUN ? "Overrun" : "Ok" - ); - return 0; - } - - - - } //for - } //if - curr_pos = 0; - - if (!wan_udp.wan_udphdr_chdlc_ismoredata){ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - timeout++; - if (timeout > 100) { - printf("Timeout!\n"); - break; - } - }else{ - to.tv_sec = 0; - to.tv_usec = 0; - } - } - return 0; -} - - -static int aft_digital_loop_test( void ) -{ - int passnum=0; - int i; - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command= CPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - wan_udp.wan_udphdr_command= CPIPE_ENABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0]=0; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0 && - wan_udp.wan_udphdr_return_code != 1) { - printf("Error: Failed to start loop test: failed to start tracing!\n"); - return -1; - } - - printf("Starting Loop Test (press ctrl-c to exit)!\n\n"); - - - - while (1) { - - wan_udp.wan_udphdr_command= DIGITAL_LOOPTEST; - wan_udp.wan_udphdr_return_code = 0xaa; - - for (i=0;i<100;i++){ - wan_udp.wan_udphdr_data[i] = 0x0F; - } - wan_udp.wan_udphdr_data_len = 100; - DO_COMMAND(wan_udp); - - switch (wan_udp.wan_udphdr_return_code) { - - case 0: - break; - case 1: - printf("Error: Failed to start loop test: dev not found\n"); - goto loop_rx_exit; - case 2: - printf("Error: Failed to start loop test: dev state not connected\n"); - goto loop_rx_exit; - case 3: - printf("Error: Failed to start loop test: memory error\n"); - goto loop_rx_exit; - case 4: - printf("Error: Failed to start loop test: invalid operation mode\n"); - goto loop_rx_exit; - - default: - printf("Error: Failed to start loop test: unknown error (%i)\n", - wan_udp.wan_udphdr_return_code); - goto loop_rx_exit; - } - - - loop_rx_data(++passnum); - usleep(500000); - fflush(stdout); - - if (passnum >= 10) { - break; - } - } - -loop_rx_exit: - - wan_udp.wan_udphdr_command= CPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - return 0; -} - - - - -static void line_trace(int trace_mode, int trace_subtype) -{ - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - line_trace_S514(trace_mode, trace_subtype); - }else{ - hw_line_trace(trace_mode); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void line_trace_S514(int trace_mode, int trace_subtype) -{ - unsigned int num_frames; - unsigned short curr_pos = 0; - wan_trace_pkt_t *trace_pkt; - unsigned int i; - int recv_buff = sizeof(wan_udp_hdr_t)+ 100; - fd_set ready; - struct timeval to; - wp_trace_output_iface_t trace_iface; - - memset(&trace_iface,0,sizeof(wp_trace_output_iface_t)); - - setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recv_buff, sizeof(int) ); - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command= CPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - wan_udp.wan_udphdr_command= CPIPE_ENABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0]=0; - if(trace_mode == TRACE_PROT){ - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] |= TRACE_SLARP_FRAMES | TRACE_CDP_FRAMES; - printf("Tracing Protocol only %X\n",wan_udp.wan_udphdr_data[0]); - }else if(trace_mode == TRACE_DATA){ - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = TRACE_DATA_FRAMES; - }else{ - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] |= TRACE_SLARP_FRAMES | - TRACE_DATA_FRAMES | - TRACE_CDP_FRAMES; - } - - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - printf("Starting trace...(Press ENTER to exit)\n"); - fflush(stdout); - } else if(wan_udp.wan_udphdr_return_code == 0xCD ) { - printf("Cannot Enable Line Tracing from Underneath.\n"); - fflush(stdout); - return; - }else if (wan_udp.wan_udphdr_return_code == 0x01 ) { - printf("Starting trace...(although it's already enabled!)\n"); - printf("Press ENTER to exit.\n"); - fflush(stdout); - }else{ - printf("Failed to Enable Line Tracing. Return code: 0x%02X\n", - wan_udp.wan_udphdr_return_code ); - fflush(stdout); - return; - } - - to.tv_sec = 0; - to.tv_usec = 0; - for(;;) { - FD_ZERO(&ready); - FD_SET(0,&ready); - fflush(stdout); - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - - wan_udp.wan_udphdr_command = CPIPE_GET_TRACE_INFO; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len) { - num_frames = wan_udp.wan_udphdr_chdlc_num_frames; - - for ( i = 0; i < num_frames; i++) { - trace_pkt= (wan_trace_pkt_t *)(&wan_udp.wan_udphdr_data[0] + curr_pos); - -#if 0 - if (annexg_trace){ - - if (trace_pkt->real_length > wan_udp.wan_udphdr_data_len){ - break; - } - curr_pos += sizeof(wan_trace_pkt_t); - - if (trace_pkt->data_avail) { - curr_pos += trace_pkt->real_length -1; - - decode_pkt(trace_pkt->data, - trace_pkt->real_length, - trace_pkt->status, - trace_pkt->time_stamp, - 0); - } - goto trace_skip; - } -#endif - - /* frame type */ - trace_iface.status=0; - if (trace_pkt->status & 0x01) { - trace_iface.status|=WP_TRACE_OUTGOING; - } else { - if (trace_pkt->status & 0x10) { - trace_iface.status|=WP_TRACE_ABORT; - } else if (trace_pkt->status & 0x20) { - trace_iface.status|=WP_TRACE_CRC; - } else if (trace_pkt->status & 0x40) { - trace_iface.status|=WP_TRACE_OVERRUN; - } - } - - trace_iface.len = trace_pkt->real_length; - trace_iface.timestamp = trace_pkt->time_stamp; - trace_iface.sec = trace_pkt->sec; - trace_iface.usec = trace_pkt->usec; - - if (trace_pkt->real_length > wan_udp.wan_udphdr_data_len){ - break; - } - - /* first update curr_pos */ - curr_pos += sizeof(wan_trace_pkt_t); - - if (trace_pkt->data_avail == 0) { - printf("the frame data is not available" ); - printf("\n"); - goto trace_skip; - } - - /* update curr_pos again */ - curr_pos += trace_pkt->real_length; - - trace_iface.trace_all_data=trace_all_data; - trace_iface.data=(unsigned char*)&trace_pkt->data[0]; - trace_iface.link_type = 104; - - if (pcap_output){ - trace_iface.type=WP_OUT_TRACE_PCAP; - }else if (raw_data) { - trace_iface.type=WP_OUT_TRACE_RAW; - }else{ - trace_iface.type=WP_OUT_TRACE_INTERP; - } - - trace_iface.sub_type = trace_subtype; - - wp_trace_output(&trace_iface); -trace_skip: - fflush(stdout); - - } //for - } //if - - curr_pos = 0; - - if (!wan_udp.wan_udphdr_chdlc_ismoredata){ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - }else{ - to.tv_sec = 0; - to.tv_usec = 0; - } - } - - wan_udp.wan_udphdr_command= CPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); -}; /* line_trace */ - -//CORBA -int CHDLCUsage(void) -{ -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - printf("%s: Wanpipe Cisco-HDLC Debugging Utility\n\n", progname); -#else - printf("%s: Wanpipe HDLC Debugging Utility\n\n", progname); -#endif - printf("Usage:\n"); - printf("-----\n\n"); - printf("wanpipemon -i -u -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address must be supplied\n"); -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - printf("\t\t Wanpipe network interface name (ex: wp1_chdlc)\n"); -#else - printf("\t\t Wanpipe network interface name (ex: hdlc0)\n"); -#endif - printf("\tOption -u: (Optional, default: 9000)\n"); -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe/wanpipe#.conf\n"); -#else - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe/ifcfg-hdlcN\n"); -#endif - printf("\tOption -full: (Optional, trace option)\n"); - printf("\t\tDisplay raw packets in full: default trace pkt len=25bytes\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t l Link Status\n"); - printf("\t cv Read Code Version\n"); - printf("\t ru Display Router UP time\n"); - printf("\tProtocol Configuration\n"); - printf("\t c rc Read CHDLC Configuration\n"); - printf("\tCard Statistics\n"); -// printf("\t s g Global Statistics\n"); - printf("\t s c Communication Error Statistics\n"); - printf("\t o Operational Statistics\n"); - printf("\t s SLARP and CDP Statistics\n"); - printf("\tTrace Data \n"); -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - printf("\t t i Trace and Interpret ALL frames\n"); - //printf("\t ip Trace and Interpret PROTOCOL frames only\n"); - //printf("\t id Trace and Interpret DATA frames only\n"); - printf("\t r Trace ALL frames, in RAW format\n"); - //printf("\t rp Trace PROTOCOL frames only, in RAW format\n"); - //printf("\t rd Trace DATA frames only, in RAW format\n"); -#else - printf("\t t r Trace ALL frames, in RAW format\n"); -#endif - printf("\tFT1/T1/E1/56K Configuration/Statistics\n"); - printf("\t T v View Status (S508/FT1 or S5143/FT1)\n"); - printf("\t s Self Test (S508/FT1 or S5143/FT1)\n"); - printf("\t l Line Loop Test (S508/FT1 or S5143/FT1)\n"); - printf("\t d Digital Loop Test (S508/FT1 or S5143/FT1)\n"); - printf("\t r Remote Test (S508/FT1 or S5143/FT1)\n"); - printf("\t o Operational Mode (S508/FT1 or S5143/FT1)\n"); - printf("\t p FT1 CSU/DSU operational statistics (S508/FT1 or S5143/FT1)\n"); - printf("\t f Flush FT1 CSU/DSU operational statistcs (S508/FT1 or S5143/FT1)\n"); - printf("\t set Set CSU/DSU configuration\n"); - printf("\t read Read CSU/DSU configuration (FT1/T1/E1 card)\n"); - printf("\t allb Active Line Loopback mode (T1/E1 card only)\n"); - printf("\t dllb Deactive Line Loopback mode (T1/E1 card only)\n"); - printf("\t aplb Active Payload Loopback mode (T1/E1 card only)\n"); - printf("\t dplb Deactive Payload Loopback mode (T1/E1 card only)\n"); - printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t salb Send Loopback Activate Code (T1/E1 card only)\n"); - printf("\t sdlb Send Loopback Deactive Code (T1/E1 card only)\n"); - printf("\t a Read T1/E1/56K alarms.\n"); - printf("\t lt Diagnostic Digital Loopback testing (T1/E1 card only)\n"); - printf("\tFlush Statistics\n"); - //printf("\t f g Flush Global Statistics\n"); - printf("\t f c Flush Communication Error Statistics\n"); - printf("\t o Flush Operational Statistics\n"); - printf("\t s Flush SLARP and CDP Statistics\n"); - printf("\t pm Flush T1/E1 performance monitoring counters\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - printf("\tex: wanpipemon -i wp1_chdlc0 -u 9000 -c xm :View Modem Status \n"); - printf("\tex: wanpipemon -i wp1_chdlc0 -c Tset :View Help for CSU/DSU Setup\n"); - printf("\tex: wanpipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n\n"); -#else - printf("\tex: %s -i hdlc0 -u 9000 -c xm :View Modem Status \n", progname); - printf("\tex: %s -i hdlc0 -c Tset :View Help for CSU/DSU Setup\n", progname); - printf("\tex: %s -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n\n", progname); -#endif - return 0; -} - -static void chdlc_router_up_time( void ) -{ - u_int32_t time; - - if(!connected_to_hw_level){ - if(make_hardware_level_connection()){ - return; - } - } - - if(global_card_type == WANOPT_S51X){ - wan_udp.wan_udphdr_command= CPIPE_ROUTER_UP_TIME; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - time = *(u_int32_t*)&wan_udp.wan_udphdr_data[0]; - - BANNER("ROUTER UP TIME (CHDLC)"); - - print_router_up_time(time); - }else{ - hw_router_up_time(); - } - - if(connected_to_hw_level){ - cleanup_hardware_level_connection(); - } -} - -static void set_FT1_monitor_status( unsigned char status) -{ - gfail = 0; - - //cb.data[0] = status; - wan_udp.wan_udphdr_command= FT1_MONITOR_STATUS_CTRL; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = status; - DO_COMMAND(wan_udp); - //if( (cb.wan_udphdr_return_code != 0) && status){ - if ((wan_udp.wan_udphdr_return_code != 0) && status){ - gfail = 1; - printf("This command is only possible with S508/FT1 board!"); - } -} /* set_FT1_monitor_status */ - - -static void read_ft1_op_stats( void ) -{ - fd_set ready; - struct timeval to; - unsigned short length; - - - printf("TIME: Time in seconds since the FT1 op stats were last reset\n"); - printf(" ES: Errored Second\n"); - printf(" BSE: Bursty Errored Second\n"); - printf(" SES: Severly Errored Second\n"); - printf(" UAS: Unavailable Second\n"); - printf("LOFC: Loss of Frame Count\n"); - printf(" ESF: ESF Error Count\n"); - - printf("\nFT1 CSU/DSU Operational Stats...(Press ENTER to exit)\n"); - for(;;){ - - - - wan_udp.wan_udphdr_command= READ_FT1_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - FD_ZERO(&ready); - FD_SET(0,&ready); - to.tv_sec = 0; - to.tv_usec = 50000; - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - //if( cb.wan_udphdr_data_len ){ - if (wan_udp.wan_udphdr_data_len ){ - int i=0; - printf(" TIME ES BES SES UAS LOFC ESF\n"); - //length = cb.wan_udphdr_data_len; - length = wan_udp.wan_udphdr_data_len; - while(length){ - - //printf("%c", cb.data[i]); - printf("%c", wan_udp.wan_udphdr_data[i]); - length--; - i++; - } - printf("\n"); - } - } -} - -static unsigned char ft1_usage_buf[]="\n" -"\n" -"---------------------------------------------------------------------------------------\n" -" \n" -"Usage: wanpipemon -i -u -c Tset \\n" -" \n" -"\n" -"Example: Setup CSU/DSU for T1, ESF, B8ZS:\n" -" wanpipemon -i chdlc0 -u 9000 -c Tset 0 0 0 1 1536 0\n" -"---------------------------------------------------------------------------------------\n" -" \n" -"FRAMING: 0 = ESF , 1 = D4\n\\n" -" Please select one of the above options as specified by\n\\n" -" your FT1 provider.\n\n" -"\n" -"ENCODING: 0 = B8ZS , 1 = AMI\n\\n" -" Please select one of the above options as specified by\n\\n" -" your FT1 provider.\n\n" -" \n" -"LINE_BUILD: 0 = CSU: 0db, DSX: 0-133ft\n\\n" -" 1 = DSX: 266-399ft\n\\n" -" 2 = DSX: 399-533ft\n\\n" -" 3 = DSX: 399-533ft\n\\n" -" 4 = DSX: 533-655ft\n\\n" -" 5 = CSU -7dB\n\\n" -" 6 = CSU -15dB\n\\n" -" 7 = CSU -22.5dB\n\\n" -"\n" -" For WANPIPE FT1 Card setup, select the first option:\n" -" * CSU 0dB DSX1 0-133ft (option 0)\n" -"\n" -" For any other setup, select an option as specified by\n" -" your FT1 provider.\n\n" -" \n" -"CHANNEL: Number between 1 to 24.\n" -" Represents the first active channel.\n" -" (Default = 1)\n" -"\n" -" The T1 line consists of 24 channels, each 64 or 56\n" -" Kbps. If this is a full T1 line, then the first\n" -" active channel is 1. Otherwise, set the first\n" -" active channel as specified by your FT1 provider.\n\n" -" \n" -"BAUD: Line baud rate (speed).\n" -"\n" -" For B8ZS Encoding:\n" -" Full T1 baud rate is: 1536 Kbps.\n" -" Each T1 channel runs at: 64 Kbps.\n" -" For AMI Encoding:\n" -" Full T1 baud rate is: 1344 Kbps.\n" -" Each T1 channel runs at: 56 Kbps.\n" -"\n" -" Enter the speed of your connection in Kbps, as\n" -" specified by your FT1 provider.\n" -"\n" -" To calculate your baud rate, find out how many\n" -" active T1 channels you have. Then multiply that\n" -" number to ether 64 (for B8ZS) or 56 (for AMI).\n" -" Note, that first active channel should be set to\n" -" 1 in most cases. (Note: CHANNEL option)\n" -" \n" -"CLOCK: 0 = NORMAL, 1 = MASTER\n" -"\n" -" Default is always Normal.\n" -"\n" -" Select clocking options as specified by your FT1\n" -" provider.\n" -"\n"; - -static void ft1_usage (void) -{ - printf("%s\n",ft1_usage_buf); -} - - - -static void set_ft1_config(int argc, char ** argv) -{ - ft1_config_t *ft1_config = (ft1_config_t *)&wan_udp.wan_udphdr_data[0]; - int i=0,found=0; - - wan_udp.wan_udphdr_command = SET_FT1_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = sizeof(ft1_config_t); - - for (i=0;iframing_mode = atoi(argv[i++]); - ft1_config->encoding_mode = atoi(argv[i++]); - ft1_config->line_build_out = atoi(argv[i++]); - ft1_config->channel_base = atoi(argv[i++]); - ft1_config->baud_rate_kbps = atoi(argv[i++]); - ft1_config->clock_mode = atoi(argv[i]); - - - if (ft1_config->framing_mode > 1){ - printf("Error: Invalid Framing Mode (0=ESF 1=D4)\n"); - return; - } - if (ft1_config->encoding_mode > 1){ - printf("Error: Invalid Encoding Mode (0=B8ZS 1=AMI)\n"); - return; - } - if (ft1_config->line_build_out > 7){ - printf("Error: Invalid Line Build Mode (0-7) Default:0\n"); - return; - } - if (ft1_config->channel_base > 24){ - printf("Error: Invalid Channel Base (1-24) Default:1 \n"); - return; - } - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps > 1536)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps > 1344)){ - printf("Error: Invalid Baud Rate: B8ZS Max=1536KBps; AMI Max=1344KBps\n"); - return; - } - - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps < 64)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps < 56)){ - printf("Error: Invalid Baud Rate: B8ZS Min=64KBps; AMI Max=56KBps\n"); - return; - } - - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps%64 != 0)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps%56 != 0)){ - printf("Error: Invalid Baud Rate: \n"); - printf(" For B8ZS: Baud rate must be a multiple of 64KBps.\n"); - printf(" For AMI: Baud rate must be a multiple of 56KBps.\n"); - return; - } - - if (ft1_config->clock_mode > 1){ - printf("Error: Invalid Clock Mode: (0=Normal, 1=Master) Default:0\n"); - return; - } - - DO_COMMAND(wan_udp); - //if (cb.wan_udphdr_return_code == 0){ - if (wan_udp.wan_udphdr_return_code == 0){ - printf("CSU/DSU Configuration Successfull!\n"); - - //}else if (cb.wan_udphdr_return_code == 0xaa){ - }else if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Sangoma Adaptor is not equiped with an onboard CSU/DSU!\n"); - printf("\tCSU/DSU Configuration Failed!\n"); - - }else{ - //printf("CSU/DSU Configuration Failed: rc %x",cb.wan_udphdr_return_code); - printf("CSU/DSU Configuration Failed: rc %x",wan_udp.wan_udphdr_return_code); - } -} - - -static void read_ft1_te1_56k_config (void) -{ - unsigned char adapter_type = 0x00; - - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } - - switch(adapter_type){ - case WAN_MEDIA_NONE: - - wan_udp.wan_udphdr_command = READ_FT1_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("CSU/DSU Read Configuration Failed"); - }else{ - //ft1_config_t *ft1_config = (ft1_config_t *)&cb.data[0]; - ft1_config_t *ft1_config = (ft1_config_t *)&wan_udp.wan_udphdr_data[0]; - printf("CSU/DSU %s Configuration:\n", if_name); - printf("\tFraming\t\t%s\n",ft1_config->framing_mode ? "D4" : "ESF"); - printf("\tEncoding\t%s\n",ft1_config->encoding_mode ? "AMI" : "B8ZS"); - printf("\tLine Build\t%i\n",ft1_config->line_build_out); - printf("\tChannel Base\t%i\n",ft1_config->channel_base); - printf("\tBaud Rate\t%i\n",ft1_config->baud_rate_kbps); - printf("\tClock Mode\t%s\n",ft1_config->clock_mode ? "MASTER":"NORMAL"); - } - break; - - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - case WAN_MEDIA_56K: - read_te1_56k_config(); - break; - } - return; -} - - -int CHDLCMain(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - - global_command = command; - global_argc = argc; - global_argv = argv; - - switch(command[0]){ - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt, "cv")){ - read_code_version(); - }else if (!strcmp(opt,"l")){ - link_status(); - }else if (!strcmp(opt,"ru")){ - chdlc_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x'\n"); - printf("ERROR: Type %s for help\n\n", progname); - } - break; - case 's': - //if (!strcmp(opt,"g")){ - // global_stats(); - //}else - if (!strcmp(opt,"c")){ - comm_err(); - }else if (!strcmp(opt,"o")){ - operational_stats(); - }else if (!strcmp(opt,"s")){ - slarp_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's'\n"); - printf("ERROR: Type %s for help\n\n", progname); - } - break; - - case 'c': - if (!strcmp(opt,"rc")){ - chdlc_configuration(); -/* - }else if (!strcmp(opt,"reset")){ - chdlc_reset_adapter(); -*/ - }else{ - printf("ERROR: Invalid Configuration Command 'c'\n"); - printf("ERROR: Type %s for help\n\n", progname); - } - break; - - case 't': - if(!strcmp(opt,"i" )){ - raw_data = WAN_FALSE; - line_trace(TRACE_ALL, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - line_trace(TRACE_ALL, WP_OUT_TRACE_RAW); - } - /* - else if (!strcmp(opt, "ip")){ - raw_data = WAN_FALSE; - line_trace(TRACE_PROT, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "id")){ - raw_data = WAN_FALSE; - line_trace(TRACE_DATA, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "rp")){ - raw_data = WAN_TRUE; - line_trace(TRACE_PROT, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "rd")){ - raw_data = WAN_TRUE; - line_trace(TRACE_DATA, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "ra")){ - raw_data = WAN_TRUE; - annexg_trace = WAN_TRUE; - line_trace(TRACE_ALL, WP_OUT_TRACE_RAW); - } - */ - else{ - printf("ERROR: Invalid Trace Command 't'\n"); - printf("ERROR: Type %s for help\n\n", progname); - } - break; - - case 'f': - if (!strcmp(opt, "o")){ - flush_operational_stats(); - operational_stats(); - }else if (!strcmp(opt, "s")){ - flush_slarp_cdp_stats(); - slarp_stats(); - //}else if (!strcmp(opt, "g")){ - // flush_global_stats(); - // global_stats(); - }else if (!strcmp(opt, "c")){ - flush_comm_err(); - comm_err(); - }else if (!strcmp(opt, "pm")){ - flush_te1_pmon(); - } else{ - printf("ERROR: Invalid Flush Command 'f'\n"); - printf("ERROR: Type %s for help\n\n", progname); - } - break; - - case 'T': - if (!strcmp(opt, "v")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - view_FT1_status(); - } - set_FT1_monitor_status(0x00); - - }else if (!strcmp(opt,"lt")){ - aft_digital_loop_test(); - - }else if (!strcmp(opt, "s")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "l")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_local_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "d")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_digital_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "r")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_remote_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "o")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_operational_mode(); - } - }else if (!strcmp(opt,"txe")){ - set_fe_tx_mode(WAN_FE_TXMODE_ENABLE); - }else if (!strcmp(opt,"txd")){ - set_fe_tx_mode(WAN_FE_TXMODE_DISABLE); -set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "p")){ - set_FT1_monitor_status(0x02); - if(!gfail) - read_ft1_op_stats(); - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "f")){ - set_FT1_monitor_status(0x04); - if(!gfail){ - printf("Flushed Operational Statistics\n"); - }else{ - printf("FT1 Flush Failed %i\n",gfail); - } - - }else if (!strcmp(opt, "set")){ - set_ft1_config(argc, argv); - }else if (!strcmp(opt,"read")){ - read_ft1_te1_56k_config(); - }else if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"a")){ - read_te1_56k_stat(0); - } else{ - printf("ERROR: Invalid FT1/T1/E1 Command 'T'\n"); - printf("ERROR: Type %s for help\n\n", progname); - } - break; - - default: - printf("ERROR: Invalid Command!\n"); - printf("ERROR: Type %s for help\n\n", progname); - break; - }//switch - printf("\n"); - fflush(stdout); - return 0; -}; //main diff --git a/util/wanpipemon.old/cpipemon.o b/util/wanpipemon.old/cpipemon.o deleted file mode 100644 index 21548c790e43c3cbe982d2ea0246c0193a6f3964..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35808 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 - char tmp_time[50]; -@@ -125,21 +126,21 @@ - time_tm = localtime(&time_val); - - strftime(tmp_time,sizeof(tmp_time)," %b",time_tm); -- sprintf(date_string+strlen(date_string), " %s ",tmp_time); -+ snprintf(date_string+strlen(date_string), 100-strlen(date_string), " %s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); -- sprintf(date_string+strlen(date_string), "%s ",tmp_time); -+ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); -- sprintf(date_string+strlen(date_string), "%s:",tmp_time); -+ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); -- sprintf(date_string+strlen(date_string), "%s:",tmp_time); -+ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); -- sprintf(date_string+strlen(date_string), "%s",tmp_time); -+ snprintf(date_string+strlen(date_string), 100-strlen(date_string), "%s",tmp_time); - -- sprintf(date_string+strlen(date_string), " %-6lu [1/100s]",trace_iface->usec ); -+ snprintf(date_string+strlen(date_string), 100-strlen(date_string), " %-6lu [1/100s]",(unsigned long)trace_iface->usec ); - } - - printf("\n%s\tLen=%d\tTimeStamp=%s\n", -@@ -331,7 +332,7 @@ - if (code == 0x39) - return "Destination Absent"; - -- sprintf(buffer, "Unknown %02X", code); -+ snprintf(buffer, 25, "Unknown %02X", code); - - return buffer; - } -@@ -558,7 +559,7 @@ - if (code == 250) - return "Reset - user resynchronization"; - -- sprintf(buffer, "Unknown %d", code); -+ snprintf(buffer, 25, "Unknown %d", code); - - return buffer; - } -@@ -567,7 +568,7 @@ - static int decode_chdlc(wp_trace_output_iface_t *trace_iface, - int *trace_started) - { -- unsigned char *data = trace_iface->data; -+ char *data= (char*)trace_iface->data; - - int inf_frame=0; - cisco_header_t *cisco_header = (cisco_header_t *)&data[0]; -@@ -586,7 +587,7 @@ - case CISCO_PACKET_IP: - printf("CISCO Packet IP-v4\n\n"); - //decode data past Cisco header -- decode_data_ipv4((unsigned char*)(cisco_header + 1), -+ decode_data_ipv4((char*)(cisco_header + 1), - trace_iface->len - sizeof(cisco_header_t)); - break; - -@@ -661,7 +662,7 @@ - #define IP_V4 4 - #define IP_V4_IHLEN 5 - --static int decode_data_ipv4(unsigned char* data, unsigned short data_len) -+static int decode_data_ipv4(char* data, unsigned short data_len) - { - iphdr_t *ip_hdr = (iphdr_t*)data; - struct tcphdr * tcp_hdr; -@@ -762,12 +763,10 @@ - case IPPROTO_RAW: /* 255 */ - printf("Raw IP packets"); - break; -- --#if 0 -+ - case IPPROTO_MAX: - printf("IPPROTO_MAX"); - break; --#endif - - default: - printf("Unknown (%d)\n", ip_hdr->w_ip_p); -@@ -843,7 +842,7 @@ - (unsigned int)(address & 0xFF000000) >>24); - } - --static void print_data_in_hex(unsigned char* data, unsigned short data_len) -+static void print_data_in_hex(char* data, unsigned short data_len) - { - int i; - -@@ -1532,7 +1531,8 @@ - fwrite(&ph, sizeof(ph), 1, trace_iface->output_file); - } - --static void get_ppp_magic_number(unsigned char* data, int len, char* outstr, char offset_flag) -+static void -+get_ppp_magic_number(char* data, int len, char* outstr, int max_len, char offset_flag) - { - if(offset_flag == 0){ - -@@ -1540,7 +1540,7 @@ - printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); - return; - } -- sprintf(outstr, "\tMagic# %02X%02X%02X%02X", -+ snprintf(outstr, max_len, "\tMagic# %02X%02X%02X%02X", - (unsigned char)data[8], (unsigned char)data[9], - (unsigned char)data[10], (unsigned char)data[11]); - }else{ -@@ -1549,12 +1549,13 @@ - printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); - return; - } -- sprintf(outstr, "\tMagic# %02X%02X%02X%02X", -+ snprintf(outstr, max_len, "\tMagic# %02X%02X%02X%02X", - (unsigned char)data[8+2], (unsigned char)data[8+3], - (unsigned char)data[8+4], (unsigned char)data[8+5]); - } - } - -+#define MAX_OUTSTR_LEN 1024 - static int decode_ppp(wp_trace_output_iface_t *trace_iface, - int *trace_started) - { -@@ -1562,10 +1563,10 @@ - int len = trace_iface->len; - int inf_frame=0; - unsigned short tmp_ushort; -- char outstr[1024]; -+ char outstr[MAX_OUTSTR_LEN]; - - trace_banner(trace_iface,trace_started); -- memset(outstr, 0x00, 1024); -+ memset(outstr, 0x00, MAX_OUTSTR_LEN); - - //print the data (including PPP header) - print_data_in_hex(data, len); -@@ -1591,58 +1592,58 @@ - - //pre-decodeing - if (tmp_ushort == 0x2180){ -- sprintf(outstr+strlen(outstr), "IPCP-v4 packet - "); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "IPCP-v4 packet - "); - } - - if (tmp_ushort == 0x5780){ -- sprintf(outstr+strlen(outstr), "IPCP-v6 packet - "); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "IPCP-v6 packet - "); - } - - if (tmp_ushort == 0x2B80){ -- sprintf(outstr+strlen(outstr), "IPXCP packet - "); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "IPXCP packet - "); - } - - if (tmp_ushort == 0x21C0){ -- sprintf(outstr+strlen(outstr), "LCP packet\tID 0x%02X - ", data[5]); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "LCP packet\tID 0x%02X - ", data[5]); - } - - //common decoding - switch(data[4]) { - case 1: -- sprintf(outstr+strlen(outstr), "Configure Request"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Request"); - break; - case 2: -- sprintf(outstr+strlen(outstr), "Configure Ack\t"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Ack\t"); - break; - case 3: -- sprintf(outstr+strlen(outstr), "Configure Nack\t"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Nack\t"); - break; - case 4: -- sprintf(outstr+strlen(outstr), "Configure Reject"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Configure Reject"); - break; - case 5: -- sprintf(outstr+strlen(outstr), "Terminate Request"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Terminate Request"); - break; - case 6: -- sprintf(outstr+strlen(outstr), "Terminate Ack\t"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Terminate Ack\t"); - break; - case 7: -- sprintf(outstr+strlen(outstr), "Code Reject\t"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Code Reject\t"); - break; - case 8: -- sprintf(outstr+strlen(outstr), "Protocol Reject"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Protocol Reject"); - break; - case 9: -- sprintf(outstr+strlen(outstr), "Echo Request\t"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Echo Request\t"); - break; - case 10: -- sprintf(outstr+strlen(outstr), "Echo Reply\t"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Echo Reply\t"); - break; - case 11: -- sprintf(outstr+strlen(outstr), "Discard Request"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Discard Request"); - break; - default: -- sprintf(outstr+strlen(outstr), "Unknown type"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); - break; - } - -@@ -1651,16 +1652,24 @@ - //LCP - switch(data[4]) { - case 1: -- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); -+ get_ppp_magic_number( -+ data, len, -+ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); - break; - case 2: -- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); -+ get_ppp_magic_number( -+ data, len, -+ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); - break; - case 3: -- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); -+ get_ppp_magic_number( -+ data, len, -+ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); - break; - case 4: -- get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); -+ get_ppp_magic_number( -+ data, len, -+ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 1); - break; - case 5: - case 6: -@@ -1669,13 +1678,19 @@ - ;//do nothing - break; - case 9: -- get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); -+ get_ppp_magic_number( -+ data, len, -+ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 0); - break; - case 10: -- get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); -+ get_ppp_magic_number( -+ data, len, -+ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 0); - break; - case 11: -- get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); -+ get_ppp_magic_number( -+ data, len, -+ outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), 0); - break; - default: - break; -@@ -1684,47 +1699,47 @@ - break; - - case 0x23C0: // PAP -- sprintf(outstr+strlen(outstr), "PAP packet - "); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "PAP packet - "); - switch(data[4]) { - case 1: -- sprintf(outstr+strlen(outstr), "Authenticate Request"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Authenticate Request"); - break; - case 2: -- sprintf(outstr+strlen(outstr), "Authenticate Ack"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Authenticate Ack"); - break; - case 3: -- sprintf(outstr+strlen(outstr), "Authenticate Nack"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Authenticate Nack"); - break; - default: -- sprintf(outstr+strlen(outstr), "Unknown type"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); - break; - } - break; - case 0x25C0: // LQR -- sprintf(outstr+strlen(outstr), "Link Quality Report"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Link Quality Report"); - break; - case 0x23C2: // CHAP -- sprintf(outstr+strlen(outstr), "CHAP packet - "); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "CHAP packet - "); - switch(data[4]) { - case 1: -- sprintf(outstr+strlen(outstr), "Challenge"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Challenge"); - break; - case 2: -- sprintf(outstr+strlen(outstr), "Responce"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Responce"); - break; - case 3: -- sprintf(outstr+strlen(outstr), "Success"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Success"); - break; - case 4: -- sprintf(outstr+strlen(outstr), "Failure"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Failure"); - break; - default: -- sprintf(outstr+strlen(outstr), "Unknown type"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); - break; - } - break; - default: // unknown -- sprintf(outstr+strlen(outstr), "Unknown type"); -+ snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr), "Unknown type"); - break; - } - diff --git a/util/wanpipemon.old/docommand.c b/util/wanpipemon.old/docommand.c deleted file mode 100644 index 35381f6..0000000 --- a/util/wanpipemon.old/docommand.c +++ /dev/null @@ -1,249 +0,0 @@ -/***************************************************************************** -* docommand.c -* -* Author: Alex Feldman -* -* Copyright: (c) 1995-1999 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. -* ---------------------------------------------------------------------------- -* Dec 04, 2001 Alex Feldman Initial version -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ft1_lib.h" - -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#define TIMEOUT 1 -#define MDATALEN 2024 - -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ -#pragma pack(1) -typedef struct { - ip_pkt_t ip_pkt PACKED; - udp_pkt_t udp_pkt PACKED; - wp_mgmt_t wp_mgmt PACKED; - char data[MDATALEN] PACKED; -} udp_packet_t; -#pragma pack() - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -struct sockaddr_in soin; -char raw_sock=0; -char i_name[16]; -extern char ipaddress[]; -extern int sock; -extern int udp_port; - -udp_packet_t udp_pkt; - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -unsigned char DoCommand(void*, int); - - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int MakeUdpConnection( void ) -{ - sock = socket( PF_INET, SOCK_DGRAM, 0 ); - - if( sock < 0 ) { - printf("Error: Unable to open socket!\n"); - return( WAN_FALSE ); - } /* if */ - - soin.sin_family = AF_INET; - soin.sin_addr.s_addr = inet_addr(ipaddress); - - if(soin.sin_addr.s_addr < 0){ - printf("Error: Invalid IP address!\n"); - return( WAN_FALSE ); - } - - soin.sin_port = htons((u_short)udp_port); - - if( !connect( sock, (struct sockaddr *)&soin, sizeof(soin)) == 0 ) { - printf("Error: Cannot make connection!\n"); - printf("Make sure the IP address is correct\n"); - return( WAN_FALSE ); - } - - return( WAN_TRUE ); -}; /* MakeConnection */ - - -#ifdef LINUX_2_1 -int MakeRawConnection( void ) -{ - struct ifreq ifr; - struct sockaddr_ll soin; - raw_sock=1; - - sock = socket(PF_PACKET, SOCK_RAW, 0); - if (sock < 0){ - printf("Error: Unable to open socket!\n"); - return( WAN_FALSE ); - } /* if */ - - soin.sll_family = AF_PACKET; - soin.sll_protocol = htons(ETH_P_IP); - strcpy (ifr.ifr_name,i_name); - if (ioctl(sock,SIOCGIFINDEX,&ifr) <0){ - perror("Ioctl: "); - return (WAN_FALSE); - } - soin.sll_ifindex = ifr.ifr_ifindex; - - if (bind(sock, (struct sockaddr *)&soin, sizeof(soin)) < 0) { - printf("Error: Cannot make connection!\n"); - printf("Make sure the IP address is correct\n"); - return( WAN_FALSE ); - } /* if */ - - return( WAN_TRUE ); - -}; /* MakeRawConnection */ -#endif - -unsigned char DoCommand(void* pkt, int data_len) -{ - wp_mgmt_t* packet = (wp_mgmt_t*)pkt; - static unsigned char id = 0; - fd_set ready; - struct timeval to; - int x, err=0; - - if (raw_sock){ - struct ifreq ifr; - - udp_pkt.ip_pkt.ver_inet_hdr_length = 0x45; - udp_pkt.ip_pkt.service_type = 0; - udp_pkt.ip_pkt.total_length = sizeof(ip_pkt_t)+ - sizeof(udp_pkt_t) + data_len; - udp_pkt.ip_pkt.identifier = 0; - udp_pkt.ip_pkt.flags_frag_offset = 0; - udp_pkt.ip_pkt.ttl = 0x7F; - udp_pkt.ip_pkt.protocol = 0x11; - udp_pkt.ip_pkt.hdr_checksum = 0x1232; - udp_pkt.ip_pkt.ip_src_address = inet_addr("1.1.1.1"); - udp_pkt.ip_pkt.ip_dst_address = inet_addr("1.1.1.2"); - - udp_pkt.udp_pkt.udp_src_port = htons((u_short)udp_port); - udp_pkt.udp_pkt.udp_dst_port = htons((u_short)udp_port); - udp_pkt.udp_pkt.udp_length = sizeof(udp_pkt_t) + data_len; - udp_pkt.udp_pkt.udp_checksum = 0x1234; - - memcpy(&udp_pkt.wp_mgmt.signature[0], packet, data_len); - - for( x = 0; x < 4; x += 1 ) { - udp_pkt.wp_mgmt.request_reply = 0x01; - udp_pkt.wp_mgmt.id=id; - - ifr.ifr_data = (void*)&udp_pkt; - strcpy (ifr.ifr_name,i_name); - ioctl(sock,SIOC_WANPIPE_PIPEMON,&ifr); - - if (err < 0){ - if (errno == -EBUSY){ - continue; - }else{ - perror("Ioctl:"); - break; - } - } - - memcpy(packet, - &udp_pkt.wp_mgmt.signature, - MDATALEN-sizeof(ip_pkt_t)-sizeof(udp_pkt_t)); - break; - } - }else{ - for( x = 0; x < 4; x += 1 ) { - packet->request_reply = 0x01; - packet->id = id; - /* 0xAA is our special return code indicating packet timeout */ - //cb.cblock.return_code = 0xaa; - //err = send(sock, &cb, 35 + cb.cblock.buffer_length, 0); - err = send(sock, packet, data_len, 0); - if (err <0){ - perror("Send"); - continue; - } - - FD_ZERO(&ready); - FD_SET(sock,&ready); - to.tv_sec = 5; - to.tv_usec = 0; - - if((err = select(sock + 1,&ready, NULL, NULL, &to))) { - - err = recv(sock, packet, MDATALEN, 0); - if( err < 0 ){ - perror("Recv"); - } - break; - }else{ - printf("Error: No Data received from the connected socket.\n"); - } - } - } - - /* make sure the id is correct (returning results from a previous - call may be disastrous if not recognized) - also make sure it is a reply - */ - - //if (cb.wp_mgmt.id != id || cb.wp_mgmt.request_reply != 0x02){ - if (packet->id != id || packet->request_reply != 0x02){ - //cb.cblock.return_code = 0xbb; - // FIXME: packet->cblock.return_code = 0xbb; - } - id++; - //if (cb.cblock.return_code == 0xCC) { - // printf("Error: Code is not running on the board!"); - // exit(1); - //} - - //return(cb.cblock.return_code); - return 0; - -}; /* DoCommand */ - diff --git a/util/wanpipemon.old/dslpipemon.c b/util/wanpipemon.old/dslpipemon.c deleted file mode 100644 index e038601..0000000 --- a/util/wanpipemon.old/dslpipemon.c +++ /dev/null @@ -1,1044 +0,0 @@ -/***************************************************************************** -* dsapipemon.c Wanpipe DSL Monitor -* -* Author: Nenad Corbic -* -* Copyright: (c) 2002 Sangoma Technologies Inc. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* ---------------------------------------------------------------------------- -* May 15, 2002 Nenad Corbic Initial version based on cpipemon -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -#define GTI_WORD unsigned short - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ - -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) - -#define BANNER(str) banner(str,0) - -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ - - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ - -/* Global variables */ -extern int sock; -extern wan_udp_hdr_t wan_udp; -extern int protocol_cb_size; -extern int trace_all_data; -unsigned int loop_counter, frame_count; - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -extern int DoCommand(wan_udp_hdr_t*); -int ADSLMain(char*,int,char**); -int ADSLUsage(void); -int ADSLConfig(void); -int ADSLDisableTrace(void); - -/* Command routines */ -static void error(void); -static void link_status(void); -static void line_trace(unsigned char trace_opt); -static void failure_counters(void); -static void last_failed_status(void); -static void error_counters(void); -static void router_up_time(void); -static void adsl_baud_rate(void); -static void adsl_atm_config(void); - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int ADSLConfig( void ) -{ - char codeversion[10]; - unsigned char x; - - x = 0; - wan_udp.wan_udphdr_command = ADSL_TEST_DRIVER_RESPONSE; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xAA; - while (++x < 4){ - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - - if (wan_udp.wan_udphdr_return_code == 0xCC ) return(WAN_FALSE); - wan_udp.wan_udphdr_return_code = 0xAA; - } - - if (x >= 4) return(WAN_FALSE); - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = ADSL_READ_DRIVER_VERSION; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0){ - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - protocol_cb_size=sizeof(wan_mgmt_t) + sizeof(wan_cmd_t) + sizeof(wan_trace_info_t) + 1; - return WAN_TRUE; -} /* ObtainConfiguration */ - - -static void error( void ) -{ - printf("Error: Command failed!\n"); - printf("This command cannot execute during re-training/connecting!\n"); -}; /* error */ - - -static void remove_vendor_id (void) -{ - memset(&wan_udp.wan_udphdr_data[0],0,10); - wan_udp.wan_udphdr_command= ADSL_RMT_VENDOR_ID_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - int i; - - BANNER("REMOTE VENDOR"); - - printf(" Remote Vendor (hex): "); - for (i=0;i MAX_DECODE_NUM){ - printf(" Modulation:\t0x%x\n", - wan_udp.wan_udphdr_data[0]); - }else{ - printf(" Modulation:\t%s\n", - decode_modulation[wan_udp.wan_udphdr_data[0]]); - } - }else { - error(); - } - - -}; /* Link Status */ - -static void attenuation (void) -{ - wan_udp.wan_udphdr_command= ADSL_ATTENUATION_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("ATTENUATION"); - - printf(" Attenuation: %i dB\n", - wan_udp.wan_udphdr_data[0]); - } else { - error(); - } -}; /* Link Status */ - - - -static void signal_to_noise (void) -{ - wan_udp.wan_udphdr_command= ADSL_LCL_SNR_MARGIN; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("SIGNAL TO NOISE RATIO"); - - printf(" Local SNR Ratio : %i dB\n", - wan_udp.wan_udphdr_data[0]); - } else { - error(); - } - - wan_udp.wan_udphdr_command= ADSL_UPSTREAM_MARGIN_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - printf(" Remote SNR Ratio: %i dB\n", - wan_udp.wan_udphdr_data[0]); - } else { - error(); - } - - -}; /* Link Status */ - - -static void power_status(void) -{ - unsigned short *data_ptr; - wan_udp.wan_udphdr_command= ADSL_LCL_XMIT_POWER_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - data_ptr = (unsigned short*)&wan_udp.wan_udphdr_data[0]; - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("XMIT POWER STATUS"); - - printf(" Local Attenuation : %i dB\n", - data_ptr[0]); - - printf(" Local Num of Bins : %i\n", - data_ptr[1]); - - } else { - error(); - } - - wan_udp.wan_udphdr_command= ADSL_RMT_TX_POWER_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - data_ptr = (unsigned short*)&wan_udp.wan_udphdr_data[0]; - - if (wan_udp.wan_udphdr_return_code == 0) { - - printf(" Remote Num of bins: %i\n", - data_ptr[0]); - } else { - error(); - } -} - -static void last_failed_status (void) -{ - wan_udp.wan_udphdr_command= ADSL_LAST_FAILED_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("LAST FAILED STATUS"); - - printf(" Last failed status: 0x%x \n", - *((unsigned short*)&wan_udp.wan_udphdr_data[0])); - } else { - error(); - } -}; /* Link Status */ - - -static void failure_counters (void) -{ - int j; - wan_udp.wan_udphdr_command= ADSL_FAILURES; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - for(j=0;jstatus & 0x01) { - sprintf(outstr,"\nOUTGOING\t"); - } else { - if (trace_pkt->status & 0x10) { - sprintf(outstr,"\nINCOMING - Aborted\t"); - } else if (trace_pkt->status & 0x20) { - sprintf(outstr,"\nINCOMING - CRC Error\t"); - } else if (trace_pkt->status & 0x40) { - sprintf(outstr,"\nINCOMING - Overrun Error\t"); - } else { - sprintf(outstr,"\nINCOMING\t"); - } - } - - /* real length and time stamp */ - sprintf(outstr+strlen(outstr), "Len=%-5u\tTimestamp=%-5u\t", - trace_pkt->real_length, trace_pkt->time_stamp); - - /* first update curr_pos */ - curr_pos += sizeof(wan_trace_pkt_t); - if (trace_pkt->real_length >= WAN_MAX_DATA_SIZE){ - sprintf( outstr+strlen(outstr), "\t:the frame data is to big (%u)!", - trace_pkt->real_length); - }else if (trace_pkt->data_avail == 0) { - sprintf( outstr+strlen(outstr), "\t:the frame data is not available" ); - }else{ - /* update curr_pos again */ - curr_pos += trace_pkt->real_length; - - if (!trace_all_data){ - if (trace_opt != 2){ - num_chars = (unsigned char) - ((trace_pkt->real_length <= 53) - ? trace_pkt->real_length : 53); - }else{ - num_chars = (unsigned char) - ((trace_pkt->real_length <= 52) - ? trace_pkt->real_length : 52); - } - }else{ - num_chars = trace_pkt->real_length; - } - - count = 0; - sprintf(outstr+strlen(outstr),"\n\t\t"); - for( j=0; j40 && !(count%20)){ - sprintf(outstr+strlen(outstr),"\n\t\t"); - } - }else{ - if (count == 5){ - - /* - sprintf(outstr+strlen(outstr)," %x %x %x %x", - trace_pkt->data[j-3], - trace_pkt->data[j-2], - trace_pkt->data[j-1], - trace_pkt->data[j-0]); - */ - - sprintf(outstr+strlen(outstr),"\tVpi=%d", - trace_pkt->data[j-4]<<4 | - (trace_pkt->data[j-3]&0xF0)>>4); - - sprintf(outstr+strlen(outstr),"\tVci=%d", - (trace_pkt->data[j-3]&0x0F)<<12 | - (trace_pkt->data[j-2]<<4)| - (trace_pkt->data[j-1]&0xF0)>>4); - - - sprintf(outstr+strlen(outstr),"\n\t\t"); - count=20; - - }else if (count>20 && !(count%20)){ - sprintf(outstr+strlen(outstr),"\n\t\t"); - } - } - - sprintf(outstr+strlen(outstr), - "%02X ", - (unsigned char)trace_pkt->data[j]); - } - - if (num_chars < trace_pkt->real_length){ - sprintf(outstr+strlen(outstr),".. "); - } - - outstr[strlen(outstr)-1] = '\0'; - } - - printf("%s\n",outstr); - fflush(stdout); - } //for - }else{ - if (wan_udp.wan_udphdr_return_code != 0){ - printf("\n\nFailed to get trace data, exiting trace rc=0x%x!\n", - wan_udp.wan_udphdr_return_code); - break; - } - }//if - curr_pos = 0; - - if (wan_udp.wan_udphdr_adsl_ismoredata){ - to.tv_sec = 0; - to.tv_usec = 0; - }else{ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - } - }//for - - wan_udp.wan_udphdr_command= ADSL_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); -}; /* line_trace */ - - - - -static char *couter_names[] = { - "fec-I", - "fec-F", - "crc-I", - "crc-F", - "sef", - "l-los", - "ffec-I", - "ffec-F", - "febe-I", - "febe-F", - "rdi", - "f-los" -}; - - - -static void error_counters (void) -{ - int j; - wan_udp.wan_udphdr_command= ADSL_COUNTERS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - - - if (wan_udp.wan_udphdr_return_code == 0) { - - adsl_failures_t *adsl_failures= - (adsl_failures_t*)&wan_udp.wan_udphdr_data[0]; - - BANNER("ERROR COUNTERS"); - - printf("Errors CRC/Min: %04ld\tOverall Failures: %04ld\n", - adsl_failures->CrcErrorsPerMin, - adsl_failures->ExcessiveConsecutiveOverallFailureCount); - - printf("Execessive CRC/Tick: %04ld\tExcessive CRC/Min: %04ld\n\n", - adsl_failures->ExcessiveConsecutiveCrcErrorsPerTickCount, - adsl_failures->ExcessiveConsecutiveCrcErrorsPerMinCount); - - for(j=sizeof(adsl_failures_t);j11?"N/A": - couter_names[j-sizeof(adsl_failures_t)], - wan_udp.wan_udphdr_data[j]); - - printf("\t"); - - printf("Cnt %02i\t:\t%s\t%03i\n", - (int32_t)(j+1-sizeof(adsl_failures_t)), - (j+1-sizeof(adsl_failures_t))>11?"N/A": - couter_names[j+1-sizeof(adsl_failures_t)], - wan_udp.wan_udphdr_data[j+1]); - } - - } else { - error(); - } -}; /* Link Status */ - - -static void router_up_time( void ) -{ - u_int32_t time; - wan_udp.wan_udphdr_command= ADSL_ROUTER_UP_TIME; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - time = *(u_int32_t*)&wan_udp.wan_udphdr_data[0]; - - if (time < 3600) { - if (time<60) - printf(" Router UP Time: %u seconds\n", time); - else - printf(" Router UP Time: %u minute(s)\n", (time/60)); - }else - printf(" Router UP Time: %u hour(s)\n", (time/3600)); - -} - -static void actual_config (void) -{ - unsigned short *data_ptr; - adsl_cfg_t* adsl_cfg = NULL; - wan_udp.wan_udphdr_command= ADSL_ACTUAL_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - data_ptr = (unsigned short*)&wan_udp.wan_udphdr_data[0]; - adsl_cfg = (adsl_cfg_t*)&wan_udp.wan_udphdr_data[0]; - - BANNER("ACTUAL ADSL CONFIGURATION"); - - printf("Framing overhead : %i\n", adsl_cfg->adsl_framing); - printf("Trellis : %s\n", - (adsl_cfg->adsl_trellis) ? "Enabled":"Disabled"); - printf("\n"); - printf("AS0 bytes : %i\n", adsl_cfg->adsl_as0); - printf("AS0 latency buf : %s\n", - (adsl_cfg->adsl_as0_latency)?"Fast":"Interleave"); - printf("AS1 bytes : %i\n", adsl_cfg->adsl_as1); - printf("AS1 latency buf : %s\n", - (adsl_cfg->adsl_as1)?"Fast":"Interleave"); - printf("\n"); - printf("LS0 bytes : %i\n", adsl_cfg->adsl_ls0); - printf("LS0 latency buf : %s\n", - (adsl_cfg->adsl_ls0)?"Fast":"Interleave"); - printf("LS1 bytes : %i\n", adsl_cfg->adsl_ls1); - printf("LS1 latency buf : %s\n", - (adsl_cfg->adsl_ls1)?"Fast":"Interleave"); - printf("\n"); - - printf("Fast UP redundand bytes : %i\n", adsl_cfg->adsl_redundant_bytes); - printf("Intr UP S value bufs : %i\n", adsl_cfg->adsl_interleave_s_up); - printf("Interleave UP depth : %i\n", adsl_cfg->adsl_interleave_d_up); - printf("Intr UP redundant bufs : %i\n", adsl_cfg->adsl_interleave_r_up); - printf("\n"); - - printf("Fast DOWN redundand bytes : %i\n", adsl_cfg->adsl_fast_r_up); - printf("Intr DOWN S value bufs : %i\n", adsl_cfg->adsl_interleave_s_down); - printf("Interleave DOWN depth : %i\n", adsl_cfg->adsl_interleave_d_down); - printf("Intr DOWN redundant bufs : %i\n", adsl_cfg->adsl_interleave_r_down); - printf("\n"); - printf("Selected standard buf : %i\n", adsl_cfg->adsl_selected_standard); - -#if 0 - printf("Framing overhead : %i\n", data_ptr[GTI_FRAMING_OVERHEAD_ACTUAL]); - printf("Trellis : %s\n", - data_ptr[GTI_TRELLIS_ACTUAL] ? "Enabled":"Disabled"); - printf("\n"); - printf("AS0 bytes : %i\n",data_ptr[GTI_AS0_BYTES_ACTUAL]); - printf("AS0 latency buf : %s\n", - data_ptr[GTI_AS0_LATENCY_ACTUAL]?"Fast":"Interleave"); - printf("AS1 bytes : %i\n",data_ptr[GTI_AS1_BYTES_ACTUAL]); - printf("AS1 latency buf : %s\n", - data_ptr[GTI_AS0_LATENCY_ACTUAL]?"Fast":"Interleave"); - printf("\n"); - printf("LS0 bytes : %i\n",data_ptr[GTI_LS0_BYTES_ACTUAL]); - printf("LS0 latency buf : %s\n", - data_ptr[GTI_LS0_LATENCY_ACTUAL]?"Fast":"Interleave"); - printf("LS1 bytes : %i\n",data_ptr[GTI_LS1_BYTES_ACTUAL]); - printf("LS1 latency buf : %s\n", - data_ptr[GTI_LS0_LATENCY_ACTUAL]?"Fast":"Interleave"); - printf("\n"); - - printf("Fast UP redundand bytes : %i\n",data_ptr[GTI_FAST_R_UP_ACTUAL]); - printf("Intr UP S value bufs : %i\n",data_ptr[GTI_INTERLEAVE_S_UP_ACTUAL]); - printf("Interleave UP depth : %i\n",data_ptr[GTI_INTERLEAVE_D_UP_ACTUAL]); - printf("Intr UP redundant bufs : %i\n",data_ptr[GTI_INTERLEAVE_R_UP_ACTUAL]); - printf("\n"); - - printf("Fast DOWN redundand bytes : %i\n",data_ptr[GTI_FAST_R_DOWN_ACTUAL]); - printf("Intr DOWN S value bufs : %i\n",data_ptr[GTI_INTERLEAVE_S_DOWN_ACTUAL]); - printf("Interleave DOWN depth : %i\n",data_ptr[GTI_INTERLEAVE_D_DOWN_ACTUAL]); - printf("Intr DOWN redundant bufs : %i\n",data_ptr[GTI_INTERLEAVE_R_DOWN_ACTUAL]); - printf("\n"); - printf("Selected standard buf : %i\n",data_ptr[GTI_SELECTED_STANDARD_ACTUAL]); -#endif - return; -} - -static void interleave_status (void) -{ - wan_udp.wan_udphdr_command= ADSL_ACTUAL_INTERLEAVE_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - BANNER("INTERLEAVE STATUS"); - - printf("Status %i\n",*((unsigned short*)&wan_udp.wan_udphdr_data[0])); -} - -static void adsl_atm_counters( void ) -{ - atm_stats_t *atm_stats; - wan_udp.wan_udphdr_command= ADSL_ATM_CELL_COUNTER; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - atm_stats=(atm_stats_t*)&wan_udp.wan_udphdr_data[0]; - - BANNER("CHIP ATM CELL COUNTERS"); - - printf("Rx Chip : %i\n",atm_stats->rx_chip); - printf("Tx Chip : %i\n",atm_stats->tx_chip); - - BANNER("DRIVER RX ATM CELL COUNTERS"); - - printf("Valid Cells : %i\n",atm_stats->rx_valid); - printf("Idll Cells : %i\n",atm_stats->rx_empty); - printf("Invalid Atm Hdr : %i\n",atm_stats->rx_invalid_atm_hdr); - printf("Invalid Prot Hdr : %i\n",atm_stats->rx_invalid_prot_hdr); - printf("Invalid PDU Size : %i\n",atm_stats->rx_atm_pdu_size); - printf("Rx Congestion : %i\n",atm_stats->rx_congestion); - printf("Rx CLP Set : %i\n",atm_stats->rx_clp); - - BANNER("DRIVER TX ATM CELL COUNTERS"); - - printf("Valid Cells : %i\n",atm_stats->tx_valid); -} - - -static void adsl_baud_rate( void ) -{ - u_int32_t down, up,rxbuf,txbuf; - wan_udp.wan_udphdr_command= ADSL_BAUD_RATE; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - down = *(u_int32_t*)&wan_udp.wan_udphdr_data[0]; - up = *(u_int32_t*)&wan_udp.wan_udphdr_data[4]; - rxbuf=*(u_int32_t*)&wan_udp.wan_udphdr_data[8]; - txbuf=*(u_int32_t*)&wan_udp.wan_udphdr_data[12]; - - BANNER("ADSL BAUD RATE"); - - printf(" Down Rate: %i kbps : %s\n",down,rxbuf?"Fast Buf":"Interleave Buf"); - printf(" Up Rate: %i kbps : %s\n",up,txbuf?"Fast Buf":"Interleave Buf"); -} - -static void adsl_atm_config( void ) -{ - u_int32_t vpi,vci,mode; - wan_udp.wan_udphdr_command= ADSL_ATM_CONF; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - vpi = *(u_int32_t*)&wan_udp.wan_udphdr_data[0]; - vci = *(u_int32_t*)&wan_udp.wan_udphdr_data[4]; - mode = *(u_int32_t*)&wan_udp.wan_udphdr_data[8]; - - BANNER("ADSL ATM CONFIGURATION"); - - printf(" VPI: %i\n",vpi); - printf(" VCI: %i\n",vci); -} - -int ADSLUsage(void) -{ - printf("dslpipemon: Wanpipe ADSL Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("dslpipemon -i -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe network interface name (ex: wp1_adsl)\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: ls = Link Status\n\n"); - printf("\tSupported Commands: x=status : c=config : s=statistics \n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x l Link Status\n"); - printf("\t fs Last Failed Status\n"); - printf("\t ru Display Router UP time\n"); - printf("\tCard Configuration\n"); - printf("\t c atm ATM Configuration\n"); - printf("\t b Baud Rate\n"); - printf("\t ac Actual Config\n"); - printf("\t is Interleave Status\n"); - printf("\t rvi Remote vendor id\n"); - printf("\tCard Statistics\n"); - printf("\t s snr Signal to noise ratio\n"); - printf("\t a Attenuation\n"); - printf("\t ec Error Counters\n"); - printf("\t acc Atm Cell Counters\n"); - printf("\t ps Xmit Power Status\n"); - printf("\tLine Trace\n"); - printf("\t t r Raw Hex trace, Layer 3 network packets\n"); - printf("\t rl2 Raw Hex trace, Layer 2 ATM PDU packets\n"); - printf("\t rl1 Raw Hex trace, Layer 1 ATM Cells\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: dslpipemon -i wp1_adsl -c xl :View Link Status \n"); - printf("\tex: dslpipemon -i wp1_adsl -c cb :View Baud Rate\n"); - printf("\tex: dslpipemon -i wp1_adsl -c sec :View Error Counters\n\n"); - return 0; -} - -static char *gui_main_menu[]={ -"card_stats_menu","Card Status", -"card_config_menu","Card Configuration", -"stats_menu", "Card Statistics", -"trace_menu", "Trace Data", -"." -}; - -static char *card_stats_menu[]={ -"xl","Link Status", -"xfs","Last Failed Status", -"xru","Display Router UP time", -"." -}; - -static char *card_config_menu[]={ -"catm","ATM Configuration", -"cb","Baud Rate", -"cac","Actual Config", -"cis","Interleave Status", -"crvi", "Remote Vendor Id", -"." -}; - -static char *stats_menu[]={ -"ssnr","Signal to noise ratio", -"sa","Attenuation", -"sec","Error Counters", -"sacc","Atm Cell Counters", -"sps","Xmit Power Status", -"." -}; - -static char *trace_menu[]={ -"tr","Raw Hex trace, Layer 3 packets", -"trl2","Raw Hex trace, Layer 2 ATM-PDU packets", -"trl1","Raw Hex trace, Layer 1 ATM Cell packets", -"." -}; - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"card_stats_menu",card_stats_menu}, - {"card_config_menu",card_config_menu}, - {"stats_menu",stats_menu}, - {"trace_menu",trace_menu}, - {".",NULL} -}; - - -char ** ADSLget_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** ADSLget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - - - -int ADSLMain(char* command, int argc, char* argv[]) -{ - char* opt = &command[1]; - - switch(command[0]){ - - case 'x': - if (!strcmp(opt,"l")){ - link_status(); - }else if (!strcmp(opt,"ru")){ - router_up_time(); - }else if (!strcmp(opt,"fs")){ - last_failed_status(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type wanpipemon for help\n\n"); - } - break; - case 'c': - if (!strcmp(opt,"atm")){ - adsl_atm_config(); - }else if (!strcmp(opt,"b")){ - adsl_baud_rate(); - }else if (!strcmp(opt,"ac")){ - actual_config(); - }else if (!strcmp(opt,"is")){ - interleave_status(); - }else if (!strcmp(opt,"rvi")){ - remove_vendor_id(); - }else{ - printf("ERROR: Invalid Status Command 'c', Type wanpipemon for help\n\n"); - } - break; - - case 's': - if (!strcmp(opt,"ec")){ - error_counters(); - }else if (!strcmp(opt,"fc")){ - failure_counters(); - }else if (!strcmp(opt,"snr")){ - signal_to_noise(); - }else if (!strcmp(opt,"ps")){ - power_status(); - }else if (!strcmp(opt,"a")){ - attenuation(); - }else if (!strcmp(opt,"acc")){ - adsl_atm_counters(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type wanpipemon for help\n\n"); - } - break; - - case 't': - if (!strcmp(opt, "r")){ - line_trace(0); - - }else if (!strcmp(opt, "rl2")){ - line_trace(1); - - }else if (!strcmp(opt, "rl1")){ - line_trace(2); - - }else{ - printf("ERROR: Invalid Statistics Command 't', Type wanpipemon for help\n\n"); - - } - break; - - default: - printf("ERROR: Invalid Command, Type wanpipemon for help\n\n"); - break; - }//switch - - return 0; -}; //main diff --git a/util/wanpipemon.old/dslpipemon.o b/util/wanpipemon.old/dslpipemon.o deleted file mode 100644 index cac3028f5cc357c9ae9ef14312a960c5fb6e5479..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19996 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®>SwgW)pu!61Kbw{zQtP`<~!#p8X7-0HQ&{EeRV zUVV4h7zl;d#o82Q>+$MkUg-IFi>1Q2eA?h^G~e|b@va}h3ss|jH&Gsaf!E0UrHJz4 zmBWj>z{IZ{W|ii>&4n%w^Q+4W6#mSc&%cGZ10~GSvcfrYOlGFd#V(4px!7B)%jVD1 ze-~;|(TygUY@RN>Kx>yX4zVL_V%* zEYG!w_z@8s&{<&m4G0*M%r^!|K3@3egnxk?`L7XvouuC&e2%0q5WZN_%Y?6x^jhJo zh2Ji`i5&H}2oFknL^#(3*3Zv?Y2Vj`_X>ZI9OWMt{%?}bb(i^{5dH(<{lcFU{yaI# z4+#IIq`xNoP2s;2{zu^_g?}LYwD5DnM`3QW{;@#ncL=|N9PPPE__e}k2+tQjS9r1T zn}t^j|Dy0Za_C2=vujH`zJHj6q{(a&9 zDSVG`e!xY2$ArHv>3a4nGK zn}xR%Vb4ENJ{$iXD4hFzdI5fmCrAB{2|gw1{gVC@k-s4FUr-Led_s=<{ux-n({aGf z15!_sV2NOb;0hq^S|xmqV54A*U{H|f3g-W^@a;tO!%oU!_v7R^U+yNyfqcKD|C}85 zy(Hr2g$K0 z)!==A^80|4ujUyLcHIu7-5zq-y_p>LY(v}FzQYL2|6RN%u>9|Vgg1|g&g*6C5L_6$&r7jq(3g{yCwYt zNk1*=&Pz>wbBUKLwUh|EsswKlyiKqXNV|N(ze0pP9h76d-Y4?=MgDEUM+JW*_+udb z@H6r}_)+keg1-^`Es*uSE&P<=X(H<7O9Ay<0;HZx1uqwzA~+35Ju`(b5L`)wo;o1) zvLcZ2XQ!CoTtZ(}<2JSKcM@$=Y!1z!^R8-gc@ zU%=goU}lcVClS$}DT31l^91J!-UOsQE67oQE%|KRp-B4eBKJ~Wpp;+aZ6eCtGX2E-b^yhuTA0fhy zM=6K??}?oM0#5mlDTn@_lVg2&i5%<6QAz(j5r?(+1V1LizO)G@W(i&<_<6x8K-w`) z_);SDFQXjw)sv(CJBhe=xl1rcg#OKfU4ngr4+5$8o5FV!q30RO(Z0PRKOpj#C`Wz2 zCP)3p$kD!cCH*uJ7Y1WKXX=?i#6`dq!RrMpBz+apQ0flBR>4jp^lt%D|2N5D*MAVF zDz!&&K=3sp+WCgyalsRUrvyI&vb~=OPsiDrD#dsF!T2%ZxB zi==bUp}rjAG^Gr|*+keqUvRNtrC^O3@;*b0Qywy@mR+ zi0o(KlZhxl70B{=MA%V8Ir7~^M7eTFuM%D>>1%{H5uv9ANIgMGk4gI7BJUL5Bk2za z-%g}IfZ88K`h#-%L(&gP`u`F6t0F%p^0!4E7x@Pw|EtIq_EOf91!O&!6H(7(%2CfW zNuMR@b46Y(@-mUH5cw@4zfI(Bk++KcA4UF8MAXwI>Aghwb(^F=CVV&1iSF~Q#p#(^A{XUL)VQ*w;U44e^IejE|B zq36qjUlr^X+zMp<-w^&J5%v9$a@f%?@}Cf)_ptC+m=1eh7k*6A{~-K-CH>FB$A8|m z<8wslpG-qa@bu*ME=`}$R8EH3CR2%KH;KGMaEssrg5LnLzU{&v7kr9{di$9U{a4{^K!06Jg!~2|<%`MDk1K?KNw{Bl zFFD%#kl?ok9~0aKWc@!7J|K8P@RZ;gL0;@o-)JDqjT8QP;!XJGoCtevU^>R@d`Vv{ zxJ+;*(@SuU$HVsE^-m*Svozv0MPrU2whhfO{4^SZn4+5J3eFOQYqY#b@J2ya$@-QE zt`+nOwh9IW+XSP6?Sh*HI|RD~w+QYK{CB}!f=>!QE%+nBX9f2O?iV~H_=4cef=7t( z^XtNo3jeL} -* Alex Feldman -* -* 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. -* ---------------------------------------------------------------------------- -* Jan 11, 2005 David Rokhvarg Added code to run above AFT card with protocol -* in the LIP layer. Fixed many not working options. -* May 24, 2000 Gideon Hack Modifications for FT1 adapters -* Sep 21, 1999 Nenad Corbic Changed the input parameters, hearders -* data types. More user friendly. -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include "unixio.h" -#if defined(__LINUX__) -# include -# include -# include -#else -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#define TIMEOUT 1 -#define NUM_OF_DS3_CHANNELS 672 -#define MDATALEN 2024 - -#define CB_SIZE sizeof(wan_mgmt_t) + sizeof(wan_cmd_t) + 1 - -#if 0 -#define CALL_CSU_DSU_FUNC(name) if (wan_protocol == WANCONFIG_CHDLC){ \ - CHDLC_##name(); \ - }else if (wan_protocol==WANCONFIG_FR || wan_protocol==WANCONFIG_MFR){ \ - FR_##name(); \ - }else if (wan_protocol==WANCONFIG_PPP){ \ - PPP_##name(); \ - } -#endif - -static void hw_set_lb_modes(unsigned char type, unsigned char mode); -static int hw_get_fe_type(unsigned char* adapter_type); - -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ - - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -extern unsigned char par_port_A_byte; -extern unsigned char par_port_B_byte; -extern int gfail; -extern FT1_LED_STATUS FT1_LED; -extern int wan_protocol; -extern wan_udp_hdr_t wan_udp; - -/****************************************************************************** - * GUI MENU DEFINITION * - *****************************************************************************/ - - -char *csudsu_menu[]={ -"","-- TE3/TE1/56K (S514-4-5-7-8/AFT) Stats --", -""," ", -"Ta","Read TE3/TE1/56K alarms", -"Tallb","E Line Loopback", -"Tdllb","D Line Loopback", -"Taplb","E Payload Loopback", -"Tdplb","D Payload Loopback", -"Tadlb","E Diag Digital Loopback", -"Tddlb","D Diag Digital Loopback", -"Tsalb","Send Loopback Activate Code", -"Tsdlb","Send Loopback Deactive Code", -"Tread","Read CSU/DSU cfg", -""," ", -"","--- FT1 (S508/S5143) Stats ----", -""," ", -"Tv","View Status", -"Ts","Self Test", -"Tl","Line Loop Test", -"Td","Digital Loop Test", -"Tr","Remote Test", -"To","Operational Mode", -"Tread","Read CSU/DSU cfg", -"." -}; - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -/* Display the status of all the lights */ -void view_FT1_status( void ) -{ - int FT1_LED_read_count = 0; - int key; - struct timeval to; - long curr_sec; - - printf("The FT1 status is depicted by the eight LEDs shown below. "); - printf("LED colours are: \n"); - printf(" R=Red G=Green O=Orange Blank=Off\n"); - - printf("INS (In-service) :solid green=unit is in service, "); - printf("flashing red=red alarm,\n"); - printf(" flashing orange=yellow alarm, "); - printf("flashing green=blue alarm\n"); - - printf("ERR (Error) :off=no line errors, "); - printf("red=Severely Errored Seconds,\n"); - printf(" orange=Bursty Errored Seconds, "); - printf("green=Errored Seconds\n"); - - printf("TxD (Transmit Data):flashing green=transmit data is present\n"); - - printf("RxD (Receive Data) :flashing green=receive data is present\n"); - - printf("ST (Self Test) Note: line must be disconnected for this test.\n"); - printf(" off=Self Test not selected, "); - printf("flashing red=awaiting result of\n"); - printf(" Self Test, flashing green=test passed\n"); - - printf("DL (Digital Loop) :off=Digital Loop not selected, "); - printf("flashing red=Digital Loop\n"); - printf(" selected\n"); - - printf("LL (Local Loop) :off=Local Loop not selected, "); - printf("flashing red=Local Loop\n"); - printf(" selected\n"); - - printf("RT (Remote Test) Note: will only work if remote card is a Sangoma FT1 card.\n"); - printf(" off=Remote Test not selected, "); - printf("flashing red=awaiting response\n"); - printf(" from remote station, "); - printf("solid green=remote station running\n"); - printf(" test, flashing green=valid response received\n\n"); - - printf("Press to exit Press to change FT1 mode\n"); - printf("\n INS ERR TxD RxD ST DL LL RT\n"); - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - gettimeofday(&to, NULL); - curr_sec = to.tv_sec; - - /* loop and display the FT1 LEDs until the or key is hit */ - for(;;) { - if(kbdhit(&key)) { - /* hit, so change the FT1 mode */ - if(toupper((char)key) == 'M') { - /*set_FT1_mode(WAN_FALSE);*/ - EXEC_PROT_VOID_FUNC(set_FT1_mode,wan_protocol,()); - printf(" Current mode: "); - /* delay 1/10th sec to let FT1 settle down */ - usleep(100000); - gettimeofday(&to, NULL); - curr_sec = to.tv_sec; - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - } - /* hit, so exit */ - if((char)key == 0x1b) { - printf("\n\nChecking current FT1 status...\n"); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - /* read the FT1 status for 1.5 seconds to */ - /* find out if we are in-service */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - if((++ FT1_LED_read_count) == 30) { - break; - } - usleep(50000); - } - if(FT1_LED.ST_red || FT1_LED.ST_green || - FT1_LED.DL_red || FT1_LED.LL_red || - FT1_LED.RT_red || FT1_LED.RT_green) { - printf("The FT1 is not currently in the operational mode and the unit is not in-service.\n"); - printf("Do you wish to return to the operational mode? (Y/N)\n"); - fflush(stdout); - for(;;) { - kbdhit(&key); - if(toupper((char)key) == 'Y') { - FT1_operational_mode(); - break; - } - if(toupper((char)key) == 'N') { - break; - } - } - } - break; - } - } - - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - display_FT1_LEDs(); - /* update the current FT1 status at 1 second intervals */ - gettimeofday(&to, NULL); - if(curr_sec != to.tv_sec) { - curr_sec = to.tv_sec; - printf(" | Current mode: | "); - if(FT1_LED.ST_red || FT1_LED.ST_green) { - printf("Self Test "); - } else if(FT1_LED.DL_red) { - printf("Digital Loop"); - } else if(FT1_LED.LL_red) { - printf("Local Loop "); - } else if(FT1_LED.RT_red || FT1_LED.RT_green) { - printf("Remote Test "); - } else { - printf("In-service "); - } - //printf(" | "); - fflush(stdout); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - } - } - - printf("Preparing FT1 LED summary...\n"); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - - /* read the FT1 status for 2.0 seconds find the current LED settings */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - if((++ FT1_LED_read_count) == 40) { - break; - } - usleep(50000); - } - - printf("\nINS (In-service) : "); - if(FT1_LED.INS_green && !FT1_LED.INS_red && !FT1_LED.INS_off) { - printf("Solid Green - Unit is in service"); - } else if (FT1_LED.INS_red && !FT1_LED.INS_green && FT1_LED.INS_off) { - printf("Flashing Red - Red alarm"); - } else if (FT1_LED.INS_red && FT1_LED.INS_green && FT1_LED.INS_off) { - printf("Flashing Orange - Yellow alarm"); - } else if (FT1_LED.INS_green && !FT1_LED.INS_red && FT1_LED.INS_off) { - printf("Flashing Green - Blue alarm"); - } else { - printf("Unknown state - Red %u, Green %u, Off %u", - FT1_LED.INS_red, FT1_LED.INS_green, FT1_LED.INS_off); - } - - printf("\nERR (Error) : "); - if(!FT1_LED.ERR_green && !FT1_LED.ERR_red && FT1_LED.ERR_off) { - printf("Off - No line errors received"); - } else if(FT1_LED.ERR_red && !FT1_LED.ERR_green && !FT1_LED.ERR_off) { - printf("Solid Red - Severely Errored Seconds"); - } else if(FT1_LED.ERR_red && FT1_LED.ERR_green) { - printf("Orange - Bursty Errored Seconds"); - } else if(!FT1_LED.ERR_red && FT1_LED.ERR_green) { - printf("Green - Errored Seconds"); - } else { - printf("Unknown state - Red %u, Green %u, Off %u", - FT1_LED.ERR_red, FT1_LED.ERR_green, FT1_LED.ERR_off); - } - - printf("\nTxD (Transmit Data): "); - if(FT1_LED.TxD_green) { - printf("Flashing Green - Transmit data is present"); - } else { - printf("Off - Transmit data is not present"); - } - - printf("\nRxD (Receive Data) : "); - if(FT1_LED.RxD_green) { - printf("Flashing Green - Receive data is present"); - } else { - printf("Off - Receive data is not present"); - } - - printf("\nST (Self Test) : "); - if(!FT1_LED.ST_green && !FT1_LED.ST_red && FT1_LED.ST_off) { - printf("Off"); - } else if(FT1_LED.ST_red && !FT1_LED.ST_green && FT1_LED.ST_off) { - printf("Flashing Red - Awaiting confirmation of self test"); - } else if(FT1_LED.ST_green && !FT1_LED.ST_red && FT1_LED.ST_off) { - printf("Flashing Green - Self test has passed"); - } else { - printf("Unknown state - Red %u, Green %u, Off %u", - FT1_LED.ST_red, FT1_LED.ST_green, FT1_LED.ST_off); - } - - printf("\nDL (Digital Loop) : "); - if(!FT1_LED.DL_red && FT1_LED.DL_off) { - printf("Off"); - } else if (FT1_LED.DL_red && FT1_LED.DL_off) { - printf("Flashing Red - Bi-directional digital loop selected"); - } - else { - printf("Unknown state - Red %u, Off %u", - FT1_LED.DL_red, FT1_LED.DL_off); - } - - printf("\nLL (Local Loop) : "); - if(!FT1_LED.LL_red && FT1_LED.LL_off) { - printf("Off"); - } else if (FT1_LED.LL_red && FT1_LED.LL_off) { - printf("Flashing Red - Line loop selected"); - } - else { - printf("Unknown state - Red %u, Off %u", - FT1_LED.LL_red, FT1_LED.LL_off); - } - - printf("\nRT (Remote Test) : "); - if(!FT1_LED.RT_green && !FT1_LED.RT_red && FT1_LED.RT_off) { - printf("Off"); - } else if(FT1_LED.RT_red && !FT1_LED.RT_green && FT1_LED.RT_off) { - printf("Flashing Red - Awaiting response from remote station"); - } else if(FT1_LED.RT_green && !FT1_LED.RT_red && !FT1_LED.RT_off) { - printf("Solid Green - Remote station running test"); - } else if(FT1_LED.RT_green && !FT1_LED.RT_red && FT1_LED.RT_off) { - printf("Flashing Green - Valid response received"); - } else { - printf("Unknown state - Red %u, Green %u, Off %u", - FT1_LED.RT_red, FT1_LED.RT_green, FT1_LED.RT_off); - } - -}/* view_FT1_status */ - -void display_FT1_LEDs(void) -{ - - printf("\r| "); - - /* display INS LED */ - switch (par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - case (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED): - putchar(' '); - break; - case (!(PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)): - putchar('O'); - break; - case (PP_B_INS_NOT_GREEN): - putchar('R'); - break; - case (PP_B_INS_NOT_RED): - putchar('G'); - break; - default: - break; - } - - /* display ERR LED */ - printf(" | "); - switch (par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - case (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED): - putchar(' '); - break; - case (!(PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)): - putchar('O'); - break; - case (PP_B_ERR_NOT_GREEN): - putchar('R'); - break; - case (PP_B_ERR_NOT_RED): - putchar('G'); - break; - default: - break; - } - - /* display TxD LED */ - printf(" | "); - switch (par_port_B_byte & PP_B_TxD_NOT_GREEN) { - case (PP_B_TxD_NOT_GREEN): - putchar(' '); - break; - case (!PP_B_TxD_NOT_GREEN): - putchar('G'); - break; - default: - break; - } - - /* display RxD LED */ - printf(" | "); - switch (par_port_B_byte & PP_B_RxD_NOT_GREEN) { - case (PP_B_RxD_NOT_GREEN): - putchar(' '); - break; - case (!PP_B_RxD_NOT_GREEN): - putchar('G'); - break; - default: - break; - } - - /* display ST LED */ - printf(" | "); - switch (par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - case (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED): - putchar(' '); - break; - case (!(PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)): - putchar('O'); - break; - case (PP_B_ST_NOT_GREEN): - putchar('R'); - break; - case (PP_B_ST_NOT_RED): - putchar('G'); - break; - default: - break; - } - - /* display DL LED */ - printf(" | "); - switch (par_port_A_byte & PP_A_DL_NOT_RED) { - case (PP_A_DL_NOT_RED): - putchar(' '); - break; - case (!PP_A_DL_NOT_RED): - putchar('R'); - break; - default: - break; - } - - /* display LL LED */ - printf(" | "); - switch (par_port_A_byte & PP_A_LL_NOT_RED) { - case (PP_A_LL_NOT_RED): - putchar(' '); - break; - case (!PP_A_LL_NOT_RED): - putchar('R'); - break; - default: - break; - } - - /* display RT LED */ - printf(" | "); - switch (par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - case (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED): - putchar(' '); - break; - case (!(PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)): - putchar('O'); - break; - case (PP_A_RT_NOT_GREEN): - putchar('R'); - break; - case (PP_A_RT_NOT_RED): - putchar('G'); - break; - default: - break; - } - - fflush(stdout); -} - - - -void FT1_operational_mode(void) -{ - - int FT1_LED_read_count = 0; - int op_mode_search_count = 0; - - printf("\nSetting FT1 into operational mode..."); - fflush(stdout); - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - - /* change the FT1 mode at 1 second intervals until we enter the */ - /* operational (in-service) mode */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - usleep(50000); - if((++ FT1_LED_read_count) == 20) { - if(FT1_LED.ST_red || FT1_LED.ST_green || FT1_LED.DL_red - || FT1_LED.LL_red || FT1_LED.RT_red - || FT1_LED.RT_green) { - if((++ op_mode_search_count) == 10) { - printf("Failed"); - printf("\nCould not enter FT1 operational mode\n"); - if(remote_running_RT_test()) { - return; - } - printf("Please contact your Sangoma representative\n"); - return; - } - EXEC_PROT_VOID_FUNC(set_FT1_mode,wan_protocol,()); - /* delay 1/10th sec to let FT1 settle down */ - usleep(100000); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - } else { - printf("Done\n"); - break; - } - } - } - -} /* FT1_operational_mode */ - - -void FT1_self_test(void) -{ - - int FT1_LED_read_count = 0; - int ST_mode_search_count = 0; - - printf("\nSetting FT1 for Self Test mode..."); - fflush(stdout); - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - - /* change the FT1 mode at 1 second intervals until we enter ST mode */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - usleep(50000); - if((++ FT1_LED_read_count) == 20) { - if(!FT1_LED.ST_red) { - if((++ ST_mode_search_count) == 10) { - printf("Failed"); - printf("\nCould not enter Self Test mode\n"); - if(remote_running_RT_test()) { - return; - } - printf("Remove T1 connection from adapter and repeat the Self Test\n"); - FT1_operational_mode(); - return; - } - EXEC_PROT_VOID_FUNC(set_FT1_mode,wan_protocol,()); - /* delay 1/10th sec to let FT1 settle down */ - usleep(100000); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - } else { - printf("Done \nSelf Test started...\n"); - break; - } - } - } - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - - /* if the ST LED is not green within 6 seconds then we fail this test */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - if(FT1_LED.ST_green) { - printf("Self Test passed\n"); - break; - } - usleep(50000); - if((++ FT1_LED_read_count) == 120) { - printf("Self Test failed\n"); - printf("Please contact your Sangoma representative\n"); - break; - } - } - - FT1_operational_mode(); - -} /* FT1_self_test */ - - -void FT1_digital_loop_mode( void ) -{ - - int FT1_LED_read_count = 0; - int DL_mode_search_count = 0; - - printf("\nSetting FT1 for Bi-Directional Digital Loop mode..."); - fflush(stdout); - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - - /* change the FT1 mode at 1 second intervals until we enter DL mode */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - usleep(50000); - if((++ FT1_LED_read_count) == 20) { - if(!FT1_LED.DL_red) { - if((++ DL_mode_search_count) == 10) { - printf("Failed"); - printf("\nCould not enter Digital Loop mode\n"); - if(remote_running_RT_test()) { - return; - } - FT1_operational_mode(); - return; - } - EXEC_PROT_VOID_FUNC(set_FT1_mode,wan_protocol,()); - /* delay 1/10th sec to let FT1 settle down */ - usleep(100000); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - } else { - printf("Done"); - break; - } - } - } - - printf("\n\nIMPORTANT: This FT1 device is in the Digital Loop mode and is not in service.\n\n"); - -} /* FT1_digital_loop_mode */ - - -void FT1_local_loop_mode( void ) -{ - - int FT1_LED_read_count = 0; - int LL_mode_search_count = 0; - - printf("\nSetting FT1 for Local Loop mode..."); - fflush(stdout); - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - - /* change the FT1 mode at 1 second intervals until we enter LL mode */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - usleep(50000); - if((++ FT1_LED_read_count) == 20) { - if(!FT1_LED.LL_red) { - if((++ LL_mode_search_count) == 10) { - printf("Failed"); - printf("\nCould not enter Local Loop mode\n"); - if(remote_running_RT_test()) { - return; - } - printf("Remove T1 connection from adapter before entering the Local Loop mode\n"); - FT1_operational_mode(); - return; - } - EXEC_PROT_VOID_FUNC(set_FT1_mode,wan_protocol,()); - /* delay 1/10th sec to let FT1 settle down */ - usleep(100000); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - } else { - printf("Done"); - break; - } - } - } - - printf("\n\nIMPORTANT: This FT1 device is in the Local Loop mode and is not in service.\n\n"); - -} /* FT1_local_loop_mode */ - -void FT1_remote_test( void ) -{ - - int FT1_LED_read_count = 0; - int RT_mode_search_count = 0; - - printf("\nSetting FT1 for Remote Test mode..."); - fflush(stdout); - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - - /* change the FT1 mode at 1 second intervals until we enter RT mode */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - usleep(50000); - if((++ FT1_LED_read_count) == 20) { - if(!FT1_LED.RT_red) { - if((++ RT_mode_search_count) == 10) { - printf("Failed"); - printf("\nCould not enter Remote Test mode\n"); - if(remote_running_RT_test()) { - return; - } - printf("Please contact your Sangoma representative\n"); - FT1_operational_mode(); - return; - } - EXEC_PROT_VOID_FUNC(set_FT1_mode,wan_protocol,()); - /* delay 1/10th sec to let FT1 settle down */ - usleep(100000); - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - } else { - printf("Done \nRemote Test started..."); - fflush(stdout); - break; - } - } - } - - /* delay 10 seconds after starting the RT before checking the result */ - for(FT1_LED_read_count = 0; FT1_LED_read_count < 10; - FT1_LED_read_count ++) { - usleep(1000000); - printf("."); - fflush(stdout); - } - - memset(&FT1_LED, 0, sizeof(FT1_LED_STATUS)); - FT1_LED_read_count = 0; - - /* the RT LED must be flashing green to pass this test, so read the */ - /* RT LEDs for the next 2 seconds to get the test result */ - for(;;) { - EXEC_PROT_VOID_FUNC(read_FT1_status,wan_protocol,()); - if(FT1_LED.RT_green && FT1_LED.RT_off) { - printf("\nRemote Test passed\n"); - break; - } - usleep(50000); - if((++ FT1_LED_read_count) == 40) { - printf("\nRemote Test failed\n"); - printf("Please ensure that the remote CSU/DSU is a Sangoma FT1 card.\n"); - break; - } - } - - FT1_operational_mode(); - -} /* FT1_remote_test */ - - - -int remote_running_RT_test(void) -{ - /* if the RT LED is on solid green, then the remote end is running */ - /* the RT test */ - if(FT1_LED.RT_green && !FT1_LED.RT_off) { - printf("\nThe remote Sangoma card is running the Remote Test\n"); - printf("Exit the Remote Test at the remote end\n\n"); - return(1); - } - return(0); -} - -int get_fe_type(unsigned char* adapter_type) -{ - int rc; - - if(make_hardware_level_connection()){ - return 0; - } - rc = hw_get_fe_type(adapter_type); - - cleanup_hardware_level_connection(); - - return rc; -} - -static int hw_get_fe_type(unsigned char* adapter_type) -{ - /* Read Adapter Type */ - wan_udp.wan_udphdr_command = WAN_GET_MEDIA_TYPE; - wan_udp.wan_udphdr_data[0] = WAN_MEDIA_NONE; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("Failed to read Adapter Type.\n"); - return 1; - } -#if 0 - if (wan_protocol == WANCONFIG_CHDLC){ - *adapter_type = wan_udp.wan_udphdr_chdlc_data[0]; - }else{ - *adapter_type = wan_udp.wan_udphdr_data[0]; - } -#endif - - *adapter_type = get_wan_udphdr_data_byte(0); - return 0; -} - -void set_lb_modes(unsigned char type, unsigned char mode) -{ - if(make_hardware_level_connection()){ - return; - } - hw_set_lb_modes(type, mode); - - cleanup_hardware_level_connection(); -} - -static void hw_set_lb_modes(unsigned char type, unsigned char mode) -{ - wan_udp.wan_udphdr_command = WAN_FE_SET_LB_MODE; - wan_udp.wan_udphdr_data_len = 2; - wan_udp.wan_udphdr_return_code = 0xaa; - - set_wan_udphdr_data_byte(0,type); - set_wan_udphdr_data_byte(1,mode); - -#if 0 - if (wan_protocol == WANCONFIG_CHDLC){ - wan_udp.wan_udphdr_chdlc_data[0] = type; - wan_udp.wan_udphdr_chdlc_data[1] = mode; - }else{ - wan_udp.wan_udphdr_data[0] = type; - wan_udp.wan_udphdr_data[1] = mode; - } -#endif - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("Failed to %s line loopback mode.\n", - (mode == WAN_TE1_ACTIVATE_LB) ? "activate" : "deactivate"); - }else{ - printf("%s mode is %s!\n", - WAN_TE1_LB_TYPE_DECODE(type), - (mode == WAN_TE1_ACTIVATE_LB) ? "activated" : "deactivated"); - } - return; -} - -void read_te1_56k_stat(int force) -{ - sdla_fe_stats_t *fe_stats; - //unsigned char* data = NULL; - unsigned char adapter_type = 0x00; - - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } - - if(make_hardware_level_connection()){ - return; - } - - /* Read T1/E1/56K alarms and T1/E1 performance monitoring counters */ - wan_udp.wan_udphdr_command = WAN_FE_GET_STAT; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fe_force = force; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("Failed to read T1/E1/56K statistics.\n"); - cleanup_hardware_level_connection(); - return; - } - -#if 0 - if (wan_protocol == WANCONFIG_CHDLC){ - data = &wan_udp.wan_udphdr_chdlc_data[0]; - }else{ - data = &wan_udp.wan_udphdr_data[0]; - } -#endif - fe_stats = (sdla_fe_stats_t*)get_wan_udphdr_data_ptr(0); - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - printf("***** %s: %s Alarms (Framer) *****\n\n", - if_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); - printf("ALOS:\t%s\t| LOS:\t%s\n", - WAN_TE_ALOS_ALARM(fe_stats->alarms), - WAN_TE_LOS_ALARM(fe_stats->alarms)); - printf("RED:\t%s\t| AIS:\t%s\n", - WAN_TE_RED_ALARM(fe_stats->alarms), - WAN_TE_AIS_ALARM(fe_stats->alarms)); - if (adapter_type == WAN_MEDIA_T1){ - printf("YEL:\t%s\t| OOF:\t%s\n", - WAN_TE_YEL_ALARM(fe_stats->alarms), - WAN_TE_OOF_ALARM(fe_stats->alarms)); - }else{ - printf("OOF:\t%s\t| RAI:\t%s\n", - WAN_TE_OOF_ALARM(fe_stats->alarms), - WAN_TE_RAI_ALARM(fe_stats->alarms)); - } - - if (fe_stats->liu_alarms & WAN_TE_BIT_LIU_ALARM){ - printf("\n***** %s: %s Alarms (LIU) *****\n\n", - if_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); - printf("Short Circuit:\t%s\n", - WAN_TE_LIU_ALARM_SC(fe_stats->liu_alarms)); - printf("Open Circuit:\t%s\n", - WAN_TE_LIU_ALARM_OC(fe_stats->liu_alarms)); - printf("Loss of Signal:\t%s\n", - WAN_TE_LIU_ALARM_LOS(fe_stats->liu_alarms)); - } - - }else if (adapter_type == WAN_MEDIA_DS3 || adapter_type == WAN_MEDIA_E3){ - printf("***** %s: %s Alarms *****\n\n", - if_name, (adapter_type == WAN_MEDIA_DS3) ? "DS3" : "E3"); - - if (adapter_type == WAN_MEDIA_DS3){ - printf("AIS:\t%s\t| LOS:\t%s\n", - WAN_TE3_AIS_ALARM(fe_stats->alarms), - WAN_TE3_LOS_ALARM(fe_stats->alarms)); - - printf("OOF:\t%s\t| YEL:\t%s\n", - WAN_TE3_OOF_ALARM(fe_stats->alarms), - WAN_TE3_YEL_ALARM(fe_stats->alarms)); - }else{ - printf("AIS:\t%s\t| LOS:\t%s\n", - WAN_TE3_AIS_ALARM(fe_stats->alarms), - WAN_TE3_LOS_ALARM(fe_stats->alarms)); - - printf("OOF:\t%s\t| YEL:\t%s\n", - WAN_TE3_OOF_ALARM(fe_stats->alarms), - WAN_TE3_YEL_ALARM(fe_stats->alarms)); - - printf("LOF:\t%s\t\n", - WAN_TE3_LOF_ALARM(fe_stats->alarms)); - } - - }else if (adapter_type == WAN_MEDIA_56K){ - printf("***** %s: 56K CSU/DSU Alarms *****\n\n\n", if_name); - printf("In Service:\t\t%s\tData mode idle:\t\t%s\n", - INS_ALARM_56K(fe_stats->alarms), - DMI_ALARM_56K(fe_stats->alarms)); - - printf("Zero supp. code:\t%s\tCtrl mode idle:\t\t%s\n", - ZCS_ALARM_56K(fe_stats->alarms), - CMI_ALARM_56K(fe_stats->alarms)); - - printf("Out of service code:\t%s\tOut of frame code:\t%s\n", - OOS_ALARM_56K(fe_stats->alarms), - OOF_ALARM_56K(fe_stats->alarms)); - - printf("Valid DSU NL loopback:\t%s\tUnsigned mux code:\t%s\n", - DLP_ALARM_56K(fe_stats->alarms), - UMC_ALARM_56K(fe_stats->alarms)); - - printf("Rx loss of signal:\t%s\t\n", - RLOS_ALARM_56K(fe_stats->alarms)); - - }else{ - printf("***** %s: Unknown Front End 0x%X *****\n\n", - if_name, adapter_type); - } - - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - sdla_te_pmon_t* pmon = &fe_stats->te_pmon; - - printf("\n\n***** %s: %s Performance Monitoring Counters *****\n\n", - if_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); - if (pmon->mask & WAN_TE_BIT_PMON_LCV){ - printf("Line Code Violation\t: %d\n", - pmon->lcv_errors); - } - if (pmon->mask & WAN_TE_BIT_PMON_BEE){ - printf("Bit Errors (CRC6/Ft/Fs)\t: %d\n", - pmon->bee_errors); - } - if (pmon->mask & WAN_TE_BIT_PMON_OOF){ - printf("Out of Frame Errors\t: %d\n", - pmon->oof_errors); - } - if (pmon->mask & WAN_TE_BIT_PMON_FEB){ - printf("Far End Block Errors\t: %d\n", - pmon->feb_errors); - } - if (pmon->mask & WAN_TE_BIT_PMON_CRC4){ - printf("CRC4 Errors\t\t: %d\n", - pmon->crc4_errors); - } - if (pmon->mask & WAN_TE_BIT_PMON_FER){ - printf("Framing Bit Errors\t: %d\n", - pmon->fer_errors); - } - if (pmon->mask & WAN_TE_BIT_PMON_FAS){ - printf("FAS Errors\t\t: %d\n", - pmon->fas_errors); - } - } - - if (adapter_type == WAN_MEDIA_DS3 || adapter_type == WAN_MEDIA_E3){ - sdla_te3_pmon_t* pmon = &fe_stats->u.te3_pmon; - - printf("\n\n***** %s: %s Performance Monitoring Counters *****\n\n", - if_name, (adapter_type == WAN_MEDIA_DS3) ? "DS3" : "E3"); - - printf("Framing Bit Error:\t%d\tLine Code Violation:\t%d\n", - pmon->pmon_framing, - pmon->pmon_lcv); - - if (adapter_type == WAN_MEDIA_DS3){ - printf("Parity Error:\t\t%d\n", - pmon->pmon_parity); - printf("CP-Bit Error Event:\t%d\tFEBE Event:\t\t%d\n", - pmon->pmon_cpbit, - pmon->pmon_febe); - }else{ - printf("Parity Error:\t%d\tFEBE Event:\t\t%d\n", - pmon->pmon_parity, - pmon->pmon_febe); - } - } - - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - if (strlen(fe_stats->u.te1_stats.rxlevel)){ - printf("\n\nRx Level\t: %s\n", - fe_stats->u.te1_stats.rxlevel); - } - } - - cleanup_hardware_level_connection(); - return; -} - -void flush_te1_pmon(void) -{ - unsigned char adapter_type = 0x00; - - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } - - if(make_hardware_level_connection()){ - return; - } - - switch(adapter_type){ - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - /* Flush perfomance mononitoring counters */ - wan_udp.wan_udphdr_command = WAN_FE_FLUSH_PMON; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("Failed to flush Perfomance Monitoring counters.\n"); - cleanup_hardware_level_connection(); - return; - } - break; - } - - printf("\nDSU/CSU Perfomance Monitoring counters were flushed.\n"); - cleanup_hardware_level_connection(); - return; -} - - -void read_te1_56k_config (void) -{ - unsigned char adapter_type = 0x00; - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } - - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - int num_of_chan = (adapter_type == WAN_MEDIA_T1) ? - NUM_OF_T1_CHANNELS : - NUM_OF_E1_TIMESLOTS; - int i = 0, start_chan = 0; - - if(make_hardware_level_connection()){ - return; - } - - /* T1/E1 card */ - wan_udp.wan_udphdr_command = WAN_FE_GET_CFG; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("CSU/DSU Read Configuration Failed"); - }else{ - sdla_fe_cfg_t *fe_cfg = NULL; - - fe_cfg = (sdla_fe_cfg_t *)get_wan_udphdr_data_ptr(0); -#if 0 - if (wan_protocol == WANCONFIG_CHDLC){ - te_cfg = (sdla_te_cfg_t *)&wan_udp.wan_udphdr_chdlc_data[0]; - }else{ - te_cfg = (sdla_te_cfg_t *)&wan_udp.wan_udphdr_data[0]; - } -#endif - printf("CSU/DSU %s Configuration:\n", if_name); - printf("\tMedia type\t%s\n", - MEDIA_DECODE(fe_cfg)); - printf("\tFraming\t\t%s\n", - FRAME_DECODE(fe_cfg)); - printf("\tEncoding\t%s\n", - LCODE_DECODE(fe_cfg)); - if (adapter_type == WAN_MEDIA_T1){ - printf("\tLine Build\t%s\n", - LBO_DECODE(fe_cfg)); - } - printf("\tChannel Base\t"); - for (i = 0, start_chan = 0; i < num_of_chan; i++){ - if (fe_cfg->cfg.te_cfg.active_ch & (1 << i)){ - if (!start_chan){ - start_chan = i+1; - } - //printf("%d ", i+1); - }else{ - if (start_chan){ - if (start_chan != i + 1){ - printf("%d-%d ", start_chan, i); - }else{ - printf("%d ", start_chan); - } - start_chan = 0; - } - } - } - if (start_chan){ - if (start_chan != num_of_chan){ - printf("%d-%d ", start_chan, num_of_chan); - }else{ - printf("%d ", start_chan); - } - } - printf("\n"); - printf("\tClock Mode\t%s\n", - TECLK_DECODE(fe_cfg)); - } - } - else if (adapter_type == WAN_MEDIA_DS3){ - - if(make_hardware_level_connection()){ - return; - } - - /* DS3 card */ - wan_udp.wan_udphdr_command = WAN_FE_GET_CFG; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("CSU/DSU Read Configuration Failed"); - }else{ - sdla_fe_cfg_t *fe_cfg = NULL; - - fe_cfg = (sdla_fe_cfg_t *) get_wan_udphdr_data_ptr(0); - - printf("CSU/DSU %s Configuration:\n", if_name); - printf("\tMedia type\t%s\n", - MEDIA_DECODE(fe_cfg)); - printf("\tFraming\t\t%s\n", - FRAME_DECODE(fe_cfg)); - printf("\tEncoding\t%s\n", - LCODE_DECODE(fe_cfg)); - printf("\tClock Mode\t%s\n", (fe_cfg->cfg.te3_cfg.clock == WAN_NORMAL_CLK) ? "Normal": (fe_cfg->cfg.te3_cfg.clock == WAN_MASTER_CLK) ? "Master" : "Unknown"); - } - } - cleanup_hardware_level_connection(); - return; -} - -void set_debug_mode(unsigned char type, unsigned char mode) -{ - sdla_fe_debug_t fe_debug; - - fe_debug.type = type; - fe_debug.mode = mode; - set_fe_debug_mode(&fe_debug); -} - -void set_fe_debug_mode(sdla_fe_debug_t *fe_debug) -{ - int err = 0; - unsigned char *data = NULL; - - if(make_hardware_level_connection()){ - return; - } - wan_udp.wan_udphdr_command = WAN_FE_SET_DEBUG_MODE; - wan_udp.wan_udphdr_data_len = sizeof(sdla_fe_debug_t); - wan_udp.wan_udphdr_return_code = 0xaa; - - data = get_wan_udphdr_data_ptr(0); - memcpy(data, (unsigned char*)fe_debug, sizeof(sdla_fe_debug_t)); - -#if 0 - if (wan_protocol == WANCONFIG_CHDLC){ - wan_udp.wan_udphdr_chdlc_data[0] = type; - wan_udp.wan_udphdr_chdlc_data[1] = mode; - }else{ - wan_udp.wan_udphdr_data[0] = type; - wan_udp.wan_udphdr_data[1] = mode; - } -#endif - err = DO_COMMAND(wan_udp); - if (fe_debug->type == WAN_FE_DEBUG_REG && fe_debug->fe_debug_reg.read == 1){ - if (err == 0 && wan_udp.wan_udphdr_return_code == 0){ - int cnt = 0; - printf("Please wait.");fflush(stdout); -repeat_read_reg: - wan_udp.wan_udphdr_return_code = 0xaa; - fe_debug->fe_debug_reg.read = 2; - memcpy(data, (unsigned char*)fe_debug, sizeof(sdla_fe_debug_t)); - usleep(100000); - err = DO_COMMAND(wan_udp); - if (err || wan_udp.wan_udphdr_return_code != 0){ - if (cnt < 5){ - printf(".");fflush(stdout); - goto repeat_read_reg; - } - } - printf("\n\n"); - } - } - - if (err || wan_udp.wan_udphdr_return_code != 0){ - if (fe_debug->type == WAN_FE_DEBUG_RBS){ - printf("Failed to %s mode.\n", - WAN_FE_DEBUG_RBS_DECODE(fe_debug->mode)); - }else{ - printf("Failed to execute debug mode (%02X).\n", - fe_debug->type); - } - }else{ - fe_debug = (sdla_fe_debug_t*)get_wan_udphdr_data_ptr(0); - switch(fe_debug->type){ - case WAN_FE_DEBUG_RBS: - if (fe_debug->mode == WAN_FE_DEBUG_RBS_READ){ - printf("Read RBS status is suceeded!\n"); - }else if (fe_debug->mode == WAN_FE_DEBUG_RBS_SET){ - printf("Setting ABCD bits (%X) for channel %d is suceeded!\n", - fe_debug->fe_debug_rbs.abcd, - fe_debug->fe_debug_rbs.channel); - }else{ - printf("%s debug mode!\n", - WAN_FE_DEBUG_RBS_DECODE(fe_debug->mode)); - } - break; - case WAN_FE_DEBUG_ALARM: - printf("%s AIS alarm!\n", - WAN_FE_DEBUG_ALARM_DECODE(fe_debug->mode)); - break; - case WAN_FE_DEBUG_REG: - if (fe_debug->fe_debug_reg.read == 2){ - printf("Read Front-End Reg:%04X=%02X\n", - fe_debug->fe_debug_reg.reg, - fe_debug->fe_debug_reg.value); - } - break; - } - } - cleanup_hardware_level_connection(); - return; -} - -void set_fe_tx_mode(unsigned char mode) -{ - if(make_hardware_level_connection()){ - return; - } - - wan_udp.wan_udphdr_command = WAN_FE_TX_MODE; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_return_code = 0xaa; - - set_wan_udphdr_data_byte(0,mode); - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("Failed to %s transmitter.\n", - (mode == WAN_FE_TXMODE_ENABLE) ? - "enable" : "disable"); - }else{ - printf("%s transmitter!\n", - (mode == WAN_FE_TXMODE_ENABLE) ? - "Enable" : "Disable"); - } - - cleanup_hardware_level_connection(); - return; -} - diff --git a/util/wanpipemon.old/fe_lib.h b/util/wanpipemon.old/fe_lib.h deleted file mode 100644 index a296b88..0000000 --- a/util/wanpipemon.old/fe_lib.h +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** -* ft1_lib.h WANPIPE(tm) Multiprotocol WAN Link Driver. -* Definitions for the Sangoma FT1 adapters. -* -* Author: Gideon Hack -* -* Copyright: (c) 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. -* ============================================================================ -* May 19, 2000 Gideon Hack Initial version. -*****************************************************************************/ -#ifndef _SDLA_FT1_H -#define _SDLA_FT1_H - -/****** Defines *************************************************************/ - -/* FT1 LEDs read from parallel port A */ -#define PP_A_RT_NOT_RED 0x01 /* the RT LED is not red */ -#define PP_A_RT_NOT_GREEN 0x02 /* the RT LED is not green */ -#define PP_A_LL_NOT_RED 0x04 /* the LL LED is not red */ -#define PP_A_DL_NOT_RED 0x08 /* the DL LED is not red */ - -/* FT1 LEDs read from parallel port B */ -#define PP_B_RxD_NOT_GREEN 0x01 /* the RxD LED is not green */ -#define PP_B_TxD_NOT_GREEN 0x02 /* the TxD LED is not green */ -#define PP_B_ERR_NOT_GREEN 0x04 /* the ERR LED is not green */ -#define PP_B_ERR_NOT_RED 0x08 /* the ERR LED is not red */ -#define PP_B_INS_NOT_RED 0x10 /* the INS LED is not red */ -#define PP_B_INS_NOT_GREEN 0x20 /* the INS LED is not green */ -#define PP_B_ST_NOT_GREEN 0x40 /* the ST LED is not green */ -#define PP_B_ST_NOT_RED 0x80 /* the ST LED is not red */ - - -typedef struct { - short RT_red; - short RT_green; - short RT_off; - short LL_red; - short LL_off; - short DL_red; - short DL_off; - short RxD_green; - short TxD_green; - short ERR_green; - short ERR_red; - short ERR_off; - short INS_red; - short INS_green; - short INS_off; - short ST_green; - short ST_red; - short ST_off; -} FT1_LED_STATUS; - -extern void view_FT1_status( void ); -extern void FT1_self_test( void ); -extern void FT1_local_loop_mode( void ); -extern void FT1_digital_loop_mode( void ); -extern void FT1_remote_test( void ); -extern void FT1_operational_mode( void ); -extern int remote_running_RT_test( void ); -extern void display_FT1_LEDs( void ); - -extern int get_fe_type(unsigned char*); -extern void set_lb_modes(unsigned char type, unsigned char mode); -extern void read_te1_56k_stat(int); -extern void read_te1_56k_config (void); - -extern void set_debug_mode(unsigned char type, unsigned char mode); -extern void set_fe_debug_mode(sdla_fe_debug_t *); -extern void set_fe_tx_mode(unsigned char mode); - -#define WAN_TRUE 1 -#define WAN_FALSE 0 -#endif /* _SDLA_FT1_H */ - diff --git a/util/wanpipemon.old/fe_lib.o b/util/wanpipemon.old/fe_lib.o deleted file mode 100644 index 88440f6841c88cfdd039f6c5c62aa622c611ac76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39700 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 diff --git a/util/wanpipemon.old/fpipemon.c b/util/wanpipemon.old/fpipemon.c deleted file mode 100644 index e53c681..0000000 --- a/util/wanpipemon.old/fpipemon.c +++ /dev/null @@ -1,1312 +0,0 @@ -/***************************************************************************** -* wanpipemon.c Frame Relay Monitor. -* -* Authors: Nenad Corbic -* Jaspreet Singh -* -* 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. -* ---------------------------------------------------------------------------- -* Feb 2, 2006 David Rokhvarg Made sure to call FRConfig() each time before -* using 'station_config', otherwise left uninitialized. -* Jan 12, 2005 David Rokhvarg Added code to run above AFT card with protocol -* in the LIP layer. -* Jul 05, 2004 David Rokhvarg Added i4 option to decode IPV4 level data -* Oct 24, 2001 Nenad Corbic Added the -full option to display all trace -* packets. i.e. disable the default 25 byte -* cutoff. -* Oct 15, 2001 Nenad Corbic Added the -x option: to format all output in -* XML format. -* Mar 14, 2000 Nenad Corbic Added Raw Socket API support. No IP addresses. -* Mar 22, 1997 Jaspreet Singh Improved Error handling -* Nov 24, 1997 Jaspreet Singh Added new stats for driver statistics -* Nov 13, 1997 Jaspreet Singh Fixed descriptions of Global Error Statistics -* Oct 20, 1997 Jaspreet Singh Added new commands for driver specific stats -* and router up time. -* Jul 28, 1997 Jaspreet Singh Added a new command for running line trace -* displaying RAW data. -* Jul 25, 1997 Jaspreet Singh Added commands for viewing specific DLCI data -* including FECN and BECN. -* Jun 24, 1997 Jaspreet Singh S508/FT1 test commands -* Apr 25, 1997 Farhan Thawar Initial version based on wanpipemon for WinNT. -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) -#define MAX_CMD_ARG 10 - -#define HDR_SIZE sizeof(fr_encap_hdr_t)+sizeof(ip_pkt_t)+sizeof(udp_pkt_t) -#define CB_SIZE sizeof(wp_mgmt_t)+sizeof(cblock_t)+1 - -#define FR_DBG if(1) printf - -#define PVC_STATE_NEW 0x01 -#define PVC_STATE_ACTIVE 0x02 - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ - -unsigned char station_config; - - -char *fr_card_stats_menu[]={ -"xm","Modem Status", -"xl","Link Status", -"xru","Display Router UP time", -"." -}; - -char *fr_card_config_menu[]={ -"cl","List Active DLCIs", -"clr","List All Reported DLCIs", -"." -}; - -char *fr_stats_menu[]={ -"sg","Global Statistics", -"sc","Communication Error Statistics", -"se","Error Statistics", -//"sd","Read Statistics for a specific DLCI", -"." -}; - -char *fr_trace_menu[]={ -"ti","Trace and Interpret ALL frames", -//"ti4","Trace and Interpret IP V4 DATA frames", -"tr","Trace ALL frames in HEX format", -//"tip","Trace and Interpret PROTOCOL frames", -//"tid","Trace and Interpret DATA frames", -//"trp","Trace RAW PROTOCOL frames", -//"trd","Trace RAW DATA frames", -"." -}; - -#if 0 -char *fr_csudsu_menu[]={ -"","--- T1/E1 (S514-4/7/8) Stats ---", -""," ", -"Ta","Read T1/E1/56K alrams", -"Tallb","E Line Loopback", -"Tdllb","D Line Loopback", -"Taplb","E Payload Loopback", -"Tdplb","D Payload Loopback", -"Tadlb","E Diag Digital Loopback", -"Tddlb","D Diag Digital Loopback", -"Tsalb","Send Loopback Activate Code", -"Tsdlb","Send Loopback Deactive Code", -"Tread","Read CSU/DSU cfg", -""," ", -"","--- FT1 (S508/S5143) Stats ----", -""," ", -"Tv","View Status", -"Ts","Self Test", -"Tl","Line Loop Test", -"Td","Digital Loop Test", -"Tr","Remote Test", -"To","Operational Mode)", -"Tread","Read CSU/DSU cfg", -"." -}; -#endif - -char *fr_driver_menu[]={ -"dd","Display Driver Statistics", -//"ds","Display Send Driver Statistics\n", -"." -}; - -char *fr_flush_menu[]={ -"fg","Flush Global Statistics", -"fc","Flush Communication Error Statistics", -"fe","Flush Error Statistics", -//"fi","Flush DLCI Statistics", -"fd","Flush Driver Statistics", -"fpm","Flush T1/E1 performance monitoring cnters", -"." -}; - - -char *fr_main_menu[]={ -"fr_card_stats_menu","Card Status", -//"fr_card_config_menu","Card Configuration", -"fr_stats_menu","Card Statistics", -"fr_trace_menu","Trace Data", -"csudsu_menu","CSU DSU Config/Stats", -"fr_driver_menu","Driver Statistics", -"fr_flush_menu","Flush Statistics", -"." -}; - -static struct cmd_menu_lookup_t fr_cmd_menu_lookup[]={ - {"fr_card_stats_menu",fr_card_stats_menu}, - {"fr_card_config_menu",fr_card_config_menu}, - {"fr_stats_menu",fr_stats_menu}, - {"fr_trace_menu",fr_trace_menu}, - {"csudsu_menu",csudsu_menu}, - {"fr_driver_menu",fr_driver_menu}, - {"fr_flush_menu",fr_flush_menu}, - {".",NULL}, -}; - -char ** FRget_main_menu(int *len) -{ - int i=0; - while(strcmp(fr_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return fr_main_menu; -} - -char ** FRget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(fr_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,fr_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=fr_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ - -void FR_set_FT1_mode( void ){ - - for(;;){ - wan_udp.wan_udphdr_command = FR_SET_FT1_MODE; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fr_dlci = 0; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0){ - break; - }else if (wan_udp.wan_udphdr_return_code == WAN_UDP_INVALID_NET_CMD){ - printf("Error: Cannot run this command from Underneath.\n"); - exit(1); - } - - } -} /* set_FT1_mode */ - -int FRConfig( void ) -{ - unsigned char x=0; - char codeversion[10]; - - protocol_cb_size=sizeof(wan_mgmt_t) + sizeof(wan_cmd_t) + 1; - wan_udp.wan_udphdr_command = FR_READ_CONFIG; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fr_dlci = 0; - while (++x < 4){ - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - if (wan_udp.wan_udphdr_return_code == 0xCC){ - return(WAN_FALSE); - } - wan_udp.wan_udphdr_return_code = 0xaa; - } - - if (x >= 4) return(WAN_FALSE); - station_config = wan_udp.wan_udphdr_data[0]; - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = FR_READ_CODE_VERSION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - return(WAN_TRUE); -}; - -void FR_read_FT1_status( void ){ - wan_udp.wan_udphdr_command = FPIPE_FT1_READ_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ){ - par_port_A_byte = wan_udp.wan_udphdr_data[0]; - par_port_B_byte = wan_udp.wan_udphdr_data[1]; - - if(!(par_port_A_byte & PP_A_RT_NOT_RED)) { - FT1_LED.RT_red ++; - } - if(!(par_port_A_byte & PP_A_RT_NOT_GREEN)) { - FT1_LED.RT_green ++; - } - if((par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) - == (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - FT1_LED.RT_off ++; - } - if(!(par_port_A_byte & PP_A_LL_NOT_RED)) { - FT1_LED.LL_red ++; - } - else { - FT1_LED.LL_off ++; - } - if(!(par_port_A_byte & PP_A_DL_NOT_RED)) { - FT1_LED.DL_red ++; - } - else { - FT1_LED.DL_off ++; - } - if(!(par_port_B_byte & PP_B_RxD_NOT_GREEN)) { - FT1_LED.RxD_green ++; - } - if(!(par_port_B_byte & PP_B_TxD_NOT_GREEN)) { - FT1_LED.TxD_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_GREEN)) { - FT1_LED.ERR_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_red ++; - } - if((par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) - == (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_off ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_RED)) { - FT1_LED.INS_red ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_GREEN)) { - FT1_LED.INS_green ++; - } - if((par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) - == (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - FT1_LED.INS_off ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_GREEN)) { - FT1_LED.ST_green ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_RED)) { - FT1_LED.ST_red ++; - } - if((par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) - == (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - FT1_LED.ST_off ++; - } - }else{ - printf("FR Error failed to recieve!\n"); - } -} /* read_FT1_status */ - -static void error( char return_code ) -{ - switch( return_code ){ - case 0x04: - printf("Error: An invalid DLCI was selected\n"); - break; - case 0x10: - printf("Error: A modem failure occurred - DCD and/or CTS were found to be unexpectedly low\n"); - break; - case 0x11: - printf("Error: The Channel moved from Operative to being Inoperative\n"); - break; - case 0x12: - printf("Error: The Channel moved from Inoperative to being Operative\n"); - break; - case 0x13: - printf("Error: The Access Node has reported a change in the status of a DLCI or a number of DLCIs\n"); - break; - case 0x14: - printf("Error: A Full Status Report included a DLCI or a number of DLCIis which were not included before\n"); - break; - case 0x1F: - printf("Error: The frame relay command is invalid\n"); - break; - default: - break; - } -}; /* error */ - -static void global_stats( void ) -{ - fr_link_stat_t *link_stats; - - FRConfig(); - - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = FR_READ_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_fr_dlci = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0){ - error(wan_udp.wan_udphdr_return_code); - return; - } - - link_stats=(fr_link_stat_t *)&wan_udp.wan_udphdr_data[0]; - - if (xml_output){ - output_start_xml_router(); - if( station_config == 0 ) { - output_start_xml_header("Global Statistics: CPE"); - output_xml_val_data("Full Status Enquiry messages sent", - link_stats->cpe_tx_FSE); - output_xml_val_data("Link Integrity Verification Status Enquiry messages sent", - link_stats->cpe_tx_LIV); - output_xml_val_data("Full Status messages received", - link_stats->cpe_rx_FSR); - output_xml_val_data("Link Integrity Verification Status messages received", - link_stats->cpe_rx_LIV); - } else { - output_start_xml_header("Global Statistics: Node"); - output_xml_val_data("Full Status Enquiry messages received", - link_stats->node_rx_FSE); - output_xml_val_data("Link Integrity Verification Status Enquiry messages received", - link_stats->node_rx_LIV); - output_xml_val_data("Full Status Reply messages sent", - link_stats->node_tx_FSR); - output_xml_val_data("Link Integrity Verification Status messages set", - link_stats->node_tx_LIV); - } //if - output_xml_val_data("CPE initializations", - link_stats->cpe_SSN_RSN); - output_xml_val_data("Current Send Sequence Number", - link_stats->current_SSN); - output_xml_val_data("Current Receive Sequence Number", - link_stats->current_RSN); - output_xml_val_data("Current N392 count", - link_stats->current_N392); - output_xml_val_data("Current N393 count", - link_stats->current_N393); - output_stop_xml_header(); - output_stop_xml_router(); - }else{ - - - if( station_config == 0 ) { - banner("GLOBAL STATISTICS: CPE",0); - - printf(" Full Status Enquiry messages sent: %u\n", - link_stats->cpe_tx_FSE); - printf("Link Integrity Verification Status Enquiry messages sent: %u\n", - link_stats->cpe_tx_LIV); - printf(" Full Status messages received: %u\n", - link_stats->cpe_rx_FSR); - printf(" Link Integrity Verification Status messages received: %u\n", - link_stats->cpe_rx_LIV); - } else { - banner("GLOBAL STATISTICS: NODE",0); - printf(" Full Status Enquiry messages received: %u\n", - link_stats->node_rx_FSE); - printf("Link Integrity Verification Status Enquiry mesg received: %u\n", - link_stats->node_rx_LIV); - printf(" Full Status Reply messages sent: %u\n", - link_stats->node_tx_FSR); - printf(" Link Integrity Verification Status messages sent: %u\n", - link_stats->node_tx_LIV); - } //if - printf(" CPE initializations: %u\n", - link_stats->cpe_SSN_RSN); - printf(" Current Send Sequence Number: %u\n", - link_stats->current_SSN); - printf(" Current Receive Sequence Number: %u\n", - link_stats->current_RSN); - printf(" Current N392 count: %u\n", - link_stats->current_N392); - printf(" Current N393 count: %u\n", - link_stats->current_N393); - } -}; /* global_stats */ - -static void flush_global_stats( void ) -{ - wan_udp.wan_udphdr_command = FR_FLUSH_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_fr_dlci = 0; - wan_udp.wan_udphdr_data[0] = 0x01; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) { - switch(wan_udp.wan_udphdr_return_code){ - case 0x06: - printf("Error: Global Statistics not flushed\n"); - break; - default: - error(wan_udp.wan_udphdr_return_code); - break; - } - } -}; /* flush_global_stats */ - -static void error_stats( void ) -{ - FRConfig(); - ResetWanUdp(&wan_udp); - - wan_udp.wan_udphdr_command = FR_READ_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_fr_dlci = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) - return; - - - if (xml_output){ - output_start_xml_router(); - output_start_xml_header("Error Statistics"); - output_xml_val_data("I-frames not transmitted after a tx. int. due to exessive frame length",*(unsigned short*)&wan_udp.wan_udphdr_data[0]); - output_xml_val_data("I-frames not transmitted after a tx. int. due to excessive throughput",*(unsigned short*)&wan_udp.wan_udphdr_data[2]); - output_xml_val_data("Received frames discarded as they were either too short or too long",*(unsigned short*)&wan_udp.wan_udphdr_data[4]); - output_xml_val_data("discarded I-frames with unconfigured DLCI",*(unsigned short*)&wan_udp.wan_udphdr_data[6]); - output_xml_val_data("discarded I-frames due to a format error",*(unsigned short*)&wan_udp.wan_udphdr_data[8]); - output_xml_val_data("App. didn't respond to the triggered IRQ within the given timeout period",*(unsigned short*)&wan_udp.wan_udphdr_data[10]); - output_xml_val_data("discarded In-channel Signalling frames due to a format error",*(unsigned short*)&wan_udp.wan_udphdr_data[28]); - output_xml_val_data("In-channel frames received with an invalid Send Seq. Numbers received",*(unsigned short*)&wan_udp.wan_udphdr_data[32]); - output_xml_val_data("In-channel frames received with an invalid Receive Seq. Numbers received",*(unsigned short*)&wan_udp.wan_udphdr_data[34]); - if( station_config == 0 ) { - output_xml_val_data("Number of unsolicited responses from the Access Node",*(unsigned short*)&wan_udp.wan_udphdr_data[30]); - output_xml_val_data("timeouts on the T391 timer",*(unsigned short*)&wan_udp.wan_udphdr_data[36]); - output_xml_val_data("consecutive timeouts on the T391 timer",*(unsigned short*)&wan_udp.wan_udphdr_data[48]); - } else { - output_xml_val_data("timeouts on the T392 timer",*(unsigned short*)&wan_udp.wan_udphdr_data[38]); - output_xml_val_data("consecutive timeouts on the T392 timer",*(unsigned short*)&wan_udp.wan_udphdr_data[50]); - } - output_xml_val_data("times that N392 error threshold was reached during N393 monitored events",*(unsigned short*)&wan_udp.wan_udphdr_data[40]); - output_stop_xml_header(); - output_stop_xml_router(); - }else{ - - banner("ERROR STATISTICS",0); - - printf(" I-frames not transmitted after a tx. int. due to exessive frame length: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[0]); - printf(" I-frames not transmitted after a tx. int. due to excessive throughput: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[2]); - printf(" Received frames discarded as they were either too short or too long: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[4]); - printf(" discarded I-frames with unconfigured DLCI: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[6]); - printf(" discarded I-frames due to a format error: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[8]); - printf("App. didn't respond to the triggered IRQ within the given timeout period: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[10]); - printf(" discarded In-channel Signalling frames due to a format error: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[28]); - printf(" In-channel frames received with an invalid Send Seq. Numbers received: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[32]); - printf("In-channel frames received with an invalid Receive Seq. Numbers received: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[34]); - if( station_config == 0 ) { - printf(" Number of unsolicited responses from the Access Node: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[30]); - printf(" timeouts on the T391 timer: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[36]); - printf(" consecutive timeouts on the T391 timer: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[48]); - } else { - printf(" timeouts on the T392 timer: %u\n",*(unsigned short*)&wan_udp.wan_udphdr_data[38]); - printf(" consecutive timeouts on the T392 timer: %u\n", - *(unsigned short*)&wan_udp.wan_udphdr_data[50]); - } - printf("times that N392 error threshold was reached during N393 monitored events: %u\n", - *(unsigned short*)&wan_udp.wan_udphdr_data[40]); - } - -}; /* error_stats */ - -int FRDisableTrace(void) -{ - wan_udp.wan_udphdr_command = FPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - return 0; -} - -#if 0 -static void list_all_dlcis(void) -{ - int i; - wan_udp.wan_udphdr_command = FR_READ_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_fr_dlci = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) { - error(wan_udp.wan_udphdr_return_code); - return; - } - - if (xml_output){ - output_start_xml_router(); - output_start_xml_header("Global DLCI Status"); - output_xml_val_asc("Channel Status",wan_udp.wan_udphdr_data[0] ? "OPERATIVE" : "INOPERATIVE"); - if (wan_udp.wan_udphdr_data_len > 2){ - unsigned char str_val[50]; - int cnt_val=0; - for (i=1;iname, - wan_fr_dlci_ptr->dlci, - wan_fr_dlci_ptr->dlci_state & PVC_STATE_ACTIVE ? " " : "in", - wan_fr_dlci_ptr->dlci_state & PVC_STATE_NEW ? " new" : " "); - - wan_fr_dlci_ptr++; - } -} - -static void list_active_dlcis( void ) -{ - int i, num_of_dlcis_in_the_list, number_of_active_dlcis; - wan_fr_dlci_t *wan_fr_dlci_ptr; - - wan_udp.wan_udphdr_command = FR_LIST_ACTIVE_DLCI; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_fr_dlci = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) { - error(wan_udp.wan_udphdr_return_code); - return; - } - - banner("LIST OF ACTIVE DLCIs",0); - - num_of_dlcis_in_the_list = *((int*)wan_udp.wan_udphdr_data); - wan_fr_dlci_ptr = (wan_fr_dlci_t*)&wan_udp.wan_udphdr_data[sizeof(int)]; - - number_of_active_dlcis = 0; - for (i=0; i < num_of_dlcis_in_the_list && wan_fr_dlci_ptr->dlci_state & PVC_STATE_ACTIVE; i++){ - printf("%s:\tDLCI %d:\tactive\n", - wan_fr_dlci_ptr->name, - wan_fr_dlci_ptr->dlci); - - number_of_active_dlcis++; - wan_fr_dlci_ptr++; - } - - if(number_of_active_dlcis == 0){ - printf("All DLCIs are Inactive.\n"); - } - -} /* list_active_dlcis */ - -static void read_dlci_stat( void ) -{ - wan_udp.wan_udphdr_command = FR_READ_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fr_dlci = dlci_number; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = 0; - - if (!dlci_number){ - printf("Error: Please enter a non-zero DLCI\n"); - return; - } - - DO_COMMAND(wan_udp); - if( wan_udp.wan_udphdr_return_code != 0 ){ - error(wan_udp.wan_udphdr_return_code); - return; - } - - - if (xml_output){ - char tmp[100]; - sprintf(tmp,"Statistics for dlci %i",dlci_number); - output_start_xml_router(); - output_start_xml_header(tmp); - - if( (wan_udp.wan_udphdr_return_code == 0) && (wan_udp.wan_udphdr_data_len == 0x20)){ - output_xml_val_data("Information frames transmitted", - *(u_int32_t*)&wan_udp.wan_udphdr_data[0]); - output_xml_val_data("Information bytes transmitted", - *(u_int32_t*)&wan_udp.wan_udphdr_data[4]); - output_xml_val_data("Information frames received", - *(u_int32_t*)&wan_udp.wan_udphdr_data[8]); - output_xml_val_data("Information bytes received", - *(u_int32_t*)&wan_udp.wan_udphdr_data[12]); - output_xml_val_data("Received I-frames discarded due to inactive DLCI", - *(u_int32_t*)&wan_udp.wan_udphdr_data[20]); - output_xml_val_data("I-frames received with Discard Eligibility (DE) indicator set", - *(u_int32_t*)&wan_udp.wan_udphdr_data[28]); - } - - wan_udp.wan_udphdr_command = FR_READ_ADD_DLC_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fr_dlci = dlci_number; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ){ - output_xml_val_data("I-frames received with the FECN bit set", - *(unsigned short*)&wan_udp.wan_udphdr_data[0]); - output_xml_val_data("I-frames received with the BECN bit set", - *(unsigned short*)&wan_udp.wan_udphdr_data[2]); - } - output_stop_xml_header(); - output_stop_xml_router(); - }else{ - - banner("STATISTICS FOR DLCI",dlci_number); - - if(wan_udp.wan_udphdr_return_code == 0){ - printf(" Information frames transmitted: %u\n", - *(u_int32_t*)&wan_udp.wan_udphdr_data[0]); - printf(" Information bytes transmitted: %u\n", - *(u_int32_t*)&wan_udp.wan_udphdr_data[4]); - printf(" Information frames received: %u\n", - *(u_int32_t*)&wan_udp.wan_udphdr_data[8]); - printf(" Information bytes received: %u\n", - *(u_int32_t*)&wan_udp.wan_udphdr_data[12]); - printf(" Received I-frames discarded due to inactive DLCI: %u\n", - *(u_int32_t*)&wan_udp.wan_udphdr_data[20]); - printf(" I-frames received with Discard Eligibility (DE) indicator set: %u\n", - *(u_int32_t*)&wan_udp.wan_udphdr_data[28]); - } - - wan_udp.wan_udphdr_command = FR_READ_ADD_DLC_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fr_dlci = dlci_number; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ){ - printf(" I-frames received with the FECN bit set: %u\n", - *(unsigned short*)&wan_udp.wan_udphdr_data[0]); - printf(" I-frames received with the BECN bit set: %u\n", - *(unsigned short*)&wan_udp.wan_udphdr_data[2]); - - } else { - printf("Error: Please enter a non-zero DLCI\n"); - } - } - -} /* read_dlci_stat */ - -static void flush_dlci_stats( void ) -{ - wan_udp.wan_udphdr_command = FR_FLUSH_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fr_dlci = dlci_number; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code != 0 ) { - switch( wan_udp.wan_udphdr_return_code ){ - case 0x06: - printf("DLCI Statistics are not flushed\n"); - break; - default: - error(wan_udp.wan_udphdr_return_code); - } - } -} /* flush_dlci_stats */ - -static void set_FT1_monitor_status( unsigned char status) -{ - fail = 0; - wan_udp.wan_udphdr_command = FR_FT1_STATUS_CTRL; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = status; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code != 0 && status){ - fail = 1; - if( wan_udp.wan_udphdr_return_code == 0xCD ) - printf("Error: Cannot run this command from Underneath.\n"); - else - printf("Error: This command is only possible with S508/FT1 board!"); - } - -} /* set_FT1_monitor_status */ - -#if 0 -static void fr_driver_stat_ifsend( void ) -{ - if_send_stat_t *stats; - wan_udp.wan_udphdr_command = FPIPE_DRIVER_STAT_IFSEND; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - - if (wan_udp.wan_udphdr_return_code != 0){ - return; - } - - stats = (if_send_stat_t *)&wan_udp.wan_udphdr_data[0]; - - - if (xml_output){ - output_start_xml_router(); - output_start_xml_header("Driver if_send statistics"); - output_xml_val_data("Total Number of Send entries", - stats->if_send_entry); -#if defined(__LINUX__) - output_xml_val_data("Number of Send entries with SKB = NULL", - stats->if_send_skb_null); -#else - output_xml_val_data("Number of Send entries with mbuf = NULL", - stats->if_send_skb_null); -#endif - output_xml_val_data("Number of Send entries with broadcast addressed packet discarded", - stats->if_send_broadcast); - output_xml_val_data("Number of Send entries with multicast addressed packet discarded", - stats->if_send_multicast); - output_xml_val_data("Number of Send entries with CRITICAL_RX_INTR set", - stats->if_send_critical_ISR); - output_xml_val_data("Number of Send entries with Critical set and packet discarded", - stats->if_send_critical_non_ISR); - output_xml_val_data("Number of Send entries with Device Busy set", - stats->if_send_tbusy); - output_xml_val_data("Number of Send entries with Device Busy Timeout", - stats->if_send_tbusy_timeout); - output_xml_val_data("Number of Send entries with FPIPE MONITOR Request", - stats->if_send_PIPE_request); - output_xml_val_data("Number of Send entries with WAN Disconnected", - stats->if_send_wan_disconnected); - output_xml_val_data("Number of Send entries with DLCI Disconnected", - stats->if_send_dlci_disconnected); - output_xml_val_data("Number of Send entries with check for Buffers failed", - stats->if_send_no_bfrs); - output_xml_val_data("Number of Send entries with Send failed", - stats->if_send_adptr_bfrs_full); - output_xml_val_data("Number of Send entries with Send passed", - stats->if_send_bfr_passed_to_adptr); - output_xml_val_data("Number of Consecutive send failures for a packet", - stats->if_send_consec_send_fail); - - output_stop_xml_header(); - output_stop_xml_router(); - }else{ - - banner("DRIVER IF_SEND STATISTICS",0); - - printf(" Total Number of Send entries: %u\n", - stats->if_send_entry); -#if defined(__LINUX__) - printf(" Number of Send entries with SKB = NULL: %u\n", - stats->if_send_skb_null); -#else - printf(" Number of Send entries with mbuf = NULL: %u\n", - stats->if_send_skb_null); -#endif - printf("Number of Send entries with broadcast addressed packet discarded: %u\n", - stats->if_send_broadcast); - printf("Number of Send entries with multicast addressed packet discarded: %u\n", - stats->if_send_multicast); - printf(" Number of Send entries with CRITICAL_RX_INTR set: %u\n", - stats->if_send_critical_ISR); - printf(" Number of Send entries with Critical set and packet discarded: %u\n", - stats->if_send_critical_non_ISR); - printf(" Number of Send entries with Device Busy set: %u\n", - stats->if_send_tbusy); - printf(" Number of Send entries with Device Busy Timeout: %u\n", - stats->if_send_tbusy_timeout); - printf(" Number of Send entries with FPIPE MONITOR Request: %u\n", - stats->if_send_PIPE_request); - printf(" Number of Send entries with WAN Disconnected: %u\n", - stats->if_send_wan_disconnected); - printf(" Number of Send entries with DLCI Disconnected: %u\n", - stats->if_send_dlci_disconnected); - printf(" Number of Send entries with check for Buffers failed: %u\n", - stats->if_send_no_bfrs); - printf(" Number of Send entries with Send failed: %u\n", - stats->if_send_adptr_bfrs_full); - printf(" Number of Send entries with Send passed: %u\n", - stats->if_send_bfr_passed_to_adptr); - printf(" Number of Consecutive send failures for a packet: %u\n", - stats->if_send_consec_send_fail); - } -} /* fr_driver_stat_ifsend */ -#endif - -static void link_status( void ) -{ - - hw_link_status(); -#if 0 - wan_udp.wan_udphdr_command = FR_READ_STATUS; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_fr_dlci = 0; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0) { - error(wan_udp.wan_udphdr_return_code); - return; - } - - banner("LINK STATUS", 0); - - if (wan_udp.wan_udphdr_data[0] == WAN_CONNECTED){ - printf("Channel status: OPERATIVE\n"); - }else{ - printf("Channel status: INOPERATIVE\n"); - } -#endif -} - -static void modem_status( void ) -{ - hw_modem(); -} - -static void comm_err( void) -{ - hw_comm_err(); -} - -static void flush_comm_err( void ) -{ - hw_flush_comm_err(); -} - -static void line_trace( int trace_mode, int trace_sub_type) -{ - hw_line_trace(trace_mode); -} - -static void fr_driver_stat_gen( void ) -{ - hw_general_stats(); -} - -static void flush_driver_stats( void ) -{ - hw_flush_general_stats(); -} - -static void fr_router_up_time( void ) -{ - hw_router_up_time(); -} - -int FRUsage( void ) -{ - printf("wanpipemon: Wanpipe Frame Relay Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("wanpipemon -i -u -c -d \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address or\n"); - printf("\t\tWanpipe network interface name (ex: w1g1f16)\n"); - printf("\tOption -u: (optional, defaults to 9000)\n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -d: \n"); - printf("\t\tDLCI Number: (optional, defaults to 0) \n"); - //printf("\tOption -x: (optional)\n"); - //printf("\t\tDisplay all output/results in XML format\n"); - printf("\tOption -full: (optional trace command)\n"); - printf("\t\tDisplay raw packets in full: default trace pkt len=25bytes\n"); - printf("\tOption -c: \n"); - printf("\t\twanpipemon Command\n"); - printf("\t\t\tFirst letter represents a command group:\n"); - printf("\t\t\tex: xm = View Modem Status\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t l Link Status\n"); - printf("\t ru Display Router UP time\n"); - printf("\tCard Configuration\n"); - printf("\t c l List Active DLCIs\n"); - printf("\t lr List All Reported DLCIs\n"); - printf("\tCard Statistics\n"); - printf("\t s g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t e Error Statistics\n"); - printf("\t d Read Statistics for a specific DLCI\n"); - printf("\tTrace Data \n"); - printf("\t t i Trace and Interpret frames\n"); - printf("\t i4 Trace and Interpret ALL frames. Try to decode data as IP V4 frames.\n"); - printf("\t r Trace ALL frames, in RAW format\n"); - //printf("\t ip Trace and Interpret PROTOCOL frames only\n"); - //printf("\t id Trace and Interpret DATA frames only\n"); - //printf("\t rp Trace PROTOCOL frames only, in RAW format\n"); - //printf("\t rd Trace DATA frames only, in RAW format\n"); - printf("\tFT1/T1/E1/56K Configuration/Statistics\n"); - printf("\t T v View Status \n"); - printf("\t s Self Test\n"); - printf("\t l Line Loop Test\n"); - printf("\t d Digital Loop Test\n"); - printf("\t r Remote Test\n"); - printf("\t o Operational Mode\n"); - printf("\t read Read CSU/DSU configuration (FT1/T1/E1 card)\n"); - printf("\t allb Active Line Loopback mode (T1/E1 card only)\n"); - printf("\t dllb Deactive Line Loopback mode (T1/E1 card only)\n"); - printf("\t aplb Active Payload Loopback mode (T1/E1 card only)\n"); - printf("\t dplb Deactive Payload Loopback mode (T1/E1 card only)\n"); - printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t salb Send Loopback Activate Code (T1/E1 card only)\n"); - printf("\t sdlb Send Loopback Deactive Code (T1/E1 card only)\n"); - printf("\t a Read T1/E1/56K alrams\n"); - printf("\tDriver Statistics\n"); - //printf("\t d s Display Send Driver Statistics\n"); - printf("\t d d Display Driver Statistics\n"); - printf("\tFlush Statistics\n"); - printf("\t f g Flush Global Statistics\n"); - printf("\t c Flush Communication Error Statistics\n"); - printf("\t e Flush Error Statistics\n"); - printf("\t i Flush DLCI Statistics\n"); - printf("\t d Flush Driver Statistics\n"); - printf("\t pm Flush T1/E1 performance monitoring counters\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: wanpipemon -i w1g1f16 -u 9000 -c xm :View Modem Status \n"); - printf("\tex: wanpipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret frames\n"); - printf("\tex: wanpipemon -i fr17 -u 9000 -c sd -d 16 :Statistics for DLCI 16 \n\n"); - return 0; - -}; //usage - -int FRMain(char* command, int argc, char* argv[]) -{ - char *opt=&command[1]; - int err=0; - - global_command = command; - global_argc = argc; - global_argv = argv; - - switch(command[0]){ - case 'x': - if (!strcmp(opt,"m")){ - modem_status(); - }else if (!strcmp(opt, "l")){ - link_status(); - }else if (!strcmp(opt, "ru")){ - fr_router_up_time(); - }else{ - output_error("Invalid Status Command 'x', Type wanpipemon for help"); - err=-1; - } - break; - case 's': - if (!strcmp(opt,"c")){ - comm_err(); - }else if (!strcmp(opt,"g")){ - global_stats(); - }else if (!strcmp(opt,"e")){ - error_stats(); - }else if (!strcmp(opt,"d")){ - read_dlci_stat(); - }else { - output_error("Invalid Status Command 's', Type wanpipemon for help"); - err=-1; - } - break; - case 't': - if(!strcmp(opt,"i" )){ - raw_data = WAN_FALSE; - line_trace(TRACE_ALL, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - line_trace(TRACE_ALL, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "i4")){ - raw_data = WAN_FALSE; - line_trace(TRACE_ALL, WP_OUT_TRACE_INTERP_IPV4); - /* - } - else if (!strcmp(opt, "ip")){ - raw_data = WAN_FALSE; - line_trace(TRACE_PROT, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "id")){ - raw_data = WAN_FALSE; - line_trace(TRACE_DATA, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "rp")){ - raw_data = WAN_TRUE; - line_trace(TRACE_PROT, WP_OUT_TRACE_RAW); - }else if (!strcmp(opt, "rd")){ - raw_data = WAN_TRUE; - line_trace(TRACE_DATA, WP_OUT_TRACE_RAW); - */ - }else{ - output_error("Invalid Status Command 't', Type wanpipemon for help"); - err=-1; - } - break; - - case 'c': - if (!strcmp(opt, "l")){ - list_active_dlcis(); - - }else if (!strcmp(opt, "lr")){ - /* list_all_dlcis(); */ - list_configured_dlcis(); - - }else if (!strcmp(opt, "lc")){ - list_configured_dlcis(); - - }else{ - output_error("Invalid Status Command 'c', Type wanpipemon for help"); - err=-1; - } - break; - - case 'd': - /* Different signature for Driver Statistics */ - //if(!strcmp(opt, "s")){ - // fr_driver_stat_ifsend(); - //}else - if (!strcmp(opt, "d")){ - fr_driver_stat_gen(); - }else{ - output_error("Invalid Status Command 'd', Type wanpipemon for help"); - err=-1; - } - break; - - case 'f': - if (!strcmp(opt, "c")){ - flush_comm_err(); - comm_err(); - }else if (!strcmp(opt, "g")){ - flush_global_stats(); - global_stats(); - }else if (!strcmp(opt, "e")){ - flush_global_stats(); - error_stats(); - }else if (!strcmp(opt, "i")){ - flush_dlci_stats(); - read_dlci_stat(); - }else if (!strcmp(opt, "d")){ - flush_driver_stats(); - }else if (!strcmp(opt,"pm" )){ - flush_te1_pmon(); - }else{ - output_error("Invalid Status Command 'f', Type wanpipemon for help"); - err=-1; - } - break; - case 'T': - if (!strcmp(opt, "v")){ - set_FT1_monitor_status(0x01); - if(!fail){ - view_FT1_status(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "s")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "l")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_local_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "d")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_digital_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "r")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_remote_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "o")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_operational_mode(); - } - set_FT1_monitor_status(0x00); - - }else if (!strcmp(opt,"read")){ - read_te1_56k_config(); - }else if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"a")){ - read_te1_56k_stat(0); - }else{ - output_error("Invalid Status Command 'T', Type wanpipemon for help"); - err=-1; - } - break; - default: - output_error("ERROR: Invalid Command, Type wanpipemon for help"); - err=-1; - break; - - } //switch - - fflush(stdout); - return err; -}; //main - -/* - * EOF wanpipemon.c - */ diff --git a/util/wanpipemon.old/fpipemon.o b/util/wanpipemon.old/fpipemon.o deleted file mode 100644 index 18a7f4d27faa773722a138ab636d6df75fa1ecbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28124 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 diff --git a/util/wanpipemon.old/mppipemon.c b/util/wanpipemon.old/mppipemon.c deleted file mode 100644 index ad1e56f..0000000 --- a/util/wanpipemon.old/mppipemon.c +++ /dev/null @@ -1,1375 +0,0 @@ -/***************************************************************************** -* mppipemon.c Multi-Port PPP Monitor -* -* Author: Nenad Corbic -* -* 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. -* ---------------------------------------------------------------------------- -* Jul 17, 2000 Nenad Corbic Exactly the same as RAW cpipemon -*****************************************************************************/ - -#if !defined(__LINUX__) -# error "Multi-Port PPP Monitor not supported on FreeBSD/OpenBSD OS!" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ft1_lib.h" - -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN 2024 - -/* Structures for data casting */ -#pragma pack(1) -typedef struct { - unsigned char link_address; /* Broadcast or Unicast */ - unsigned char control; - unsigned short packet_type; /* IP/SLARP/CDP */ -} cisco_header_t; -#pragma pack() - -#pragma pack(1) -typedef struct { - wp_mgmt_t wp_mgmt PACKED; - cblock_t cblock PACKED; - trace_info_t trace_info PACKED; - unsigned char data[SIZEOF_MB_DATA_BFR] PACKED; -} udp_mgmt_pkt_t; -#pragma pack() - -#pragma pack(1) -typedef struct { - ip_pkt_t ip_pkt; - udp_pkt_t udp_pkt; - udp_mgmt_pkt_t cb; -}udp_packet; -#pragma pack() - -//#define CB_SIZE sizeof(wp_mgmt_t)+sizeof(cblock_t)+sizeof(trace_info_t) -#define CB_SIZE sizeof(wp_mgmt_t)+sizeof(cblock_t)+sizeof(trace_info_t)+1 - -/* Link addresses */ -#define CISCO_ADDR_UNICAST 0x0F -#define CISCO_ADDR_BCAST 0x8F - -/* Packet Types */ -#define CISCO_PACKET_IP 0x0800 -#define CISCO_PACKET_SLARP 0x8035 -#define CISCO_PACKET_CDP 0x2000 - -#pragma pack(1) -typedef struct { - unsigned long code; /* Slarp Control Packet Code */ - union { - struct { - unsigned long address; /* IP address */ - unsigned long mask; /* IP mask */ - unsigned short reserved[3]; - } address; - struct { - unsigned long my_sequence; - unsigned long your_sequence; - unsigned short reliability; - unsigned short t1; /* time alive (upper) */ - unsigned short t2; /* time alive (lower) */ - } keepalive; - } un; -} cisco_slarp_t; -#pragma pack() -/* Packet Codes */ - -#define SLARP_REQUEST 0 -#define SLARP_REPLY 1 -#define SLARP_KEEPALIVE 2 - -/* storage for FT1 LEDs */ -FT1_LED_STATUS FT1_LED; - -/* Prototypes */ - -int main(int, char** ); -void init(int, char** ); -void usage( void ); -#ifdef LINUX_2_1 -int MakeRawConnection( void ); -#endif -int ObtainConfiguration( void ); -unsigned char DoCommand( void ); -void error( void ); - -/* Command routines */ -void modem( void ); -void global_stats( void ); -void comm_stats( void ); -void read_code_version( void ); -void chdlc_configuration( void ); -void link_status( void ); -void operational_stats( void ); -void slarp_stats( void ); -void line_trace( int ); -void chdlc_router_up_time( void ); -void flush_operational_stats( void ); -void flush_global_stats( void ); -void flush_comm_stats( void ); -void get_ip_addr(char *if_name); -void banner(char *); -void set_FT1_monitor_status( unsigned char); -void set_FT1_mode(int verbose); -void read_FT1_status( void ); -void read_ft1_op_stats( void ); - - -/* Global variables */ -int sock = 0; -struct sockaddr_in soin; -unsigned int loop_counter, frame_count; -int is_508, raw_data=WAN_FALSE, udp_port = 9000; -char ipaddress[16]; -char src_ip[16]; -char i_name[16]; -char cmd[5]; -char raw_sock=0; - -/* The ft1_lib needs these global variables */ -unsigned char par_port_A_byte; -unsigned char par_port_B_byte; -int gfail; -udp_mgmt_pkt_t cb; - - -#ifdef LINUX_2_1 -int MakeRawConnection( void ) -{ - struct ifreq ifr; - struct sockaddr_ll soin; - - raw_sock=1; - - sock = socket(PF_PACKET, SOCK_RAW, 0); - if (sock < 0){ - printf("Error: Unable to open socket!\n"); - return( WAN_FALSE ); - } /* if */ - - soin.sll_family = AF_PACKET; - soin.sll_protocol = htons(ETH_P_IP); - strcpy (ifr.ifr_name,i_name); - ioctl(sock,SIOCGIFINDEX,&ifr); - soin.sll_ifindex = ifr.ifr_ifindex; - - - if (bind(sock, (struct sockaddr *)&soin, sizeof(soin)) < 0) { - printf("Error: Cannot make connection!\nMake sure the IP address is correct\n"); - return( WAN_FALSE ); - } /* if */ - - if (!ObtainConfiguration()) { - printf("Error: Unable to obtain CHDLC information.\n"); - printf("Make sure the IP and UDP port are correct.\n"); - close( sock ); - return( WAN_FALSE ); - } /* if */ - - return( WAN_TRUE ); - -}; /* MakeRawConnection */ -#endif - -int ObtainConfiguration( void ) -{ - unsigned char codeversion[10]; - unsigned char x; - - x = 0; - cb.cblock.command= READ_CHDLC_CONFIGURATION; - cb.cblock.buffer_length = 0; - - while (DoCommand() != 0 && ++x < 4) { - if (cb.cblock.return_code == 0xaa) { - printf("Error: Command timeout occurred"); - return(WAN_FALSE); - } - - if (cb.cblock.return_code == 0xCC ) return(WAN_FALSE); - } - - if (x >= 4) return(WAN_FALSE); - - if( cb.cblock.buffer_length == sizeof(CHDLC_CONFIGURATION_STRUCT)) { - is_508 = WAN_TRUE; - } else { - is_508 = WAN_FALSE; - } - - strcpy(codeversion, "?.??"); - - cb.cblock.command= READ_CHDLC_CODE_VERSION; - cb.cblock.buffer_length = 0; - DoCommand(); - if (cb.cblock.return_code == 0) { - cb.data[cb.cblock.buffer_length] = 0; - strcpy(codeversion, cb.data); - } - - return(WAN_TRUE); -}; /* ObtainConfiguration */ - - -unsigned char DoCommand( void ) -{ - static unsigned char id = 0; - fd_set ready; - struct timeval to; - int x, err=0; - - if (raw_sock){ - udp_packet udp_pkt; - memset(&udp_pkt,0,sizeof(udp_pkt)); - - udp_pkt.ip_pkt.ver_inet_hdr_length = 0x45; - udp_pkt.ip_pkt.service_type = 0; - udp_pkt.ip_pkt.total_length = sizeof(ip_pkt_t)+ - sizeof(udp_pkt_t)+CB_SIZE+cb.cblock.buffer_length; - udp_pkt.ip_pkt.identifier = 0; - udp_pkt.ip_pkt.flags_frag_offset = 0; - udp_pkt.ip_pkt.ttl = 0x7F; - udp_pkt.ip_pkt.protocol = 0x11; - udp_pkt.ip_pkt.hdr_checksum = 0x1232; - udp_pkt.ip_pkt.ip_src_address = inet_addr("1.1.1.1"); - udp_pkt.ip_pkt.ip_dst_address = inet_addr("1.1.1.2"); - - udp_pkt.udp_pkt.udp_src_port = htons((u_short)udp_port); - udp_pkt.udp_pkt.udp_dst_port = htons((u_short)udp_port); - udp_pkt.udp_pkt.udp_length = sizeof(udp_pkt_t)+CB_SIZE+cb.cblock.buffer_length; - udp_pkt.udp_pkt.udp_checksum = 0x1234; - - memcpy(&udp_pkt.cb, &cb, CB_SIZE); - if (cb.cblock.buffer_length){ - memcpy(&udp_pkt.cb.data, &cb.data, cb.cblock.buffer_length); - } - - for( x = 0; x < 4; x += 1 ) { - udp_pkt.cb.cblock.opp_flag = 0; - udp_pkt.cb.wp_mgmt.request_reply = 0x01; - udp_pkt.cb.wp_mgmt.id=id; - udp_pkt.cb.cblock.return_code = 0xaa; - send(sock, &udp_pkt, udp_pkt.ip_pkt.total_length,0); - - if (err <0){ - perror("Send"); - continue; - } - - FD_ZERO(&ready); - FD_SET(sock,&ready); - to.tv_sec = 5; - to.tv_usec = 0; - - if((err = select(sock + 1,&ready, NULL, NULL, &to))) { - err = recv(sock, &udp_pkt, - (sizeof(ip_pkt_t)+sizeof(udp_pkt_t)+CB_SIZE+MDATALEN),0); - - if (err >= (CB_SIZE+udp_pkt.cb.cblock.buffer_length)){ - - memcpy(&cb,&udp_pkt.cb.wp_mgmt.signature, - (CB_SIZE+udp_pkt.cb.cblock.buffer_length)); - } - break; - }else{ - printf("Error: No Data received from the connected socket.\n"); - } - } - - }else{ - - for( x = 0; x < 4; x += 1 ) { - cb.cblock.opp_flag = 0; - cb.wp_mgmt.request_reply = 0x01; - cb.wp_mgmt.id = id; - /* 0xAA is our special return code indicating packet timeout */ - cb.cblock.return_code = 0xaa; - err = send(sock, &cb, 35 + cb.cblock.buffer_length, 0); - if (err <0){ - perror("Send"); - continue; - } - - FD_ZERO(&ready); - FD_SET(sock,&ready); - to.tv_sec = 5; - to.tv_usec = 0; - - if((err = select(sock + 1,&ready, NULL, NULL, &to))) { - - err = recv(sock, &cb, 35+MDATALEN,0); - if( err < 0 ){ - perror("Recv"); - } - break; - }else{ - printf("Error: No Data received from the connected socket.\n"); - } - } - } - - /* make sure the id is correct (returning results from a previous - call may be disastrous if not recognized) - also make sure it is a reply - */ - - if (cb.wp_mgmt.request_reply != 0x02){ - cb.cblock.return_code = 0xbb; - } - id++; - if (cb.cblock.return_code == 0xCC) { - printf("Error: Code is not running on the board!"); - exit(1); - } - - return(cb.cblock.return_code); - -}; /* DoCommand */ - - -void init( int argc, char *argv[]) -{ - int i, i_cnt=0, u_cnt=0, c_cnt=0, if_found=0; - struct in_addr *ip_str=NULL; - cb.wp_mgmt.id = 0; - - for (i=0;i argc-1){ - printf("ERROR: Invalid IP or Interface Name, Type mppipemon for help\n\n"); - exit(0); - } - - strcpy(ipaddress,argv[i+1]); - if (inet_aton(ipaddress,ip_str) != 0 ){ - }else{ - strcpy(i_name,ipaddress); - if_found=1; - } - i_cnt=1; - }else if (!strcmp(argv[i],"-u")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid UDP PORT, Type mppipemon for help\n\n"); - exit(0); - } - - if(isdigit(argv[i+1][0])){ - udp_port = atoi(argv[i+1]); - }else{ - printf("ERROR: Invalid UDP Port, Type mppipemon for help\n\n"); - exit(0); - } - u_cnt=1; - }else if (!strcmp(argv[i],"-c")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid Command, Type mppipemon for help\n\n"); - exit(0); - } - - strcpy(cmd,argv[i+1]); - c_cnt=1; - } - } - - if (!i_cnt){ - printf("ERROR: No IP address or Interface Name, Type mppipemon for help\n\n"); - exit(0); - } - if (!c_cnt){ - printf("ERROR: No Command, Type mppipemon for help\n\n"); - exit(0); - } - - if (if_found){ - get_ip_addr(ipaddress); - } - - /* signature for UDP Management */ - strcpy(cb.wp_mgmt.signature, "CTPIPEAB"); -}; - -void get_ip_addr(char *if_name){ - - int skfd; - struct sockaddr_in *sin; - struct ifreq ifr; - - if ((skfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) { - printf("SOCKET FAILED\n"); - perror("socket"); - exit(1); - } - - strncpy(ifr.ifr_ifrn.ifrn_name, if_name, sizeof(ifr.ifr_ifrn.ifrn_name)); - - if (ioctl(skfd, SIOCGIFFLAGS , &ifr) < 0) { - fprintf(stderr, "Error: Unknown interface: %s\n",if_name); - exit(0); - } - - if (ioctl(skfd, SIOCGIFDSTADDR , &ifr) < 0) { - - strcpy(ipaddress,"0.0.0.0"); - }else{ - sin = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_dstaddr; - strcpy(ipaddress,inet_ntoa(sin->sin_addr)); - } - - if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0) { - - strcpy(src_ip,"0.0.0.0"); - }else{ - sin = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_addr; - strcpy(src_ip,inet_ntoa(sin->sin_addr)); - } - - - close (skfd); - - return; - -} - - -void error( void ) -{ - - printf("Error: Command failed!\n"); - -}; /* error */ - - -void global_stats (void) -{ - GLOBAL_STATS_STRUCT* global_stats; - cb.cblock.command= READ_GLOBAL_STATISTICS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - banner("GLOBAL STATISTICS"); - global_stats = (GLOBAL_STATS_STRUCT *)&cb.data[0]; - printf("Times application did not respond to IRQ: %d", - global_stats->app_IRQ_timeout_count); - } else { - error(); - } -}; /* global stats */ - -void flush_global_stats (void) -{ - cb.cblock.command= FLUSH_GLOBAL_STATISTICS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code != 0 ) error(); -}; /* flush global stats */ - -void modem( void ) -{ - unsigned char cts_dcd; - - cb.cblock.command= READ_MODEM_STATUS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - banner("MODEM STATUS"); - memcpy(&cts_dcd,&cb.data[0],1); - printf("DCD: "); - (cts_dcd & 0x08) ? printf("High\n") : printf("Low\n"); - printf("CTS: "); - (cts_dcd & 0x20) ? printf("High\n") : printf("Low\n"); - } else { - error(); - } -}; /* modem */ - - -void comm_stats (void) -{ - COMMS_ERROR_STATS_STRUCT* comm_stats; - cb.cblock.command= READ_COMMS_ERROR_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - banner("COMMUNICATION ERROR STATISTICS"); - - comm_stats = (COMMS_ERROR_STATS_STRUCT *)&cb.data[0]; - - printf(" Number of receiver overrun errors: %d\n", comm_stats->Rx_overrun_err_count); - printf(" Number of receiver CRC errors: %d\n", comm_stats->CRC_err_count); - printf(" Number of abort frames received: %d\n", comm_stats->Rx_abort_count); - printf(" Number of times receiver disabled: %d\n", comm_stats->Rx_dis_pri_bfrs_full_count); - printf(" Number of transmitted abort frames (missed Tx interrupt): %d\n", comm_stats->sec_Tx_abort_msd_Tx_int_count); - printf(" Number of transmit underruns: %d\n", comm_stats->missed_Tx_und_int_count); - printf(" Number of abort frames transmitted: %d\n", comm_stats->sec_Tx_abort_count); - printf(" Number of times DCD changed state: %d\n", comm_stats->DCD_state_change_count); - printf(" Number of times CTS changed state: %d\n", comm_stats->CTS_state_change_count); - } else { - error(); - } -}; /* comm_stats */ - - -void flush_comm_stats( void ) -{ - cb.cblock.command= FLUSH_COMMS_ERROR_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code != 0 ) error(); -}; /* flush_comm_stats */ - - -void read_code_version (void) -{ - cb.cblock.command= READ_CHDLC_CODE_VERSION; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - unsigned char version[10]; - banner("CODE VERSION"); - memcpy(version,&cb.data,cb.cblock.buffer_length); - version[cb.cblock.buffer_length] = '\0'; - printf("Cisco HDLC Code version: %s\n", version); - } -}; /* read code version */ - -void chdlc_configuration (void) -{ - CHDLC_CONFIGURATION_STRUCT *chdlc_cfg; - cb.cblock.command = READ_CHDLC_CONFIGURATION; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - chdlc_cfg = (CHDLC_CONFIGURATION_STRUCT *)&cb.data[0]; - banner("CHDLC CONFIGURATION"); - - printf("Baud rate: %ld", chdlc_cfg->baud_rate); - - printf("\nLine configuration: "); - switch (chdlc_cfg->line_config_options) { - case INTERFACE_LEVEL_V35: - printf("V.35"); - break; - case INTERFACE_LEVEL_RS232: - printf("RS-232"); - break; - } - - printf("\n\nLink State depends on:"); - if (chdlc_cfg->CHDLC_protocol_options & IGNORE_DCD_FOR_LINK_STAT) - printf ("\n\t\t\tDCD: NO"); - else - printf ("\n\t\t\tDCD: YES"); - - if (chdlc_cfg->CHDLC_protocol_options & IGNORE_CTS_FOR_LINK_STAT) - printf ("\n\t\t\tCTS: NO\n"); - else - printf ("\n\t\t\tCTS: YES\n"); - - if (chdlc_cfg->CHDLC_protocol_options & IGNORE_KPALV_FOR_LINK_STAT) - printf ("\tKeepalive Reception: NO\n"); - else - printf ("\tKeepalive Reception: YES\n"); - - printf("\n\n Maximum data field length: %d", - chdlc_cfg->max_CHDLC_data_field_length); - - printf( "\n Keepalive transmit interval (ms): %d", - chdlc_cfg->transmit_keepalive_timer); - - printf( "\nExpected keepalive reception interval (ms): %d", - chdlc_cfg->receive_keepalive_timer); - - printf( "\n Keepalive reception error tolerance: %d", - chdlc_cfg->keepalive_error_tolerance); - - printf( "\n SLARP request transmit interval (ms): %d", - chdlc_cfg->SLARP_request_timer); - - } else { - error(); - } -}; /* chdlc_configuration */ - - -void link_status (void) -{ - CHDLC_LINK_STATUS_STRUCT *status; - cb.cblock.command= READ_CHDLC_LINK_STATUS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - - banner("LINK STATUS"); - - status = (CHDLC_LINK_STATUS_STRUCT *)&cb.data[0]; - - printf(" Link status: "); - switch (status->CHDLC_link_status) { - case CHDLC_LINK_INACTIVE: - printf("Inactive\n"); - break; - case CHDLC_LINK_ACTIVE: - printf("Active\n"); - break; - } - - printf("Available data frames for application: %d\n", - status->no_Data_frms_for_app); - - printf(" Receiver status: "); - if (status->receiver_status & 0x01) - printf("Disabled due to flow control restrictions\n"); - else printf("Enabled\n"); - } else { - error(); - } -}; /* Link Status */ - - -void operational_stats (void) -{ - CHDLC_OPERATIONAL_STATS_STRUCT *stats; - cb.cblock.command= READ_CHDLC_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - banner("OPERATIONAL STATISTICS"); - stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)&cb.data[0]; - - printf( " Number of frames transmitted: %ld",stats->Data_frames_Tx_count); - printf( "\n Number of bytes transmitted: %ld",stats->Data_bytes_Tx_count); - printf( "\n Transmit Throughput: %ld",stats->Data_Tx_throughput); - printf( "\n Transmit frames discarded (length error): %ld",stats->Tx_Data_discard_lgth_err_count); - - printf("\n\n Number of frames received: %ld",stats->Data_frames_Rx_count); - printf( "\n Number of bytes received: %ld",stats->Data_bytes_Rx_count); - printf( "\n Receive Throughput: %ld",stats->Data_Rx_throughput); - printf( "\n Received frames discarded (too short): %ld",stats->Rx_Data_discard_short_count); - printf( "\n Received frames discarded (too long): %ld",stats->Rx_Data_discard_long_count); - printf( "\nReceived frames discarded (link inactive): %ld",stats->Rx_Data_discard_inactive_count); - - - printf("\n\nIncoming frames with format errors"); - printf( "\n Frames of excessive length: %d", stats->Rx_frms_too_long_count); - printf( "\n Incomplete Cisco Header: %d", stats->Rx_frm_incomp_CHDLC_hdr_count); - printf( "\n Invalid Cisco HDLC link address: %d", stats->Rx_invalid_CHDLC_addr_count); - printf( "\n Invalid Cisco HDLC control: %d", stats->Rx_invalid_CHDLC_ctrl_count); - printf( "\n Invalid Cisco HDLC frame type: %d", stats->Rx_invalid_CHDLC_type_count); - - printf("\n\nCisco HDLC link active/inactive and loopback statistics"); - printf( "\n Times that the link went active: %d", stats->link_active_count); - printf( "\n Times that the link went inactive (modem failure): %d", stats->link_inactive_modem_count); - printf( "\n Times that the link went inactive (keepalive failure): %d", stats->link_inactive_keepalive_count); - printf( "\n link looped count: %d", stats->link_looped_count); - } else { - error(); - } -} /* Operational_stats */ - - -void flush_operational_stats( void ) -{ - cb.cblock.command= FLUSH_CHDLC_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if( cb.cblock.return_code != 0 ) { - error(); - } - -}; /* flush_operational_stats */ - -void slarp_stats (void) -{ - CHDLC_OPERATIONAL_STATS_STRUCT *stats; - cb.cblock.command= READ_CHDLC_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - if (cb.cblock.return_code == 0) { - banner("SLARP STATISTICS"); - stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)&cb.data[0]; - - printf("\n SLARP frame transmission/reception statistics"); - printf( "\n SLARP request packets transmitted: %ld", - stats->CHDLC_SLARP_REQ_Tx_count); - printf( "\n SLARP request packets received: %ld", - stats->CHDLC_SLARP_REQ_Rx_count); - printf("\n\n SLARP Reply packets transmitted: %ld", - stats->CHDLC_SLARP_REPLY_Tx_count); - printf( "\n SLARP Reply packets received: %ld", - stats->CHDLC_SLARP_REPLY_Rx_count); - printf("\n\n SLARP keepalive packets transmitted: %ld", - stats->CHDLC_SLARP_KPALV_Tx_count); - printf( "\n SLARP keepalive packets received: %ld", - stats->CHDLC_SLARP_KPALV_Rx_count); - - printf( "\n\nIncoming SLARP Packets with format errors"); - printf( "\n Invalid SLARP Code: %d", stats->Rx_SLARP_invalid_code_count); - printf( "\n Replies with bad IP addr: %d", stats->Rx_SLARP_Reply_bad_IP_addr); - printf( "\n Replies with bad netmask: %d",stats->Rx_SLARP_Reply_bad_netmask); - printf( "\n\nSLARP timeout/retry statistics"); - printf( "\n SLARP Request timeouts: %d",stats->SLARP_Request_TO_count); - printf( "\n keepalive reception timeouts: %d",stats->SLARP_Rx_keepalive_TO_count); - - printf("\n\nCisco Discovery Protocol frames"); - printf( "\n Transmitted: %ld", stats->CHDLC_CDP_Tx_count); - printf( "\n Received: %ld", stats->CHDLC_CDP_Rx_count); - - } else { - error(); - } - -} /* slarp_stats */ - - - -void line_trace(int trace_mode) -{ - unsigned char num_frames, num_chars; - unsigned short curr_pos = 0; - trace_pkt_t *trace_pkt; - unsigned int i, j; - unsigned char outstr[2000]; - int recv_buff = sizeof(udp_mgmt_pkt_t ) + MDATALEN + 100; - fd_set ready; - struct timeval to; - cisco_header_t *cisco_header; - - setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recv_buff, sizeof(int) ); - - /* Disable trace to ensure that the buffers are flushed */ - cb.cblock.command= CPIPE_DISABLE_TRACING; - cb.cblock.buffer_length = 0; - DoCommand(); - - cb.cblock.command= CPIPE_ENABLE_TRACING; - cb.cblock.buffer_length = 0; - cb.data[0]=0; - if(trace_mode == TRACE_PROT){ - cb.cblock.buffer_length = 1; - cb.data[0] |= TRACE_SLARP_FRAMES | TRACE_CDP_FRAMES; - printf("Tracing Protocol only %X\n",cb.data[0]); - }else if(trace_mode == TRACE_DATA){ - cb.cblock.buffer_length = 1; - cb.data[0] = TRACE_DATA_FRAMES; - }else{ - cb.cblock.buffer_length = 1; - cb.data[0] |= TRACE_SLARP_FRAMES | - TRACE_DATA_FRAMES | - TRACE_CDP_FRAMES; - } - DoCommand(); - - if( cb.cblock.return_code == 0 ) { - printf("Starting trace...(Press ENTER to exit)\n"); - fflush(stdout); - } else if( cb.cblock.return_code == 0xCD ) { - printf("Cannot Enable Line Tracing from Underneath.\n"); - fflush(stdout); - return; - } else if( cb.cblock.return_code == 0x01 ) { - printf("Starting trace...(although it's already enabled!)\n"); - printf("Press ENTER to exit.\n"); - fflush(stdout); - } else { - printf("Failed to Enable Line Tracing. Return code: 0x%02X\n", - cb.cblock.return_code ); - fflush(stdout); - return; - } - - to.tv_sec = 0; - to.tv_usec = 0; - - for(;;) { - FD_ZERO(&ready); - FD_SET(0,&ready); - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - - cb.cblock.command = CPIPE_GET_TRACE_INFO; - cb.cblock.buffer_length = 0; - DoCommand(); - if (cb.cblock.return_code == 0 && cb.cblock.buffer_length) { - num_frames = cb.trace_info.num_frames; - for ( i = 0; i < num_frames; i++) { - trace_pkt= (trace_pkt_t *)(&cb.data[0] + curr_pos); - - /* frame type */ - if (trace_pkt->status & 0x01) { - sprintf(outstr,"OUTGOING\t"); - } else { - if (trace_pkt->status & 0x10) { - sprintf(outstr,"INCOMING - Aborted\t"); - } else if (trace_pkt->status & 0x20) { - sprintf(outstr,"INCOMING - CRC Error\t"); - } else if (trace_pkt->status & 0x40) { - sprintf(outstr,"INCOMING - Overrun Error\t"); - } else { - sprintf(outstr,"INCOMING\t"); - } - } - - /* real length and time stamp */ - sprintf(outstr+strlen(outstr), "%d\t%d\t", - trace_pkt->real_length, trace_pkt->time_stamp); - - /* first update curr_pos */ - curr_pos += sizeof(trace_pkt_t); - if (trace_pkt->data_avail == 0) { - sprintf( outstr+strlen(outstr), "the frame data is not available" ); - } else { - /* update curr_pos again */ - curr_pos += trace_pkt->real_length - 1; - num_chars = (unsigned char) - ((trace_pkt->real_length <= 25) - ? trace_pkt->real_length : 25); - - if (raw_data) { /* show raw data */ - for( j=0; jdata[j]); - } - outstr[strlen(outstr)-1] = '\0'; - } else { /* show int data */ - cisco_header = (cisco_header_t *) - &trace_pkt->data[0]; - switch(ntohs(cisco_header->packet_type)) { - - case CISCO_PACKET_IP: - sprintf(outstr+strlen(outstr), - "IP packet from %ld.%ld.%ld.%ld to %ld.%ld.%ld.%ld", - ((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0x000000FF, - (((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0x0000FF00) >> 8, - (((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0x00FF0000) >>16, - (((ip_pkt_t *)(cisco_header + 1))->ip_src_address & 0xFF000000) >>24, - - ((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0x000000FF, - (((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0x0000FF00) >> 8, - (((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0x00FF0000) >>16, - (((ip_pkt_t *)(cisco_header + 1))->ip_dst_address & 0xFF000000) >>24 -); - break; - - case CISCO_PACKET_SLARP: { - cisco_slarp_t *cisco_slarp = - (cisco_slarp_t*)(cisco_header+1); - - switch(ntohl(cisco_slarp->code)) { - case SLARP_REQUEST: - sprintf(outstr+strlen(outstr), - "SLARP Request packet"); - break; - - case SLARP_REPLY: - sprintf(outstr+strlen(outstr), - "SLARP Reply packet"); - break; - - case SLARP_KEEPALIVE: - sprintf(outstr+strlen(outstr), - "SLARP Keepalive packet"); - break; - - default: - sprintf(outstr+strlen(outstr), - "Unrecognized SLARP packet"); - break; - } /* Slarp code switch */ - break; - } /* slarp case */ - - case CISCO_PACKET_CDP: - sprintf(outstr+strlen(outstr), - "Cisco Discover Protocol packet"); - break; - - default: - sprintf(outstr+strlen(outstr),"Unknown type"); - } /* Switch packet type */ - } //if - } //if - - printf("%s\n",outstr); - fflush(stdout); - } //for - } //if - curr_pos = 0; - - if (!cb.trace_info.ismoredata){ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - }else{ - to.tv_sec = 0; - to.tv_usec = 0; - } - } - - cb.cblock.command= CPIPE_DISABLE_TRACING; - cb.cblock.buffer_length = 0; - DoCommand(); -}; /* line_trace */ - -//CORBA -void usage(void) -{ - printf("mppipemon: Wanpipe Multi-Port PPP Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("Multi-Port PPP Debugger\n\n"); - printf("mppipemon -i -u -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address must be supplied\n"); - printf("\t\t Wanpipe network interface name (ex: wp1_chdlc)\n"); - printf("\tOption -u: (Optional, default: 9000)\n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t l Link Status\n"); - printf("\t cv Read Code Version\n"); - printf("\t ru Display Router UP time\n"); - printf("\tCard Configuration\n"); - printf("\t c rc Read CHDLC Configuration\n"); - printf("\tCard Statistics\n"); - printf("\t s g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t o Operational Statistics\n"); - printf("\t s SLARP and CDP Statistics\n"); - printf("\tTrace Data \n"); - printf("\t t i Trace and Interpret ALL frames\n"); - printf("\t ip Trace and Interpret PROTOCOL frames only\n"); - printf("\t id Trace and Interpret DATA frames only\n"); - printf("\t r Trace ALL frames, in RAW format\n"); - printf("\t rp Trace PROTOCOL frames only, in RAW format\n"); - printf("\t rd Trace DATA frames only, in RAW format\n"); - printf("\tFT1 Configuration\n"); - printf("\t T v View Status \n"); - printf("\t s Self Test\n"); - printf("\t l Line Loop Test\n"); - printf("\t d Digital Loop Test\n"); - printf("\t r Remote Test\n"); - printf("\t o Operational Mode\n"); - printf("\t p FT1 CSU/DSU operational statistics\n"); - printf("\t f Flush FT1 CSU/DSU operational statistcs\n"); - printf("\tFlush Statistics\n"); - printf("\t f g Flush Global Statistics\n"); - printf("\t c Flush Communication Error Statistics\n"); - printf("\t o Flush Operational Statistics\n"); - printf("\t s Flush SLARP and CDP Statistics\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: mppipemon -i wp1_chdlc0 -u 9000 -c xm :View Modem Status \n"); - printf("\tex: mppipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n\n"); -} - -void chdlc_router_up_time( void ) -{ - unsigned long time; - cb.cblock.command= CPIPE_ROUTER_UP_TIME; - cb.cblock.buffer_length = 0; - cb.data[0] = 0; - DoCommand(); - - time = *(unsigned long*)&cb.data[0]; - - if (time < 3600) { - if (time<60) - printf(" Router UP Time: %ld seconds\n", time); - else - printf(" Router UP Time: %ld minute(s)\n", (time/60)); - }else - printf(" Router UP Time: %ld hour(s)\n", (time/3600)); - - -} - -void banner (char *title){ - - int len,i; - - len = strlen(title); - printf("\n\t"); - for (i=0;i<(len+16);i++) - printf("-"); - printf("\n\t\t%s",title); - printf("\n\t"); - for (i=0;i<(len+16);i++) - printf("-"); - printf("\n\n"); - -} - -void set_FT1_monitor_status( unsigned char status) -{ - gfail = 0; - cb.cblock.command= FT1_MONITOR_STATUS_CTRL; - cb.cblock.buffer_length = 1; - cb.data[0] = status; - DoCommand(); - if( (cb.cblock.return_code != 0) && status){ - gfail = 1; - printf("This command is only possible with S508/FT1 board!"); - } -} /* set_FT1_monitor_status */ - - -/* Subroutine for changing modes on a FT1 boards */ - -void set_FT1_mode(int verbose) -{ - int cnt=0; - - for(;;) { - cb.cblock.command= SET_FT1_MODE; - cb.cblock.buffer_length = 0; - DoCommand(); - if(cb.cblock.return_code == 0) { - if(verbose) { - printf("."); - fflush(stdout); - } - break; - } - if (++cnt == MAX_FT1_RETRY){ - break; - } - } -} /* set_FT1_mode */ - -/* Read the data for status of all the lights */ - -void read_FT1_status( void ) -{ - - cb.cblock.command= CPIPE_FT1_READ_STATUS; - cb.cblock.buffer_length = 0; - DoCommand(); - if(cb.cblock.return_code == 0) { - par_port_A_byte = cb.data[0]; - par_port_B_byte = cb.data[1]; - - if(!(par_port_A_byte & PP_A_RT_NOT_RED)) { - FT1_LED.RT_red ++; - } - if(!(par_port_A_byte & PP_A_RT_NOT_GREEN)) { - FT1_LED.RT_green ++; - } - if((par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) - == (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - FT1_LED.RT_off ++; - } - if(!(par_port_A_byte & PP_A_LL_NOT_RED)) { - FT1_LED.LL_red ++; - } - else { - FT1_LED.LL_off ++; - } - if(!(par_port_A_byte & PP_A_DL_NOT_RED)) { - FT1_LED.DL_red ++; - } - else { - FT1_LED.DL_off ++; - } - if(!(par_port_B_byte & PP_B_RxD_NOT_GREEN)) { - FT1_LED.RxD_green ++; - } - if(!(par_port_B_byte & PP_B_TxD_NOT_GREEN)) { - FT1_LED.TxD_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_GREEN)) { - FT1_LED.ERR_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_red ++; - } - if((par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) - == (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_off ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_RED)) { - FT1_LED.INS_red ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_GREEN)) { - FT1_LED.INS_green ++; - } - if((par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) - == (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - FT1_LED.INS_off ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_GREEN)) { - FT1_LED.ST_green ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_RED)) { - FT1_LED.ST_red ++; - } - if((par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) - == (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - FT1_LED.ST_off ++; - } - } -} /* read_FT1_status */ - -void read_ft1_op_stats( void ) -{ - fd_set ready; - struct timeval to; - unsigned short length; - - - printf("TIME: Time in seconds since the FT1 op stats were last reset\n"); - printf(" ES: Errored Second\n"); - printf(" BSE: Bursty Errored Second\n"); - printf(" SES: Severly Errored Second\n"); - printf(" UAS: Unavailable Second\n"); - printf("LOFC: Loss of Frame Count\n"); - printf(" ESF: ESF Error Count\n"); - - printf("\nFT1 CSU/DSU Operational Stats...(Press ENTER to exit)\n"); - for(;;){ - - cb.cblock.command= READ_FT1_OPERATIONAL_STATS; - cb.cblock.buffer_length = 0; - DoCommand(); - - FD_ZERO(&ready); - FD_SET(0,&ready); - to.tv_sec = 0; - to.tv_usec = 50000; - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - if( cb.cblock.buffer_length ){ - int i=0; - printf(" TIME ES BES SES UAS LOFC ESF\n"); - length = cb.cblock.buffer_length; - while(length){ - - printf("%c", cb.data[i]); - length--; - i++; - } - printf("\n"); - } - } -} - -int main(int argc, char* argv[]) -{ - int proceed; - char command; - char *opt; - - memset(&cb,0,sizeof(udp_mgmt_pkt_t)); - - printf("\n"); - if( argc > 2 ) { - - init( argc, argv); - command = cmd[0]; - opt = (char *) &cmd[1]; - - #ifdef LINUX_2_1 - proceed = MakeRawConnection(); - #else - printf("ERROR: Multi-Port PPP is not supported for kernels lower than 2.2.X\n"); - printf(" Upgrate to 2.2.X kernel for Multi-Port PPP support\n"); - exit(1); - #endif - - if(proceed == WAN_TRUE){ - switch(command){ - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt, "cv")){ - read_code_version(); - }else if (!strcmp(opt,"l")){ - link_status(); - }else if (!strcmp(opt,"ru")){ - chdlc_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type mppipemon for help\n\n"); - } - break; - case 's': - if (!strcmp(opt,"g")){ - global_stats(); - }else if (!strcmp(opt,"c")){ - comm_stats(); - }else if (!strcmp(opt,"o")){ - operational_stats(); - }else if (!strcmp(opt,"s")){ - slarp_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type mppipemon for help\n\n"); - - } - break; - case 'c': - if (!strcmp(opt,"rc")){ - chdlc_configuration(); - }else{ - printf("ERROR: Invalid Configuration Command 'c', Type mppipemon for help\n\n"); - } - break; - case 't': - if(!strcmp(opt,"i" )){ - raw_data = WAN_FALSE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "ip")){ - raw_data = WAN_FALSE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "id")){ - raw_data = WAN_FALSE; - line_trace(TRACE_DATA); - }else if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "rp")){ - raw_data = WAN_TRUE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "rd")){ - raw_data = WAN_TRUE; - line_trace(TRACE_DATA); - }else{ - printf("ERROR: Invalid Trace Command 't', Type mppipemon for help\n\n"); - } - break; - case 'f': - if (!strcmp(opt, "o")){ - flush_operational_stats(); - operational_stats(); - }else if (!strcmp(opt, "s")){ - flush_operational_stats(); - slarp_stats(); - }else if (!strcmp(opt, "g")){ - flush_global_stats(); - global_stats(); - }else if (!strcmp(opt, "c")){ - flush_comm_stats(); - comm_stats(); - } else{ - printf("ERROR: Invalid Flush Command 'f', Type mppipemon for help\n\n"); - } - break; - - case 'T': - if (!strcmp(opt, "v")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - view_FT1_status(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "s")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "l")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_local_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "d")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_digital_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "r")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_remote_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "o")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_operational_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "p")){ - set_FT1_monitor_status(0x02); - if(!gfail) - read_ft1_op_stats(); - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "f")){ - set_FT1_monitor_status(0x04); - if(!gfail){ - printf("Flushed Operational Statistics\n"); - }else{ - printf("FT1 Flush Failed %i\n",gfail); - } - } else{ - printf("ERROR: Invalid FT1 Command 'T', Type mppipemon for help\n\n"); - } - break; - - default: - printf("ERROR: Invalid Command, Type mppipemon for help\n\n"); - break; - }//switch - } - close( sock ); - } else { - usage(); - } //if - printf("\n"); - - return 0; -}; //main diff --git a/util/wanpipemon.old/ppipemon.c b/util/wanpipemon.old/ppipemon.c deleted file mode 100644 index a9ded73..0000000 --- a/util/wanpipemon.old/ppipemon.c +++ /dev/null @@ -1,1375 +0,0 @@ -/***************************************************************************** -* ppipemon.c PPP Monitor. -* -* Author: Nenad Corbic -* -* Copyright: (c) 1995-1999 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. -* ---------------------------------------------------------------------------- -* June 2, 2006 David Rokhvarg Fixed Statistics counters for PPP. -* Jan 11, 2005 David Rokhvarg Added code to run above AFT card with protocol -* in the LIP layer. -* Oct 18, 1999 Nenad Corbic Added new features for 2.1.0 release version -* Aug 13, 1998 Jaspreet Singh Improved line tracing code -* Dec 19, 1997 Jaspreet Singh Added 'irq timeouts' stat in -* 'READ_COMMS_ERR_STATISTICS'. -* Nov 24, 1997 Jaspreet Singh Added new stats for driver statistics -* Oct 20, 1997 Jaspreet Singh Added new wan_udphdr_commands for Driver statistics and -* Router Up time. -* Jul 28, 1997 Jaspreet Singh Added a new wan_udphdr_command for running line trace -* displaying RAW data. -* Jun 24, 1997 Jaspreet Singh S508/FT1 test wan_udphdr_commands -* Apr 25, 1997 Farhan Thawar Initial version based on wanpipemon for WinNT. -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) - -#define BANNER(str) banner(str,0) - - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -/* storage for FT1 LEDs */ -FT1_LED_STATUS FT1_LED; - -/* for S508/FT1 test wan_udphdr_commands */ -int fail; - -/* defines for now */ -extern int sock; -extern int raw_data; -extern int udp_port; -extern int trace_all_data; -extern char i_name[]; -extern int is_508; -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -static u_int32_t decode_bps( unsigned char bps ); -static void set_FT1_monitor_status( unsigned char); - - -static void ppp_driver_stat_gen( void ); - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -void PPP_set_FT1_mode( void ) -{ - for(;;){ - wan_udp.wan_udphdr_command = SET_FT1_MODE; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - if(wan_udp.wan_udphdr_return_code == 0){ - break; - } - } -} /* set_FT1_mode */ - -/* This subroutine enables the FT1 monitor on the board */ -static void set_FT1_monitor_status( unsigned char status) -{ - fail = 0; - wan_udp.wan_udphdr_command = FT1_MONITOR_STATUS_CTRL; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = status; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code != 0 && status){ - fail = 1; - printf("This wan_udphdr_command is only possible with S508/FT1 board!"); - } -} - -int PPPConfig( void ) -{ - unsigned char x=0; - char codeversion[20]; - - protocol_cb_size=sizeof(wan_mgmt_t) + sizeof(wan_cmd_t) + 1; - wan_udp.wan_udphdr_command = PPP_READ_CONFIG; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - while (++x < 4){ - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - - if (wan_udp.wan_udphdr_return_code == 0xCC){ - return(WAN_FALSE); - } - wan_udp.wan_udphdr_return_code = 0xaa; - } - - if (x >= 4) return(WAN_FALSE); - - if( wan_udp.wan_udphdr_data_len == 0x73 ) { - is_508 = WAN_TRUE; - } else { - is_508 = WAN_FALSE; - } - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = PPP_READ_CODE_VERSION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - return(WAN_TRUE); -}; - -void PPP_read_FT1_status( void ) -{ - wan_udp.wan_udphdr_command = PPIPE_FT1_READ_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ){ - par_port_A_byte = wan_udp.wan_udphdr_data[0]; - par_port_B_byte = wan_udp.wan_udphdr_data[1]; - - - if(!(par_port_A_byte & PP_A_RT_NOT_RED)) { - FT1_LED.RT_red ++; - } - if(!(par_port_A_byte & PP_A_RT_NOT_GREEN)) { - FT1_LED.RT_green ++; - } - if((par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) - == (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - FT1_LED.RT_off ++; - } - if(!(par_port_A_byte & PP_A_LL_NOT_RED)) { - FT1_LED.LL_red ++; - } - else { - FT1_LED.LL_off ++; - } - if(!(par_port_A_byte & PP_A_DL_NOT_RED)) { - FT1_LED.DL_red ++; - } - else { - FT1_LED.DL_off ++; - } - if(!(par_port_B_byte & PP_B_RxD_NOT_GREEN)) { - FT1_LED.RxD_green ++; - } - if(!(par_port_B_byte & PP_B_TxD_NOT_GREEN)) { - FT1_LED.TxD_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_GREEN)) { - FT1_LED.ERR_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_red ++; - } - if((par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) - == (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_off ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_RED)) { - FT1_LED.INS_red ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_GREEN)) { - FT1_LED.INS_green ++; - } - if((par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) - == (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - FT1_LED.INS_off ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_GREEN)) { - FT1_LED.ST_green ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_RED)) { - FT1_LED.ST_red ++; - } - if((par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) - == (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - FT1_LED.ST_off ++; - } - } -} /* read_FT1_status */ - - - -static u_int32_t decode_bps( unsigned char bps ) -{ - u_int32_t number; - - switch( bps ) { - case 0x00: - number = 0; - break; - case 0x01: - number = 1200; - break; - case 0x02: - number = 2400; - break; - case 0x03: - number = 4800; - break; - case 0x04: - number = 9600; - break; - case 0x05: - number = 19200; - break; - case 0x06: - number = 38400; - break; - case 0x07: - number = 45000; - break; - case 0x08: - number = 56000; - break; - case 0x09: - number = 64000; - break; - case 0x0A: - number = 74000; - break; - case 0x0B: - number = 112000; - break; - case 0x0C: - number = 128000; - break; - case 0x0D: - number = 156000; - break; - default: - number = 0; - break; - } /* switch */ - - return number; -}; /* decode_bps */ - -static void error( void ) -{ - printf("Error: Command failed!\n"); -} - -static void general_conf( void ) -{ - u_int32_t baud; - unsigned short s_number, mtu, mru; - unsigned char misc; - - wan_udp.wan_udphdr_command = PPP_READ_CONFIG; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - if( is_508 == WAN_TRUE ) { - BANNER("GENERAL CONFIGURATION 508 Board"); - memcpy(&baud,&wan_udp.wan_udphdr_data[0],4); - memcpy(&s_number,&wan_udp.wan_udphdr_data[4],2); - printf("Transmit buffer allocation in percent: %u\n", - s_number); - misc = wan_udp.wan_udphdr_data[6]; - printf("Use alternate adapter frequency: "); - ( misc & 0x10 ) ? printf("Yes\n") : printf("No\n"); - printf("Set interface type to RS-232: "); - ( misc & 0x20 ) ? printf("Yes\n") : printf("No\n"); - memcpy(&mtu, &wan_udp.wan_udphdr_data[8],2); - memcpy(&mru, &wan_udp.wan_udphdr_data[10],2); - } else { - BANNER("GENERAL CONFIGURATION 502 Board"); - baud = decode_bps(wan_udp.wan_udphdr_data[0]); - misc = wan_udp.wan_udphdr_data[3]; - printf("Discard transmit-aborted frames: "); - ( misc & 0x01 ) ? printf("Yes\n") : printf("No\n"); - memcpy(&mtu, &wan_udp.wan_udphdr_data[5],2); - memcpy(&mru, &wan_udp.wan_udphdr_data[7],2); - } - - printf("Baud rate in bps: %u\n",baud); - printf("Update transmit statistics( user data ): "); - ( misc & 0x02 ) ? printf("Yes\n") : printf("No\n"); - printf("Update receive statistics( user data ): "); - ( misc & 0x04 ) ? printf("Yes\n") : printf("No\n"); - printf("Timestamp received packets: "); - ( misc & 0x08 ) ? printf("Yes\n") : printf("No\n"); - printf("Maximum Receive/Transmit Unit(MRU/MTU): %u\n",mtu); - printf("Minimum remote MRU required on connection: %u\n",mtu); - } else { - error(); - } -}; /* general_conf */ - -static void authent( void ) -{ - s_auth_t *auth = (s_auth_t *)&wan_udp.wan_udphdr_data[0]; - - wan_udp.wan_udphdr_command = PPP_READ_AUTH; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("PPP AUTHENTICATION"); - printf("Allow the use of PAP for inbound/outbound: "); - if (auth->proto == PPP_PAP) { - printf("Yes\n"); - } - else { - printf("No\n"); - } - printf("Allow the use of CHAP for inbound/outbound: "); - if (auth->proto == PPP_CHAP) { - printf("Yes\n"); - } - else { - printf("No\n"); - } - - printf("Current Authentication Status:"); - if (auth->authenticated == 1) { - printf(" Authenticated\n"); - } - else { - printf(" Not Authenticated\n"); - } - -#if 0 - if( is_508 == WAN_TRUE ) { - tmp = wan_udp.wan_udphdr_data[32]; - } else { - tmp = wan_udp.wan_udphdr_data[29]; - } - - if( tmp & 0x01 ) { - printf("Allow the use of PAP for inbound/outbound: Yes\n"); - if( tmp & 0x80 ) { - printf("Using inbound authentication.\n"); - } else { - printf("Using outbound authentication.\n"); - } //if - } else { - printf("Allow the use of PAP for inbound/outbound: No\n" ); - } //if - - if( tmp & 0x02 ) { - printf("Allow the use of CHAP for inbound/outbound: Yes\n"); - if( tmp & 0x80 ) { - printf("Using inbound authentication.\n"); - } else { - printf("Using outbound authentication.\n"); - } //if - } else { - printf("Allow the use of CHAP for inbound/outbound: No\n"); - } //if -#endif - } else { - error(); - } //if -}; /* authent */ - -static void ip_config( void ) -{ - int i; - - wan_udp.wan_udphdr_command = PPP_READ_CONFIG; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("PPP IP CONFIGURATION"); - - if( is_508 == WAN_TRUE ) { - i = 33; - } else { - i = 30; - } //if - printf("Enable the use of IP: "); - ( wan_udp.wan_udphdr_data[i] & 0x80 ) ? printf("Yes\n") : printf("No\n"); - printf("Notify remote of locally-configure address: "); - ( wan_udp.wan_udphdr_data[i] & 0x01 ) ? printf("Yes\n") : printf("No\n"); - printf("Local IP address( 0.0.0.0 = request ): %u.%u.%u.%u\n", - wan_udp.wan_udphdr_data[i+1],wan_udp.wan_udphdr_data[i+2],wan_udp.wan_udphdr_data[i+3],wan_udp.wan_udphdr_data[i+4]); - printf("Request remote to provide local address: "); - ( wan_udp.wan_udphdr_data[i] & 0x02 ) ? printf("Yes\n") : printf("No\n"); - printf("Provide remote with pre-configured address: "); - ( wan_udp.wan_udphdr_data[i] & 0x04 ) ? printf("Yes\n") : printf("No\n"); - printf("Remote IP address: %u.%u.%u.%u\n",wan_udp.wan_udphdr_data[i+5], - wan_udp.wan_udphdr_data[i+6],wan_udp.wan_udphdr_data[i+7],wan_udp.wan_udphdr_data[i+8]); - printf("Require that remote provide an address: "); - ( wan_udp.wan_udphdr_data[i] & 0x08 ) ? printf("Yes\n") : printf("No\n"); - } else { - error(); - } -}; /* ip_config */ - -static void ipx_config( void ) -{ - int i; - - wan_udp.wan_udphdr_command = PPP_READ_CONFIG; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("PPP IPX CONFIGURATION"); - - if( is_508 == WAN_TRUE ) { - i = 42; - } else { - i = 39; - } //if - - printf("Enable the use of IPX: "); - ( wan_udp.wan_udphdr_data[i] & 0x80 ) ? printf("Yes\n") : printf("No\n"); - printf("Include network number in Config-Request: "); - ( wan_udp.wan_udphdr_data[i] & 0x01 ) ? printf("Yes\n") : printf("No\n"); - printf("Network number( 00000000 = request ): %02X %02X %02X %02X\n",wan_udp.wan_udphdr_data[i+1],wan_udp.wan_udphdr_data[i+2],wan_udp.wan_udphdr_data[i+3],wan_udp.wan_udphdr_data[i+4]); - printf("Include local node # in Config-Request: "); - ( wan_udp.wan_udphdr_data[i] & 0x02 ) ? printf("Yes\n") : printf("No\n"); - printf("Local node number( 000000000000 = request ): %02X %02X %02X %02X %02X %02X\n",wan_udp.wan_udphdr_data[i+5],wan_udp.wan_udphdr_data[i+6],wan_udp.wan_udphdr_data[i+7],wan_udp.wan_udphdr_data[i+8],wan_udp.wan_udphdr_data[i+9],wan_udp.wan_udphdr_data[i+10]); - printf("Force remote to accept remote node number: "); - ( wan_udp.wan_udphdr_data[i] & 0x04 ) ? printf("Yes\n") : printf("No\n"); - printf("Remote node number: %02X %02X %02X %02X %02X %02X\n", - wan_udp.wan_udphdr_data[i+11],wan_udp.wan_udphdr_data[i+12],wan_udp.wan_udphdr_data[i+13],wan_udp.wan_udphdr_data[i+14], - wan_udp.wan_udphdr_data[i+15],wan_udp.wan_udphdr_data[i+16]); - printf("Include config-complete in Config-Request: "); - ( wan_udp.wan_udphdr_data[i] & 0x40 ) ? printf("Yes\n") : printf("No\n"); - - if( wan_udp.wan_udphdr_data[i] & 0x20 ) { - printf("Routing protocol: Request default( normally RIP/SAP )\n"); - } else if( wan_udp.wan_udphdr_data[i] & 0x18 ){ - printf("Routing protocol: Use either RIP/SAP or NLSP\n"); - } else if( wan_udp.wan_udphdr_data[i] & 0x08 ){ - printf("Routing protocol: Use RIP/SAP only\n"); - } else if( wan_udp.wan_udphdr_data[i] & 0x10 ){ - printf("Routing protocol: Use NLSP only\n"); - } else { - printf("Routing protocol: No routing protocol\n"); - } //if - printf("Local router name( max. 47 characters ): %s\n", - &wan_udp.wan_udphdr_data[i+17]); - } else { - error(); - } //if -}; /* ipx_config */ - -/* -static void set_state( unsigned char tmp ) -{ - switch( tmp ) { - case 0: - printf("Initial\n"); - break; - case 1: - printf("Starting\n"); - break; - case 2: - printf("Closed\n"); - break; - case 3: - printf("Stopped\n"); - break; - case 4: - printf("Closing\n"); - break; - case 5: - printf("Stopping\n"); - break; - case 6: - printf("Request Sent\n"); - break; - case 7: - printf("Ack Received\n"); - break; - case 8: - printf("Ack Sent\n"); - break; - case 9: - printf("Opened\n"); - break; - default: - printf("Unknown\n"); - break; - } //switch - -} -*/ - -static void state( void ) -{ - wan_udp.wan_udphdr_command = PPP_GET_LINK_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("PPP LINK STATUS"); - printf("Link Status: %s\n", (wan_udp.wan_udphdr_data[0] == 1 ? "Connected" : "Disconnected")); - } else { - error(); - } -}; /* state */ - -static void lcp( void ) -{ - ppp_lcp_stats_t *lcp_stats = (ppp_lcp_stats_t *)&wan_udp.wan_udphdr_data[0]; - - wan_udp.wan_udphdr_command = PPP_READ_LCP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("LCP STATISTICS"); - - printf("Packets discarded (unknown LCP code): %u\n", - lcp_stats->rx_unknown); - printf("Received LCP packets too large: %u\n", - lcp_stats->rx_too_large); - printf("Received packets invalid or out-of-sequence Configure-Acks: %u\n", - lcp_stats->rx_ack_inval); - printf("Received packets invalid Configure-Naks or Configure-Rejects: %u\n", - lcp_stats->rx_rej_inval); - printf("Configure-Naks or Configure-Rejects with bad Identifier: %u\n", - lcp_stats->rx_rej_badid); - - printf("\n\t\t\tReceived\tTransmitted\n"); - printf("Number of Config-Request pkts: %u\t%u\n", - lcp_stats->rx_conf_rqst, lcp_stats->tx_conf_rqst); - - printf("Number of Config-Ack packets : %u\t%u\n", - lcp_stats->rx_conf_ack ,lcp_stats->tx_conf_ack ); - printf("Number of Config-Nack packets: %u\t%u\n", - lcp_stats->rx_conf_nak, lcp_stats->tx_conf_nak); - printf("Number of Config-Reject packets: %u\t%u\n", - lcp_stats->rx_conf_rej , lcp_stats->tx_conf_rej); - printf("Number of Term-Reqst packets : %u\t%u\n", - lcp_stats->rx_term_rqst, lcp_stats->tx_term_rqst); - printf("Number of Terminate-Ack packets: %u\t%u\n", - lcp_stats->rx_term_ack, lcp_stats->tx_term_ack); - printf("Number of Code-Reject packets: %u\t%u\n", - lcp_stats->rx_code_rej, lcp_stats->tx_code_rej); - printf("Number of Protocol-Rej packets: %u\t%u\n", - lcp_stats->rx_proto_rej, lcp_stats->tx_proto_rej); - printf("Number of Echo-Request packets: %u\t%u\n", - lcp_stats->rx_echo_rqst, lcp_stats->tx_echo_rqst); - printf("Number of Echo-Reply packets : %u\t%u\n", - lcp_stats->rx_echo_reply, lcp_stats->tx_echo_reply); - printf("Number of Discard-Request packets: %u\t%u\n", - lcp_stats->rx_disc_rqst, lcp_stats->tx_disc_rqst); - } else { - error(); - } -}; /* lcp */ - -static void flush_lcp( void ) -{ - wan_udp.wan_udphdr_command = PPP_FLUSH_LCP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - if( wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -}; /* flush_packet */ - -static void ipcp( void ) -{ - ppp_prot_stats_t *ipcp_stats = (ppp_prot_stats_t*)&wan_udp.wan_udphdr_data[0]; - - wan_udp.wan_udphdr_command = PPP_READ_IPCP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("IPCP STATISTICS"); - - printf("Packets discarded (unknown IPCP code): %u\n", ipcp_stats->rx_unknown); - printf("Received IPCP packets too large: %u\n", ipcp_stats->rx_too_large); - printf("Received packets invalid or out-of-sequence Configure-Acks: %u\n", ipcp_stats->rx_ack_inval); - printf("Received packets invalid Configure-Naks or Configure-Rejects: %u\n", ipcp_stats->rx_ack_inval); - printf("Configure-Naks or Configure-Rejects with bad Identifier: %u\n", ipcp_stats->rx_rej_badid); - - printf("\n\t\t\tReceived\tTransmitted\n"); - printf("Number of Config-Request pkts: %u\t%u\n", - ipcp_stats->rx_conf_rqst, ipcp_stats->tx_conf_rqst); - printf("Number of Config-Ack packets : %u\t%u\n", - ipcp_stats->rx_conf_ack, ipcp_stats->tx_conf_ack); - printf("Number of Config-Nack packets: %u\t%u\n", - ipcp_stats->rx_conf_nak, ipcp_stats->tx_conf_nak); - printf("Number of Config-Reject packets: %u\t%u\n", - ipcp_stats->rx_conf_rej, ipcp_stats->tx_conf_rej); - printf("Number of Term-Reqst packets : %u\t%u\n", - ipcp_stats->rx_term_rqst, ipcp_stats->tx_term_rqst); - printf("Number of Terminate-Ack packets: %u\t%u\n", - ipcp_stats->rx_term_ack, ipcp_stats->tx_term_ack); - printf("Number of Code-Reject packets: %u\t%u\n", - ipcp_stats->rx_code_rej, ipcp_stats->tx_code_rej); - } else { - error(); - } -}; /* ipcp */ - -static void flush_ipcp( void ) -{ - wan_udp.wan_udphdr_command = PPP_FLUSH_IPCP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -}; /* flush_ipcp */ - -#if 0 -static void ipxcp( void ) -{ - unsigned short tmp, tmp2; - - wan_udp.wan_udphdr_command = PPP_READ_IPXCP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - if( wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("IPXCP STATISTICS"); - - memcpy(&tmp,&wan_udp.wan_udphdr_data[0],2); - printf("Packets discarded (unknown IPXCP code): %u\n",tmp); - memcpy(&tmp,&wan_udp.wan_udphdr_data[32],2); - printf("Received IPXCP packets too large: %u\n",tmp); - memcpy(&tmp,&wan_udp.wan_udphdr_data[34],2); - printf("Received packets invalid or out-of-sequence Configure-Acks: %u\n",tmp); - memcpy(&tmp,&wan_udp.wan_udphdr_data[36],2); - printf("Received packets invalid Configure-Naks or Configure-Rejects: %u\n",tmp); - memcpy(&tmp,&wan_udp.wan_udphdr_data[38],2); - printf("Configure-Naks or Configure-Rejects with bad Identifier: %u\n",tmp); - printf("\n\t\t\tReceived\tTransmitted\n"); - memcpy(&tmp,&wan_udp.wan_udphdr_data[2],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[18],2); - printf("Number of Config-Request pkts: %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[4],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[20],2); - printf("Number of Config-Ack packets : %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[6],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[22],2); - printf("Number of Config-Nack packets: %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[8],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[24],2); - printf("Number of Config-Reject packets: %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[10],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[26],2); - printf("Number of Term-Reqst packets : %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[12],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[28],2); - printf("Number of Terminate-Ack packets: %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[14],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[30],2); - printf("Number of Code-Reject packets: %u\t%u\n",tmp,tmp2); - } else { - error(); - } //if -}; /* ipxcp */ - -static void flush_ipxcp( void ) -{ - wan_udp.wan_udphdr_command = PPP_FLUSH_IPXCP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - if( wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -}; /* flush_ipxcp */ -#endif - -static void pap( void ) -{ - unsigned short tmp, tmp2; - - wan_udp.wan_udphdr_command = PPP_READ_PAP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - - BANNER("PAP STATISTICS"); - - memcpy(&tmp,&wan_udp.wan_udphdr_data[0],2); - printf("Packets discarded (unknown PAP code): %u\n",tmp); - memcpy(&tmp,&wan_udp.wan_udphdr_data[16],2); - printf("Received PAP packets too large: %u\n",tmp); - memcpy(&tmp,&wan_udp.wan_udphdr_data[18],2); - printf("Received packets invalid inbound PeerID: %u\n",tmp); - memcpy(&tmp,&wan_udp.wan_udphdr_data[20],2); - printf("Received packets invalid inbound Password: %u\n",tmp); - printf("\n\t\t\tReceived\tTransmitted\n"); - memcpy(&tmp,&wan_udp.wan_udphdr_data[2],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[10],2); - printf("Number of Authent-Request pkts: %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[4],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[12],2); - printf("Number of Authent-Ack packets : %u\t%u\n",tmp,tmp2); - memcpy(&tmp,&wan_udp.wan_udphdr_data[6],2); - memcpy(&tmp2,&wan_udp.wan_udphdr_data[14],2); - printf("Number of Authent-Nack packets: %u\t%u\n",tmp,tmp2); - } else { - error(); - } -}; /* pap */ - -static void flush_pap( void ) -{ - wan_udp.wan_udphdr_command = PPP_FLUSH_PAP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - if( wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -}; /* flush_pap */ - -static void chap( void ) -{ - ppp_chap_stats_t *chap_stats; - - wan_udp.wan_udphdr_command = PPP_READ_CHAP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("CHAP STATISTICS"); - chap_stats = (ppp_chap_stats_t*)&wan_udp.wan_udphdr_data[0]; - /*chap_stats = (ppp_chap_stats_t*)&wan_udp.wan_udphdr_u.data[0];*/ - - printf("Packets discarded (unknown CHAP code): %u\n", chap_stats->rx_unknown); - printf("Received CHAP packets too large: %u\n", chap_stats->rx_too_large); - printf("Received packets invalid inbound PeerID: %u\n", chap_stats->rx_bad_peerid); - printf("Received packets invalid inbound Password/Secret: %u\n", chap_stats->rx_bad_passwd); - printf("Received packets invalid inbound MD5 message digest format: %u\n", chap_stats->rx_bad_md5); - /*printf("Invalid inbound ID or out-of-order or unelicited responses: %u\n", chap_stats->);*/ - printf("\n\t\t\tReceived\tTransmitted\n"); - printf("Number of Challenge packets : %u\t%u\n", chap_stats->rx_challenge, chap_stats->tx_challenge); - printf("Number of Response packets : %u\t%u\n", chap_stats->rx_response, chap_stats->tx_response); - printf("Number of Success packets : %u\t%u\n", chap_stats->rx_success, chap_stats->tx_success); - printf("Number of Failure packets : %u\t%u\n", chap_stats->rx_failure, chap_stats->tx_failure); - } else { - error(); - } -}; /* chap */ - -static void flush_chap( void ) -{ - wan_udp.wan_udphdr_command = PPP_FLUSH_CHAP_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -}; /* flush_chap */ - -static void data_packet_stats( void ) -{ - ppp_pkt_stats_t *packet_stats; - wan_udp.wan_udphdr_command = PPP_READ_PACKET_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - packet_stats = (ppp_pkt_stats_t *)&wan_udp.wan_udphdr_data[0]; - - if( wan_udp.wan_udphdr_return_code == 0 ) { - - BANNER("PACKET STATISTICS"); - - printf("Number discards( bad header ): %u\n", - packet_stats->rx_bad_header); - printf("Number discards( unknown/unsupported protocol ): %u\n", - packet_stats->rx_prot_unknwn); - printf("Number discards(unknown/unsupported protocol+too large for Protocol-Reject): %u\n", - packet_stats->rx_too_large); - printf("\n\t\t\tReceived\tTransmitted\n"); - printf("Number of LCP packets: %u\t\t%u\n", - packet_stats->rx_lcp,packet_stats->tx_lcp); - printf("Number of IPCP packets: %u\t\t%u\n", - packet_stats->rx_ipcp, packet_stats->tx_ipcp); - printf("Number of IPXCP packets: %u\t\t%u\n", - packet_stats->rx_ipxcp,packet_stats->tx_ipxcp); - printf("Number of PAP packets: %u\t\t%u\n", - packet_stats->rx_pap,packet_stats->tx_pap); - printf("Number of CHAP packets: %u\t\t%u\n", - packet_stats->rx_chap,packet_stats->tx_chap); - printf("Number of LQR packets: %u\t\t%u\n", - packet_stats->rx_lqr,packet_stats->tx_lqr); - printf("Number of IP packets: %u\t\t%u\n", - packet_stats->rx_ip,packet_stats->tx_ip); - printf("Number of IPX packets: %u\t\t%u\n", - packet_stats->rx_ipx,packet_stats->tx_ipx); - } else { - error(); - } -}; /* packet */ - -static void flush_data_packet_stats(void) -{ - flush_lcp(); - flush_ipcp(); - flush_pap(); - flush_chap(); - - wan_udp.wan_udphdr_command = PPP_FLUSH_PACKET_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } -}; - -int PPPUsage( void ) -{ - printf("wanpipemon: Wanpipe PPP Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("wanpipemon -i -u -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address must be supplied\n"); - printf("\t\t Wanpipe network interface name (ex: w1g1ppp)\n"); - printf("\tOption -u: (Optional, default: 9000)\n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -full: (Optional, trace option)\n"); - printf("\t\tDisplay raw packets in full: default trace pkt len=25bytes\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t n PPP Link Status\n"); - printf("\t ru Display Router UP time\n"); - printf("\tCard Statistics\n"); - printf("\t s g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t p General Packet Statistics\n"); - printf("\t lcp LCP Statistics\n"); - printf("\t ipc IP Control Protocol( IPCP )Statistics\n"); - //printf("\t xcp IPX Control Protocol( IPXCP )Statistics\n"); - printf("\t pap Password Authentication (PAP) Statistics\n"); - printf("\t chp Challenge-Handshake Auth.(CHAP) Statistics\n"); - printf("\tTrace Data\n"); - printf("\t t i Trace and Interpret ALL frames\n"); - //printf("\t ip Trace and Interpret PROTOCOL frames only\n"); - //printf("\t id Trace and Interpret DATA frames only\n"); - printf("\t r Trace ALL frames, in RAW format\n"); - //printf("\t rp Trace PROTOCOL frames only, in RAW format\n"); - //printf("\t rd Trace DATA frames only, in RAW format\n"); - printf("\tFT1/T1/E1/56K Configuration/Statistics\n"); - printf("\t T v View Status\n"); - printf("\t s Self Test\n"); - printf("\t l Line Loop Test\n"); - printf("\t d Digital Loop Test\n"); - printf("\t r Remote Test\n"); - printf("\t o Operational Mode\n"); - printf("\t read Read CSU/DSU configuration (FT1/T1/E1 card)\n"); - printf("\t allb Active Line Loopback mode (T1/E1 card only)\n"); - printf("\t dllb Deactive Line Loopback mode (T1/E1 card only)\n"); - printf("\t aplb Active Payload Loopback mode (T1/E1 card only)\n"); - printf("\t dplb Deactive Payload Loopback mode (T1/E1 card only)\n"); - printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t salb Send Loopback Activate Code (T1/E1 card only)\n"); - printf("\t sdlb Send Loopback Deactive Code (T1/E1 card only)\n"); - printf("\t a Read T1/E1/56K alarms\n"); - printf("\tFlush Statistics\n"); - printf("\t f g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t p General Packet Statistics\n"); - printf("\t lcp LCP Statistics\n"); - printf("\t ipc IP Control Protocol( IPCP )Statistics\n"); - printf("\t ipxc IPX Control Protocol( IPXCP )Statistics\n"); - printf("\t pap Password Authentication (PAP) Statistics\n"); - printf("\t chp Challenge-Handshake Auth.(CHAP) Statistics\n"); - printf("\t d Flush Driver Statistics\n"); - printf("\t pm Flush T1/E1 performance monitoring counters\n"); - printf("\tDriver Statistics\n"); - printf("\t d s Display Send Driver Statistics\n"); - printf("\t i Display Interrupt Driver Statistics\n"); - printf("\t g Display General Driver Statistics\n"); - printf("\n\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: wanpipemon -i w1g1ppp -u 9000 -c xm :View Modem Status \n"); - printf("\tex: wanpipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n\n"); - return 0; -} - -static char *gui_main_menu[]={ -"ppp_card_stats_menu","Card Status", -"ppp_stats_menu","Card Statistics", -"ppp_trace_menu","Trace Data", -"csudsu_menu","CSU DSU Config/Stats", -"ppp_flush_menu","Flush Statistics", -"ppp_driver_menu","Driver Statistics", -"." -}; - -static char *ppp_card_stats_menu[]={ -"xm","Modem Status", -"xs","PPP Link Status", -"xru","Display Router UP time", -"." -}; - -static char *ppp_stats_menu[]={ -"sg","Global Statistics", -"sc","Communication Error Statistics", -"sp","Data Packet Statistics", -"slcp","LCP Statistics", -"sipc","IP Control Protocol( IPCP )Statistics", -//"sxcp","IPX Control Protocol( IPXCP )Statistics", -"spap","Password Authentication (PAP) Statistics", -"schp","Challenge-Handshake Auth.(CHAP) Statistics", -"." -}; - -static char *ppp_trace_menu[]={ -"ti","Trace and Interpret ALL frames", -//"tip","Trace and Interpret PROTOCOL frames only", -//"tid","Trace and Interpret DATA frames only", -"tr","Trace ALL frames, in RAW format", -//"trp","Trace PROTOCOL frames only, in RAW format", -//"trd","Trace DATA frames only, in RAW format", -"." -}; - -#if 0 -static char *ppp_csudsu_menu[]={ -"Tv","View Status", -"Ts","Self Test", -"Tl","Line Loop Test", -"Td","Digital Loop Test", -"Tr","Remote Test", -"To","Operational Mode", -"Tread","Read CSU/DSU config (FT1/T1/E1)", -"Tallb","E Line Loopback (T1/E1)", -"Tdllb","D Line Loopback (T1/E1)", -"Taplb","E Payload Loopback (T1/E1)", -"Tdplb","D Payload Loopback (T1/E1)", -"Tadlb","E Diag Digital Loopback (T1/E1)", -"Tddlb","D Diag Digital Loopback (T1/E1)", -"Tsalb","Send Loopback Activate Code (T1/E1)", -"Tsdlb","Send Loopback Deactive Code (T1/E1)", -"Ta","Read T1/E1/56K alrams", -"." -}; -#endif - -static char *ppp_flush_menu[]={ -"fg","Flush Global Statistics", -"fc","Flush Communication Error Statistics", -"fp","Flush General Packet Statistics", -"flcp","Flush LCP Statistics", -"fipc","Flush IP Control Protocol( IPCP )Statistics", -//"fxcp","Flush IPX Control Protocol( IPXCP )Statistics", -"fpap","Flush Password Authentication (PAP) Statistics", -"fchp","Flush Challenge-Handshake Auth.(CHAP) Statistics", -"fd","Flush Driver Statistics", -"fpm","Flush T1/E1 performance monitoring counters", -"." -}; - -static char *ppp_driver_menu[]={ -"ds","Display Send Driver Statistics", -//"di","Display Interrupt Driver Statistics", -"dg","Display General Driver Statistics", -"." -}; - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"ppp_card_stats_menu",ppp_card_stats_menu}, - {"ppp_stats_menu",ppp_stats_menu}, - {"ppp_trace_menu",ppp_trace_menu}, - {"csudsu_menu",csudsu_menu}, - {"ppp_flush_menu",ppp_flush_menu}, - {"ppp_driver_menu",ppp_driver_menu}, - {".",NULL} -}; - - -char ** PPPget_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** PPPget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - -int PPPDisableTrace(void) -{ - wan_udp.wan_udphdr_command = PPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = DISABLE_TRACING; - DO_COMMAND(wan_udp); - return 0; -} - -static void line_trace(int trace_mode) -{ - hw_line_trace(trace_mode); -} - -static void modem( void ) -{ - hw_modem(); -} - -static void general_stats( void ) -{ - hw_general_stats(); -} - -static void flush_general_stats( void ) -{ - hw_flush_general_stats(); -} - -static void comm_err( void ) -{ - hw_comm_err(); -} - -static void flush_comm_err( void ) -{ - hw_flush_comm_err(); -} - -static void ppp_driver_stat_ifsend( void ) -{ - ppp_driver_stat_gen(); -} - -static void ppp_driver_stat_gen( void ) -{ - hw_general_stats(); -} - -static void flush_driver_stats( void ) -{ - hw_flush_general_stats(); -} - -static void ppp_router_up_time( void ) -{ - hw_router_up_time(); -} - -int PPPMain(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - - global_command = command; - global_argc = argc; - global_argv = argv; - - printf("\n"); - switch(command[0]) { - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt,"s")){ - state(); - }else if (!strcmp(opt,"ru")){ - ppp_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type wanpipemon for help\n\n"); - } - break; - - case 'c': - if (!strcmp(opt,"i")){ - ip_config(); - }else if (!strcmp(opt,"x")){ - ipx_config(); - }else if (!strcmp(opt,"a")){ - authent(); - }else if (!strcmp(opt,"g")){ - general_conf(); - }else{ - printf("ERROR: Invalid Configuration Command 'c', Type wanpipemon for help\n\n"); - } - break; - - case 's': - if (!strcmp(opt,"g")){ - general_stats(); - }else if (!strcmp(opt,"c")){ - comm_err(); - }else if (!strcmp(opt,"pap")){ - pap(); - }else if (!strcmp(opt,"chp")){ - chap(); - }else if (!strcmp(opt,"ipc")){ - ipcp(); - /* - }else if (!strcmp(opt,"xcp")){ - ipxcp(); - */ - }else if (!strcmp(opt,"lcp")){ - lcp(); - }else if (!strcmp(opt,"p")){ - data_packet_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type wanpipemon for help\n\n"); - } - break; - - case 't': - if(!strcmp(opt,"i" )){ - raw_data = WAN_FALSE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "ip")){ - raw_data = WAN_FALSE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "id")){ - raw_data = WAN_FALSE; - line_trace(TRACE_DATA); - }else if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "rp")){ - raw_data = WAN_TRUE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "rd")){ - raw_data = WAN_TRUE; - line_trace(TRACE_DATA); - }else{ - printf("ERROR: Invalid Trace Command 't', Type wanpipemon for help\n\n"); - } - break; - - case 'd': - if(!strcmp(opt,"s" )){ - ppp_driver_stat_ifsend(); - }else if (!strcmp(opt,"g" )){ - ppp_driver_stat_gen(); - }else{ - printf("ERROR: Invalid Driver Stat Command 't', Type wanpipemon for help\n\n"); - } - break; - - case 'f': - if(!strcmp(opt,"g" )){ - flush_general_stats(); - general_stats(); - }else if (!strcmp(opt,"c" )){ - flush_comm_err(); - comm_err(); - }else if (!strcmp(opt,"p" )){ - flush_data_packet_stats(); - data_packet_stats(); - }else if (!strcmp(opt,"lcp" )){ - flush_lcp(); - lcp(); - }else if (!strcmp(opt,"ipc" )){ - flush_ipcp(); - ipcp(); - /* - }else if (!strcmp(opt,"xcp" )){ - flush_ipxcp(); - ipxcp(); - */ - }else if (!strcmp(opt,"pap" )){ - flush_pap(); - pap(); - }else if (!strcmp(opt,"chp" )){ - flush_chap(); - chap(); - }else if (!strcmp(opt,"d" )){ - flush_driver_stats(); - }else if (!strcmp(opt,"pm" )){ - flush_te1_pmon(); - } else { - printf("ERROR: Invalid Flush Command: '%s', Type wanpipemon for help\n\n", opt); - } - break; - case 'T': - if (!strcmp(opt,"v" )){ - set_FT1_monitor_status(0x01); - if(!fail){ - view_FT1_status(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt,"s" )){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt,"l" )){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_local_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt,"d" )){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_digital_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt,"r" )){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_remote_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt,"o" )){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_operational_mode(); - } - set_FT1_monitor_status(0x00); - - }else if (!strcmp(opt,"read")){ - read_te1_56k_config(); - }else if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"a")){ - read_te1_56k_stat(0); - } else{ - printf("ERROR: Invalid FT1 Command 'T', Type wanpipemon for help\n\n"); - } - break; - default: - printf("ERROR: Invalid Command, Type wanpipemon for help\n\n"); - - } //switch - printf("\n"); - fflush(stdout); - return 0; -}; //main - -/* - * EOF wanpipemon.c - */ diff --git a/util/wanpipemon.old/ppipemon.o b/util/wanpipemon.old/ppipemon.o deleted file mode 100644 index 29411be0c521dc3b74838906a76a6eb87a8ed722..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31008 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 diff --git a/util/wanpipemon.old/prot_trace.c b/util/wanpipemon.old/prot_trace.c deleted file mode 100644 index 8c0aa5d..0000000 --- a/util/wanpipemon.old/prot_trace.c +++ /dev/null @@ -1,1892 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - -#define X25_MOD8 0x01 -#define X25_MOD128 0x10 - -#define PCAP_MAGIC 0xa1b2c3d4 - -extern trace_prot_t trace_prot_opt; -extern trace_prot_t trace_x25_prot_opt; -extern unsigned int TRACE_DLCI; -extern unsigned char TRACE_PROTOCOL; -extern unsigned int DECODE_PROTOCOL; -extern unsigned int TRACE_X25_LCN; -extern unsigned char TRACE_X25_OPT; -extern char TRACE_EBCDIC; -extern char TRACE_ASCII; -extern char TRACE_HEX; -extern int sys_timestamp; - -extern wanpipe_hdlc_engine_t *rx_hdlc_eng; - -static char ebcdic[] = -{ -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ -/* 40 */ ' ','.','.','.','.','.','.','.','.','.','[','.','<','(','+','!', -/* 50 */ '&','.','.','.','.','.','.','.','.','.',']','$','*',')',';','^', -/* 60 */ '-','/','.','.','.','.','.','.','.','.','|',',','%','_','>','?', -/* 70 */ '.','.','.','.','.','.','.','.','.','`',':','#','@','\'','=','"', -/* 80 */ '.','a','b','c','d','e','f','g','h','i','.','.','.','.','.','.', -/* 90 */ '.','j','k','l','m','n','o','p','q','r','.','.','.','.','.','.', -/* A0 */ '.','~','s','t','u','v','w','x','y','z','.','.','.','.','.','.', -/* B0 */ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', -/* C0 */ '{','A','B','C','D','E','F','G','H','I','.','.','.','.','.','.', -/* D0 */ '}','J','K','L','M','N','O','P','Q','R','.','.','.','.','.','.', -/* E0 */ '\\','.','S','T','U','V','W','X','Y','Z','.','.','.','.','.','.', -/* F0 */ '0','1','2','3','4','5','6','7','8','9','.','.','.','.','.','.', -}; - - -int match_trace_criteria(unsigned char *pkt, int len, int *dlci); -unsigned char hexdig(unsigned char n); -unsigned char dighex(unsigned char n); -int x25_call_request_decode (unsigned char *data, int len); -void trace_banner (wp_trace_output_iface_t *trace_iface, int *trace_started); - -static void decode_chdlc_ip_transaction(cisco_slarp_t *cisco_slarp); -static void print_ipv4_address(unsigned int address); -static int decode_data_ipv4(unsigned char* data, unsigned short data_len); -static char* decode_tcp_level_protocol(unsigned short port); -static void print_data_in_hex(unsigned char* data, unsigned short data_len); - -int match_trace_criteria(unsigned char *pkt, int len, int *dlci) -{ - unsigned int tmp_val; - tmp_val=(pkt[0] >> 2)&0x3F; - tmp_val = tmp_val<<4; - tmp_val|=(pkt[1]>>4)&0x0F; - - *dlci=tmp_val; - - if (TRACE_DLCI > 0){ - if (TRACE_DLCI == tmp_val){ - return 0; - } - }else if (TRACE_DLCI == 0){ - return 0; - } - - return 1; -} - -void trace_banner (wp_trace_output_iface_t *trace_iface, int *trace_started) -{ - int len =trace_iface->len; - unsigned char status =trace_iface->status; - unsigned int timestamp =trace_iface->timestamp; - - if (!(*trace_started)){ - char date_string[100]; - - date_string[0] = '\0'; - - sprintf(date_string, "%5d", timestamp); - - if (trace_iface->sec){ - char tmp_time[50]; - time_t time_val=trace_iface->sec; - struct tm *time_tm; - - /* Parse time and date */ - time_tm = localtime(&time_val); - - strftime(tmp_time,sizeof(tmp_time)," %b",time_tm); - sprintf(date_string+strlen(date_string), " %s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); - sprintf(date_string+strlen(date_string), "%s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); - sprintf(date_string+strlen(date_string), "%s",tmp_time); - - sprintf(date_string+strlen(date_string), " %-6lu [1/100s]",trace_iface->usec ); - } - - printf("\n%s\tLen=%d\tTimeStamp=%s\n", - (status & 0x01) ? - "OUTGOING" : "INCOMING", - len, - date_string); - - trace_iface->status&=(~WP_TRACE_OUTGOING); - if (trace_iface->status){ - printf("\t\tReceive error - "); - - if(trace_iface->status & WP_TRACE_ABORT){ - printf("\t\tAbort"); - }else{ - printf((trace_iface->status & WP_TRACE_CRC) ? "\t\tBad CRC" : "\t\tOverrun"); - } - } - - *trace_started=1; - } -} - - -unsigned char hexdig(unsigned char n) -{ - n &= 0x0F; - /* only operate on the low four bits - * return a single hexadecmal ASCII digit */ - return((n >= 10) ? (n - 10 + 'A') : (n + '0')); -} - - -unsigned char dighex(unsigned char n) -{ - - if (n >= 'a') - /* provide the adjustment if the passed ASCII value is greater */ - return(n + 10 - 'a') ; /* than 'a' */ - else - /* provide the adjustment if the passed ASCII value is greater */ - /* than 'A' or is a numeral */ - return((n >= 'A') ? (n + 10 - 'A') : (n - '0')); -} - - -int x25_call_request_decode (unsigned char *data, int len) -{ - int len1, len2; - int i; - char addr1[16], addr2[16]; - char udata[200]; - char *first, *second; - char byte; - int localoffset; - int offset=3; - int facil_len; - unsigned char tmp_val; - - byte = data[offset]; - len2 = (byte >> 4) & 0x0F; - len1 = (byte >> 0) & 0x0F; - - if ((len1+len2) > len){ - return 1; - } - - - localoffset = ++offset; - byte = data[localoffset]; - - first=addr1; - second=addr2; - for (i = 0; i < (len1+len2); i++) { - if (i < len1) { - if (i % 2 != 0) { - *first++ = ((byte >> 0) & 0x0F) + '0'; - localoffset++; - byte = data[localoffset]; - } else { - *first++ = ((byte >> 4) & 0x0F) + '0'; - } - } else { - if (i % 2 != 0) { - *second++ = ((byte >> 0) & 0x0F) + '0'; - localoffset++; - byte = data[localoffset]; - } else { - *second++ = ((byte >> 4) & 0x0F) + '0'; - } - } - } - - *first = '\0'; - *second = '\0'; - - if (len1) { - printf("Called=%s ",addr1); - } - if (len2) { - printf("Calling=%s ",addr2); - } - - localoffset = 4; - localoffset += ((len1 + len2 + 1) / 2); - - if (localoffset >= len) - return 0; - - /* Look for facilities */ - facil_len=data[localoffset]; - - /* Skip facilites for now */ - if (facil_len){ - printf ("Facil="); - localoffset++; - - for (i=0;i= len) - return 0; - - len1=localoffset; - - first=udata; - byte=data[localoffset]; - for (i=0;i<((len-len1)*2) && i> 0) & 0x0F; - *first++ = hexdig(tmp_val); -#if 0 - if (tmp_val >= 0 && tmp_val <= 9){ - *first++ = tmp_val + '0'; - }else{ - *first++ = tmp_val + 55; - } -#endif - localoffset++; - byte = data[localoffset]; - } else { - tmp_val=(byte >> 4) & 0x0F; - *first++ = hexdig(tmp_val); - } - } - - *first='\0'; - printf("Data=%s",udata); - - /* Look for user data */ - return 0; -} - -static char *clear_code(unsigned char code) -{ - static char buffer[25]; - - if (code == 0x00 || (code & 0x80) == 0x80) - return "DTE Originated"; - if (code == 0x01) - return "Number Busy"; - if (code == 0x03) - return "Invalid Facility Requested"; - if (code == 0x05) - return "Network Congestion"; - if (code == 0x09) - return "Out Of Order"; - if (code == 0x0B) - return "Access Barred"; - if (code == 0x0D) - return "Not Obtainable"; - if (code == 0x11) - return "Remote Procedure Error"; - if (code == 0x13) - return "Local Procedure Error"; - if (code == 0x15) - return "RPOA Out Of Order"; - if (code == 0x19) - return "Reverse Charging Acceptance Not Subscribed"; - if (code == 0x21) - return "Incompatible Destination"; - if (code == 0x29) - return "Fast Select Acceptance Not Subscribed"; - if (code == 0x39) - return "Destination Absent"; - - sprintf(buffer, "Unknown %02X", code); - - return buffer; -} - -static char *clear_diag(unsigned char code) -{ - static char buffer[25]; - - if (code == 0) - return "No additional information"; - if (code == 1) - return "Invalid P(S)"; - if (code == 2) - return "Invalid P(R)"; - if (code == 16) - return "Packet type invalid"; - if (code == 17) - return "Packet type invalid for state r1"; - if (code == 18) - return "Packet type invalid for state r2"; - if (code == 19) - return "Packet type invalid for state r3"; - if (code == 20) - return "Packet type invalid for state p1"; - if (code == 21) - return "Packet type invalid for state p2"; - if (code == 22) - return "Packet type invalid for state p3"; - if (code == 23) - return "Packet type invalid for state p4"; - if (code == 24) - return "Packet type invalid for state p5"; - if (code == 25) - return "Packet type invalid for state p6"; - if (code == 26) - return "Packet type invalid for state p7"; - if (code == 27) - return "Packet type invalid for state d1"; - if (code == 28) - return "Packet type invalid for state d2"; - if (code == 29) - return "Packet type invalid for state d3"; - if (code == 32) - return "Packet not allowed"; - if (code == 33) - return "Unidentifiable packet"; - if (code == 34) - return "Call on one-way logical channel"; - if (code == 35) - return "Invalid packet type on a PVC"; - if (code == 36) - return "Packet on unassigned LC"; - if (code == 37) - return "Reject not subscribed to"; - if (code == 38) - return "Packet too short"; - if (code == 39) - return "Packet too long"; - if (code == 40) - return "Invalid general format identifier"; - if (code == 41) - return "Restart/registration packet with nonzero bits"; - if (code == 42) - return "Packet type not compatible with facility"; - if (code == 43) - return "Unauthorised interrupt confirmation"; - if (code == 44) - return "Unauthorised interrupt"; - if (code == 45) - return "Unauthorised reject"; - if (code == 48) - return "Time expired"; - if (code == 49) - return "Time expired for incoming call"; - if (code == 50) - return "Time expired for clear indication"; - if (code == 51) - return "Time expired for reset indication"; - if (code == 52) - return "Time expired for restart indication"; - if (code == 53) - return "Time expired for call deflection"; - if (code == 64) - return "Call set-up/clearing or registration pb."; - if (code == 65) - return "Facility/registration code not allowed"; - if (code == 66) - return "Facility parameter not allowed"; - if (code == 67) - return "Invalid called DTE address"; - if (code == 68) - return "Invalid calling DTE address"; - if (code == 69) - return "Invalid facility/registration length"; - if (code == 70) - return "Incoming call barred"; - if (code == 71) - return "No logical channel available"; - if (code == 72) - return "Call collision"; - if (code == 73) - return "Duplicate facility requested"; - if (code == 74) - return "Non zero address length"; - if (code == 75) - return "Non zero facility length"; - if (code == 76) - return "Facility not provided when expected"; - if (code == 77) - return "Invalid CCITT-specified DTE facility"; - if (code == 78) - return "Max. nb of call redir/defl. exceeded"; - if (code == 80) - return "Miscellaneous"; - if (code == 81) - return "Improper cause code from DTE"; - if (code == 82) - return "Not aligned octet"; - if (code == 83) - return "Inconsistent Q bit setting"; - if (code == 84) - return "NUI problem"; - if (code == 112) - return "International problem"; - if (code == 113) - return "Remote network problem"; - if (code == 114) - return "International protocol problem"; - if (code == 115) - return "International link out of order"; - if (code == 116) - return "International link busy"; - if (code == 117) - return "Transit network facility problem"; - if (code == 118) - return "Remote network facility problem"; - if (code == 119) - return "International routing problem"; - if (code == 120) - return "Temporary routing problem"; - if (code == 121) - return "Unknown called DNIC"; - if (code == 122) - return "Maintenance action"; - if (code == 144) - return "Timer expired or retransmission count surpassed"; - if (code == 145) - return "Timer expired or retransmission count surpassed for INTERRUPT"; - if (code == 146) - return "Timer expired or retransmission count surpassed for DATA " - "packet transmission"; - if (code == 147) - return "Timer expired or retransmission count surpassed for REJECT"; - if (code == 160) - return "DTE-specific signals"; - if (code == 161) - return "DTE operational"; - if (code == 162) - return "DTE not operational"; - if (code == 163) - return "DTE resource constraint"; - if (code == 164) - return "Fast select not subscribed"; - if (code == 165) - return "Invalid partially full DATA packet"; - if (code == 166) - return "D-bit procedure not supported"; - if (code == 167) - return "Registration/Cancellation confirmed"; - if (code == 224) - return "OSI network service problem"; - if (code == 225) - return "Disconnection (transient condition)"; - if (code == 226) - return "Disconnection (permanent condition)"; - if (code == 227) - return "Connection rejection - reason unspecified (transient " - "condition)"; - if (code == 228) - return "Connection rejection - reason unspecified (permanent " - "condition)"; - if (code == 229) - return "Connection rejection - quality of service not available " - "transient condition)"; - if (code == 230) - return "Connection rejection - quality of service not available " - "permanent condition)"; - if (code == 231) - return "Connection rejection - NSAP unreachable (transient condition)"; - if (code == 232) - return "Connection rejection - NSAP unreachable (permanent condition)"; - if (code == 233) - return "reset - reason unspecified"; - if (code == 234) - return "reset - congestion"; - if (code == 235) - return "Connection rejection - NSAP address unknown (permanent " - "condition)"; - if (code == 240) - return "Higher layer initiated"; - if (code == 241) - return "Disconnection - normal"; - if (code == 242) - return "Disconnection - abnormal"; - if (code == 243) - return "Disconnection - incompatible information in user data"; - if (code == 244) - return "Connection rejection - reason unspecified (transient " - "condition)"; - if (code == 245) - return "Connection rejection - reason unspecified (permanent " - "condition)"; - if (code == 246) - return "Connection rejection - quality of service not available " - "(transient condition)"; - if (code == 247) - return "Connection rejection - quality of service not available " - "(permanent condition)"; - if (code == 248) - return "Connection rejection - incompatible information in user data"; - if (code == 249) - return "Connection rejection - unrecognizable protocol indentifier " - "in user data"; - if (code == 250) - return "Reset - user resynchronization"; - - sprintf(buffer, "Unknown %d", code); - - return buffer; -} - - -static int decode_chdlc(wp_trace_output_iface_t *trace_iface, - int *trace_started) -{ - unsigned char *data = trace_iface->data; - - int inf_frame=0; - cisco_header_t *cisco_header = (cisco_header_t *)&data[0]; - u_int32_t time_alive; - - trace_banner(trace_iface,trace_started); - - - //print the data (including Cisco header) - print_data_in_hex(data, trace_iface->len); - - printf("CHDLC decode\t"); - - switch(ntohs(cisco_header->packet_type)) { - - case CISCO_PACKET_IP: - printf("CISCO Packet IP-v4\n\n"); - //decode data past Cisco header - decode_data_ipv4((unsigned char*)(cisco_header + 1), - trace_iface->len - sizeof(cisco_header_t)); - break; - - case CISCO_PACKET_SLARP: - { - cisco_slarp_t *cisco_slarp = - (cisco_slarp_t*)(cisco_header+1); - - switch(ntohl(cisco_slarp->code)) { - case SLARP_REQUEST: - printf("SLARP Request packet\n"); - decode_chdlc_ip_transaction(cisco_slarp); - break; - - case SLARP_REPLY: - printf("SLARP Reply packet\n"); - decode_chdlc_ip_transaction(cisco_slarp); - break; - - case SLARP_KEEPALIVE: - printf("SLARP Keepalive packet\n"); - printf("\t\tlocal sequence number: %lu\tremote sequence number: %lu\n", - (unsigned long)ntohl(cisco_slarp->un.keepalive.my_sequence), - (unsigned long)ntohl(cisco_slarp->un.keepalive.your_sequence)); - - { - unsigned short t1; - unsigned short t2; - - t1 = (cisco_slarp->un.keepalive.t1 << 8) | (cisco_slarp->un.keepalive.t1 >> 8); - t2 = (cisco_slarp->un.keepalive.t2 << 8) | (cisco_slarp->un.keepalive.t2 >> 8); - - time_alive = t1; - time_alive = (time_alive << 16) | t2; - - } - printf("\t\treliability number: 0x%X\t\ttime alive: %u", - (unsigned short)ntohs(cisco_slarp->un.keepalive.reliability), - time_alive); - break; - - default: - printf("Unrecognized SLARP packet"); - break; - } /* Slarp code switch */ - - break; - - } /* slarp case */ - - case CISCO_PACKET_CDP: - printf("Cisco Discover Protocol packet"); - break; - - default: - printf("Unknown Cisco packet"); - break; - } - - return inf_frame; -} - -static void decode_chdlc_ip_transaction(cisco_slarp_t *cisco_slarp) -{ - printf("\t\tIP address: "); - print_ipv4_address(cisco_slarp->un.address.address); - - printf("\tIP netmask: "); - print_ipv4_address(cisco_slarp->un.address.mask); -} - -#define IP_V4 4 -#define IP_V4_IHLEN 5 - -static int decode_data_ipv4(unsigned char* data, unsigned short data_len) -{ - iphdr_t *ip_hdr = (iphdr_t*)data; - struct tcphdr * tcp_hdr; - char is_port_valid_for_protocol = 1; - - printf("TCP/IP decode\t"); - - if(data_len < sizeof(iphdr_t) + sizeof(struct tcphdr)){ - printf("Data length is invalid for IP V4.\n"); - return 1; - } - - if(ip_hdr->w_ip_v != IP_V4){ - printf("Invalid IP version: %d.\n", - ip_hdr->w_ip_v); - return 1; - } - - if(ip_hdr->w_ip_hl != IP_V4_IHLEN){ - printf("Invalid IP header length: %d.\n", - ip_hdr->w_ip_hl); - return 1; - } - - printf("IP Level Protocol: "); - - switch(ip_hdr->w_ip_p) - { - case IPPROTO_IP: /* 0 - Dummy protocol for TCP */ - printf("TCP"); - break; - - case IPPROTO_ICMP: /* 1 */ - printf("Internet Control Message Protocol (ICMP)"); - is_port_valid_for_protocol = 0; - break; - - case IPPROTO_IGMP: /* 2 */ - printf("Internet Group Management Protocol (IGMP)"); - break; - - case IPPROTO_IPIP: /* 4 */ - printf("IPIP tunnels"); - break; - - case IPPROTO_TCP: /* 6 */ - printf("Transmission Control Protocol (TCP)"); - break; - - case IPPROTO_EGP: /* 8 */ - printf("Exterior Gateway Protocol (EGP)"); - break; - - case IPPROTO_PUP: /* 12 */ - printf("PUP protocol"); - break; - - case IPPROTO_UDP: /* 17 */ - printf("User Datagram Protocol (UDP)"); - break; - - case IPPROTO_IDP: /* 22 */ - printf("XNS IDP protocol"); - break; - - case IPPROTO_RSVP: /* 46 */ - printf("RSVP protocol"); - break; - - case IPPROTO_GRE: /* 47 */ - printf("Cisco GRE tunnels (rfc 1701,1702)"); - break; - - case IPPROTO_IPV6: /* 41 */ - printf("IPv6-in-IPv4 tunnelling"); - break; - - case IPPROTO_PIM: /* 103 */ - printf("Protocol Independent Multicast"); - break; - - case IPPROTO_ESP: /* 50 */ - printf("Encapsulation Security Payload protocol"); - break; - - case IPPROTO_AH: /* 51 */ - printf("Authentication Header protocol"); - break; - -#if defined(__LINUX__) - case IPPROTO_COMP: /* 108 */ -#else - case IPPROTO_IPCOMP: /* 108 */ -#endif - printf("Compression Header protocol"); - break; - - case IPPROTO_RAW: /* 255 */ - printf("Raw IP packets"); - break; - -#if 0 - case IPPROTO_MAX: - printf("IPPROTO_MAX"); - break; -#endif - - default: - printf("Unknown (%d)\n", ip_hdr->w_ip_p); - //not a serious error, but stop here anyway - return 0; - } - - printf(", TTL: %d.\n", ip_hdr->w_ip_ttl); - - printf("\t\tSource IP: "); - print_ipv4_address(ip_hdr->w_ip_src); - printf(", Destination IP: "); - print_ipv4_address(ip_hdr->w_ip_dst); - printf("\n"); - - //not all protocols actually using a port - if(is_port_valid_for_protocol == 1){ - //now decode TCP part - tcp_hdr = (struct tcphdr*)&data[sizeof(iphdr_t)]; - printf("\t\tSource Port: %u (%s), Destination Port: %u (%s)\n", - ntohs(tcp_hdr->w_tcp_sport), - decode_tcp_level_protocol(ntohs(tcp_hdr->w_tcp_sport)), - ntohs(tcp_hdr->w_tcp_dport), - decode_tcp_level_protocol(ntohs(tcp_hdr->w_tcp_dport))); - } - return 0; -} - -//define here most used protocols -#define ECHO 7 -#define FTP_DATA 20 -#define FTP 21 -#define TELNET 23 -#define SMTP 24 -#define FINGER 79 -#define SNMP 161 - -static char* decode_tcp_level_protocol(unsigned short port) -{ - switch(port) - { - case ECHO: - return "ECHO"; - - case FTP_DATA: - return "FTP-DATA"; - - case FTP: - return "FTP"; - - case TELNET: - return "TELNET"; - - case SMTP: - return "SMTP"; - - case FINGER: - return "FINGER"; - - case SNMP: - return "SNMP"; - - default: - return "Unknown"; - } -} - -static void print_ipv4_address(unsigned int address) -{ - printf("%u.%u.%u.%u",(u_int32_t)address & 0x000000FF, - (unsigned int)(address & 0x0000FF00) >> 8, - (unsigned int)(address & 0x00FF0000) >>16, - (unsigned int)(address & 0xFF000000) >>24); -} - -static void print_data_in_hex(unsigned char* data, unsigned short data_len) -{ - int i; - - printf("Raw (HEX)\t"); - - for(i = 0; i < data_len; i++){ - if(i && i%16 == 0){ - printf("\n\t\t"); - } - printf("%02X ", (unsigned char)data[i]); - - //can be too much to print. limit to 256 - if (!trace_all_data){ - if(i == 256){ - printf("...\n"); - break; - } - } - - } - printf("\n\n"); -} - -#define SIZEOF_FR_HEADER 4 - -/* -ANSI -OUTGOING : Len=16 TimeStamp=15210 - 00 01 03 08 00 75 95 01 01 01 03 02 08 01 FF FF - -INCOMING : Len=16 TimeStamp=15211 - 00 01 03 08 00 7D 95 01 01 01 03 02 02 08 53 CC - - -OUTGOING : Len=16 TimeStamp=65210 - 00 01 03 08 00 75 95 01 01 00 03 02 0D 06 FF FF - -INCOMING : Len=21 TimeStamp=65211 - 00 01 03 08 00 7D 95 01 01 00 03 02 07 0D 07 03 01 80 82 2C - A7 - -*/ - -/* -Q.933 -OUTGOING : Len=15 TimeStamp=40746 - 00 01 03 08 00 75 51 01 01 53 02 04 01 FF FF - -INCOMING : Len=15 TimeStamp=40747 - 00 01 03 08 00 7D 51 01 01 53 02 02 04 02 3D - - -OUTGOING : Len=15 TimeStamp=25210 - 00 01 03 08 00 75 51 01 00 53 02 09 06 FF FF - -INCOMING : Len=20 TimeStamp=25211 - 00 01 03 08 00 7D 51 01 00 53 02 07 09 57 03 01 80 82 A0 E6 -*/ - -/* -LMI -OUTGOING : Len=15 TimeStamp=60746 - FC F1 03 09 00 75 01 01 01 03 02 06 05 FF FF - -INCOMING : Len=15 TimeStamp=60747 - FC F1 03 09 00 7D 01 01 01 03 02 06 06 19 44 - -OUTGOING : Len=15 TimeStamp= 5210 - FC F1 03 09 00 75 01 01 00 03 02 07 06 FF FF - -INCOMING : Len=31 TimeStamp= 5211 - FC F1 03 09 00 7D 01 01 00 03 02 07 07 07 06 00 10 02 00 00 - 00 07 06 00 12 02 00 00 00 C2 B1 -*/ - -#define ANSI_LINK_VERIFICATION_LEN_WCRC 16 -#define ANSI_LINK_VERIFICATION_LEN 14 -#define ANSI_FULL_STATUS_LEN_WCRC 21 -#define ANSI_FULL_STATUS_LEN 19 -#define ANSI_OFFSET 9 - -#define Q933_LINK_VERIFICATION_LEN_WCRC 15 -#define Q933_LINK_VERIFICATION_LEN 13 -#define Q933_FULL_STATUS_LEN_WCRC 20 -#define Q933_FULL_STATUS_LEN 18 -#define Q933_OFFSET 8 - - -#define LMI_LINK_VERIFICATION_LEN Q933_LINK_VERIFICATION_LEN -#define LMI_OFFSET 8 - -static int decode_fr(wp_trace_output_iface_t *trace_iface, - int *trace_started,int dlci) -{ - unsigned char *data =trace_iface->data; - int len =trace_iface->len; - - int inf_frame=1; - int j; - - static int signalling_offset = 0; - static char lmi = 0; - - trace_banner(trace_iface,trace_started); - - //print the data (including FR header) - print_data_in_hex(data, len); - - //printf("Frame Relay decode"); - printf("FR decode\t"); - - //printf("\tFR : "); - printf("DLCI=%i ", dlci); - printf("C/R=%i ", (data[0]&0x2)>>1); - printf("EA=%i ", data[0]&0x1); - printf("FECN=%i ", (data[1]&0x8)>>3); - printf("BECN=%i ", (data[1]&0x4)>>2); - printf("DE=%i ", (data[1]&0x2)>>1); - printf("EA=%i ", data[1]&0x1); - printf("\n"); - - if (len <= SIZEOF_FR_HEADER){ - return inf_frame; - } - - if (!dlci || dlci==1023){ - - //printf("len: %d\n", len); - if(signalling_offset == 0){ - //need at least one signalling frame to detect signalling type. - switch(len) - { - case ANSI_LINK_VERIFICATION_LEN: - case ANSI_LINK_VERIFICATION_LEN_WCRC: - signalling_offset = ANSI_OFFSET; - break; - - case Q933_LINK_VERIFICATION_LEN: - signalling_offset = Q933_OFFSET; - - if(dlci == 1023){ - lmi = 1; - }else{ - lmi = 0; - } - break; - - default: - printf("Unknow Signalling: Wait for signalling frame...\n"); - return 0; - }//switch() - }//if() - - //printf("signalling_offset: %d\n", signalling_offset); - - printf("\t\tSignalling "); - switch(signalling_offset) - { - case ANSI_OFFSET: - printf("ANSI"); - break; - - case Q933_OFFSET: - if(lmi == 0){ - printf("Q.933"); - }else{ - printf("LMI"); - } - break; - default: - printf("Unknown: 0x%X",signalling_offset); - } - printf("\n"); - - printf("\t\t"); - if(data[signalling_offset]){ - printf("Link Verification "); - }else{ - printf("Full Status "); - } - - if (data[5] == 0x75){ - printf("Req"); - }else{ - printf("Reply"); - } - - printf("\tSx=0x%02X Rx=0x%02X ", - (unsigned char)data[signalling_offset + 3], - (unsigned char)data[signalling_offset + 4]); - - - if (!data[signalling_offset] && (data[5]==0x7D) ) { - /* full status reply */ - if(lmi == 0){ -#if 0 - printf("\nFull Rep: Sig off=%i, Len=%i\n", - signalling_offset,len); -#endif - for( j=signalling_offset + 5; (j>3) & 0x0F); - - printf("\n\t"); - printf("\tDLCI=%-3u ",dlci); - - if (data[j+4] & 0x08){ - printf("New, "); - }else{ - printf("Present, "); - } - - if (data[j+4] & 0x02){ - printf("Active "); - }else{ - printf("Inactive "); - } - }//for() - }else{ - - for(j=signalling_offset + 5; ((j+8)sub_type == WP_OUT_TRACE_INTERP_IPV4){ - decode_data_ipv4(data + SIZEOF_FR_HEADER, len - SIZEOF_FR_HEADER); - } - - - }else if (data[2] == 0x03 && - data[3] == 0x00 && - data[4] == 0x80 && - data[8] == 0x08 && - data[9] == 0x06) { - - /* Request packet */ - printf("\t : "); - if(data[17] == 0x08){ - printf("Inverse Arp Request on DLCI %u", dlci); - }else if(data[17] == 0x09){ - printf("Inverse Arp Reply on DLCI %u", dlci); - } - }else{ - printf("\t\tUnknown frame type on on DLCI %u", dlci); - } - - return inf_frame; -} - -static int decode_lapb(wp_trace_output_iface_t *trace_iface, - int *trace_started) -{ - unsigned char *data =trace_iface->data; - int len =trace_iface->len; - - int inf_frame=0; - trace_banner(trace_iface,trace_started); - - printf("\tLAPB : %02i | ",data[0]); - - if (!(data[1]&0x01)){ - if (len >= 5){ - printf("INF Ns=%1i Nr=%1i P=%1i : ", - (data[1]>>1)&0x07, - data[1]>>5, - (data[1]>>4)&0x01,(len-2)); - inf_frame=1; - }else{ - printf("INF Ns=%1i Nr=%1i P=%1i ", - (data[1]>>1)&0x07, - data[1]>>5, - (data[1]>>4)&0x01); - } - goto end_lapb_decode; - } - - switch ((data[1]&0x0F)){ - - case 0x01: - printf("RR Pr=%1i P=%1i", - (data[1]>>5), - (data[1]>>4)&0x01); - break; - - case 0x05: - printf("RNR Pr=%1i P=%1i", - (data[1]>>5), - (data[1]>>4)&0x01); - - break; - - case 0x09: - printf("REJ Pr=%1i P=%1i", - (data[1]>>5), - (data[1]>>4)&0x01); - break; - - default: - - switch (data[1]&0xEF){ - - case 0x2F: - printf("SBM P=%1i", - (data[1]>>4)&0x01); - break; - - case 0x83: - printf("SNRM P=%1i", - (data[1]>>4)&0x01); - break; - case 0x0F: - printf("DM F=%1i", - (data[1]>>4)&0x01); - break; - - case 0x43: - printf("DSC P=%1i", - (data[1]>>4)&0x01); - break; - case 0x63: - printf("UA F=%1i", - (data[1]>>4)&0x01); - break; - - case 0x87: - printf("FMR F=%1i", - (data[1]>>4)&0x01); - break; - - default: - printf("Unknown lapb pkt : 0x%02X ", data[1]); - break; - } - } - -end_lapb_decode: - printf("\n"); - - return inf_frame; -} - -static int decode_x25(wp_trace_output_iface_t *trace_iface, - int *trace_started) -{ - unsigned char *data =trace_iface->data; - int len =trace_iface->len; - - unsigned int lcn = ((data[0]&0x0F)<<8)|(data[1]&0xFF); - unsigned char mod = (data[0]>>4)&0x03; - unsigned char pkt_type; - unsigned char pr,ps,mbit; - unsigned char inf_frame=0; - - if (TRACE_X25_LCN){ - if (lcn != 0 && TRACE_X25_LCN != lcn){ - return inf_frame; - } - } - - pkt_type=data[2]; - - if (!(pkt_type&0x01)){ - if (!(TRACE_X25_OPT & DATA)){ - return inf_frame; - } - }else{ - if (!(TRACE_X25_OPT & PROT)){ - return inf_frame; - } - } - - trace_banner(trace_iface,trace_started); - - printf("\tX25 : LCN=%i Q=%i D=%i Modulo=%i : ", - lcn, - data[0]&0x80, - data[0]&0x40, - data[0]&0x10 ? 8 : 128); - - if (!(pkt_type&0x01)){ - - if (mod==X25_MOD8){ - pr=data[2]>>5; - ps=(data[2]>>1)&0x07; - mbit=(data[2]&0x10)>>4; - }else{ - ps=data[2]>>1; - pr=data[3]>>1; - mbit=data[3]&0x01; - } - - printf("DATA Pr=%02i Ps=%02i M=%i", - pr,ps,mbit); - inf_frame=1; - goto end_x25_decode; - }else{ - if (mod==X25_MOD8){ - pr=data[2]>>5; - }else{ - pr=data[3]>>1; - } - } - - switch(pkt_type&0x1F){ - - case 0x01: - printf("\n\t "); - printf("RR Pr=%02i",pr); - break; - - case 0x05: - printf("\n\t "); - printf("RNR Pr=%02i",pr); - break; - - case 0x09: - printf("\n\t "); - printf("REJ Pr=%02i",pr); - break; - - default: - - printf("\n\t * "); - - switch(pkt_type){ - - case 0x0B: - printf("CALL REQUEST :\n\t "); - x25_call_request_decode(data,len); - break; - - case 0x0F: - printf("CALL ACCEPT "); - break; - - case 0x13: - printf("CLEAR REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x17: - printf("CLEAR CONFIRM :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x23: - printf("INTERRUPT :\n\t "); - printf("Data=(0x%02X)",data[3]); - break; - - case 0x27: - printf("INTERRUPT CONFIRM"); - break; - - case 0x1B: - printf("RESET REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x1F: - printf("RESET CONFIRM"); - break; - - case 0xFB: - printf("RESTART REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0xFF: - printf("RESTART CONFIRM"); - break; - - case 0xF1: - printf("\nDIAGNOSTIC"); - break; - - default: - printf("\nUnknown x25 cmd 0x%2X",data[2]); - break; - } - break; - } -end_x25_decode: - - if (inf_frame){ - int i; - char ch; - char *specials = "\b\f\n\r\t"; - char *escapes = "bfnrt"; - char *cp; - - printf("\n"); - - if (TRACE_HEX){ - printf("\n\thex : "); - for (i=3;i= 0x40) ? ebcdic[data[i] - 0x40] : '.'; - - if ((ch != '.' || data[i] == ebcdic['.'])) - (void) printf("%c", ch); - else if (data[i] && (cp = strchr(specials, data[i]))) - (void) printf("\\%c", escapes[cp - specials]); - else - (void) printf("%02X", data[i]); - - //if (((i-2) % 25) == 0){ - // printf("\n\t "); - //} - - } - printf("\n"); - } - - }else{ //end of inf frame - printf("\n"); - } - - return inf_frame; -} - - -static void decode_annexg_x25_pkt (wp_trace_output_iface_t *trace_iface, - int annexg) -{ - - unsigned char *data =trace_iface->data; - int len =trace_iface->len; - - int inf_frame=0; - int trace_started=0; - int dlci; - - if (!TRACE_EBCDIC && !TRACE_ASCII && !TRACE_HEX){ - TRACE_HEX=1; - } - - if (annexg){ - - if (match_trace_criteria(data,len,&dlci) != 0) - return; - - if (TRACE_PROTOCOL & FRAME){ - - inf_frame=decode_fr(trace_iface,&trace_started,dlci); - if (!inf_frame){ - return; - } - } - data+=2; - len-=2; - - if (!dlci || dlci==1023){ - return; - } - } - - - if (len<2){ - return; - } - - if (TRACE_PROTOCOL & LAPB){ - inf_frame = decode_lapb(trace_iface,&trace_started); - if (!inf_frame){ - return; - } - }else{ - /* Do not pass non information frames to X25 */ - if ((data[1]&0x01)){ - return; - } - } - - data+=2; - len-=2; - - if (len<3){ - return; - } - - if (TRACE_PROTOCOL & X25){ - decode_x25(trace_iface,&trace_started); - } -} - - - - -static void print_pcap_file_header (wp_trace_output_iface_t *trace_iface) -{ - struct pcap_hdr fh; - - fh.magic = PCAP_MAGIC; - fh.version_major = 2; - fh.version_minor = 4; - fh.thiszone = 0; - fh.sigfigs = 0; - fh.snaplen = 102400; - fh.network = trace_iface->link_type; - - fwrite(&fh, sizeof(fh), 1, trace_iface->output_file); -} - -static void print_pcap_record_header(wp_trace_output_iface_t *trace_iface) -{ - struct pcaprec_hdr ph; - - /* Write PCap header */ - ph.ts_sec = trace_iface->sec; - ph.ts_usec = trace_iface->usec; - ph.incl_len = trace_iface->len; - ph.orig_len = trace_iface->len; - - fwrite(&ph, sizeof(ph), 1, trace_iface->output_file); -} - -static void get_ppp_magic_number(unsigned char* data, int len, char* outstr, char offset_flag) -{ - if(offset_flag == 0){ - - if(len < 12){ - printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); - return; - } - sprintf(outstr, "\tMagic# %02X%02X%02X%02X", - (unsigned char)data[8], (unsigned char)data[9], - (unsigned char)data[10], (unsigned char)data[11]); - }else{ - - if(len < 14){ - printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); - return; - } - sprintf(outstr, "\tMagic# %02X%02X%02X%02X", - (unsigned char)data[8+2], (unsigned char)data[8+3], - (unsigned char)data[8+4], (unsigned char)data[8+5]); - } -} - -static int decode_ppp(wp_trace_output_iface_t *trace_iface, - int *trace_started) -{ - unsigned char *data = trace_iface->data; - int len = trace_iface->len; - int inf_frame=0; - unsigned short tmp_ushort; - char outstr[1024]; - - trace_banner(trace_iface,trace_started); - memset(outstr, 0x00, 1024); - - //print the data (including PPP header) - print_data_in_hex(data, len); - - printf("PPP decode\t"); - - tmp_ushort = *(unsigned short*)&data[2]; - switch(tmp_ushort) { - case 0x2100: // IP packet - printf("IP-v4 data packet\n\n"); - decode_data_ipv4(&data[4], len - 4); - break; - case 0x2B00: // IPX packet - printf("IPX data packet\n\n"); - break; - case 0x5700: - printf("IP-v6 data packet\n\n"); - break; - case 0x2180: // IPCP-v4 - case 0x5780: // IPCP-v6 - case 0x2B80: // IPXCP - case 0x21C0: // LCP - - //pre-decodeing - if (tmp_ushort == 0x2180){ - sprintf(outstr+strlen(outstr), "IPCP-v4 packet - "); - } - - if (tmp_ushort == 0x5780){ - sprintf(outstr+strlen(outstr), "IPCP-v6 packet - "); - } - - if (tmp_ushort == 0x2B80){ - sprintf(outstr+strlen(outstr), "IPXCP packet - "); - } - - if (tmp_ushort == 0x21C0){ - sprintf(outstr+strlen(outstr), "LCP packet\tID 0x%02X - ", data[5]); - } - - //common decoding - switch(data[4]) { - case 1: - sprintf(outstr+strlen(outstr), "Configure Request"); - break; - case 2: - sprintf(outstr+strlen(outstr), "Configure Ack\t"); - break; - case 3: - sprintf(outstr+strlen(outstr), "Configure Nack\t"); - break; - case 4: - sprintf(outstr+strlen(outstr), "Configure Reject"); - break; - case 5: - sprintf(outstr+strlen(outstr), "Terminate Request"); - break; - case 6: - sprintf(outstr+strlen(outstr), "Terminate Ack\t"); - break; - case 7: - sprintf(outstr+strlen(outstr), "Code Reject\t"); - break; - case 8: - sprintf(outstr+strlen(outstr), "Protocol Reject"); - break; - case 9: - sprintf(outstr+strlen(outstr), "Echo Request\t"); - break; - case 10: - sprintf(outstr+strlen(outstr), "Echo Reply\t"); - break; - case 11: - sprintf(outstr+strlen(outstr), "Discard Request"); - break; - default: - sprintf(outstr+strlen(outstr), "Unknown type"); - break; - } - - //post-decoding - if (tmp_ushort == 0x21C0){ - //LCP - switch(data[4]) { - case 1: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); - break; - case 2: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); - break; - case 3: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); - break; - case 4: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); - break; - case 5: - case 6: - case 7: - case 8: - ;//do nothing - break; - case 9: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); - break; - case 10: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); - break; - case 11: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); - break; - default: - break; - } - } - break; - - case 0x23C0: // PAP - sprintf(outstr+strlen(outstr), "PAP packet - "); - switch(data[4]) { - case 1: - sprintf(outstr+strlen(outstr), "Authenticate Request"); - break; - case 2: - sprintf(outstr+strlen(outstr), "Authenticate Ack"); - break; - case 3: - sprintf(outstr+strlen(outstr), "Authenticate Nack"); - break; - default: - sprintf(outstr+strlen(outstr), "Unknown type"); - break; - } - break; - case 0x25C0: // LQR - sprintf(outstr+strlen(outstr), "Link Quality Report"); - break; - case 0x23C2: // CHAP - sprintf(outstr+strlen(outstr), "CHAP packet - "); - switch(data[4]) { - case 1: - sprintf(outstr+strlen(outstr), "Challenge"); - break; - case 2: - sprintf(outstr+strlen(outstr), "Responce"); - break; - case 3: - sprintf(outstr+strlen(outstr), "Success"); - break; - case 4: - sprintf(outstr+strlen(outstr), "Failure"); - break; - default: - sprintf(outstr+strlen(outstr), "Unknown type"); - break; - } - break; - default: // unknown - sprintf(outstr+strlen(outstr), "Unknown type"); - break; - } - - printf(outstr); - printf("\n\n"); - return inf_frame; -} - - -void wp_trace_output(wp_trace_output_iface_t *trace_iface) -{ - //int num_chars; - //int j; - int trace_started=0; - -try_trace_again: - - switch (trace_iface->type){ - - case WP_OUT_TRACE_INTERP: - - switch (trace_iface->link_type){ - - case 0: - case WANCONFIG_AFT: - case WANCONFIG_AFT_TE1: - case WANCONFIG_AFT_TE3: - if (trace_iface->data[0] == 0x8F || trace_iface->data[0] == 0x0F){ - trace_iface->link_type=WANCONFIG_CHDLC; - goto try_trace_again; - }else if (trace_iface->data[0] == 0xFF && trace_iface->data[1] == 0x03){ - trace_iface->link_type=WANCONFIG_PPP; - goto try_trace_again; - }else if (trace_iface->data[0] != 0x45){ - trace_iface->link_type=WANCONFIG_FR; - goto try_trace_again; - }else{ - printf("\nFailed to autodetect protocol (use -p option)\n"); - } - - case WANCONFIG_CHDLC://104 - - if (trace_iface->data[0] == 0x8F || trace_iface->data[0] == 0x0F){ - //this is CHDLC - decode_chdlc(trace_iface,&trace_started); - printf("\n"); - }else if (trace_iface->data[0] == 0xFF && trace_iface->data[1] == 0x03){ - //on S514 LIP layer runs above CHDLC firmware - trace_iface->link_type=WANCONFIG_PPP; - goto try_trace_again; - }else if (trace_iface->data[0] != 0x45){ - //on S514, LIP layer runs above CHDLC firmware - trace_iface->link_type=WANCONFIG_FR; - goto try_trace_again; - }else{ - decode_annexg_x25_pkt(trace_iface,0); - } - break; - - case WANCONFIG_MPROT://107 - case WANCONFIG_FR://107 - { - int dlci; - match_trace_criteria(trace_iface->data,trace_iface->len,&dlci); - decode_fr(trace_iface,&trace_started,dlci); - printf("\n"); - } - break; - - case 9: - case WANCONFIG_PPP: - /* ppp decoding */ - decode_ppp(trace_iface,&trace_started); - break; - - case 200: - decode_annexg_x25_pkt(trace_iface,0); - break; - - case WANCONFIG_ATM://115 - printf("\n"); - //print the data (past ATM header. header discarded on the card) - print_data_in_hex(trace_iface->data, trace_iface->len); - - if(trace_iface->sub_type == WP_OUT_TRACE_INTERP_IPV4){ - //decode data past ATM header - decode_data_ipv4(trace_iface->data, trace_iface->len); - } - break; - - default: - printf("\nUnknown Configured Wanpipe Protocol 0x%X\n",trace_iface->link_type); - break; - } - - break; - - case WP_OUT_TRACE_PCAP: - - trace_iface->output_file = pcap_output_file; - if (trace_iface->output_file == NULL){ - printf("Error: No output binary file specified!\n"); - return; - } - - if (trace_iface->init==0){ - - if (pcap_prot){ - trace_iface->link_type=pcap_prot; - } - - print_pcap_file_header(trace_iface); - printf("Staring PCAP File Trace in: %s\n\n", - pcap_output_file_name); - trace_iface->init=1; - } - - print_pcap_record_header(trace_iface); - - fwrite(&trace_iface->data[0], trace_iface->len, 1, trace_iface->output_file); - - printf("\rTotal Captured=%-5u (Len=%i)",trace_iface->pkts_written+1,trace_iface->len); - - break; - - case WP_OUT_TRACE_HDLC: - - trace_banner(trace_iface,&trace_started); - - if (trace_iface->len == 0){ - printf("the frame data is not available" ); - return; - } - - if (rx_hdlc_eng) { - wanpipe_hdlc_decode(rx_hdlc_eng,trace_iface->data,trace_iface->len); - } - - break; - - - case WP_OUT_TRACE_RAW: - default: - - trace_banner(trace_iface,&trace_started); - - if (trace_iface->len == 0){ - printf("the frame data is not available" ); - return; - } - - print_data_in_hex(trace_iface->data, trace_iface->len); - - break; - } - - trace_iface->pkts_written++; - trace_iface->status=0; -} - -int trace_hdlc_data(wanpipe_hdlc_engine_t *hdlc_eng, void *data, int len) -{ - print_data_in_hex(data, len); - return 0; -} diff --git a/util/wanpipemon.old/prot_trace.o b/util/wanpipemon.old/prot_trace.o deleted file mode 100644 index a084828c1fd242a428b49124efa286c342953162..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26604 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 QTxgZhTA|B@UM2MZ1BSaGO#lD@ diff --git a/util/wanpipemon.old/prot_trace.orig.c b/util/wanpipemon.old/prot_trace.orig.c deleted file mode 100644 index 086b02e..0000000 --- a/util/wanpipemon.old/prot_trace.orig.c +++ /dev/null @@ -1,1249 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -#else -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - -#define X25_MOD8 0x01 -#define X25_MOD128 0x10 - -#define PCAP_MAGIC 0xa1b2c3d4 - -extern trace_prot_t trace_prot_opt; -extern trace_prot_t trace_x25_prot_opt; -extern unsigned int TRACE_DLCI; -extern unsigned char TRACE_PROTOCOL; -extern unsigned int TRACE_X25_LCN; -extern unsigned char TRACE_X25_OPT; -extern char TRACE_EBCDIC; -extern char TRACE_ASCII; -extern char TRACE_HEX; -extern int sys_timestamp; - -static char ebcdic[] = -{ -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ -/* 40 */ ' ','.','.','.','.','.','.','.','.','.','[','.','<','(','+','!', -/* 50 */ '&','.','.','.','.','.','.','.','.','.',']','$','*',')',';','^', -/* 60 */ '-','/','.','.','.','.','.','.','.','.','|',',','%','_','>','?', -/* 70 */ '.','.','.','.','.','.','.','.','.','`',':','#','@','\'','=','"', -/* 80 */ '.','a','b','c','d','e','f','g','h','i','.','.','.','.','.','.', -/* 90 */ '.','j','k','l','m','n','o','p','q','r','.','.','.','.','.','.', -/* A0 */ '.','~','s','t','u','v','w','x','y','z','.','.','.','.','.','.', -/* B0 */ '.','.','.','.','.','.','.','.','.','.','.','.','.','.','.','.', -/* C0 */ '{','A','B','C','D','E','F','G','H','I','.','.','.','.','.','.', -/* D0 */ '}','J','K','L','M','N','O','P','Q','R','.','.','.','.','.','.', -/* E0 */ '\\','.','S','T','U','V','W','X','Y','Z','.','.','.','.','.','.', -/* F0 */ '0','1','2','3','4','5','6','7','8','9','.','.','.','.','.','.', -}; - - -int match_trace_criteria(unsigned char *pkt, int len, int *dlci); -void trace_banner (int len, unsigned char status, unsigned int timestamp, int *trace_started); -unsigned char hexdig(unsigned char n); -unsigned char dighex(unsigned char n); -int x25_call_request_decode (unsigned char *data, int len); - - -int match_trace_criteria(unsigned char *pkt, int len, int *dlci) -{ - unsigned int tmp_val; - tmp_val=(pkt[0] >> 2)&0x3F; - tmp_val = tmp_val<<4; - tmp_val|=(pkt[1]>>4)&0x0F; - - *dlci=tmp_val; - - if (TRACE_DLCI > 0){ - if (TRACE_DLCI == tmp_val){ - return 0; - } - }else if (TRACE_DLCI == 0){ - return 0; - } - - return 1; -} -void trace_banner (int len, unsigned char status, unsigned int timestamp, int *trace_started) -{ - if (!(*trace_started)){ - unsigned char date_string[50]; - - date_string[0] = '\0'; - - sprintf(date_string, "%5d", timestamp); - - if (sys_timestamp){ - char tmp_time[10]; - time_t time_val; - struct tm *time_tm; - - /* Parse time and date */ - time(&time_val); - time_tm = localtime(&time_val); - - strftime(tmp_time,sizeof(tmp_time),"%m",time_tm); - sprintf(date_string+strlen(date_string), " | %s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); - sprintf(date_string+strlen(date_string), "%s ",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); - sprintf(date_string+strlen(date_string), "%s\t",tmp_time); - } - - printf("\n%s : Len=%d\tTime Stamp=%s\n", - (status & 0x01) ? - "OUTGOING" : "INCOMING", - len, - date_string); - - *trace_started=1; - } -} - - -unsigned char hexdig(unsigned char n) -{ - n &= 0x0F; - /* only operate on the low four bits - * return a single hexadecmal ASCII digit */ - return((n >= 10) ? (n - 10 + 'A') : (n + '0')); -} - - -unsigned char dighex(unsigned char n) -{ - - if (n >= 'a') - /* provide the adjustment if the passed ASCII value is greater */ - return(n + 10 - 'a') ; /* than 'a' */ - else - /* provide the adjustment if the passed ASCII value is greater */ - /* than 'A' or is a numeral */ - return((n >= 'A') ? (n + 10 - 'A') : (n - '0')); -} - - -int x25_call_request_decode (unsigned char *data, int len) -{ - int len1, len2; - int i; - char addr1[16], addr2[16]; - char udata[200]; - char *first, *second; - char byte; - int localoffset; - int offset=3; - int facil_len; - unsigned char tmp_val; - - byte = data[offset]; - len2 = (byte >> 4) & 0x0F; - len1 = (byte >> 0) & 0x0F; - - if ((len1+len2) > len){ - return 1; - } - - - localoffset = ++offset; - byte = data[localoffset]; - - first=addr1; - second=addr2; - for (i = 0; i < (len1+len2); i++) { - if (i < len1) { - if (i % 2 != 0) { - *first++ = ((byte >> 0) & 0x0F) + '0'; - localoffset++; - byte = data[localoffset]; - } else { - *first++ = ((byte >> 4) & 0x0F) + '0'; - } - } else { - if (i % 2 != 0) { - *second++ = ((byte >> 0) & 0x0F) + '0'; - localoffset++; - byte = data[localoffset]; - } else { - *second++ = ((byte >> 4) & 0x0F) + '0'; - } - } - } - - *first = '\0'; - *second = '\0'; - - if (len1) { - printf("Called=%s ",addr1); - } - if (len2) { - printf("Calling=%s ",addr2); - } - - localoffset = 4; - localoffset += ((len1 + len2 + 1) / 2); - - if (localoffset >= len) - return 0; - - /* Look for facilities */ - facil_len=data[localoffset]; - - /* Skip facilites for now */ - if (facil_len){ - printf ("Facil="); - localoffset++; - - for (i=0;i= len) - return 0; - - len1=localoffset; - - first=udata; - byte=data[localoffset]; - for (i=0;i<((len-len1)*2) && i> 0) & 0x0F; - *first++ = hexdig(tmp_val); -#if 0 - if (tmp_val >= 0 && tmp_val <= 9){ - *first++ = tmp_val + '0'; - }else{ - *first++ = tmp_val + 55; - } -#endif - localoffset++; - byte = data[localoffset]; - } else { - tmp_val=(byte >> 4) & 0x0F; - *first++ = hexdig(tmp_val); - } - } - - *first='\0'; - printf("Data=%s",udata); - - /* Look for user data */ - return 0; -} - -static char *clear_code(unsigned char code) -{ - static char buffer[25]; - - if (code == 0x00 || (code & 0x80) == 0x80) - return "DTE Originated"; - if (code == 0x01) - return "Number Busy"; - if (code == 0x03) - return "Invalid Facility Requested"; - if (code == 0x05) - return "Network Congestion"; - if (code == 0x09) - return "Out Of Order"; - if (code == 0x0B) - return "Access Barred"; - if (code == 0x0D) - return "Not Obtainable"; - if (code == 0x11) - return "Remote Procedure Error"; - if (code == 0x13) - return "Local Procedure Error"; - if (code == 0x15) - return "RPOA Out Of Order"; - if (code == 0x19) - return "Reverse Charging Acceptance Not Subscribed"; - if (code == 0x21) - return "Incompatible Destination"; - if (code == 0x29) - return "Fast Select Acceptance Not Subscribed"; - if (code == 0x39) - return "Destination Absent"; - - sprintf(buffer, "Unknown %02X", code); - - return buffer; -} - -static char *clear_diag(unsigned char code) -{ - static char buffer[25]; - - if (code == 0) - return "No additional information"; - if (code == 1) - return "Invalid P(S)"; - if (code == 2) - return "Invalid P(R)"; - if (code == 16) - return "Packet type invalid"; - if (code == 17) - return "Packet type invalid for state r1"; - if (code == 18) - return "Packet type invalid for state r2"; - if (code == 19) - return "Packet type invalid for state r3"; - if (code == 20) - return "Packet type invalid for state p1"; - if (code == 21) - return "Packet type invalid for state p2"; - if (code == 22) - return "Packet type invalid for state p3"; - if (code == 23) - return "Packet type invalid for state p4"; - if (code == 24) - return "Packet type invalid for state p5"; - if (code == 25) - return "Packet type invalid for state p6"; - if (code == 26) - return "Packet type invalid for state p7"; - if (code == 27) - return "Packet type invalid for state d1"; - if (code == 28) - return "Packet type invalid for state d2"; - if (code == 29) - return "Packet type invalid for state d3"; - if (code == 32) - return "Packet not allowed"; - if (code == 33) - return "Unidentifiable packet"; - if (code == 34) - return "Call on one-way logical channel"; - if (code == 35) - return "Invalid packet type on a PVC"; - if (code == 36) - return "Packet on unassigned LC"; - if (code == 37) - return "Reject not subscribed to"; - if (code == 38) - return "Packet too short"; - if (code == 39) - return "Packet too long"; - if (code == 40) - return "Invalid general format identifier"; - if (code == 41) - return "Restart/registration packet with nonzero bits"; - if (code == 42) - return "Packet type not compatible with facility"; - if (code == 43) - return "Unauthorised interrupt confirmation"; - if (code == 44) - return "Unauthorised interrupt"; - if (code == 45) - return "Unauthorised reject"; - if (code == 48) - return "Time expired"; - if (code == 49) - return "Time expired for incoming call"; - if (code == 50) - return "Time expired for clear indication"; - if (code == 51) - return "Time expired for reset indication"; - if (code == 52) - return "Time expired for restart indication"; - if (code == 53) - return "Time expired for call deflection"; - if (code == 64) - return "Call set-up/clearing or registration pb."; - if (code == 65) - return "Facility/registration code not allowed"; - if (code == 66) - return "Facility parameter not allowed"; - if (code == 67) - return "Invalid called DTE address"; - if (code == 68) - return "Invalid calling DTE address"; - if (code == 69) - return "Invalid facility/registration length"; - if (code == 70) - return "Incoming call barred"; - if (code == 71) - return "No logical channel available"; - if (code == 72) - return "Call collision"; - if (code == 73) - return "Duplicate facility requested"; - if (code == 74) - return "Non zero address length"; - if (code == 75) - return "Non zero facility length"; - if (code == 76) - return "Facility not provided when expected"; - if (code == 77) - return "Invalid CCITT-specified DTE facility"; - if (code == 78) - return "Max. nb of call redir/defl. exceeded"; - if (code == 80) - return "Miscellaneous"; - if (code == 81) - return "Improper cause code from DTE"; - if (code == 82) - return "Not aligned octet"; - if (code == 83) - return "Inconsistent Q bit setting"; - if (code == 84) - return "NUI problem"; - if (code == 112) - return "International problem"; - if (code == 113) - return "Remote network problem"; - if (code == 114) - return "International protocol problem"; - if (code == 115) - return "International link out of order"; - if (code == 116) - return "International link busy"; - if (code == 117) - return "Transit network facility problem"; - if (code == 118) - return "Remote network facility problem"; - if (code == 119) - return "International routing problem"; - if (code == 120) - return "Temporary routing problem"; - if (code == 121) - return "Unknown called DNIC"; - if (code == 122) - return "Maintenance action"; - if (code == 144) - return "Timer expired or retransmission count surpassed"; - if (code == 145) - return "Timer expired or retransmission count surpassed for INTERRUPT"; - if (code == 146) - return "Timer expired or retransmission count surpassed for DATA " - "packet transmission"; - if (code == 147) - return "Timer expired or retransmission count surpassed for REJECT"; - if (code == 160) - return "DTE-specific signals"; - if (code == 161) - return "DTE operational"; - if (code == 162) - return "DTE not operational"; - if (code == 163) - return "DTE resource constraint"; - if (code == 164) - return "Fast select not subscribed"; - if (code == 165) - return "Invalid partially full DATA packet"; - if (code == 166) - return "D-bit procedure not supported"; - if (code == 167) - return "Registration/Cancellation confirmed"; - if (code == 224) - return "OSI network service problem"; - if (code == 225) - return "Disconnection (transient condition)"; - if (code == 226) - return "Disconnection (permanent condition)"; - if (code == 227) - return "Connection rejection - reason unspecified (transient " - "condition)"; - if (code == 228) - return "Connection rejection - reason unspecified (permanent " - "condition)"; - if (code == 229) - return "Connection rejection - quality of service not available " - "transient condition)"; - if (code == 230) - return "Connection rejection - quality of service not available " - "permanent condition)"; - if (code == 231) - return "Connection rejection - NSAP unreachable (transient condition)"; - if (code == 232) - return "Connection rejection - NSAP unreachable (permanent condition)"; - if (code == 233) - return "reset - reason unspecified"; - if (code == 234) - return "reset - congestion"; - if (code == 235) - return "Connection rejection - NSAP address unknown (permanent " - "condition)"; - if (code == 240) - return "Higher layer initiated"; - if (code == 241) - return "Disconnection - normal"; - if (code == 242) - return "Disconnection - abnormal"; - if (code == 243) - return "Disconnection - incompatible information in user data"; - if (code == 244) - return "Connection rejection - reason unspecified (transient " - "condition)"; - if (code == 245) - return "Connection rejection - reason unspecified (permanent " - "condition)"; - if (code == 246) - return "Connection rejection - quality of service not available " - "(transient condition)"; - if (code == 247) - return "Connection rejection - quality of service not available " - "(permanent condition)"; - if (code == 248) - return "Connection rejection - incompatible information in user data"; - if (code == 249) - return "Connection rejection - unrecognizable protocol indentifier " - "in user data"; - if (code == 250) - return "Reset - user resynchronization"; - - sprintf(buffer, "Unknown %d", code); - - return buffer; -} - - -void decode_pkt (unsigned char *data,int len, - unsigned char status, unsigned int timestamp, - int protocol) -{ - int inf_frame=0; - int trace_started=0; - int dlci; - - if (match_trace_criteria(data,len,&dlci) != 0) - return; - - if (!TRACE_EBCDIC && !TRACE_ASCII && !TRACE_HEX){ - TRACE_HEX=1; - } - - if (protocol){ - if (TRACE_PROTOCOL & FRAME){ - - trace_banner(len,status,timestamp,&trace_started); - - printf("\tFR : "); - printf("DLCI=%i ", dlci); - printf("C/R=%i ", (data[0]&0x2)>>1); - printf("EA=%i ", data[0]&0x1); - printf("FECN=%i ", (data[1]&0x8)>>3); - printf("BECN=%i ", (data[1]&0x4)>>2); - printf("DE=%i ", (data[1]&0x2)>>1); - printf("EA=%i ", data[1]&0x1); - printf("\n"); - - if (!dlci || dlci==1023){ - printf("\n"); - return; - } - } - data+=2; - len-=2; - - if (!dlci || dlci==1023){ - return; - } - } - - - if (len<2){ - return; - } - - if (TRACE_PROTOCOL & LAPB){ - - trace_banner(len,status,timestamp,&trace_started); - - inf_frame=0; - printf("\tLAPB : %02i | ",data[0]); - - if (!(data[1]&0x01)){ - if (len >= 5){ - printf("INF Ns=%1i Nr=%1i P=%1i : ", - (data[1]>>1)&0x07, - data[1]>>5, - (data[1]>>4)&0x01,(len-2)); - inf_frame=1; - }else{ - printf("INF Ns=%1i Nr=%1i P=%1i ", - (data[1]>>1)&0x07, - data[1]>>5, - (data[1]>>4)&0x01); - } - goto end_lapb_decode; - } - - switch ((data[1]&0x0F)){ - - case 0x01: - printf("RR Pr=%1i P=%1i", - (data[1]>>5), - (data[1]>>4)&0x01); - break; - - case 0x05: - printf("RNR Pr=%1i P=%1i", - (data[1]>>5), - (data[1]>>4)&0x01); - - break; - - case 0x09: - printf("REJ Pr=%1i P=%1i", - (data[1]>>5), - (data[1]>>4)&0x01); - break; - - default: - - switch (data[1]&0xEF){ - - case 0x2F: - printf("SBM P=%1i", - (data[1]>>4)&0x01); - break; - case 0x0F: - printf("DM F=%1i", - (data[1]>>4)&0x01); - break; - - case 0x43: - printf("DSC P=%1i", - (data[1]>>4)&0x01); - break; - case 0x63: - printf("UA F=%1i", - (data[1]>>4)&0x01); - break; - - case 0x87: - printf("FMR F=%1i", - (data[1]>>4)&0x01); - break; - - default: - printf("Unknown lapb pkt : 0x%02X ", data[1]); - break; - } - } - -end_lapb_decode: - printf("\n"); - - if (!inf_frame){ - return; - } - - }else{ - /* Do not pass non information frames to X25 */ - if ((data[1]&0x01)){ - return; - } - } - - data+=2; - len-=2; - - if (len<3){ - return; - } - - - if (TRACE_PROTOCOL & X25){ - - unsigned int lcn = ((data[0]&0x0F)<<8)|(data[1]&0xFF); - unsigned char mod = (data[0]>>4)&0x03; - unsigned char pkt_type; - unsigned char pr,ps,mbit; - - inf_frame=0; - if (TRACE_X25_LCN){ - if (lcn != 0 && TRACE_X25_LCN != lcn){ - return; - } - } - - pkt_type=data[2]; - - if (!(pkt_type&0x01)){ - if (!(TRACE_X25_OPT & DATA)){ - return; - } - }else{ - if (!(TRACE_X25_OPT & PROT)){ - return; - } - } - - trace_banner(len,status,timestamp,&trace_started); - - printf("\tX25 : LCN=%i Q=%i D=%i Modulo=%i : ", - lcn, - data[0]&0x80, - data[0]&0x40, - data[0]&0x10 ? 8 : 128); - - if (!(pkt_type&0x01)){ - - if (mod==X25_MOD8){ - pr=data[2]>>5; - ps=(data[2]>>1)&0x07; - mbit=(data[2]&0x10)>>4; - }else{ - ps=data[2]>>1; - pr=data[3]>>1; - mbit=data[3]&0x01; - } - - printf("DATA Pr=%02i Ps=%02i M=%i", - pr,ps,mbit); - inf_frame=1; - goto end_x25_decode; - }else{ - if (mod==X25_MOD8){ - pr=data[2]>>5; - }else{ - pr=data[3]>>1; - } - } - - switch(pkt_type&0x1F){ - - case 0x01: - printf("\n\t "); - printf("RR Pr=%02i",pr); - break; - - case 0x05: - printf("\n\t "); - printf("RNR Pr=%02i",pr); - break; - - case 0x09: - printf("\n\t "); - printf("REJ Pr=%02i",pr); - break; - - default: - - printf("\n\t * "); - - switch(pkt_type){ - - case 0x0B: - printf("CALL REQUEST :\n\t "); - x25_call_request_decode(data,len); - break; - - case 0x0F: - printf("CALL ACCEPT "); - break; - - case 0x13: - printf("CLEAR REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x17: - printf("CLEAR CONFIRM :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x23: - printf("INTERRUPT :\n\t "); - printf("Data=(0x%02X)",data[3]); - break; - - case 0x27: - printf("INTERRUPT CONFIRM"); - break; - - case 0x1B: - printf("RESET REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x1F: - printf("RESET CONFIRM"); - break; - - case 0xFB: - printf("RESTART REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0xFF: - printf("RESTART CONFIRM"); - break; - - case 0xF1: - printf("\nDIAGNOSTIC"); - break; - - default: - printf("\nUnknown x25 cmd 0x%2X",data[2]); - break; - } - break; - } -end_x25_decode: - - if (inf_frame){ - int i; - char ch; - char *specials = "\b\f\n\r\t"; - char *escapes = "bfnrt"; - char *cp; - - printf("\n"); - - if (TRACE_HEX){ - printf("\n\thex : "); - for (i=3;i= 0x40) ? ebcdic[data[i] - 0x40] : '.'; - - if ((ch != '.' || data[i] == ebcdic['.'])) - (void) printf("%c", ch); - else if (data[i] && (cp = strchr(specials, data[i]))) - (void) printf("\\%c", escapes[cp - specials]); - else - (void) printf("%02X", data[i]); - - //if (((i-2) % 25) == 0){ - // printf("\n\t "); - //} - - } - printf("\n"); - } - - }else{ //end of inf frame - printf("\n"); - } - } -} - -static void decode_x25(unsigned char *data) -{ - unsigned int lcn = ((data[0]&0x0F)<<8)|(data[1]&0xFF); - unsigned char mod = (data[0]>>4)&0x03; - unsigned char pkt_type; - unsigned char pr,ps,mbit; - unsigned char inf_frame=0; - - if (TRACE_X25_LCN){ - if (lcn != 0 && TRACE_X25_LCN != lcn){ - return; - } - } - - pkt_type=data[2]; - - if (!(pkt_type&0x01)){ - if (!(TRACE_X25_OPT & DATA)){ - return; - } - }else{ - if (!(TRACE_X25_OPT & PROT)){ - return; - } - } - - trace_banner(len,status,timestamp,&trace_started); - - printf("\tX25 : LCN=%i Q=%i D=%i Modulo=%i : ", - lcn, - data[0]&0x80, - data[0]&0x40, - data[0]&0x10 ? 8 : 128); - - if (!(pkt_type&0x01)){ - - if (mod==X25_MOD8){ - pr=data[2]>>5; - ps=(data[2]>>1)&0x07; - mbit=(data[2]&0x10)>>4; - }else{ - ps=data[2]>>1; - pr=data[3]>>1; - mbit=data[3]&0x01; - } - - printf("DATA Pr=%02i Ps=%02i M=%i", - pr,ps,mbit); - inf_frame=1; - goto end_x25_decode; - }else{ - if (mod==X25_MOD8){ - pr=data[2]>>5; - }else{ - pr=data[3]>>1; - } - } - - switch(pkt_type&0x1F){ - - case 0x01: - printf("\n\t "); - printf("RR Pr=%02i",pr); - break; - - case 0x05: - printf("\n\t "); - printf("RNR Pr=%02i",pr); - break; - - case 0x09: - printf("\n\t "); - printf("REJ Pr=%02i",pr); - break; - - default: - - printf("\n\t * "); - - switch(pkt_type){ - - case 0x0B: - printf("CALL REQUEST :\n\t "); - x25_call_request_decode(data,len); - break; - - case 0x0F: - printf("CALL ACCEPT "); - break; - - case 0x13: - printf("CLEAR REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x17: - printf("CLEAR CONFIRM :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x23: - printf("INTERRUPT :\n\t "); - printf("Data=(0x%02X)",data[3]); - break; - - case 0x27: - printf("INTERRUPT CONFIRM"); - break; - - case 0x1B: - printf("RESET REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0x1F: - printf("RESET CONFIRM"); - break; - - case 0xFB: - printf("RESTART REQUEST :\n\t "); - printf("Code=(0x%02X)%s : Diag=(0x%02X)%s", - data[3],clear_code(data[3]), - data[4],clear_diag(data[4])); - break; - - case 0xFF: - printf("RESTART CONFIRM"); - break; - - case 0xF1: - printf("\nDIAGNOSTIC"); - break; - - default: - printf("\nUnknown x25 cmd 0x%2X",data[2]); - break; - } - break; - } -end_x25_decode: - - if (inf_frame){ - int i; - char ch; - char *specials = "\b\f\n\r\t"; - char *escapes = "bfnrt"; - char *cp; - - printf("\n"); - - if (TRACE_HEX){ - printf("\n\thex : "); - for (i=3;i= 0x40) ? ebcdic[data[i] - 0x40] : '.'; - - if ((ch != '.' || data[i] == ebcdic['.'])) - (void) printf("%c", ch); - else if (data[i] && (cp = strchr(specials, data[i]))) - (void) printf("\\%c", escapes[cp - specials]); - else - (void) printf("%02X", data[i]); - - //if (((i-2) % 25) == 0){ - // printf("\n\t "); - //} - - } - printf("\n"); - } - - }else{ //end of inf frame - printf("\n"); - } -} - - - -static void print_pcap_file_header (wp_trace_output_iface_t *trace_iface) -{ - struct pcap_hdr fh; - - fh.magic = PCAP_MAGIC; - fh.version_major = 2; - fh.version_minor = 4; - fh.thiszone = 0; - fh.sigfigs = 0; - fh.snaplen = 102400; - fh.network = trace_iface->link_type; - - fwrite(&fh, sizeof(fh), 1, trace_iface->output_file); -} - -static void print_pcap_record_header(wp_trace_output_iface_t *trace_iface) -{ - struct pcaprec_hdr ph; - - /* Write PCap header */ - ph.ts_sec = trace_iface->pkts_written; - ph.ts_usec = trace_iface->pkts_written; - ph.incl_len = trace_iface->len; - ph.orig_len = trace_iface->len; - - fwrite(&ph, sizeof(ph), 1, trace_iface->output_file); -} - -void wp_trace_output(wp_trace_output_iface_t *trace_iface) -{ - int num_chars; - int j; - - switch (trace_iface->type){ - - - case WP_OUT_TRACE_INTERP: - - decode_pkt(trace_iface->data, - trace_iface->len, - trace_iface->status, - trace_iface->timestamp, - 0); - - break; - - case WP_OUT_TRACE_PCAP: - - trace_iface->output_file = pcap_output_file; - if (trace_iface->output_file == NULL){ - printf("Error: No output binary file specified!\n"); - return; - } - - if (trace_iface->init==0){ - - if (pcap_prot){ - trace_iface->link_type=pcap_prot; - } - - print_pcap_file_header(trace_iface); - printf("Staring PCAP File Trace in: %s\n\n", - pcap_output_file_name); - trace_iface->init=1; - } - - print_pcap_record_header(trace_iface); - - fwrite(&trace_iface->data[0], trace_iface->len, 1, trace_iface->output_file); - - printf("\rTotal Captured=%-5u (Len=%i)",trace_iface->pkts_written+1,trace_iface->len); - - break; - - case WP_OUT_TRACE_RAW: - default: - - if (trace_iface->status & WP_TRACE_OUTGOING){ - printf("\nOUTGOING\t"); - }else{ - printf("\nINCOMING\t"); - } - - printf("Len=%-5u\tTimestamp=%-5u\t", - trace_iface->len, - trace_iface->timestamp); - - trace_iface->status&=(~WP_TRACE_OUTGOING); - - if (trace_iface->status){ - printf("Receive error - "); - - if(trace_iface->status & WP_TRACE_ABORT){ - printf("Abort"); - }else{ - printf((trace_iface->status & WP_TRACE_CRC) ? "Bad CRC" : "Overrun"); - } - } - - if (trace_iface->len == 0){ - printf("the frame data is not available" ); - return; - } - - if (!trace_iface->trace_all_data){ - num_chars = ((trace_iface->len <= DEFAULT_TRACE_LEN)? - trace_iface->len:DEFAULT_TRACE_LEN); - }else{ - num_chars = trace_iface->len; - } - - printf("\n\t\t"); - for( j=0; jdata[j]); - } - - if (num_chars < trace_iface->len){ - printf(".."); - } - - printf("\n"); - - break; - } - - trace_iface->pkts_written++; - trace_iface->status=0; -} - - - diff --git a/util/wanpipemon.old/ss7pipemon.c b/util/wanpipemon.old/ss7pipemon.c deleted file mode 100644 index 4da88a3..0000000 --- a/util/wanpipemon.old/ss7pipemon.c +++ /dev/null @@ -1,1196 +0,0 @@ -/***************************************************************************** -* wanpipemon.c Cisco HDLC Monitor -* -* Author: Nenad Corbic -* -* Copyright: (c) 1995-1999 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. -* ---------------------------------------------------------------------------- -* Dec 05, 2001 Alex Feldman Added T1/E1 Statistics. -* Nov 07, 2000 Nenad Corbic Added Keyboard Led Debugging Commands. -* Mar 14, 2000 Nenad Corbic Added API support. No IP addresses needed. -* Sep 21, 1999 Nenad Corbic Changed the input parameters, hearders -* data types. More user friendly. -* Aug 06, 1998 David Fong Initial version based on ppipemon -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include /* offsetof(), etc. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# error "Non Linux OS Not supproted!" -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define TIMEOUT 1 -#define MDATALEN MAX_LGTH_UDP_MGNT_PKT -#define MAX_TRACE_BUF ((MDATALEN+200)*2) - -#define BANNER(str) banner(str,0) -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ -/* Structures for data casting */ - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -/* The ft1_lib needs these global variables */ - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -static void error( void ); - -/* Command routines */ -static void modem( void ); -static void global_stats( void ); -static void comm_stats( void ); -static void read_code_version( void ); -static void ss7_configuration( void ); -static void link_status( void ); -static void operational_stats( void ); -static void line_trace( int ); -static void ss7_router_up_time( void ); -static void flush_operational_stats( void ); -static void flush_global_stats( void ); -static void flush_comm_stats( void ); -//static void set_FT1_monitor_status( unsigned char); -//static void read_ft1_op_stats( void ); -//static void read_ft1_te1_56k_config( void ); -//static void ft1_usage (void); - - -static char *gui_main_menu[]={ -"ss7_card_stats_menu","Card Status", -"ss7_card_config_menu","Card Configuration", -"ss7_stats_menu", "Card Statistics", -"ss7_trace_menu", "Trace Data", -"csudsu_menu", "CSU DSU Config/Stats", -"ss7_flush_menu","Flush Statistics", -"." -}; - - -static char *ss7_card_stats_menu[]={ -"xm","Modem Status", -"xl","Link Status", -"xcv","Read Code Version", -"xru","Display Router UP time", -"." -}; - -static char *ss7_card_config_menu[]={ -"crc","Read Configuration\n", -"creset","Reset Adapter\n", -"." -}; - -static char *ss7_stats_menu[]={ -"sg","Global Statistics", -"sc","Communication Error Statistics", -"so","Operational Statistics", -"ss","SLARP and CDP Statistics", -"." -}; - -static char *ss7_trace_menu[]={ -"tr" ,"Trace ALL Diff SS7 frames, in Hex", -"trf","Trace Diff FISU frames, in Hex", -"trl","Trace Diff LSSU frames, in Hex", -"trm","Trace Diff MSU frames, in Hex", - -"." -}; - -#if 0 -static char *ss7_csudsu_menu[]={ -"Tv","View Status", -"Ts","Self Test", -"Tl","Line Loop Test", -"Td","Digital Loop Test", -"Tr","Remote Test", -"To","Operational Mode", -"Tp","Operational stats (FT1)", -"Tf", "Flush operational stats (FT1)", -"Tset", "Set FT1 configuration", -"Tread","Read CSU/DSU config (FT1/T1/E1)", -"Tallb","E Line Loopback (T1/E1)", -"Tdllb","D Line Loopback (T1/E1)", -"Taplb","E Payload Loopback (T1/E1)", -"Tdplb","D Payload Loopback (T1/E1)", -"Tadlb","E Diag Digital Loopback (T1/E1)", -"Tddlb","D Diag Digital Loopback (T1/E1)", -"Tsalb","Send Loopback Activate Code (T1/E1)", -"Tsdlb","Send Loopback Deactive Code (T1/E1)", -"Ta","Read T1/E1/56K alrams", -"." -}; -#endif - -static char *ss7_flush_menu[]={ -"fg","Flush Global Statistics", -"fc","Flush Communication Error Statistics", -"fo","Flush Operational Statistics", -"fs","Flush SLARP and CDP Statistics", -"fp","Flush T1/E1 performance monitoring counters", -"." -}; - - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"ss7_card_stats_menu",ss7_card_stats_menu}, - {"ss7_card_config_menu",ss7_card_config_menu}, - {"ss7_stats_menu",ss7_stats_menu}, - {"ss7_trace_menu",ss7_trace_menu}, - {"csudsu_menu",csudsu_menu}, - {"ss7_flush_menu",ss7_flush_menu}, - {".",NULL} -}; - - -char ** SS7get_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** SS7get_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int SS7Config(void) -{ - char codeversion[10]; - unsigned char x=0; - - protocol_cb_size = sizeof(wan_mgmt_t) + - sizeof(wan_cmd_t) + - sizeof(wan_trace_info_t) + 1; - wan_udp.wan_udphdr_command= L2_READ_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - while (++x < 4) { - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - - if (wan_udp.wan_udphdr_return_code == 0xCC){ - return(WAN_FALSE); - } - wan_udp.wan_udphdr_return_code = 0xaa; - } - - if (x >= 4) return(WAN_FALSE); - - if (wan_udp.wan_udphdr_data_len == sizeof(L2_CONFIGURATION_STRUCT)) { - is_508 = WAN_TRUE; - } else { - is_508 = WAN_FALSE; - } - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = READ_SS7_CODE_VERSION; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - return(WAN_TRUE); -}; - -#if 0 -void ss7_set_FT1_mode( void ) -{ - for(;;){ - wan_udp.wan_udphdr_command= SET_FT1_MODE; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0){ - break; - } - } -} /* set_FT1_mode */ - -void ss7_read_FT1_status( void ) -{ - - wan_udp.wan_udphdr_command= SPIPE_FT1_READ_STATUS; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = 0xaa; - DO_COMMAND(wan_udp); - if(wan_udp.wan_udphdr_return_code == 0) { - par_port_A_byte = wan_udp.wan_udphdr_data[0]; - par_port_B_byte = wan_udp.wan_udphdr_data[1]; - - if(!(par_port_A_byte & PP_A_RT_NOT_RED)) { - FT1_LED.RT_red ++; - } - if(!(par_port_A_byte & PP_A_RT_NOT_GREEN)) { - FT1_LED.RT_green ++; - } - if((par_port_A_byte & (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) - == (PP_A_RT_NOT_GREEN | PP_A_RT_NOT_RED)) { - FT1_LED.RT_off ++; - } - if(!(par_port_A_byte & PP_A_LL_NOT_RED)) { - FT1_LED.LL_red ++; - } - else { - FT1_LED.LL_off ++; - } - if(!(par_port_A_byte & PP_A_DL_NOT_RED)) { - FT1_LED.DL_red ++; - } - else { - FT1_LED.DL_off ++; - } - if(!(par_port_B_byte & PP_B_RxD_NOT_GREEN)) { - FT1_LED.RxD_green ++; - } - if(!(par_port_B_byte & PP_B_TxD_NOT_GREEN)) { - FT1_LED.TxD_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_GREEN)) { - FT1_LED.ERR_green ++; - } - if(!(par_port_B_byte & PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_red ++; - } - if((par_port_B_byte & (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) - == (PP_B_ERR_NOT_GREEN | PP_B_ERR_NOT_RED)) { - FT1_LED.ERR_off ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_RED)) { - FT1_LED.INS_red ++; - } - if(!(par_port_B_byte & PP_B_INS_NOT_GREEN)) { - FT1_LED.INS_green ++; - } - if((par_port_B_byte & (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) - == (PP_B_INS_NOT_GREEN | PP_B_INS_NOT_RED)) { - FT1_LED.INS_off ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_GREEN)) { - FT1_LED.ST_green ++; - } - if(!(par_port_B_byte & PP_B_ST_NOT_RED)) { - FT1_LED.ST_red ++; - } - if((par_port_B_byte & (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) - == (PP_B_ST_NOT_GREEN | PP_B_ST_NOT_RED)) { - FT1_LED.ST_off ++; - } - } -} /* read_FT1_status */ - -#endif - -static void error( void ) -{ - printf("Error: Command failed!\n"); - -}; /* error */ - - -static void global_stats (void) -{ - GLOBAL_STATS_STRUCT* global_stats; - wan_udp.wan_udphdr_command= READ_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("GLOBAL STATISTICS"); - global_stats = (GLOBAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - printf("Times application did not respond to IRQ: %u", - global_stats->app_IRQ_timeout_count); - } else { - error(); - } -}; /* global stats */ - -static void flush_global_stats (void) -{ - wan_udp.wan_udphdr_command= FLUSH_GLOBAL_STATISTICS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) error(); -}; /* flush global stats */ - -static void modem( void ) -{ - unsigned char cts_dcd; - wan_udp.wan_udphdr_command= READ_MODEM_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("MODEM STATUS"); - memcpy(&cts_dcd, &wan_udp.wan_udphdr_data[0],1); - printf("DCD: "); - (cts_dcd & 0x08) ? printf("High\n") : printf("Low\n"); - printf("CTS: "); - (cts_dcd & 0x20) ? printf("High\n") : printf("Low\n"); - } else { - error(); - } -}; /* modem */ - - -static void comm_stats (void) -{ - COMMS_ERROR_STATS_STRUCT* comm_stats; - wan_udp.wan_udphdr_command= READ_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 ) { - BANNER("COMMUNICATION ERROR STATISTICS"); - - comm_stats = (COMMS_ERROR_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf(" Number of receiver overrun errors: %u\n", comm_stats->Rx_overrun_err_count); - printf(" Number of receiver CRC errors: %u\n", comm_stats->CRC_err_count); - printf(" Number of abort frames received: %u\n", comm_stats->Rx_abort_count); - printf(" Number of times receiver disabled: %u\n", comm_stats->Rx_dis_pri_bfrs_full_count); - printf(" Number of times DCD changed state: %u\n", comm_stats->DCD_state_change_count); - printf(" Number of times CTS changed state: %u\n", comm_stats->CTS_state_change_count); - } else { - error(); - } -}; /* comm_stats */ - - -static void flush_comm_stats( void ) -{ - wan_udp.wan_udphdr_command= FLUSH_COMMS_ERROR_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) error(); -}; /* flush_comm_stats */ - - -static void read_code_version (void) -{ - wan_udp.wan_udphdr_command= READ_SS7_CODE_VERSION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - unsigned char version[10]; - BANNER("CODE VERSION"); - memcpy(version,&wan_udp.wan_udphdr_data,wan_udp.wan_udphdr_data_len); - version[wan_udp.wan_udphdr_data_len] = '\0'; - printf("SS7 Code version: %s\n", version); - } -}; /* read code version */ - -static void ss7_configuration (void) -{ - L2_CONFIGURATION_STRUCT *ss7_cfg; - wan_udp.wan_udphdr_command = L2_READ_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - ss7_cfg = (L2_CONFIGURATION_STRUCT *)&wan_udp.wan_udphdr_data[0]; - BANNER("SS7 CONFIGURATION"); - - printf("Baud rate: %lu", ss7_cfg->baud_rate); - - printf("\nLine configuration: "); - switch (ss7_cfg->line_config_options) { - case INTERFACE_LEVEL_V35: - printf("V.35"); - break; - case INTERFACE_LEVEL_RS232: - printf("RS-232"); - break; - } - - printf("\n Modem Config Options on: 0x%04X", - ss7_cfg->modem_config_options); - - printf("\n Modem Status Timer: %u", - ss7_cfg->modem_status_timer); - - printf("\n L2 API Options: 0x%04X", - ss7_cfg->L2_API_options); - - printf("\n L2 Protocol Options: 0x%04X", - ss7_cfg->L2_protocol_options); - - } else { - error(); - } -}; /* ss7_configuration */ - - -static void link_status (void) -{ - L2_LINK_STATUS_STRUCT *status; - wan_udp.wan_udphdr_command= L2_READ_LINK_STATUS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("LINK STATUS"); - - status = (L2_LINK_STATUS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - printf(" Link status: "); - switch (status->L2_link_status) { - case L2_LINK_STAT_IN_SERVICE: - printf("In Service\n"); - break; - default: - printf("Inactive 0x%X\n", - wan_udp.wan_udphdr_return_code); - break; - } - - printf("Available data frames for application: %u\n", - status->no_Rx_MSUs_avail_for_L3); - - printf(" Receiver status: "); - if (status->receiver_status & 0x01) - printf("Disabled due to flow control restrictions\n"); - else printf("Enabled\n"); - } else { - error(); - } -}; /* Link Status */ - - -static void operational_stats (void) -{ - L2_OPERATIONAL_STATS_STRUCT *stats; - wan_udp.wan_udphdr_command= L2_READ_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - BANNER("OPERATIONAL STATISTICS"); - stats = (L2_OPERATIONAL_STATS_STRUCT *)&wan_udp.wan_udphdr_data[0]; - - } else { - error(); - } -} /* Operational_stats */ - - -static void flush_operational_stats( void ) -{ - wan_udp.wan_udphdr_command= L2_FLUSH_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0 ) { - error(); - } - -}; /* flush_operational_stats */ - -int SS7DisableTrace(void) -{ - wan_udp.wan_udphdr_command= SPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - return 0; -} - -static void line_trace(int trace_mode) -{ - unsigned int num_frames, num_chars; - unsigned short curr_pos = 0; - wan_trace_pkt_t *trace_pkt; - unsigned int i, j; - int recv_buff = sizeof(wan_udp_hdr_t)+ 100; - fd_set ready; - struct timeval to; - - setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recv_buff, sizeof(int) ); - - /* Disable trace to ensure that the buffers are flushed */ - wan_udp.wan_udphdr_command= SPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - wan_udp.wan_udphdr_command= SPIPE_ENABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = trace_mode; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - printf("Starting trace...(Press ENTER to exit)\n"); - fflush(stdout); - } else if(wan_udp.wan_udphdr_return_code == 0xCD ) { - printf("Cannot Enable Line Tracing from Underneath.\n"); - fflush(stdout); - return; - }else if (wan_udp.wan_udphdr_return_code == 0x01 ) { - printf("Starting trace...(although it's already enabled!)\n"); - printf("Press ENTER to exit.\n"); - fflush(stdout); - }else{ - printf("Failed to Enable Line Tracing. Return code: 0x%02X\n", - wan_udp.wan_udphdr_return_code ); - fflush(stdout); - return; - } - - to.tv_sec = 0; - to.tv_usec = 0; - for(;;) { - FD_ZERO(&ready); - FD_SET(0,&ready); - fflush(stdout); - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - - wan_udp.wan_udphdr_command = SPIPE_GET_TRACE_INFO; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len) { - num_frames = wan_udp.wan_udphdr_ss7_num_frames; - - for ( i = 0; i < num_frames; i++) { - trace_pkt= (wan_trace_pkt_t *)(&wan_udp.wan_udphdr_data[0] + curr_pos); - - /* frame type */ - if (trace_pkt->status & 0x01) { - printf("\nOUTGOING\t"); - } else { - if (trace_pkt->status & 0x10) { - printf("\nINCOMING - Aborted\t"); - } else if (trace_pkt->status & 0x20) { - printf("\nINCOMING - CRC Error\t"); - } else if (trace_pkt->status & 0x40) { - printf("\nINCOMING - Overrun Error\t"); - } else { - printf("\nINCOMING\t"); - } - } - - /* real length and time stamp */ - printf("Len=%-5u\tTimestamp=%-5u\t", - trace_pkt->real_length, trace_pkt->time_stamp); - - if (trace_pkt->real_length > wan_udp.wan_udphdr_data_len){ - break; - } - - /* first update curr_pos */ - curr_pos += sizeof(wan_trace_pkt_t); - - if (trace_pkt->data_avail == 0) { - printf("the frame data is not available" ); - printf("\n"); - goto trace_skip; - } - - /* update curr_pos again */ - curr_pos += trace_pkt->real_length - 1; - - if (!trace_all_data){ - num_chars = (unsigned char) - ((trace_pkt->real_length <= DEFAULT_TRACE_LEN) - ? trace_pkt->real_length : DEFAULT_TRACE_LEN); - }else{ - num_chars = trace_pkt->real_length; - } - - printf("\n\t\t"); - for( j=0; jdata[j]); - } - - if (num_chars < trace_pkt->real_length){ - printf(".."); - } - printf("\n"); -trace_skip: - fflush(stdout); - - } //for - - }else{ //if - //printf("No Frames Rc=%i Data len %i!\n", - // wan_udp.wan_udphdr_return_code, - // wan_udp.wan_udphdr_data_len); - } - - curr_pos = 0; - - if (!wan_udp.wan_udphdr_ss7_ismoredata){ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - }else{ - to.tv_sec = 0; - to.tv_usec = 0; - } - } - - - wan_udp.wan_udphdr_command= SPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); -}; /* line_trace */ - -//CORBA -int SS7Usage(void) -{ - printf("wanpipemon: Wanpipe SS7 Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("wanpipemon -i -c \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe network interface name (ex: wp1ss7)\n"); - printf("\tOption -full: (Optional, trace option)\n"); - printf("\t\tDisplay raw packets in full: default trace pkt len=25bytes\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t l Link Status\n"); - printf("\t cv Read Code Version\n"); - printf("\t ru Display Router UP time\n"); - printf("\tCard Configuration\n"); - printf("\t c rc Read SS7 Configuration\n"); - printf("\tCard Statistics\n"); - printf("\t s g Global Statistics\n"); - printf("\t c Communication Error Statistics\n"); - printf("\t o Operational Statistics\n"); - printf("\tTrace Data \n"); - printf("\t t i Trace and Interpret ALL frames\n"); - printf("\t ip Trace and Interpret PROTOCOL frames only\n"); - printf("\t id Trace and Interpret DATA frames only\n"); - printf("\t r Trace ALL frames, in RAW format\n"); - printf("\t rp Trace PROTOCOL frames only, in RAW format\n"); - printf("\t rd Trace DATA frames only, in RAW format\n"); - printf("\tFT1/T1/E1/56K Configuration/Statistics\n"); - printf("\t T v View Status \n"); - printf("\t s Self Test\n"); - printf("\t l Line Loop Test\n"); - printf("\t d Digital Loop Test\n"); - printf("\t r Remote Test\n"); - printf("\t o Operational Mode\n"); - printf("\t p FT1 CSU/DSU operational statistics\n"); - printf("\t f Flush FT1 CSU/DSU operational statistcs\n"); - printf("\t set Set CSU/DSU configuration\n"); - printf("\t read Read CSU/DSU configuration (FT1/T1/E1 card)\n"); - printf("\t allb Active Line Loopback mode (T1/E1 card only)\n"); - printf("\t dllb Deactive Line Loopback mode (T1/E1 card only)\n"); - printf("\t aplb Active Payload Loopback mode (T1/E1 card only)\n"); - printf("\t dplb Deactive Payload Loopback mode (T1/E1 card only)\n"); - printf("\t adlb Active Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t ddlb Deactive Diagnostic Digital Loopback mode (T1/E1 card only)\n"); - printf("\t salb Send Loopback Activate Code (T1/E1 card only)\n"); - printf("\t sdlb Send Loopback Deactive Code (T1/E1 card only)\n"); - printf("\t a Read T1/E1/56K alarms.\n"); - printf("\tFlush Statistics\n"); - printf("\t f g Flush Global Statistics\n"); - printf("\t c Flush Communication Error Statistics\n"); - printf("\t o Flush Operational Statistics\n"); - printf("\t p Flush T1/E1 performance monitoring counters\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: wanpipemon -i wp1_chdlc0 -u 9000 -c xm :View Modem Status \n"); - printf("\tex: wanpipemon -i wp1_chdlc0 -c Tset :View Help for CSU/DSU Setup\n"); - printf("\tex: wanpipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n\n"); - return 0; -} - - -static void ss7_router_up_time( void ) -{ - unsigned long time; - - wan_udp.wan_udphdr_command= SPIPE_ROUTER_UP_TIME; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - time = *(unsigned long*)&wan_udp.wan_udphdr_data[0]; - - BANNER("ROUTER UP TIME"); - - print_router_up_time(time); -} - -#if 0 -static void set_FT1_monitor_status( unsigned char status) -{ - gfail = 0; - - - //cb.data[0] = status; - wan_udp.wan_udphdr_command= FT1_MONITOR_STATUS_CTRL; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 1; - wan_udp.wan_udphdr_data[0] = status; - DO_COMMAND(wan_udp); - //if( (cb.wan_udphdr_return_code != 0) && status){ - if ((wan_udp.wan_udphdr_return_code != 0) && status){ - gfail = 1; - printf("This command is only possible with S508/FT1 board!"); - } -} /* set_FT1_monitor_status */ - - -static void read_ft1_op_stats( void ) -{ - fd_set ready; - struct timeval to; - unsigned short length; - - - printf("TIME: Time in seconds since the FT1 op stats were last reset\n"); - printf(" ES: Errored Second\n"); - printf(" BSE: Bursty Errored Second\n"); - printf(" SES: Severly Errored Second\n"); - printf(" UAS: Unavailable Second\n"); - printf("LOFC: Loss of Frame Count\n"); - printf(" ESF: ESF Error Count\n"); - - printf("\nFT1 CSU/DSU Operational Stats...(Press ENTER to exit)\n"); - for(;;){ - - - - wan_udp.wan_udphdr_command= READ_FT1_OPERATIONAL_STATS; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - FD_ZERO(&ready); - FD_SET(0,&ready); - to.tv_sec = 0; - to.tv_usec = 50000; - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - //if( cb.wan_udphdr_data_len ){ - if (wan_udp.wan_udphdr_data_len ){ - int i=0; - printf(" TIME ES BES SES UAS LOFC ESF\n"); - //length = cb.wan_udphdr_data_len; - length = wan_udp.wan_udphdr_data_len; - while(length){ - - //printf("%c", cb.data[i]); - printf("%c", wan_udp.wan_udphdr_data[i]); - length--; - i++; - } - printf("\n"); - } - } -} - -#endif - -#if 0 -static void set_ft1_config(int argc, char ** argv) -{ - ft1_config_t *ft1_config = (ft1_config_t *)&wan_udp.wan_udphdr_data[0]; - int i=0,found=0; - - wan_udp.wan_udphdr_command = SET_FT1_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = sizeof(ft1_config_t); - - for (i=0;iframing_mode = atoi(argv[i++]); - ft1_config->encoding_mode = atoi(argv[i++]); - ft1_config->line_build_out = atoi(argv[i++]); - ft1_config->channel_base = atoi(argv[i++]); - ft1_config->baud_rate_kbps = atoi(argv[i++]); - ft1_config->clock_mode = atoi(argv[i]); - - - if (ft1_config->framing_mode > 1){ - printf("Error: Invalid Framing Mode (0=ESF 1=D4)\n"); - return; - } - if (ft1_config->encoding_mode > 1){ - printf("Error: Invalid Encoding Mode (0=B8ZS 1=AMI)\n"); - return; - } - if (ft1_config->line_build_out > 7){ - printf("Error: Invalid Line Build Mode (0-7) Default:0\n"); - return; - } - if (ft1_config->channel_base > 24){ - printf("Error: Invalid Channel Base (1-24) Default:1 \n"); - return; - } - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps > 1536)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps > 1344)){ - printf("Error: Invalid Baud Rate: B8ZS Max=1536KBps; AMI Max=1344KBps\n"); - return; - } - - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps < 64)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps < 56)){ - printf("Error: Invalid Baud Rate: B8ZS Min=64KBps; AMI Max=56KBps\n"); - return; - } - - if ((ft1_config->encoding_mode ==0 && ft1_config->baud_rate_kbps%64 != 0)|| - (ft1_config->encoding_mode ==1 && ft1_config->baud_rate_kbps%56 != 0)){ - printf("Error: Invalid Baud Rate: \n"); - printf(" For B8ZS: Baud rate must be a multiple of 64KBps.\n"); - printf(" For AMI: Baud rate must be a multiple of 56KBps.\n"); - return; - } - - if (ft1_config->clock_mode > 1){ - printf("Error: Invalid Clock Mode: (0=Normal, 1=Master) Default:0\n"); - return; - } - - DO_COMMAND(wan_udp); - //if (cb.wan_udphdr_return_code == 0){ - if (wan_udp.wan_udphdr_return_code == 0){ - printf("CSU/DSU Configuration Successfull!\n"); - - //}else if (cb.wan_udphdr_return_code == 0xaa){ - }else if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Sangoma Adaptor is not equiped with an onboard CSU/DSU!\n"); - printf("\tCSU/DSU Configuration Failed!\n"); - - }else{ - //printf("CSU/DSU Configuration Failed: rc %x",cb.wan_udphdr_return_code); - printf("CSU/DSU Configuration Failed: rc %x",wan_udp.wan_udphdr_return_code); - } -} - -static void read_ft1_te1_56k_config (void) -{ - unsigned char adapter_type = 0x00; - - /* Read Adapter Type */ - if (get_fe_type(&adapter_type)){ - return; - } - - switch(adapter_type){ - case WAN_MEDIA_NONE: - - wan_udp.wan_udphdr_command = READ_FT1_CONFIGURATION; - wan_udp.wan_udphdr_return_code = 0xaa; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - printf("CSU/DSU Read Configuration Failed"); - }else{ - //ft1_config_t *ft1_config = (ft1_config_t *)&cb.data[0]; - ft1_config_t *ft1_config = (ft1_config_t *)&wan_udp.wan_udphdr_data[0]; - printf("CSU/DSU %s Conriguration:\n", if_name); - printf("\tFraming\t\t%s\n",ft1_config->framing_mode ? "D4" : "ESF"); - printf("\tEncoding\t%s\n",ft1_config->encoding_mode ? "AMI" : "B8ZS"); - printf("\tLine Build\t%i\n",ft1_config->line_build_out); - printf("\tChannel Base\t%i\n",ft1_config->channel_base); - printf("\tBaud Rate\t%i\n",ft1_config->baud_rate_kbps); - printf("\tClock Mode\t%s\n",ft1_config->clock_mode ? "MASTER":"NORMAL"); - } - break; - - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - case WAN_MEDIA_56K: - read_te1_56k_config(); - break; - } - return; -} -#endif - -int SS7Main(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - - switch(command[0]){ - - case 'x': - if (!strcmp(opt,"m")){ - modem(); - }else if (!strcmp(opt, "cv")){ - read_code_version(); - }else if (!strcmp(opt,"l")){ - link_status(); - }else if (!strcmp(opt,"ru")){ - ss7_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type wanpipemon for help\n\n"); - } - break; - case 's': - if (!strcmp(opt,"g")){ - global_stats(); - }else if (!strcmp(opt,"c")){ - comm_stats(); - }else if (!strcmp(opt,"o")){ - operational_stats(); - }else{ - printf("ERROR: Invalid Statistics Command 's', Type wanpipemon for help\n\n"); - - } - break; - case 'c': - if (!strcmp(opt,"rc")){ - ss7_configuration(); - - }else{ - printf("ERROR: Invalid Configuration Command 'c', Type wanpipemon for help\n\n"); - } - break; - case 't': - if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - line_trace(TRACE_FISU|TRACE_LSSU|TRACE_MSU); - }else if (!strcmp(opt, "rf")){ - raw_data = WAN_TRUE; - line_trace(TRACE_FISU); - }else if (!strcmp(opt, "rl")){ - raw_data = WAN_TRUE; - line_trace(TRACE_LSSU); - }else if (!strcmp(opt, "rm")){ - raw_data = WAN_TRUE; - annexg_trace = WAN_TRUE; - line_trace(TRACE_MSU); - }else{ - printf("ERROR: Invalid Trace Command 't', Type wanpipemon for help\n\n"); - } - break; - case 'f': - if (!strcmp(opt, "o")){ - flush_operational_stats(); - operational_stats(); - }else if (!strcmp(opt, "g")){ - flush_global_stats(); - global_stats(); - }else if (!strcmp(opt, "c")){ - flush_comm_stats(); - comm_stats(); - }else if (!strcmp(opt, "p")){ - flush_te1_pmon(); - } else{ - printf("ERROR: Invalid Flush Command 'f', Type wanpipemon for help\n\n"); - } - break; - - case 'T': -#if 0 - if (!strcmp(opt, "v")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - view_FT1_status(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "s")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "l")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_local_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "d")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_digital_loop_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "r")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_remote_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "o")){ - set_FT1_monitor_status(0x01); - if(!gfail){ - FT1_operational_mode(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "p")){ - set_FT1_monitor_status(0x02); - if(!gfail) - read_ft1_op_stats(); - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "f")){ - set_FT1_monitor_status(0x04); - if(!gfail){ - printf("Flushed Operational Statistics\n"); - }else{ - printf("FT1 Flush Failed %i\n",gfail); - } - if (!strcmp(opt,"read")){ - read_ft1_te1_56k_config(); -#endif - if (!strcmp(opt,"allb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dllb")){ - set_lb_modes(WAN_TE1_LINELB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"aplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"dplb")){ - set_lb_modes(WAN_TE1_PAYLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"adlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"ddlb")){ - set_lb_modes(WAN_TE1_DDLB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"salb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_ACTIVATE_LB); - }else if (!strcmp(opt,"sdlb")){ - set_lb_modes(WAN_TE1_TX_LB_MODE, WAN_TE1_DEACTIVATE_LB); - }else if (!strcmp(opt,"a")){ - read_te1_56k_stat(0); - } else{ - printf("ERROR: Invalid FT1 Command 'T', Type wanpipemon for help\n\n"); - } - break; - - default: - printf("ERROR: Invalid Command, Type wanpipemon for help\n\n"); - break; - }//switch - printf("\n"); - fflush(stdout); - return 0; -}; //main diff --git a/util/wanpipemon.old/ss7pipemon.o b/util/wanpipemon.old/ss7pipemon.o deleted file mode 100644 index 8e4197158f0c8bb0bfbc2de68659efefe0df943b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19048 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 G{Qm*pCU)@v diff --git a/util/wanpipemon.old/wangui.c b/util/wanpipemon.old/wangui.c deleted file mode 100644 index 9911508..0000000 --- a/util/wanpipemon.old/wangui.c +++ /dev/null @@ -1,594 +0,0 @@ -#include -#include /* offsetof(), etc. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef LOCALE -#include -#endif - -#if defined(__LINUX__) -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -#endif -#include "unixio.h" -#include "fe_lib.h" -#include "wanpipemon.h" - -#define SELECT_OK 0 -#define SELECT_EXIT 256 -#define SELECT_BACK SELECT_EXIT -#define SELECT_HELP 512 -#define MAX_TOKENS 32 - -#define UNKNOWN_SYS 0 -#define LOCAL_SYS 1 -#define REMOTE_SYS 2 -#define MAX_IF_NUM 100 - -#if 0 -#undef system -#define system(a) -#endif - -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ - -#if 0 -#define GET_MENU(func,rc, arg) {switch (wan_protocol){ \ - case WANCONFIG_CHDLC: \ - rc = CHDLC##func arg; \ - break; \ - case WANCONFIG_FR: \ - rc = FR##func arg; \ - break; \ - case WANCONFIG_PPP: \ - rc = PPP##func arg; \ - break; \ - case WANCONFIG_X25: \ - rc = X25##func arg; \ - break; \ - case WANCONFIG_ADSL: \ - rc = ADSL##func arg; \ - break; \ - default:\ - rc=NULL;\ - printf("Unknown protocol type %i!\n",wan_protocol); \ - break;\ - }\ - } -#endif - - -static char* str_strip (char*, char*); -static int tokenize (char*, char **, char *, char *, char *); -static int wan_if_ip_menu(void); -static int wan_ip_menu(void); -static int wan_iface_menu(void); -static void wan_main_menu(void); - -/*============================================================================ - * Strip leading and trailing spaces off the string str. - */ -static char* str_strip (char* str, char* s) -{ - char* eos = str + strlen(str); /* -> end of string */ - - while (*str && strchr(s, *str)) - ++str; /* strip leading spaces */ - while ((eos > str) && strchr(s, *(eos - 1))) - --eos; /* strip trailing spaces */ - *eos = '\0'; - return str; -} - - -/*============================================================================ - * Tokenize string. - * Parse a string of the following syntax: - * =,,... - * and fill array of tokens with pointers to string elements. - * - * Return number of tokens. - */ -static int tokenize (char* str, char **tokens, char *arg1, char *arg2, char *arg3) -{ - int cnt = 0; - - tokens[0] = strtok(str, arg1); - while (tokens[cnt] && (cnt < MAX_TOKENS - 1)) { - tokens[cnt] = str_strip(tokens[cnt], arg2); - tokens[++cnt] = strtok(NULL, arg3); - } - return cnt; -} - - -static int hit_enter_or_space_key(void) -{ - int ch; - printf("\nHit ENTER to return to menu / SPACE to repeat\n"); - - for (;;){ - kbdhit(&ch); - - if (ch==10) - return 0; - - if (ch==32) - return 1; - - } - - fflush(stdout); - return 0; -} - - -static int wan_if_ip_menu(void) -{ - int err=0; - char data[100]; - char current[100]; - char title[100]; - char prompt[100]; - int pipefds[2]; - pid_t pid; - int stat; - char *menu[]={"local", "Local System Debugging", "remote", "Remote System Debugging"}; - - if (pipe(pipefds) == -1){ - printf("Error pipe() failed!\n"); - return -1; - } - - sprintf(current, "lo"); - sprintf(title,"Operation Mode Seleciton"); - sprintf(prompt,"Local System: device resides on the server, if name needed. Remote System: device resides on the network, thus ip address needed"); - - memset(data,0,100); - - if (!(pid=fork())){ - close(pipefds[0]); - err=dup2(pipefds[1],2); - if (!err){ - exit(SELECT_EXIT); - } - - init_dialog(); - err=dialog_menu(title, prompt, 20, 50, 2, current, 2, (const char *const*)menu); - end_dialog(); - exit(err); - } - - pid=waitpid(pid,&stat,WUNTRACED); - - read(pipefds[0],data,50); - data[strlen(data)-1]='\0'; - - close(pipefds[0]); - close(pipefds[1]); - - if (stat == SELECT_OK){ - if (strcmp(data,"remote") == 0){ - return REMOTE_SYS; - }else{ - return LOCAL_SYS; - } - } - - return -1; -} - -static int wan_ip_menu(void) -{ - int err=0; - char data[100]; - char title[100]; - char prompt[100]; - int pipefds[2]; - pid_t pid; - int stat; - - memset(data,0,100); - - if (pipe(pipefds) == -1){ - printf("Error pipe() failed!\n"); - return -1; - } - - sprintf(title,"IP Address Setup"); - sprintf(prompt,"Specify a remote IP address"); - - if (!(pid=fork())){ - - close(pipefds[0]); - err=dup2(pipefds[1],2); - if (!err){ - exit(SELECT_EXIT); - } - - init_dialog(); - err=dialog_inputbox (title, prompt, 10, 50, "201.1.1.2"); - end_dialog(); - - fprintf(stderr,"%s",dialog_input_result); - exit(err); - } - - pid=waitpid(pid,&stat,WUNTRACED); - - read(pipefds[0],data,99); - - if (stat==SELECT_OK){ - struct in_addr *ip_str = NULL; - strcpy(ipaddress,data); - if (inet_aton(ipaddress,ip_str) != 0 ){ - ip_addr = WAN_TRUE; - }else{ - printf("Invalid IP address %s!\n",ipaddress); - } - }else{ - return -1; - } - - sprintf(title,"UPD Port Setup"); - sprintf(prompt,"Specify remote UPD port"); - - if (!(pid=fork())){ - - close(pipefds[0]); - err=dup2(pipefds[1],2); - if (!err){ - exit(SELECT_EXIT); - } - - init_dialog(); - err=dialog_inputbox (title, prompt, 10, 50, "9000"); - end_dialog(); - - fprintf(stderr,"%s",dialog_input_result); - exit(err); - } - - pid=waitpid(pid,&stat,WUNTRACED); - - memset(data,0,100); - - read(pipefds[0],data,99); - - close(pipefds[0]); - close(pipefds[1]); - - if (err==SELECT_OK){ - udp_port=atoi(data); - return 0; - } - - return -1; -} - - -static int wan_iface_menu(void) -{ - int err=0; - char data[100]; - char current[100]; - char title[100]; - char prompt[100]; - int pipefds[2]; - pid_t pid; - int stat; - - int i=0; - int j=0; - int len=0; - char *menu[MAX_IF_NUM]; - int toknum; - char line[1000]; - char* token[MAX_TOKENS]; - FILE* pfd; - - - memset(menu,0,sizeof(menu)); - - if (pipe(pipefds) == -1){ - printf("Error pipe() failed!\n"); - return -1; - } - -#if defined(__LINUX__) - pfd = popen("cat /proc/net/dev","r"); - if (pfd == NULL) - return -1; - - while (fgets(line,sizeof(line)-1,pfd)){ - if (++i<3) - continue; - toknum = tokenize(line, token, ":", " \t\n", ":"); - if (toknum>1){ - if (j>=MAX_IF_NUM) - break; - menu[j++]=strdup(token[0]); - menu[j++]=strdup(token[0]); - } - } - len = j/2; - - pclose(pfd); -#elif defined(__FreeBSD__) - pfd = popen("ifconfig -l","r"); - i=0; - fgets(line,sizeof(line)-1,pfd); - toknum = tokenize(line, token, " ", " \t\n", " "); - for (j=0;j=MAX_IF_NUM) - break; - menu[i++]=strdup(token[j]); - menu[i++]=strdup(token[j]); - } - len = i/2; - pclose(pfd); -#else - pfd = popen("ifconfig -a","r"); - i=0; - while(fgets(line,sizeof(line)-1,pfd)){ - if (!isalpha(line[0])){ - continue; - } - toknum = tokenize(line, token, ":", " \t\n", ":"); - if (toknum != 2){ - continue; - } - if (j>=MAX_IF_NUM) - break; - menu[i++]=strdup(token[0]); - menu[i++]=strdup(token[0]); - - - } - len = i/2; - pclose(pfd); -#endif - - if (len==0){ - return -1; - } - - sprintf(current, "lo"); - sprintf(title,"Interface Selection"); - sprintf(prompt,"Please select a WANPIPE interface using UP and DOWN keys"); - - - memset(data,0,100); - - if (!(pid=fork())){ - close(pipefds[0]); - err=dup2(pipefds[1],2); - if (!err){ - exit(SELECT_EXIT); - } - - init_dialog(); - err=dialog_menu(title, prompt, 20, 50, 10, current, len, (const char *const*)menu); - end_dialog(); - - for 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 diff --git a/util/wanpipemon.old/wanpipemon.c b/util/wanpipemon.old/wanpipemon.c deleted file mode 100644 index 6d2a6ea..0000000 --- a/util/wanpipemon.old/wanpipemon.c +++ /dev/null @@ -1,1402 +0,0 @@ -/***************************************************************************** -* wanpipemon.c Sangoma WANPIPE Monitor -* -* Author: Alex Feldman -* Nenad Corbic -* -* Copyright: (c) 1995-2002 Sangoma Technologies Inc. -* -* ---------------------------------------------------------------------------- -* Jan 11, 2005 David Rokhvarg Added code to run above AFT card with protocol -* in the LIP layer. Fixed many not working options. -* Aug 02, 2002 Nenad Corbic Updated all linux utilites and added -* GUI features. -* May 30, 2002 Alex Feldman Initial version based on ppipemon -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#define MDATALEN 2024 - -#ifndef SIOC_WANPIPE_MONITOR -#define SIOC_WANPIPE_MONITOR SIOC_WANPIPE_PIPEMON -#endif - - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -#if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -char* progname = "wanutil"; -#else -char* progname = "wanpipemon"; -#endif - -wan_udp_hdr_t wan_udp; -int sock = 0; -int wan_protocol = 0; -int get_config_flag = 0; -int protocol_cb_size = sizeof(wan_mgmt_t)+sizeof(wan_cmd_t)+1; - -int is_508; -int gui_interface=0; - - -extern int trace_hdlc_data(wanpipe_hdlc_engine_t *hdlc_eng, void *data, int len); - -static sa_family_t af = AF_INET; -static struct sockaddr_in soin; - char ipaddress[16]; -int udp_port = 9000; - -short dlci_number=16; -char if_name[WAN_IFNAME_SZ+1]; -int ip_addr = -1; -int start_xml_router=0; -int stop_xml_router=1; -int raw_data=0; -int trace_all_data=0; -int zap_monitor=0; -int zap_chan = 0; -int lcn_number=0; -unsigned char par_port_A_byte, par_port_B_byte; - -char *global_command; -int global_argc; -char** global_argv; -char original_global_if_name[WAN_IFNAME_SZ+1]; -int original_global_wan_protocol; -int global_card_type = WANOPT_AFT; -int connected_to_hw_level = 0; - -int sys_timestamp=0; -int annexg_trace =0; - -int pcap_output=0; -int pcap_prot=0; -FILE *pcap_output_file; -char pcap_output_file_name[50]; - -wanpipe_hdlc_engine_t *rx_hdlc_eng; - -trace_prot_t trace_prot_opt[]={ - {"FR", FRAME,107}, - {"LAPB", LAPB, 0}, - {"X25", X25, 200}, - {"PPP", PPP,9}, - {"CHDLC", CHDLC,104}, - {"ETH", ETH, 1}, - {"IP", IP,12}, - {"",-1}, -}; - -trace_prot_t trace_x25_prot_opt[]={ - {"DATA",DATA}, - {"PROT",PROT}, - {"",-1}, -}; - -/* tracing global variables */ -unsigned int TRACE_DLCI=0; -unsigned char TRACE_PROTOCOL=ALL_PROT; -unsigned int TRACE_X25_LCN=0; -unsigned char TRACE_X25_OPT=ALL_X25; -char TRACE_EBCDIC=0; -char TRACE_ASCII=0; -char TRACE_HEX=0; - -char *cmd[MAX_CMD_ARG]; -FT1_LED_STATUS FT1_LED; - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -void sig_end(int signal); -int main(int, char**); -static int init(int, char**,char*); -static void usage(void); -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -static void usage_trace_info(void); -static void usage_long(void); -#endif -static int GetWANConfig(void); -static char* GetMasterDevName( void ); -#if 0 -static void sig_handler(int sigint); -#endif -int fail=0; -int xml_output=0; -//static sa_family_t get_if_family(char*); - -#if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -struct fun_protocol function_lookup[] = { - { WANCONFIG_CHDLC, "hdlc", CHDLCConfig, CHDLCUsage, CHDLCMain, CHDLCDisableTrace, - CHDLCget_main_menu, CHDLCget_cmd_menu, - CHDLC_read_FT1_status, CHDLC_set_FT1_mode, 2}, - - { WANCONFIG_AFT, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace, - AFTget_main_menu, AFTget_cmd_menu, - NULL,NULL, 2 }, - - { WANCONFIG_AFT_TE1, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace, - AFTget_main_menu, AFTget_cmd_menu, - NULL,NULL, 2 }, - - { WANCONFIG_AFT_TE3, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace, - AFTget_main_menu, AFTget_cmd_menu, - NULL,NULL, 2 }, - - { 0, "N/A", 0, 0, 0, 0,0 }, -}; -#else -struct fun_protocol function_lookup[] = { - { WANCONFIG_FR, "fr", FRConfig, FRUsage, FRMain, FRDisableTrace, - FRget_main_menu, FRget_cmd_menu, - FR_read_FT1_status, FR_set_FT1_mode, 0 }, -#if defined(__LINUX__) - { WANCONFIG_MFR, "fr", FRConfig, FRUsage, FRMain, FRDisableTrace, - FRget_main_menu, FRget_cmd_menu, - FR_read_FT1_status, FR_set_FT1_mode,0 }, -#else - { WANCONFIG_MFR, "fr", NULL, NULL, NULL, NULL,NULL,NULL,0 }, -#endif - { WANCONFIG_PPP, "ppp", PPPConfig, PPPUsage, PPPMain, PPPDisableTrace, - PPPget_main_menu, PPPget_cmd_menu, - PPP_read_FT1_status, PPP_set_FT1_mode,0 }, - - { WANCONFIG_CHDLC, "chdlc", CHDLCConfig, CHDLCUsage, CHDLCMain, CHDLCDisableTrace, - CHDLCget_main_menu, CHDLCget_cmd_menu, - CHDLC_read_FT1_status, CHDLC_set_FT1_mode, 2}, - - { WANCONFIG_ATM, "atm", ATMConfig, ATMUsage, ATMMain, ATMDisableTrace, - ATMget_main_menu, ATMget_cmd_menu, - ATM_read_FT1_status, ATM_set_FT1_mode, 2 }, - - { WANCONFIG_AFT, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace, - AFTget_main_menu, AFTget_cmd_menu, - NULL,NULL, 2 }, - - { WANCONFIG_AFT_TE1, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace, - AFTget_main_menu, AFTget_cmd_menu, - NULL,NULL, 2 }, - - { WANCONFIG_AFT_ANALOG, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace, - AFTget_main_menu, AFTget_cmd_menu, - NULL,NULL, 2 }, - -#ifdef WANPIPEMON_ZAP - { WANCONFIG_ZAP, "zap", NULL, ZAPUsage, ZAPMain, NULL, - ZAPget_main_menu, ZAPget_cmd_menu, - NULL,NULL, 0 }, -#endif - - { WANCONFIG_AFT_TE3, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace, - AFTget_main_menu, AFTget_cmd_menu, - NULL,NULL, 2 }, - - - { WANCONFIG_ADSL, "adsl", ADSLConfig, ADSLUsage, ADSLMain, ADSLDisableTrace, - ADSLget_main_menu, ADSLget_cmd_menu, - NULL, NULL, 2 }, - -#if defined(__LINUX__) - { WANCONFIG_SS7, "ss7", SS7Config, SS7Usage, SS7Main, SS7DisableTrace, - SS7get_main_menu, SS7get_cmd_menu, - NULL, NULL, 2 }, - { WANCONFIG_X25, "x25", X25Config, X25Usage, X25Main, X25DisableTrace, - X25get_main_menu, X25get_cmd_menu , - NULL, NULL, 0}, - { WANCONFIG_BITSTRM, "bitstrm", BITSTRMConfig, BITSTRMUsage, BITSTRMMain, NULL, - BITSTRMget_main_menu, BITSTRMget_cmd_menu , - NULL, NULL, 0}, -#else - { WANCONFIG_SS7, "ss7", NULL, NULL, NULL, NULL,NULL,NULL,0 }, - { WANCONFIG_X25, "x25", NULL, NULL, NULL, NULL,NULL,NULL,0 }, -#endif - { WANCONFIG_BSC, "bsc", NULL, NULL, NULL, NULL,NULL,NULL,0 }, - { WANCONFIG_HDLC, "hdlc", NULL, NULL, NULL, NULL,NULL,NULL,0 }, - { 0, "N/A", 0, 0, 0, 0,0 }, -}; -#endif - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ -int MakeConnection( void ) -{ -#ifdef WANPIPEMON_ZAP - if(zap_monitor == 1){ - return MakeZapConnection(); - } -#endif - if (ip_addr == WAN_TRUE){ - - sock = socket((af == AF_INET) ? PF_INET : PF_INET6, SOCK_DGRAM, 0); - if (sock < 0){ - perror("socket"); - return WAN_FALSE; - } /* if */ - - if (af == AF_INET){ - soin.sin_addr.s_addr = inet_addr(ipaddress); - soin.sin_family = AF_INET; - soin.sin_port = htons((u_short)udp_port); - if (soin.sin_addr.s_addr < 0){ - printf("Error: Invalid IP address!\n"); - return WAN_FALSE; - } - if (connect( sock, (struct sockaddr *)&soin, sizeof(soin)) != 0){ - perror("connect"); - printf("Make sure the IP address is correct\n"); - return( WAN_FALSE ); - } /* if */ - }else{ -#ifdef ENABLE_IPV6 - inet_pton(AF_INET6, ipaddress, &soin6.sin6_addr); - //soin6.sin6_len = sizeof(struct sockaddr_in6); - soin6.sin6_family = AF_INET6; - soin6.sin6_scope_id = 0xc; - soin6.sin6_port = htons((u_short)udp_port); - if (connect( sock, (struct sockaddr *)&soin6, sizeof(soin6)) != 0){ - perror("connect"); - printf("Make sure the IP address is correct\n"); - return WAN_FALSE; - } /* if */ -#else - printf("Ipv6 protocol not supported!\n"); - return WAN_FALSE; -#endif - - } - }else{ - sock = socket((af == AF_INET) ? PF_INET : PF_INET6, SOCK_STREAM, IPPROTO_IP); - if (sock < 0){ - perror("socket"); - return WAN_FALSE; - } - - } - - if (!GetWANConfig()){ - printf("Error: Unable to obtain network interface information.\n"); - printf("Make sure the IP and UDP port are correct.\n"); - close(sock); - return WAN_FALSE; - } - - return WAN_TRUE; -} /* MakeConnection */ - -static int GetWANConfig( void ) -{ - int cnt = 0, err = 0; - - if (wan_protocol != 0){ - - /* If the user specified protocol, do not try to - * autodetect it. Old drivers do not have protocol - * detect option. */ - goto skip_protocol_detect; - } - - /* Get Protocol type */ - wan_udp.wan_udphdr_command = WAN_GET_PROTOCOL; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD; - while (DO_COMMAND(wan_udp) < 0 && ++cnt < 4) { - if (wan_udp.wan_udphdr_return_code == WAN_UDP_TIMEOUT_CMD) { - printf("Error: Command timeout occurred\n"); - return WAN_FALSE; - } - if (wan_udp.wan_udphdr_return_code == 0xCC ) - return WAN_FALSE; - } - - if (cnt >= 4){ - return WAN_FALSE; - } - - wan_protocol = wan_udp.wan_udphdr_data[0]; - -skip_protocol_detect: - if(get_config_flag == 1){ -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - printf("Network interface running %s protocol...\n", - DECODE_PROT(wan_protocol)); -#endif - - EXEC_PROT_FUNC(config,wan_protocol,err,()); - }else{ - err = WAN_TRUE; - } - return err; -} - -extern char* GetMasterDevName( void ) -{ - int cnt = 0; - - wan_udp.wan_udphdr_command = WAN_GET_MASTER_DEV_NAME; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD; - - //important! clean the data area before calling the driver - memset(wan_udp.wan_udphdr_data, 0x00, WAN_IFNAME_SZ+1); - - while (DO_COMMAND(wan_udp) < 0 && ++cnt < 4) { - if (wan_udp.wan_udphdr_return_code == WAN_UDP_TIMEOUT_CMD) { - printf("Error: Command timeout occurred\n"); - return NULL; - } - if (wan_udp.wan_udphdr_return_code) { - //command failed - return NULL; - } - } - - if (cnt >= 4){ - //command failed - return NULL; - } - - return (char*)wan_udp.wan_udphdr_data; -} - -char* get_hardware_level_interface_name(char* interface_name) -{ - char* tmp_master_dev_name = NULL; - static char master_dev_name[WAN_IFNAME_SZ+1]; - char found_hardware_level = 0; - - //initialize 'master name' with current name, so in case - //of failure to get the 'maser name' current name will be used. - strncpy(master_dev_name, interface_name, WAN_IFNAME_SZ); - master_dev_name[WAN_IFNAME_SZ]='\0'; - - //save the original values. - strncpy(original_global_if_name, if_name, WAN_IFNAME_SZ); - original_global_if_name[WAN_IFNAME_SZ]='\0'; - original_global_wan_protocol = wan_protocol; - - while(found_hardware_level == 0){ - - tmp_master_dev_name = NULL; - wan_protocol = 0; - //get_config_flag = 0; - - if(interface_name != if_name){ - //on the first iteration 'interface_name' is the same pointer as the global 'if_name'. - //after the first iteration, use 'tmp_master_dev_name'. - strncpy(if_name, interface_name, WAN_IFNAME_SZ); - if_name[WAN_IFNAME_SZ]='\0'; - } - - if(MakeConnection() == WAN_FALSE){ - close(sock); - return NULL; - } - - //get_config_flag = 1; - - tmp_master_dev_name = GetMasterDevName(); - //if 'tmp_master_dev_name' was NOT changed, we reached - //the the hardware level. - if(strlen(tmp_master_dev_name) == 0){ - //printf("Reached Hardware Level!\n"); - found_hardware_level = 1; - if(wan_protocol == WANCONFIG_CHDLC){ - //on S514 LIP layer runs above CHDLC firmware. - global_card_type = WANOPT_S51X; - }else{ - global_card_type = WANOPT_AFT; - } - }else{ - strncpy(if_name, tmp_master_dev_name, WAN_IFNAME_SZ+1); - strncpy(master_dev_name, tmp_master_dev_name, WAN_IFNAME_SZ+1); - } - - close(sock); - - }//while() - - //restore the original values. - strncpy(if_name, original_global_if_name, WAN_IFNAME_SZ+1); - wan_protocol = original_global_wan_protocol; - - //and restore the original connection to the driver - if(MakeConnection() == WAN_FALSE){ - close(sock); - return NULL; - } - - return master_dev_name; -} - -int make_hardware_level_connection() -{ - char* tmp = NULL; - - if(connected_to_hw_level){ - return 0; - } - - get_config_flag = 0; - - //save the original values. - strncpy(original_global_if_name, if_name, WAN_IFNAME_SZ+1); - original_global_wan_protocol = wan_protocol; - - tmp = get_hardware_level_interface_name(if_name); - if(tmp == NULL){ - printf("Failed to get Hardware Level Interface name!!\n"); - return 1; - } - - strncpy(if_name, tmp, WAN_IFNAME_SZ+1); - wan_protocol = 0; - - //connect to the hardware level - if (MakeConnection() == WAN_FALSE){ - close(sock); - return 2; - } - - connected_to_hw_level = 1; - - return 0; -} - -void cleanup_hardware_level_connection() -{ - if(!connected_to_hw_level){ - return; - } - - //close what was opened by make_hardware_level_connection() - close(sock); - - //restore the original values. - strncpy(if_name, original_global_if_name, WAN_IFNAME_SZ+1); - wan_protocol = original_global_wan_protocol; - - connected_to_hw_level = 0; - - //and restore the original connection to the driver - if(MakeConnection() == WAN_FALSE){ - close(sock); - return; - } - get_config_flag = 1; -} - -void hw_line_trace(int trace_mode) -{ - int err; - - if(make_hardware_level_connection()){ - return; - } - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - EXEC_PROT_VOID_FUNC(disable_trace,wan_protocol,()); - cleanup_hardware_level_connection(); -} - -void hw_modem( void ) -{ - int err; - - if(make_hardware_level_connection()){ - return; - } - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - cleanup_hardware_level_connection(); -} - -void hw_general_stats( void ) -{ - int err; - - if(make_hardware_level_connection()){ - return; - } - global_command = "so"; //run operational_stats() - at the hardware layer - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - cleanup_hardware_level_connection(); -} - -void hw_flush_general_stats( void ) -{ - int err; - if(make_hardware_level_connection()){ - return; - } - global_command = "fo"; //run flush_operational_stats() - at the hardware layer - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - cleanup_hardware_level_connection(); -} - -void hw_comm_err( void ) -{ - int err; - if(make_hardware_level_connection()){ - return; - } - global_command = "sc"; //run comm_err_stats() - at the hardware layer - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - cleanup_hardware_level_connection(); -} - -void hw_flush_comm_err( void ) -{ - int err; - - if(make_hardware_level_connection()){ - return; - } - global_command = "fc"; //run flush_comm_err_stats() - at the hardware layer - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - cleanup_hardware_level_connection(); -} - -void hw_router_up_time() -{ - int err; - - if(make_hardware_level_connection()){ - return; - } - - global_command = "xru"; //run aft_router_up_time() - at the hardware layer - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - - cleanup_hardware_level_connection(); -} - -void print_router_up_time(u_int32_t time) -{ - u_int32_t minutes; - u_int32_t seconds; - - if (time < 3600) { - if (time<60){ - printf(" Router UP Time: %u seconds\n", time); - }else{ - printf(" Router UP Time: %u minute(s), %u seconds\n", - time/60, time%60); - } - }else{ - minutes = (time%3600) / 60; - seconds = (time%3600) % 60; - - printf(" Router UP Time: %u hour(s), %u minute(s), %u seconds.\n", - time/3600, minutes, seconds); - } -} - -void hw_read_code_version() -{ - int err; - - if(make_hardware_level_connection()){ - return; - } - - global_command = "xcv"; //run aft_router_up_time() - at the hardware layer - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - - cleanup_hardware_level_connection(); -} - -void hw_link_status() -{ - int err; - - if(make_hardware_level_connection()){ - return; - } - - global_command = "xl"; //run aft_router_up_time() - at the hardware layer - //depending on 'wan_protocol' cpipemon or aftpipemon will be called - EXEC_PROT_FUNC(main, wan_protocol, err,(global_command, global_argc, global_argv)); - - cleanup_hardware_level_connection(); -} - -int DoCommand(wan_udp_hdr_t* wan_udp) -{ - static unsigned char id = 0; - fd_set ready; - struct timeval to; - int data_len = protocol_cb_size+wan_udp->wan_udphdr_data_len; - int x, err=0; - - if (ip_addr == WAN_TRUE){ - for( x = 0; x < 4; x += 1 ) { - wan_udp->wan_udphdr_request_reply = 0x01; - wan_udp->wan_udphdr_id = id; - /* 0xAA is our special return code indicating packet timeout */ - //wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD; - //err = send(sock, &wan_udp. 35 + cb.cblock.buffer_length, 0); - err = send(sock, (caddr_t)wan_udp, data_len, 0); - if (err < 0){ - perror("Send: "); - continue; - } - - FD_ZERO(&ready); - FD_SET(sock,&ready); - to.tv_sec = 5; - to.tv_usec = 0; - - if((err = select(sock + 1,&ready, NULL, NULL, &to))){ - err = recv(sock, (caddr_t)wan_udp, sizeof(wan_udp_hdr_t), 0); - if (err < 0){ - perror("Recv: "); - } - break; - }else{ - printf("Error: No Data received from the connected socket.\n"); - } - } - }else{ - struct ifreq ifr; - wan_udp->wan_udphdr_request_reply = 0x01; - wan_udp->wan_udphdr_id = id; - strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); - ifr.ifr_data = (caddr_t)wan_udp; - - if ((err=ioctl(sock, SIOC_WANPIPE_MONITOR , &ifr)) < 0){ - if (errno != EBUSY){ - perror("Ioctl: "); - exit (1); - } - return err; - } - } - -#if 0 - { - int i; - printf("Rx Packet :\n"); - for (i=0;i argc-1){ - printf("ERROR: Invalid IP or Interface Name!\n"); - printf("Type wanpipemon for help\n"); - return WAN_FALSE; - } - - strncpy(ipaddress,argv[i+1], WAN_IFNAME_SZ+1); - if (inet_aton(ipaddress,ip_str) != 0 ){ - ip_addr = WAN_TRUE; - }else{ -#ifdef ENABLE_IPV6 - if (inet_pton(AF_INET6,ipaddress,(void*)&ip6_str) == 1){ - af = AF_INET6; - ip_addr = WAN_TRUE; - }else{ - ip_addr = WAN_FALSE; - strncpy(if_name, ipaddress, WAN_IFNAME_SZ); - } -#else - ip_addr = WAN_FALSE; - strncpy(if_name, ipaddress, WAN_IFNAME_SZ); -#endif - } - i_cnt=1; - - }else if (!strcmp(argv[i],"-g")){ -#ifdef WANPIPEMON_GUI - gui_interface=1; - trace_all_data=1; - return WAN_TRUE; -#else - printf("wanpipemon: Warning GUI interface not compiled in!\n\n"); -#endif - -#ifdef WANPIPEMON_ZAP - }else if (!strcmp(argv[i],"-zap")){ - zap_monitor=1; - wan_protocol = WANCONFIG_ZAP; - - }else if (!strcmp(argv[i],"-zapchan")){ - if (i+1 > argc-1){ - printf("ERROR: No Zap channel specified! i.e. '-zapchan 1'\n"); - return WAN_FALSE; - } - if(isdigit(argv[i+1][0]) == 0 || (zap_chan = atoi(argv[i+1])) == 0){ - printf("ERROR: Invalid -zapchan input: %s! Has to be a number greater than zero.\n", - argv[i+1]); - return WAN_FALSE; - } -#endif - }else if (!strcmp(argv[i],"-u")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid UDP PORT!\n"); - printf("Type wanpipemon for help\n"); - return WAN_FALSE; - } - - if(isdigit(argv[i+1][0])){ - udp_port = atoi(argv[i+1]); - }else{ - printf("ERROR: Invalid UDP Port!\n"); - printf("Type wanpipemon for help\n"); - return WAN_FALSE; - } - u_cnt=1; - }else if (!strcmp(argv[i],"-c")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid Command!\n"); - printf("Type wanpipemon for help\n"); - return WAN_FALSE; - } - - memset(command, 0, MAX_CMD_LENGTH+1); - strncpy(command,argv[i+1], strlen(argv[i+1])); - //strncpy(command,argv[i+1], MAX_CMD_LENGTH); - //command[MAX_CMD_LENGTH]='\0'; - c_cnt=1; - }else if (!strcmp(argv[i], "-d")){ - TRACE_DLCI=dlci_number=16; - d_cnt=1; - }else if (!strcmp(argv[i],"-pv6")){ - af = AF_INET6; // IPV6 - - }else if (!strcmp(argv[i],"-p")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid Command!\n"); - printf("Type wanpipemon for help\n"); - return WAN_FALSE; - } - - if (argc == 3){ - char *name=argv[i+1]; - EXEC_NAME_FUNC(usage,name,()); - return WAN_FALSE; - } - - if (strcmp(argv[i+1], "chdlc") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_CHDLC_SIGNATURE); - wan_protocol=WANCONFIG_CHDLC; - }else if (strcmp(argv[i+1], "fr") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_FR_SIGNATURE); - wan_protocol=WANCONFIG_FR; - }else if (strcmp(argv[i+1], "ppp") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_PPP_SIGNATURE); - wan_protocol=WANCONFIG_PPP; - }else if (strcmp(argv[i+1], "x25") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_X25_SIGNATURE); - wan_protocol=WANCONFIG_X25; - }else if (strcmp(argv[i+1], "adsl") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, GLOBAL_UDP_SIGNATURE); - wan_protocol=WANCONFIG_ADSL; - }else{ - usage(); - return WAN_FALSE; - } - - }else if (!strcmp(argv[i], "-x")){ - xml_output=1; - - }else if (!strcmp(argv[i], "-full")){ - trace_all_data=1; - - }else if (!strcmp(argv[i], "-systime")){ - sys_timestamp=1; - - }else if (!strcmp(argv[i], "-prot")){ - int x; - if (i+1 > argc-1){ - printf("ERROR: Invalid Command -prot\n"); - printf("ERROR: Type %s for help\n\n", - progname); - exit(1); - } - TRACE_PROTOCOL=0; - for (x=0;;x++){ - if (trace_prot_opt[x].prot_index == -1) - break; - - if (strstr(argv[i+1],trace_prot_opt[x].prot_name) != NULL){ - TRACE_PROTOCOL|=trace_prot_opt[x].prot_index; - pcap_prot=trace_prot_opt[x].pcap_prot; - } - } - - if (!TRACE_PROTOCOL){ - printf("ERROR: Invalid Protocol in Command -prot!\n"); - printf("ERROR: Type %s for help\n\n", - progname); - exit(1); - } - }else if (!strcmp(argv[i], "-lcn")){ - if (i+1 > argc-1){ - printf("ERROR: Invalid Command -lcn, Type %s for help\n\n", progname); - exit(1); - } - - if (isdigit(argv[i+1][0])){ - TRACE_X25_LCN=atoi(argv[i+1]); - }else{ - printf("ERROR: LCN must be an integer,Type %s for help\n\n", progname); - exit(0); - } - - }else if (!strcmp(argv[i], "-ascii")){ - - TRACE_ASCII=1; - - }else if (!strcmp(argv[i], "-ebcdic")){ - - TRACE_EBCDIC=1; - - }else if (!strcmp(argv[i], "-hex")){ - - TRACE_HEX=1; - - }else if (!strcmp(argv[i], "-pcap")){ - - pcap_output=1; - - }else if (!strcmp(argv[i], "-pcap_file")){ - - if (i+1 > argc-1){ - printf("ERROR: Invalid Command -pcap_file, Type %s for help\n\n", progname); - exit(1); - } - - strncpy(pcap_output_file_name, argv[i+1], WAN_IFNAME_SZ); - - }else if (!strcmp(argv[i], "-x25opt")){ - int x; - if (i+1 > argc-1){ - printf("ERROR: Invalid Command -x25prot, Type %s for help\n\n", progname); - exit(1); - } - - TRACE_X25_OPT=0; - for (x=0;;x++){ - if (trace_x25_prot_opt[x].prot_index == -1) - break; - - if (strstr(argv[i+1],trace_x25_prot_opt[x].prot_name) != NULL){ - TRACE_X25_OPT|=trace_x25_prot_opt[x].prot_index; - } - } - - if (!TRACE_X25_OPT){ - printf("ERROR: Invalid X25 Option in Command -x25opt, Type %s for help\n\n", - progname); - exit(1); - } - } - } - -#ifdef WANPIPEMON_ZAP - if (zap_monitor == 1){ - return WAN_TRUE; - } -#endif - - if (!i_cnt){ - printf("ERROR: No IP address or Interface Name!\n"); - printf("Type %s for help\n", progname); - return WAN_FALSE; - } - if (!u_cnt && ip_addr == WAN_TRUE){ - printf("ERROR: No UDP Port!\n"); - printf("Type %s for help\n", progname); - return WAN_FALSE; - } - if (!c_cnt){ - printf("ERROR: No Command!\n"); - printf("Type %s for help\n", progname); - return WAN_FALSE; - } - if (!d_cnt){ - /* Default DLCI Number to 16 */ - dlci_number = 16; - } - - return WAN_TRUE; -} - -void ResetWanUdp(wan_udp_hdr_t *wan) -{ - memset((void *)&wan->wan_cmd, 0, sizeof(wan_cmd_t)); -} - -void banner (char *title,int dlci_number){ - - int len,i; - - len = strlen(title) + strlen(if_name); - printf("\n\t"); - for (i=0;i<(len+16);i++) - printf("-"); - printf("\n\t\t%s: %s", if_name, title); - printf("\n\t"); - for (i=0;i<(len+16);i++) - printf("-"); - printf("\n\n"); - -} - - -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -static unsigned char usage_info[]="\n" -"Wanpipemon Verison 1.0\n" -"Copyright (C) 2002 - Sangoma Technologies\n" -"www.sangoma.com\n" -"This may be freely redistributed under the terms of the GNU GPL\n" -" \n" -"Usage: (Options in {} brackets are optional)\n" -"\n" -" #Command prompt Local debugging\n" -" wanpipemon -i -c { -p }\n" -" \n" -" #Command prompt Remote debugging\n" -" wanpipemon -i -u -c { -p }\n" -"\n" -" #GUI interface\n" -" wanpipemon -g { -i -u -p } \n" -" \n" -" #Display usage for each protocol\n" -" wanpipemon -p [fr|ppp|chdlc|x25|adsl|aft] \n" -"\n" -" #Detailed usage for each option\n" -" wanpipemon -h\n" -"\n" -" #Detailed usage for advanced tracing\n" -" wanpipemon -traceinfo\n"; -#else -static unsigned char usage_info[]="\n" -"Wanutil Verison 1.0\n" -"Copyright (C) 2004 - Sangoma Technologies\n" -"www.sangoma.com\n" -"This may be freely redistributed under the terms of the GNU GPL\n" -" \n" -"Usage: (Options in {} brackets are optional)\n" -"\n" -" #Command prompt Local debugging\n" -" wanutil -i -c \n" -" \n" -" #Command prompt Remote debugging\n" -" wanutil -i -u -c \n" -"\n" -" #Detailed usage for each option\n" -" wanutil -h\n" -"\n" -" #Detailed usage for advanced tracing\n" -" wanutil -traceinfo\n"; -#endif - - -static void usage(void) -{ - printf("%s\n", usage_info); -} - - -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -static unsigned char usage_long_buf[]= "\n" -"\n" -"Wanpipemon Verison 1.0\n" -"Copyright (C) 2002 - Sangoma Technologies\n" -"www.sangoma.com\n" -"This may be freely redistributed under the terms of the GNU GPL\n" -"\n" -"Usage: (Options in {} brackets are optional)\n" -"\n" -" #Command prompt Local debugging\n" -" wanpipemon -i -c { -p }\n" -" \n" -" #Command prompt Remote debugging\n" -" wanpipemon -i -u -c { -p }\n" -"\n" -" #GUI interface\n" -" wanpipemon -g { -i -u -p } \n" -" \n" -" #Display usage for each protocol\n" -" wanpipemon -p [fr|ppp|chdlc|x25|adsl|aft] \n" -"\n" -" #Detailed usage for each option\n" -" wanpipemon -h\n" -"\n" -"-----------------------------------------------------------\n" -"Option -p: \n" -"\n" -" wanpipemon -p [fr|ppp|chdlc|x25|adsl|aft]\n" -"\n" -" When used by itself:\n" -" Displays the command list for each protocol\n" -"\n" -" wanpipemon -p fr -i wp1_fr16 -c xm \n" -" \n" -" When used with other commands:\n" -" Specifies the protocol and skips the protocol\n" -" autodetect feature. \n" -" \n" -" Used for backward compatibility, since\n" -" old drivers do not support protocol detect option.\n" -"\n" -"----------------------------------------------------------- \n" -"Option -g:\n" -"\n" -" Start wanpipemon in GUI mode\n" -"\n" -" wanpipemon -g\n" -" \n" -" For local debugging: \n" -" GUI will display list of active interfaces.\n" -" \n" -" For remote debugging:\n" -" GUI will ask for an IP address and UDP port.\n" -" \n" -" wanpipemon -i wp1_fr16 -g\n" -" \n" -" Specifies the interface, do not show the list of interfaces\n" -"\n" -" wanpipemon -p fr -i wp1_fr16 -g\n" -" \n" -" Specify the interface and protocol. \n" -" \n" -"-----------------------------------------------------------\n" -"Option -i: \n" -"\n" -" wanpipemon -i wp1_fr16\n" -" wanpipemon -i 192.168.1.1\n" -"\n" -" Specify the Local interface name or Remote IP\n" -" address which will be used to connect to the driver.\n" -" \n" -" \n" -"-----------------------------------------------------------\n" -"Option -u: \n" -"\n" -" wanpiemon -i 192.168.1.1 -u 9000 -c xm\n" -"\n" -" Wanpipe UDPPORT specified in /etc/wanpipe/wanpipe?.conf\n" -" Note: This option is only valid when using Remote IP address.\n" -"\n" -"\n" -"-----------------------------------------------------------\n" -"Option -c: \n" -"\n" -" Wanpipe monitor command (for list of command per protocol)\n" -" For list of commands run: \n" -" wanpipemon -p [fr|ppp|chdlc|x25|adsl|aft]\n" -"\n" -"\n"; - -static void usage_long(void) -{ - printf("%s\n",usage_long_buf); -} -#endif - - -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -static unsigned char trace_info[]="\n" -"\n" -"Wanpipemon Verison 1.1\n" -"Copyright (C) 2004 - Sangoma Technologies\n" -"www.sangoma.com\n" -"This may be freely redistributed under the terms of the GNU GPL\n" -" \n" -"Advanced Line Trace Options\n" -"===========================\n" -"\n" -"Advanced trace options include protocol decoding\n" -"and parsing, system timestamping as well as\n" -"packet filtering.\n" -"\n" -"The Advanced trace command is: 'tri'\n" -" \n" -" wanpipemon -i -c tri { trace options }\n" -"\n" -"\n" -"trace options:\n" -"------------- \n" -"\n" -" -prot [FR|LAPB|X25] #Filter packets based on\n" -" #protocol. Multiple protocols can\n" -" #be selected: \n" -" # -...\n" -" # eg: -prot LAPB-X25\n" -" #Default: All frames\n" -"\n" -" [FR|PPP|CHDLC|IP|ETH|LAPB|X25]\n" -" #Also used by -pcap option to\n" -" #specify what protocol we are\n" -" #capturing. By default protocol is\n" -" #autodetected, but in datascoping\n" -" #this option is a must.\n" -"\n" -" -pcap\n" -" #Trace to a pcap type file\n" -" #that can be read by Ethereal\n" -" #By default file name is wp_trace_pcap.bin\n" -" #writen in current/local directory\n" -"\n" -" -pcap_file \n" -"\n" -" #Specify your own pcap file name\n" -"\n" -" -x25opt [DATA|PROT] #Filter x25 packets based on \n" -" #protcol or information frames\n" -" #Default: All frames\n" -"\n" -" -lcn #Filter x25 packets based on\n" -" #specific lcn number\n" -" #Default: All lcns\n" -"\n" -" -hex #Display packet info in HEX \n" -" #Default: Hex\n" -"\n" -" -ascii #Display packet info in ASCII\n" -"\n" -" -ebcdic #Display packet info in EBCDIC \n" -"\n" -" -systime #Display timestamp as system time\n" -" #instead of absolute number\n" -" \n" -" -full #Display packet data in full.\n" -"\n" -"Examples:\n" -"---------\n" -"\n" -"#Trace and decode all frames, and display packets\n" -"#in full with timestampe decoded into system time.\n" -"\n" -" wanpipemon -i wp1mp -c tri -full -systime\n" -"\n" -"#Trace LAPB and X25 protocol frames. Futhtermore, \n" -"#only decode x25 frames with LCN=1\n" -"\n" -" wanpipemon -i wp1mp -c tri -prot LAPB-X25 -lcn 1\n" -"\n" -"#Trace X25 protocol frames and display x25 data\n" -"#in ASCII.\n" -"\n" -" wanpipemon -i wp1mp -c tri -prot X25 -ascii -full -systime \n" -"\n" -"#Trace data to a pcap type file\n" -"\n" -" wanpipemon -i wan0 -pcap -c tr\n" -" wanpipemon -i wan0 -pcap -pcap_file myfile.bin -c tr\n" -" wanpipemon -i wan0 -pcap -prot FRAME -c tr\n\n"; - -static void usage_trace_info(void) -{ - printf("%s\n",trace_info); -} -#endif - -#if 0 -static void sig_handler(int sigint) -{ - int err; - EXEC_PROT_FUNC(disable_trace,wan_protocol,err,()); -} -#endif - -void sig_end(int signal) -{ - if (pcap_output_file){ - fclose(pcap_output_file); - pcap_output_file=NULL; - } - - if (sock) { - close(sock); - sock=-1; - } - - if (rx_hdlc_eng) { - wanpipe_unreg_hdlc_engine(rx_hdlc_eng); - rx_hdlc_eng=NULL; - } - - //printf("\n\nSignal: Terminating wanpipemon\n"); - - exit(0); -} - -int main(int argc, char* argv[]) -{ - char command[MAX_CMD_LENGTH+1]; - int err = 0; - - strcpy((char*)wan_udp.wan_udphdr_signature, GLOBAL_UDP_SIGNATURE); - sprintf(pcap_output_file_name,"wp_trace_pcap.bin"); - - signal(SIGHUP,sig_end); - signal(SIGINT,sig_end); - signal(SIGTERM,sig_end); - - rx_hdlc_eng = wanpipe_reg_hdlc_engine(); - if (rx_hdlc_eng) { - rx_hdlc_eng->hdlc_data = trace_hdlc_data; - } - - printf("\n"); - if (argc >= 2){ - - if (init(argc, argv, command) == WAN_FALSE){ - err=-EINVAL; - goto main_exit; - } - - if (pcap_output){ - - if (pcap_prot){ - printf("Using custom pcap_prot=%d\n",pcap_prot); - } - - unlink(pcap_output_file_name); - pcap_output_file=fopen(pcap_output_file_name,"wb"); - if (!pcap_output_file){ - printf("wanpipemon: Failed to open %s binary file!\n", - pcap_output_file_name); - err=-EINVAL; - goto main_exit; - } - } - -#ifdef WANPIPEMON_GUI - if (gui_interface && ip_addr==-1){ - if (wan_main_gui() == WAN_FALSE){ - err=-EINVAL; - goto main_exit; - } - } -gui_loop: -#endif - if (MakeConnection() == WAN_FALSE){ - close(sock); - err=-ENODEV; - goto main_exit; - } - - //get_hardware_level_interface_name(if_name); - -#ifdef WANPIPEMON_GUI - if (gui_interface && wan_protocol != 0){ - if (wan_main_gui() == WAN_FALSE){ - return 0; - } - wan_protocol=0; - goto gui_loop; - } -#endif - EXEC_PROT_FUNC(main,wan_protocol,err,(command,argc,argv)); - close(sock); - - if (pcap_output_file){ - fclose(pcap_output_file); - pcap_output_file=NULL; - } - }else{ - usage(); - } - - printf("\n"); - -main_exit: - - if (rx_hdlc_eng) { - wanpipe_unreg_hdlc_engine(rx_hdlc_eng); - rx_hdlc_eng=NULL; - } - - return err; -} - - diff --git a/util/wanpipemon.old/wanpipemon.h b/util/wanpipemon.old/wanpipemon.h deleted file mode 100644 index 3ed4173..0000000 --- a/util/wanpipemon.old/wanpipemon.h +++ /dev/null @@ -1,492 +0,0 @@ -#ifdef WANPIPEMON_GUI -#include "../lxdialog/dialog.h" -#endif - -#include - -#ifdef WANPIPEMON_ZAP -extern int MakeZapConnection(void); -extern int zap_chan; -#endif - -extern int output_start_xml_router (void); -extern int output_stop_xml_router (void); -extern int output_start_xml_header (char *hdr); -extern int output_stop_xml_header (void); - -extern void output_xml_val_data (char *value_name, int value); -extern void output_xml_val_asc (char *value_name, char * value); -extern void output_error(char *value); - -extern void flush_te1_pmon(void); -extern void read_te1_56k_stat(int); -extern void banner(char *, int); -extern int DoCommand(wan_udp_hdr_t*); - -extern int MakeConnection(void); - -extern char *global_command; -extern int global_argc; -extern char** global_argv; -extern int global_card_type; - -extern int connected_to_hw_level; - -extern void CHDLC_set_FT1_mode(void); -extern void ATM_set_FT1_mode(void); -extern void FR_set_FT1_mode(void); -extern void PPP_set_FT1_mode(void); -extern void CHDLC_read_FT1_status(void); -extern void FR_read_FT1_status(void); -extern void PPP_read_FT1_status(void); -extern void ATM_read_FT1_status(void); - -extern int sock; -extern char i_name[]; -extern FT1_LED_STATUS FT1_LED; -extern int raw_data; -extern int fail; -extern int xml_output; -extern int trace_all_data; -extern short dlci_number; -extern int start_xml_router; -extern int stop_xml_router; -extern int is_508; -extern wan_udp_hdr_t wan_udp; -extern unsigned char par_port_A_byte, par_port_B_byte; -extern int lcn_number; -extern void ResetWanUdp(wan_udp_hdr_t *wan); -extern int protocol_cb_size; -extern char if_name[]; -extern int ip_addr; -extern char ipaddress[]; -extern int udp_port; -extern int wan_protocol; -extern int annexg_trace; - -extern char *csudsu_menu[]; - -extern int pcap_output; -extern int pcap_prot; -extern FILE *pcap_output_file; -extern char pcap_output_file_name[]; - - -#define MAX_CMD_ARG 10 -#define MAX_CMD_LENGTH 15 -#define DEFAULT_TRACE_LEN 39 -#define DO_COMMAND(packet) DoCommand((wan_udp_hdr_t*)&packet) - -#define UDP_CHDLC_SIGNATURE "CTPIPEAB" -#define UDP_PPP_SIGNATURE "PTPIPEAB" -#define UDP_FR_SIGNATURE "FPIPE8ND" -#define UDP_X25_SIGNATURE "XLINK8ND" - -/* Trace delay value in micro seconds */ -#define WAN_TRACE_DELAY 20000 - -struct cmd_menu_lookup_t -{ - char *cmd_menu_name; - char **cmd_menu_ptr; -}; - -extern char ** FRget_main_menu(int *len); -extern char ** FRget_cmd_menu(char *cmd_name,int *len); -extern char ** CHDLCget_main_menu(int *len); -extern char ** CHDLCget_cmd_menu(char *cmd_name,int *len); -extern char ** PPPget_main_menu(int *len); -extern char ** PPPget_cmd_menu(char *cmd_name,int *len); -#if defined(__LINUX__) -extern char ** X25get_main_menu(int *len); -extern char ** X25get_cmd_menu(char *cmd_name,int *len); - -extern char ** SS7get_main_menu(int *len); -extern char ** SS7get_cmd_menu(char *cmd_name,int *len); - -extern char ** BITSTRMget_main_menu(int *len); -extern char ** BITSTRMget_cmd_menu(char *cmd_name,int *len); - -#endif -extern char ** ADSLget_main_menu(int *len); -extern char ** ATMget_main_menu(int *len); -extern char ** AFTget_main_menu(int *len); -extern char ** ZAPget_main_menu(int *len); -extern char ** ADSLget_cmd_menu(char *cmd_name,int *len); -extern char ** ATMget_cmd_menu(char *cmd_name,int *len); -extern char ** AFTget_cmd_menu(char *cmd_name,int *len); -extern char ** ZAPget_cmd_menu(char *cmd_name,int *len); - -typedef int config_t(void); -typedef int usage_t(void); -typedef int main_t(char*,int,char**); -typedef int dis_trace_t(void); -typedef char ** main_menu_t(int *len); -typedef char ** cmd_menu_t(char *cmd_name,int *len); -typedef void ft1_cfg_t(void); - -struct fun_protocol { - int protocol_id; - char prot_name[10]; - config_t* config; - usage_t* usage; - main_t* main; - dis_trace_t* disable_trace; - main_menu_t* get_main_menu; - cmd_menu_t* get_cmd_menu; - ft1_cfg_t* read_FT1_status; - ft1_cfg_t* set_FT1_mode; - unsigned char mbox_offset; -}; - -extern int wan_main_gui(void); -extern config_t CHDLCConfig; -extern config_t FRConfig; -extern config_t PPPConfig; -extern config_t ADSLConfig; -extern config_t ATMConfig; -extern config_t AFTConfig; - -#if defined(__LINUX__) -extern config_t X25Config; -extern config_t SS7Config; -extern config_t BITSTRMConfig; -#endif - -extern usage_t ATMUsage; -extern usage_t AFTUsage; -extern usage_t ZAPUsage; -extern usage_t CHDLCUsage; -extern usage_t FRUsage; -extern usage_t PPPUsage; -extern usage_t ADSLUsage; -#if defined(__LINUX__) -extern usage_t X25Usage; -extern usage_t SS7Usage; -extern usage_t BITSTRMUsage; -#endif - -extern main_t CHDLCMain; -extern main_t ATMMain; -extern main_t AFTMain; -extern main_t ZAPMain; -extern main_t FRMain; -extern main_t PPPMain; -extern main_t ADSLMain; -#if defined(__LINUX__) -extern main_t SS7Main; -extern main_t X25Main; -extern main_t BITSTRMMain; -#endif - -extern dis_trace_t CHDLCDisableTrace; -extern dis_trace_t FRDisableTrace; -extern dis_trace_t PPPDisableTrace; -extern dis_trace_t ADSLDisableTrace; -extern dis_trace_t ATMDisableTrace; -extern dis_trace_t AFTDisableTrace; -#if defined(__LINUX__) -extern dis_trace_t SS7DisableTrace; -extern dis_trace_t X25DisableTrace; -#endif - -extern struct fun_protocol function_lookup[]; - -#define DECODE_PROT(prot)((prot==WANCONFIG_FR)?"Frame Relay": \ - (prot==WANCONFIG_MFR)?"Frame Relay": \ - (prot==WANCONFIG_PPP)?"PPP Point-to-Point":\ - (prot==WANCONFIG_CHDLC)?"Cisco HDLC": \ - (prot==WANCONFIG_X25)?"X25": \ - (prot==WANCONFIG_ADSL)?"ADSL: Eth,IP,PPP/ATM":\ - (prot==WANCONFIG_ATM)?"ATM":\ - (prot==WANCONFIG_AFT)?"AFT":\ - (prot==WANCONFIG_AFT_TE1)?"AFT_TE1":\ - (prot==WANCONFIG_AFT_TE3)?"AFT_TE3":\ - (prot==WANCONFIG_AFT_ANALOG)?"AFT_ANALOG":\ - (prot==WANCONFIG_ZAP)?"Zaptel":\ - "Unknown") - -#define EXEC_PROT_FUNC(func,prot,err,arg) {\ - int i=0; \ - err=WAN_FALSE; \ - for(;;){ \ - if (function_lookup[i].protocol_id == 0){\ - printf("\nProtocol: %s support not compiled in!\n\n", \ - DECODE_PROT(prot)); \ - break;\ - }\ - \ - if (function_lookup[i].protocol_id == prot){\ - if (function_lookup[i].func){\ - err=function_lookup[i].func arg;\ - break; \ - }\ - printf("\nProtocol: %s support not compiled in!\n\n", \ - DECODE_PROT(prot)); \ - break;\ - }\ - i++;\ - }\ -} - -#define EXEC_PROT_VOID_FUNC(func,prot,arg) {\ - int i=0; \ - for(;;){ \ - if (function_lookup[i].protocol_id == 0){\ - printf("\nProtocol: %s support not compiled in!\n\n", \ - DECODE_PROT(prot)); \ - break;\ - }\ - \ - if (function_lookup[i].protocol_id == prot){\ - if (function_lookup[i].func){\ - function_lookup[i].func arg;\ - break; \ - }\ - printf("\nProtocol: %s support not compiled in!\n\n", \ - DECODE_PROT(prot)); \ - break;\ - }\ - i++;\ - }\ -} - -#define EXEC_NAME_FUNC(func,name,arg) {\ - int i=0; \ - for(;;){ \ - if (function_lookup[i].protocol_id == 0){\ - printf("\nProtocol: '%s' support not compiled in!\n\n", \ - name); \ - break;\ - }\ - \ - if (strcmp(function_lookup[i].prot_name,name)==0){\ - if (function_lookup[i].func){\ - function_lookup[i].func arg;\ - break;\ - }\ - printf("\nProtocol: '%s' support not compiled in!\n\n", \ - name); \ - break;\ - }\ - i++;\ - }\ -} - - -static inline unsigned char get_wan_udphdr_data_byte(unsigned char off) -{ - int i=0; - for (;;){ - if (function_lookup[i].protocol_id == 0){ - printf("\nProtocol: '%s' support not compiled in!\n\n", - DECODE_PROT(wan_protocol)); - break; - }; - - if (function_lookup[i].protocol_id == wan_protocol){ - -#if 0 - printf("Ptr %p Off %i New Ptr %p Chdlc %p\n", - &wan_udp.wan_udphdr_data[0], - function_lookup[i].mbox_offset, - (((unsigned char*)&wan_udp.wan_udphdr_data[0])+ - function_lookup[i].mbox_offset), - wan_udp.wan_udphdr_chdlc_data); -#endif - return (((unsigned char*)&wan_udp.wan_udphdr_data[0])+ - function_lookup[i].mbox_offset)[off]; - } - i++; - } - - return 0; -} - -static inline unsigned char *get_wan_udphdr_data_ptr(unsigned char off) -{ - int i=0; - for (;;){ - if (function_lookup[i].protocol_id == 0){ - printf("\nProtocol: '%s' support not compiled in!\n\n", - DECODE_PROT(wan_protocol)); - break; - }; - - if (function_lookup[i].protocol_id == wan_protocol){ - - return &(((unsigned char*)&wan_udp.wan_udphdr_data[0])+ - function_lookup[i].mbox_offset)[off]; - } - i++; - } - - return 0; -} - - - -static inline unsigned char set_wan_udphdr_data_byte(unsigned char off, unsigned char data) -{ - int i=0; - for (;;){ - if (function_lookup[i].protocol_id == 0){ - printf("\nProtocol: '%s' support not compiled in!\n\n", - DECODE_PROT(wan_protocol)); - break; - }; - - if (function_lookup[i].protocol_id == wan_protocol){ - - (((unsigned char*)&wan_udp.wan_udphdr_data[0])+ - function_lookup[i].mbox_offset)[off] = data; - - return 0; - } - i++; - } - - return -1; -} - -#define FRAME 0x01 -#define LAPB 0x02 -#define X25 0x04 -#define PPP 0x08 -#define CHDLC 0x10 -#define ETH 0x20 -#define IP 0x40 -#define ALL_PROT (FRAME|LAPB|X25|PPP|CHDLC); - -#define DATA 0x1 -#define PROT 0x2 -#define ALL_X25 (DATA|PROT) - -typedef struct { - char prot_name[15]; - signed char prot_index; - unsigned int pcap_prot; -} trace_prot_t; - - -/* "libpcap" file header (minus magic number). */ -struct pcap_hdr { - u_int32_t magic; /* magic */ - unsigned short version_major; /* major version number */ - unsigned short version_minor; /* minor version number */ - u_int32_t thiszone; /* GMT to local correction */ - u_int32_t sigfigs; /* accuracy of timestamps */ - u_int32_t snaplen; /* max length of captured packets, in octets */ - u_int32_t network; /* data link type */ -}; - -/* "libpcap" record header. */ -struct pcaprec_hdr { - u_int32_t ts_sec; /* timestamp seconds */ - u_int32_t ts_usec; /* timestamp microseconds */ - u_int32_t incl_len; /* number of octets of packet saved in file */ - u_int32_t orig_len; /* actual length of packet */ -}; - - - -enum { - WP_OUT_TRACE_RAW, - WP_OUT_TRACE_INTERP, - WP_OUT_TRACE_PCAP, - WP_OUT_TRACE_INTERP_IPV4, - WP_OUT_TRACE_ATM_RAW_PHY, - WP_OUT_TRACE_ATM_INTERPRETED_PHY, - WP_OUT_TRACE_HDLC -}; - -#define WP_TRACE_OUTGOING 0x01 -#define WP_TRACE_INCOMING 0x02 -#define WP_TRACE_ABORT 0x04 -#define WP_TRACE_CRC 0x08 -#define WP_TRACE_OVERRUN 0x10 - - -typedef struct { - unsigned char *data; - unsigned int len; - unsigned int status; - unsigned short timestamp; - unsigned long systimestamp; - unsigned int type; - unsigned int link_type; - unsigned int prot_criteria; - unsigned char trace_all_data; - unsigned int pkts_written; - unsigned char init; - time_t sec,usec; - FILE *output_file; - unsigned int sub_type; -} wp_trace_output_iface_t; - - - -#pragma pack(1) -typedef struct { - unsigned char link_address; /* Broadcast or Unicast */ - unsigned char control; - unsigned short packet_type; /* IP/SLARP/CDP */ -} cisco_header_t; - -typedef struct { - u_int32_t code; /* Slarp Control Packet Code */ - union { - struct { - u_int32_t address; /* IP address */ - u_int32_t mask; /* IP mask */ - unsigned short reserved[3]; - } address; - struct { - u_int32_t my_sequence; - u_int32_t your_sequence; - unsigned short reliability; - unsigned short t1; /* time alive (upper) */ - unsigned short t2; /* time alive (lower) */ - } keepalive; - } un; -} cisco_slarp_t; -#pragma pack() - -/* Link addresses */ -#define CISCO_ADDR_UNICAST 0x0F -#define CISCO_ADDR_BCAST 0x8F - -/* Packet Types */ -#define CISCO_PACKET_IP 0x0800 -#define CISCO_PACKET_SLARP 0x8035 -#define CISCO_PACKET_CDP 0x2000 - -/* Packet Codes */ -#define SLARP_REQUEST 0 -#define SLARP_REPLY 1 -#define SLARP_KEEPALIVE 2 - - -//extern void decode_pkt (unsigned char *data,int len, -// unsigned char status, unsigned int timestamp, int protocol); - -extern void wp_trace_output(wp_trace_output_iface_t *trace_iface); -extern void print_router_up_time(u_int32_t time); - -extern char* get_hardware_level_interface_name(char* interface_name); -extern int make_hardware_level_connection(void); -extern void cleanup_hardware_level_connection(void); - -extern void read_te1_56k_stat(int); -extern void flush_te1_pmon(void); - -extern void hw_line_trace(int trace_mode); -extern void hw_modem( void ); -extern void hw_general_stats( void ); -extern void hw_flush_general_stats( void ) ; -extern void hw_comm_err( void ) ; -extern void hw_flush_comm_err( void ); -extern void hw_router_up_time(void); -extern void hw_read_code_version(void); -extern void hw_link_status(void); - diff --git a/util/wanpipemon.old/wanpipemon.o b/util/wanpipemon.old/wanpipemon.o deleted file mode 100644 index 2dd1891fcf905e7f78f8391df44f9e254bdf9386..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32852 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 Y5+8(}#D`!f@u#ql_%Q07_=r;f8((ov8~^|S diff --git a/util/wanpipemon.old/wpkbdmon.c b/util/wanpipemon.old/wpkbdmon.c deleted file mode 100644 index 644ab2d..0000000 --- a/util/wanpipemon.old/wpkbdmon.c +++ /dev/null @@ -1,363 +0,0 @@ -/***************************************************************************** -* wpkbdmon.c Keyboard Led Debugger/Monitor -* -* Author: Nenad Corbic -* -* Copyright: (c) 2000-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. -* ---------------------------------------------------------------------------- -* Nov 13, 2000 Nenad Corbic Initial version based on kblights() program -* written by Joseph Nicholas. -*****************************************************************************/ - -#include //printf() -#include -#include //open() -#include //open() -#include //open() -#include //ioctl() -#include //KDSETLED,LED_SCR,LED_CAP,LED_NUM -#include //errno() -#include -#include -#include -#include - -#define MAX_TOKENS 32 -#define KBD_NUM 'n' -#define KBD_CAP 'c' -#define KBD_SCR 's' - -char CONSOLE[] = "/dev/console"; -static unsigned int tx_orig=0, rx_orig=0; -static void cleanup(void); - -int kbd_lights(unsigned char led) -{ - int ttyfd; //fd for console device - int result; //results of ioctl() - - - //This is the console device we will open - - //open console device for later ioctl() call - - ttyfd = open(CONSOLE, O_RDWR); - if (ttyfd < 0) - { - printf("cannot open %s\n", CONSOLE); - return 1; - } // end if() - - result = ioctl(ttyfd,KDSETLED,&led); - if (result < 0) - { - printf("ioctl returned error: %d\n", errno); - close(ttyfd); - return 1; - } - - close(ttyfd); - return 0; -} // end kbd_lights() - - -void sig_handler(int signum) -{ - kbd_lights(0); - cleanup(); - exit(0); -} - - -/*============================================================================ - * Strip leading and trailing spaces off the string str. - */ -char* str_strip (char* str, char* s) -{ - char* eos = str + strlen(str); /* -> end of string */ - - while (*str && strchr(s, *str)) - ++str; /* strip leading spaces */ - while ((eos > str) && strchr(s, *(eos - 1))) - --eos; /* strip trailing spaces */ - *eos = '\0'; - return str; -} - - -/*============================================================================ - * Tokenize string. - * Parse a string of the following syntax: - * =,,... - * and fill array of tokens with pointers to string elements. - * - * Return number of tokens. - */ -int tokenize (char* str, char **tokens, char *arg1, char *arg2, char *arg3) -{ - int cnt = 0; - - tokens[0] = strtok(str, arg1); - while (tokens[cnt] && (cnt < MAX_TOKENS - 1)) { - tokens[cnt] = str_strip(tokens[cnt], arg2); - tokens[++cnt] = strtok(NULL, arg3); - } - return cnt; -} - -void get_tx_rx_data (char *if_name, unsigned int *tx_data, unsigned int *rx_data) -{ - char net_dev[] = "/proc/net/dev"; - struct stat file_stat; - int toknum; - char* token[MAX_TOKENS]; - FILE *pipe_fd; - char line[500]; - int i,len,found=0; - char *ptr; - - *tx_data = *rx_data = 0; - - if (stat(net_dev, &file_stat) < 0) - return; - - pipe_fd = popen("cat /proc/net/dev", "r"); - if (pipe_fd == NULL){ - printf("Failed to open /proc/net/dev\n"); - return; - } - - i=0; - while (fgets(line,sizeof(line)-1,pipe_fd)){ - if (++i < 2) - continue; - if (strstr(line,if_name) != NULL){ - found = 1; - break; - } - } - - pclose(pipe_fd); - - if (!found){ - return; - } - - /* Bug Fix: Dec 7 2000 - * When the packet count gets too high, - * the space between the interface name and the - * count is used yp. This breaks our parsing procedure, - * Therefore, replace the first colon by SPACE, this - * way there will always be space between the interface - * name and the byte count */ - - if ((ptr=strchr(line,':')) != NULL){ - *ptr=' '; - } - - len = strlen(line) + 1; - toknum = tokenize(line, token, " ", " \t\n", " "); - - if (toknum < 13) - return; - - *rx_data = atoi(token[2]); - *tx_data = atoi(token[10]); - - return; -} - - -void get_wanpipe_state (char *device_name, char *state) -{ - char router_dir[] = "/proc/net/wanrouter"; - FILE *pipe_fd; - char line[100]; - int i,len,found=0; - int toknum; - char* token[MAX_TOKENS]; - struct stat file_stat; - - strcpy(state,"unconfigured"); - - if (stat(router_dir, &file_stat) < 0) - return; - - pipe_fd = popen("cat /proc/net/wanrouter/status", "r"); - if (pipe_fd == NULL) - return; - - i=0; - while (fgets(line,sizeof(line)-1,pipe_fd)){ - if (strstr(line,device_name) != NULL){ - found = 1; - break; - } - } - - pclose(pipe_fd); - - if (!found){ - return; - } - - len = strlen(line) + 1; - toknum = tokenize(line, token, "|", " \t\n", "|"); - - if (toknum <= 3) - return; - - if (strcmp(token[0],device_name)) - return; - - strcpy(state,token[3]); - - return; -} - -int check_and_set_lock_file(void) -{ - char wanpipe_dir[] = "/usr/local/wanrouter"; - char lock_file[] = "/usr/local/wanrouter/wpkbd_lock"; - struct stat file_stat; - - if (stat(wanpipe_dir, &file_stat) < 0){ - printf("wpkbdmon: Error, WANPIPE utilites not installed\n"); - printf("wpkbdmon: Directory not found: %s\n",wanpipe_dir); - return 1; - } - - if (stat(lock_file, &file_stat) < 0){ - system ("touch /usr/local/wanrouter/wpkbd_lock"); - }else{ - printf("\nwpkbdmon: Error, WANPIPE Keyboard Led Monitor already running!\n"); - printf(" The /usr/local/wanrouter/wpkbd_lock exits.\n\n"); - return 1; - } - - return 0; -} - - -void cleanup (void) -{ - system("rm -f /usr/local/wanrouter/wpkbd_lock"); -} - - -int main (int argc, char **argv) -{ - int update_interval=5; - char device[15]; - char interface[15]; - char state[50]; - int errno; - unsigned int tx_data, rx_data; - unsigned char led_state=0; - struct sigaction sa; - - //General Error Message - const char *help = - "\n wpkbdmon v1.0 - (c)2000 Nenad Corbic \n\n" - " This program is distributed under the terms of GPL.\n\n" - " This program uses the keyboard leds to convey \n" - " operational statistics of the Sangoma WANPIPE adapter.\n" - " NUM_LOCK = Line State (On=connected, Off=disconnected)\n" - " CAPS_LOCK = Tx data (On=transmitting, Off=no tx data)\n" - " SCROLL_LOCK = Rx data (On=receiving, Off=no rx data)\n\n" - " Usage:\n" - " wpkbdmon [update_interval]\n\n" - " = wanpipe# (#=1,2,3 ...)\n" - " = wanpipe network interface ex: wp1_fr16\n" - " [update interval] = 1-60 seconds , optional (default 5 sec)\n\n"; - - if (argc < 3){ - printf("\nError in usage: Arguments missing\n"); - printf("%s",help); - exit(1); - } - - if (argc == 4){ - update_interval = atoi(argv[3]); - if (update_interval < 1 || update_interval > 60){ - printf("Error: Update interval out of range!\n"); - printf("%s",help); - exit(1); - } - printf("\nUsing Time Interval: %i sec\n",update_interval); - }else{ - printf("\nUsing Default Time Interval: %i sec\n",update_interval); - } - - if (check_and_set_lock_file()) - exit(0); - - memset(&sa,0,sizeof(sa)); - sa.sa_handler=sig_handler; - - if (sigaction(SIGINT,&sa,NULL)){ - perror("sigaction"); - } - - strcpy(device,argv[1]); - strcpy(interface,argv[2]); - - printf ("Starting Wanpipe Keyboard Debugger, Device: %s Interface: %s\n",argv[1],argv[2]); - for (;;){ - - get_wanpipe_state(device, state); - - if (!strcmp(state,"unconfigured")){ - kbd_lights(0); - printf("Warning: Device %s is down, exiting debugger\n",device); - goto wpkbd_exit; - - }else if (!strcmp(state, "connected")){ - led_state |= LED_NUM; - }else{ - if (kbd_lights(0)) - goto wpkbd_exit; - goto skip_tx_rx; - } - - - get_tx_rx_data(interface,&tx_data,&rx_data); - - /* If number of tx packets has not changed, or - * number of tx packets is 0 while original value is - * not, the packet transmission has stopped. - * Thus, turn off the CAP led. */ - - if (tx_data == tx_orig || (tx_orig && !tx_data)){ - led_state &= ~LED_CAP; - }else{ - led_state |= LED_CAP; - } - tx_orig=tx_data; - - if (rx_data == rx_orig || (rx_orig && !rx_data)){ - led_state &= ~LED_SCR; - }else{ - led_state |= LED_SCR; - } - rx_orig=rx_data; - - if (kbd_lights(led_state)) - goto wpkbd_exit; - -skip_tx_rx: - sleep(update_interval); - } - -wpkbd_exit: - - cleanup(); - return 0; -} - - diff --git a/util/wanpipemon.old/xml_lib.c b/util/wanpipemon.old/xml_lib.c deleted file mode 100644 index 4ba5bcc..0000000 --- a/util/wanpipemon.old/xml_lib.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -# include -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - - -int output_start_xml_router (void) -{ - FILE* pipe_fd; - char host[50]; - char tmp_time[10]; - time_t time_val; - struct tm *time_tm; - - if (start_xml_router) - return 0; - - /* Get the host name of the router */ - pipe_fd = popen("cat /etc/hostname","r"); - if (!pipe_fd) - return 1; - - fgets(host,sizeof(host)-1,pipe_fd); - pclose(pipe_fd); - host[strlen(host)-1]='\0'; - - /* Parse time and date */ - time(&time_val); - time_tm = localtime(&time_val); - - printf("\n",host); - - printf("\n"); - - strftime(tmp_time,sizeof(tmp_time),"%Y",time_tm); - printf("%s\n",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%m",time_tm); - printf("%s\n",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); - printf("%s\n",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); - printf("%s\n",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); - printf("%s\n",tmp_time); - - strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); - printf("%s\n",tmp_time); - - printf("\n\n"); - - return 0; -} - -int output_stop_xml_router(void) -{ - if (stop_xml_router) - return 0; - - printf("\n\n"); - return 0; -} - -int output_start_xml_header(char *hdr) -{ - printf("

    \n",hdr); - return 0; -} - -int output_stop_xml_header(void) -{ - printf("
    \n"); - return 0; -} - -void output_xml_val_data (char *value_name, int value) -{ - printf(" \n %i\n \n",value_name,value); -} - -void output_xml_val_asc(char *value_name, char *value) -{ - printf(" \n %s\n \n",value_name,value); -} - -void output_error(char *value) -{ - if (xml_output){ - output_start_xml_router(); - printf(" \n %s\n \n",value); - output_stop_xml_router(); - }else{ - printf("ERROR: %s\n",value); - } -} diff --git a/util/wanpipemon.old/xml_lib.o b/util/wanpipemon.old/xml_lib.o deleted file mode 100644 index 7622029981ef8a4fb079a958b6a6466e2e9beae2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2972 zcma)7ZERCj7=F7>m~*nphZ;q!vqOl|uFLR)T1)I(H}@i%08_ z+AIH+N~QeChVjBtQiUHLqbciKfo@mdRL<|^O%zq;UCak=5pt<|I_@qF)ccHehl_(0 zMrI0o$2KR5Z*0n6-8jk=GJL_Emp{32>$dLk!jYwnoW@GHc8q-zMim(u|BhQU{EK_B zun&vviq=tfu)H_ktD;{D4*Xzt{V6GKBHjr+Tq=|cXe z@ba65uITzx9Sw~#;tyUNMeIc{;l5}s=CF=6PN@h`7m&xg(FTmdEb7vTaW?hST$dWz zJB`cQcdBUj&Y~?;(T>fc{iKTa^I5dtR?+g(RIcsED%x|t7JKrm@8cX3MV{pGKb!K$ zYbFm(l}f#1IP1F6yP=WMu4vQn8Fz_S#M`9p<-v7ZCwYN!xZL+^L1G*rf@bVWWd_Yi zE|oQ(ZEkUzll6>7A}x+`jJV>HJPBdEs=mL9-n4DYz9p-UO2p_hQ$3~~oB)DxFPao1 zZVkEvgKo0kh}&>YJ1MrLQ*I<~y6JeI<+z->7#=wzjnR{G&7`z!5o3>;vXd>25m!#V zv}DD|S~<5*1w9YZ9>JJBDn^UQIx+gJL2s;b5PJn<`*WC!H`sF#-z0`(rd5!(9+Ouy zs5kT)WKC!1tDUR3w<2p-uU-{dwsyno%OmZvL@W_$Yi)h1HPN~BM7k+WPg zhB>To+*JB)p7HIrhau$OevTgSJnZ!v4PctI`yg!awVePcVjwRR$Je6Qp|@xphGl!& zcRZ+cbRS2j-lwbS_%btp8#)_xdCyh9tV{kmZGGMM(A`uD?}r-p4cdB9kt0YD^Fe^y z9PmkBW}!f1F1CBn{WTC%x08-;zK%Aqt@6ZNk;4eyg*f+>>ABbRgZU=7Nq&-O7z zB*^tosmw56kR=XQAfCCnu;>r1P7qyUq`g<9hxR@Z3zl_v5o2EOYWx8) z>K@SeW8(WozSQ_@V(5=)d{*<9H2zuhlN$f4`4H|1>&=1X_(d8w6C?i$joUQ;g2o#( zzeVG1n$K#ySM$Rff28>X8XqFYdX5r5fcsC3$Lkz1&fy|4=JN+J=66-&3ED=H{{g3? BdF22A diff --git a/util/wanpipemon.old/xpipemon.c b/util/wanpipemon.old/xpipemon.c deleted file mode 100644 index 0c9c447..0000000 --- a/util/wanpipemon.old/xpipemon.c +++ /dev/null @@ -1,1111 +0,0 @@ -/***************************************************************************** -* wanpipemon.c X25 Debugg Monitor. -* -* Authors: Nenad Corbic -* -* Copyright: (c) 1999 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. -* -* NOTE: This program is still under construction. Only critical features -* are enabled. -* ---------------------------------------------------------------------------- -* Jun 28, 1999 Nenad Corbic Initial version based on wanpipemon for linux. -*****************************************************************************/ - -#if !defined(__LINUX__) -# error "X25 Monitor not supported on FreeBSD/OpenBSD OS!" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include "fe_lib.h" -#include "wanpipemon.h" - - -#define TIMEOUT 1 -#define MDATALEN 2024 - -#define BANNER(str) banner(str,0) - -/****************************************************************************** - * Structure for tracing - * - */ - -/* Prototypes */ -void error( char return_code); -void read_hdlc_stat(void); -void flush_hdlc_stat(void); - -/* global for now */ -static unsigned char station_config; -int off_counter, green_counter, red_counter; -int loop_counter, fail; - -/* defines for now */ -extern int lcn_number; - - -int X25Config (void) -{ - unsigned char x; - char codeversion[10]; - x = 0; - wan_udp.wan_udphdr_command = X25_READ_CONFIGURATION; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_x25_lcn = 0; - while (++x < 4){ - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code == 0x00){ - break; - } - if (wan_udp.wan_udphdr_return_code == 0xaa){ - printf("Error: Command timeout occurred\n"); - return(WAN_FALSE); - } - if (wan_udp.wan_udphdr_return_code == 0xCC ) return(WAN_FALSE); - } - - if (x >= 4) return(WAN_FALSE); - station_config = wan_udp.wan_udphdr_data[0]; - - strcpy(codeversion, "?.??"); - - wan_udp.wan_udphdr_command = X25_READ_CODE_VERSION; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); - } - - protocol_cb_size=sizeof(wan_mgmt_t) + sizeof(wan_cmd_t) + 1; - return(WAN_TRUE); -}; /* ObtainConfiguration */ - -void error( char return_code ) -{ - switch( return_code ){ - case 0x04: - printf("Error: An invalid DLCI was selected\n"); - break; - case 0x10: - printf("Error: A modem failure occurred - DCD and/or CTS were found to be unexpectedly low\n"); - break; - case 0x11: - printf("Error: The Channel moved from Operative to being Inoperative\n"); - break; - case 0x12: - printf("Error: The Channel moved from Inoperative to being Operative\n"); - break; - case 0x13: - printf("Error: The Access Node has reported a change in the status of a DLCI or a number of DLCIs\n"); - break; - case 0x14: - printf("Error: A Full Status Report included a DLCI or a number of DLCIis which were not included before\n"); - break; - case 0x1F: - printf("Error: The frame relay command is invalid\n"); - break; - default: - break; - } -}; /* error */ - -/*=============================================== - * Link Status - * - *==============================================*/ - -void link_status( void ) -{ - wan_udp.wan_udphdr_command = X25_HDLC_LINK_STATUS; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_x25_lcn = 0; - DO_COMMAND(wan_udp); - - if(wan_udp.wan_udphdr_return_code == 0 || wan_udp.wan_udphdr_return_code == 1){ - - BANNER("LINK STATUS"); - - switch (wan_udp.wan_udphdr_return_code){ - case 0: - printf("\t Link is in a disconnected mode : Disconnected\n"); - break; - case 1: - printf("\t Asynchronously Balanced Mode (ABM): Connected\n"); - break; - default: - printf("\t Error: Command Failed, Please try again\n"); - return; - } - - printf("\tNumber of Inf. Frames queued for tx: %i\n", - wan_udp.wan_udphdr_data[0]); - printf("\tNumber of Inf. Frames queued for rx: %i\n", - wan_udp.wan_udphdr_data[1]); - switch (wan_udp.wan_udphdr_data[2]){ - case 1: - printf("\t Link Configured as: DTE\n"); - break; - case 2: - printf("\t Link Confiugred as: DCE\n"); - break; - default: - printf("\t Unknown Link Configuration: DTE or DCE ?\n"); - } - - printf("\t Supervisory frame count: %i\n",wan_udp.wan_udphdr_data[4]); - - }else - error(wan_udp.wan_udphdr_return_code); - -} /* link_status */ - - -/*=============================================== - * Modem Status - * - *==============================================*/ - -void modem_status( void ) -{ - wan_udp.wan_udphdr_command = X25_READ_MODEM_STATUS; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - - BANNER("MODEM STATUS"); - - /* If bit 3 is set DCD is hight, otherwise low */ - if (wan_udp.wan_udphdr_data[0] & 0x08) - printf("DCD: HIGH\n"); - else - printf("DCD: LOW\n"); - - /* If bit 5 is set CTS is hight, otherwise low */ - if( wan_udp.wan_udphdr_data[0] & 0x20) - printf("CTS: HIGH\n"); - else - printf("CTS: LOW\n"); - } else { - error(wan_udp.wan_udphdr_return_code); - } - -} - -/*=============================================== - * HDLC Statistics - * - *==============================================*/ - -void read_hdlc_stat( void) -{ - read_hdlc_stat_t *stat; - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = X25_HDLC_READ_STATS; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - stat = (read_hdlc_stat_t *)&wan_udp.wan_udphdr_data[0]; - - if (!wan_udp.wan_udphdr_return_code) - { - BANNER("X25: HDLC STATISTICS"); - - printf(" Inf. Frames received successfuly : %i\n", - stat->inf_frames_rx_ok); - printf(" Inf. Frames received out of sequence : %i\n", - stat->inf_frames_rx_out_of_seq); - printf("Inf. Frames received with no data filed : %i\n", - stat->inf_frames_rx_no_data); - printf(" Incomming Inf. Frames discarded : %i\n", - stat->inf_frames_rx_dropped); - printf("Incomming Inf. Frames with data to long : %i\n", - stat->inf_frames_rx_data_too_long); - printf(" Frames received with invalid HDLC addr : %i\n", - stat->inf_frames_rx_invalid_addr); - printf(" Inf. Frames tarnsmitted successfully : %i\n", - stat->inf_frames_tx_ok); - printf(" Inf. Frames retransmitted : %i\n", - stat->inf_frames_tx_retransmit); - printf(" Number of T1 Timeouts : %i\n", - stat->T1_timeouts); - printf(" Number of SABM frames received : %i\n", - stat->SABM_frames_rx); - printf(" Number of DISC frames received : %i\n", - stat->DISC_frames_rx); - printf(" Number of DM frames received : %i\n", - stat->DM_frames_rx); - printf(" Number of FRMR frames received : %i\n", - stat->FRMR_frames_rx); - printf(" Number of SABM frames transmitted : %i\n", - stat->SABM_frames_tx); - printf(" Number of DISC frames transmitted : %i\n", - stat->DISC_frames_tx); - printf(" Number of DM frames transmitted : %i\n", - stat->DM_frames_tx); - printf(" Number of FRMR frames transmitted : %i\n", - stat->FRMR_frames_tx); - }else - error(wan_udp.wan_udphdr_return_code); - -} /* read_hdlc_stat */ - -/*=============================================== - * Flush HDLC Statistics - * - *==============================================*/ - -void flush_hdlc_stat( void) -{ - wan_udp.wan_udphdr_command = X25_HDLC_FLUSH_STATS; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - if (!wan_udp.wan_udphdr_return_code) - printf("\n\tHDLC Statistics have been cleared \n"); - else - error(wan_udp.wan_udphdr_return_code); - -} /* flush_hdlc_stat */ - - -/*=============================================== - * Communication Error Statistics - * - *==============================================*/ - -void comm_err(void) -{ - read_comms_err_stats_t *stat; - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = X25_HDLC_READ_COMM_ERR; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_x25_lcn = 0; // for supervisor display - - DO_COMMAND(wan_udp); - - stat = (read_comms_err_stats_t *)&wan_udp.wan_udphdr_data[0]; - - if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len == 0x0A) { - - BANNER("X25: COMMUNICATION ERROR STATISTICS"); - - printf(" Number of receiver overrun errors: %d\n", - stat->overrun_err_rx); - printf(" Number of receiver CRC errors: %d\n", - stat->CRC_err); - printf(" Number of abort frames received: %d\n", - stat->abort_frames_rx); - printf("Number of times receiver disabled (buffers full): %d\n", - stat->frames_dropped_buf_full); - printf(" Number of abort frames transmitted: %d\n", - stat->abort_frames_tx); - printf(" Number fo transmit underruns: %d\n", - stat->transmit_underruns); - printf(" Number of transmit underrun interrupts missed: %d\n", - stat->missed_tx_underruns_intr); - printf(" Number of times DCD dropped unexpectedly: %d\n", - stat->DCD_drop); - printf(" Number of times CTS dropped unexpectedly: %d\n", - stat->CTS_drop); - } else { - error(wan_udp.wan_udphdr_return_code); - } -}; /* comm_err(); */ - - -/*=============================================== - * Flush Communication Error Statistics - * - *==============================================*/ - - -void flush_comm_err( void ) -{ - wan_udp.wan_udphdr_command = X25_HDLC_FLUSH_COMM_ERR; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_x25_lcn = 0; - DO_COMMAND(wan_udp); - if (!wan_udp.wan_udphdr_return_code) - printf("Comm Error Statistics have been Cleared\n"); - else - error(wan_udp.wan_udphdr_return_code); -}; /* flush_comm_err */ - - -#ifdef NEX_XPIPE - -/* FIXME: The following code is not used. The wanpipemon is half - finished, and only supports critical commands */ - -void global_stats( void ) -{ - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = READ_DLC_STATISTICS; - wan_udp.wan_udphdr_data_len = 0; - cb.dlci = 0; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code == 0) { - if( station_config == 0 ) { - printf(" Full Status Enquiry messages sent: %d\n", *(unsigned short*)&wan_udp.wan_udphdr_data[12]); - printf("Link Integrity Verification Status Enquiry messages sent: %d\n", *(unsigned short*)&wan_udp.wan_udphdr_data[14]); - printf(" Full Status messages received: %d\n", *(unsigned short*)&wan_udp.wan_udphdr_data[16]); - printf(" Link Integrity Verification Status messages received: %d\n", *(unsigned short*)&wan_udp.wan_udphdr_data[18]); - } - } else { - error(wan_udp.wan_udphdr_return_code); - } -}; /* global_stats */ - - - -void flush_global_stats( void ) -{ - wan_udp.wan_udphdr_command = FLUSH_DLC_STATISTICS; - wan_udp.wan_udphdr_data_len = 1; - cb.dlci = 0; - wan_udp.wan_udphdr_data[0] = 0x01; - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code != 0) { - switch(wan_udp.wan_udphdr_return_code){ - case 0x06: - printf("Error: Global Statistics not flushed\n"); - break; - default: - error(wan_udp.wan_udphdr_return_code); - break; - } - } -}; /* flush_global_stats */ - -#endif - -int X25DisableTrace(void) -{ - wan_udp.wan_udphdr_command = XPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_data_len = 2; - wan_udp.wan_udphdr_data[0] = 0x00; - wan_udp.wan_udphdr_data[1] = 0x00; - DO_COMMAND(wan_udp); - return 0; -} - - -void decode_timestamp (trace_data_t *trace_info) -{ - time_t time_val=trace_info->sec; - struct tm *time_tm = localtime(&time_val); - char tmp_time[50]; - - /* week day */ - //strftime(tmp_time,sizeof(tmp_time),"%a",time_tm); - //printf("%s ",tmp_time); - - /* month */ - strftime(tmp_time,sizeof(tmp_time),"%b",time_tm); - printf("%s ",tmp_time); - - /* numeric day of the month */ - strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); - printf("%s ",tmp_time); - - /* Hour of day */ - strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); - printf("%s:",tmp_time); - - /* Minute of hour */ - strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); - printf("%s:",tmp_time); - - /* Second of minute */ - strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); - printf("%s ",tmp_time); - - printf("%u [1/100s]",trace_info->usec ); -} - -void line_trace(int trace_mode) -{ - fd_set ready; - struct timeval to; - char *trace_data; - trace_data_t *trace_info; - wp_trace_output_iface_t trace_iface; - - memset(&trace_iface,0,sizeof(wp_trace_output_iface_t)); - - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = XPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_data_len = 2; - wan_udp.wan_udphdr_data[0] = 0x00; - wan_udp.wan_udphdr_data[1] = 0x00; - DO_COMMAND(wan_udp); - - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = XPIPE_ENABLE_TRACING; - wan_udp.wan_udphdr_data_len = 0x02; - wan_udp.wan_udphdr_data[0] |= TRACE_DEFAULT; - - if (trace_mode == TRACE_PROT){ - wan_udp.wan_udphdr_data[0] |= TRACE_SUPERVISOR_FRMS | - TRACE_ASYNC_FRMS; - - }else if (trace_mode == TRACE_DATA){ - wan_udp.wan_udphdr_data[0] |= TRACE_DATA_FRMS; - - }else{ - wan_udp.wan_udphdr_data[0] |= TRACE_ALL_HDLC_FRMS; - } - wan_udp.wan_udphdr_data[1] = 0x00; - DO_COMMAND(wan_udp); - - if( wan_udp.wan_udphdr_return_code == 0 ) { - printf("Starting trace...(Press ENTER to exit)\n"); - } else if (wan_udp.wan_udphdr_return_code == 0x1F) { - printf("Line Tracing is possible only with S508 board.\n"); - return; - } else if( wan_udp.wan_udphdr_return_code == 0xCD ) { - printf("Cannot Enable Line Tracing from Underneath.\n"); - return; - } else if( wan_udp.wan_udphdr_return_code == 0x01 ) { - printf("Starting trace...(although it's already enabled!)\n"); - printf("Press ENTER to exit.\n"); - } else { - printf("Failed to Enable Line Tracing. Return code: 0x%02X\n", wan_udp.wan_udphdr_return_code ); - return; - } - fflush(stdout); - to.tv_sec = 0; - to.tv_usec = 0; - - for(;;){ - - FD_ZERO(&ready); - FD_SET(0,&ready); - - if(select(1,&ready, NULL, NULL, &to)) { - break; - } /* if */ - - to.tv_sec = 0; - to.tv_usec = 0; - - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = XPIPE_GET_TRACE_INFO; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - trace_info = (trace_data_t *)&wan_udp.wan_udphdr_data[0]; - trace_data = (char *)&trace_info->data; - - if (wan_udp.wan_udphdr_return_code == 0 && - wan_udp.wan_udphdr_data_len) { - - /* frame type */ -// printf("\n\nLength = %i",trace_info->length); -// printf("\nTime Stamp = 0x%04X",trace_info->timestamp); - - trace_iface.status=0; - if (trace_info->type & 0x01) { - trace_iface.status|=WP_TRACE_OUTGOING; - } - - trace_iface.len = trace_info->length; - trace_iface.timestamp=trace_info->timestamp; - trace_iface.sec=trace_info->sec; - trace_iface.usec=trace_info->usec; - - if (trace_info->length > wan_udp.wan_udphdr_data_len){ - continue; - } - - if (trace_info->length == 0) { - printf("the frame data is not available" ); - printf("\n"); - fflush(stdout); - continue; - } - - - trace_iface.trace_all_data=trace_all_data; - trace_iface.data=(unsigned char*)&trace_data[0]; - trace_iface.link_type = 3; - - if (pcap_output){ - trace_iface.type=WP_OUT_TRACE_PCAP; - }else if (raw_data) { - trace_iface.type=WP_OUT_TRACE_RAW; - }else{ - trace_iface.type=WP_OUT_TRACE_INTERP; - } - - wp_trace_output(&trace_iface); - fflush(stdout); - - to.tv_sec = 0; - to.tv_usec = 0; - }else{ - to.tv_sec = 0; - to.tv_usec = WAN_TRACE_DELAY; - } - } - - fflush(stdout); - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = XPIPE_DISABLE_TRACING; - wan_udp.wan_udphdr_data_len = 2; - wan_udp.wan_udphdr_data[0] = 0x00; - wan_udp.wan_udphdr_data[1] = 0x00; - DO_COMMAND(wan_udp); -}; //line_trace - - -void x25_driver_stat_ifsend( void ) -{ - if_send_stat_t *if_snd_stat; - - wan_udp.wan_udphdr_command = XPIPE_DRIVER_STAT_IFSEND; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - if_snd_stat = (if_send_stat_t *) &wan_udp.wan_udphdr_data[0]; - - BANNER("X25: DRIVER IF_SEND STATISTICS"); - - printf(" Total Number of Send entries: %lu\n", - if_snd_stat->if_send_entry); - printf(" Number of Send entries with SKB = NULL: %lu\n", - if_snd_stat->if_send_skb_null); - printf("Number of Send entries with broadcast addressed packet discarded: %lu\n", - if_snd_stat->if_send_broadcast); - printf("Number of Send entries with multicast addressed packet discarded: %lu\n", - if_snd_stat->if_send_multicast); - printf(" Number of Send entries with CRITICAL_RX_INTR set: %lu\n", - if_snd_stat->if_send_critical_ISR); - printf(" Number of Send entries with Critical set and packet discarded: %lu\n", - if_snd_stat->if_send_critical_non_ISR); - printf(" Number of Send entries with Device Busy set: %lu\n", - if_snd_stat->if_send_tbusy); - printf(" Number of Send entries with Device Busy Timeout: %lu\n", - if_snd_stat->if_send_tbusy_timeout); - printf(" Number of Send entries with XPIPE MONITOR Request: %lu\n", - if_snd_stat->if_send_PIPE_request); - printf(" Number of Send entries with WAN Disconnected: %lu\n", - if_snd_stat->if_send_wan_disconnected); - printf(" Number of Send entries with Send failed: %lu\n", - if_snd_stat->if_send_bfr_not_passed_to_adptr); - printf(" If_send, number of packets passed to the board successfully: %lu\n", - if_snd_stat->if_send_bfr_passed_to_adptr); - - -} /* x25_driver_stat_ifsend */ - -void x25_driver_stat_intr( void ) -{ - global_stats_t *global_stat; - rx_intr_stat_t *rx_int_stat; - wan_udp.wan_udphdr_command = XPIPE_DRIVER_STAT_INTR; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - global_stat = (global_stats_t *)&wan_udp.wan_udphdr_data[0]; - rx_int_stat = (rx_intr_stat_t *)&wan_udp.wan_udphdr_data[sizeof(global_stats_t)]; - - BANNER("X25: DRIVER INTERRUPT STATISTICS"); - - printf(" Number of ISR entries: %lu\n" , - global_stat->isr_entry); - printf(" Number of ISR entries with Critical Set: %lu\n" , - global_stat->isr_already_critical); - printf(" Number of Receive Interrupt: %lu\n" , - global_stat->isr_rx); - printf(" Number of Transmit Interrupt: %lu\n" , - global_stat->isr_tx); - printf(" Number of ISR entries for Interrupt Testing: %lu\n" , - global_stat->isr_intr_test); - printf(" Number of Spurious Interrupt: %lu\n" , - global_stat->isr_spurious); - printf(" Number of Times Transmit Interrupts Enabled in ISR: %lu\n" , - global_stat->isr_enable_tx_int); - printf(" Number of Receive Interrupts with Corrupt Buffer: %lu\n\n" , - global_stat->rx_intr_corrupt_rx_bfr); - - printf(" Number of Poll Entries: %lu\n", - global_stat->poll_entry); - printf(" Number of Poll Entries with Critical set: %lu\n", - global_stat->poll_already_critical); - printf(" Number of Poll Entries Processed: %lu\n\n", - global_stat->poll_processed); - - - printf(" Number of Receive Interrupts with No socket: %lu\n" , - rx_int_stat->rx_intr_no_socket); - printf(" Number of Receive Interrupts for XPIPE MONITOR Request: %lu\n" , - rx_int_stat->rx_intr_PIPE_request); - printf("Number of Receive Interrupts with Buffer Passed to Stack: %lu\n" , - rx_int_stat->rx_intr_bfr_passed_to_stack); - - -} /* x25_driver_stat_intr */ - - -void x25_driver_stat_gen( void ) -{ - - pipe_mgmt_stat_t *pipe_mgmt_stat; - - wan_udp.wan_udphdr_command = XPIPE_DRIVER_STAT_GEN; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - pipe_mgmt_stat = (pipe_mgmt_stat_t *)&wan_udp.wan_udphdr_data[0]; - - BANNER("X25: DRIVER GENERAL STATISTICS"); - - printf(" Number of XPIPE Monitor call with kmalloc error: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_kmalloc_err); - printf(" Number of XPIPE Monitor call with Adapter Type error: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_adptr_type_err); - printf(" Number of XPIPE Monitor call with Direction Error: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_direction_err); - printf(" Number of XPIPE Monitor call with Adapter Command Timeout: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_adptr_cmnd_timeout); - printf(" Number of XPIPE Monitor call with Adapter Command OK: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_adptr_cmnd_OK); - printf(" Number of XPIPE Monitor call with Adapter Send passed: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_adptr_send_passed); - printf(" Number of XPIPE Monitor call with Adapter Send failed: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_adptr_send_failed); - printf(" Number of XPIPE Monitor call with packet passed to stack: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_passed_to_stack); - printf(" Number of XPIPE Monitor call with pkt NOT passed to stack: %lu\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_not_passed_to_stack); - printf(" Number of XPIPE Monitor call with no socket: %lu\n\n", - pipe_mgmt_stat->UDP_PIPE_mgmt_no_socket); - -} /* x25_driver_stat_gen */ - - -void flush_driver_stats( void ) -{ - wan_udp.wan_udphdr_command = XPIPE_FLUSH_DRIVER_STATS; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - printf("All Driver Statistics are Flushed.\n"); - -} /* flush_driver_stats */ - -void x25_router_up_time( void ) -{ - unsigned long time; - wan_udp.wan_udphdr_command = XPIPE_ROUTER_UP_TIME; - wan_udp.wan_udphdr_data_len = 0; - wan_udp.wan_udphdr_data[0] = 0; - DO_COMMAND(wan_udp); - - BANNER("X25: ROUTER/API UP TIME"); - - time = wan_udp.wan_udphdr_data[0] + (wan_udp.wan_udphdr_data[1]*256) + (wan_udp.wan_udphdr_data[2]*65536) + - (wan_udp.wan_udphdr_data[3]*16777216); - if (time < 3600) { - if (time<60) - printf(" Router UP Time: %lu seconds\n", time); - else - printf(" Router UP Time: %lu minute(s)\n", (time/60)); - }else - printf(" Router UP Time: %lu hour(s)\n", (time/3600)); - - -} /* x25_router_up_time */ - -void read_x25_statistics (void) -{ - TX25Stats *stats; - - ResetWanUdp(&wan_udp); - wan_udp.wan_udphdr_command = X25_READ_STATISTICS; - wan_udp.wan_udphdr_data_len = 0; - DO_COMMAND(wan_udp); - - BANNER("X25: X25 STATISTICS"); - - printf("Command %x\n",wan_udp.wan_udphdr_command); - - if (wan_udp.wan_udphdr_return_code != 0){ - printf("\t Error X25 Statistics Command Failed. Please Try Again\n"); - return; - } - - stats = (TX25Stats *)&wan_udp.wan_udphdr_data[0]; - - printf (" Restart Request Tx : %i\n", stats->txRestartRqst); - printf (" Restart Request Rx : %i\n", stats->rxRestartRqst); - printf (" Restart Confirmations Tx : %i\n", stats->txRestartConf); - printf (" Restart Confirmations Rx : %i\n", stats->rxRestartConf); - printf (" Reset Request Tx : %i\n", stats->txResetRqst); - printf (" Reset Request Rx : %i\n", stats->rxResetRqst); - printf (" Reset Confirmations Tx : %i\n", stats->txResetConf); - printf (" Reset Confirmations Rx : %i\n", stats->rxResetConf); - printf (" Call Request Tx : %i\n",stats->txCallRequest); - printf (" Call Request Rx : %i\n",stats->rxCallRequest); - printf (" Call Accepted Tx : %i\n",stats->txCallAccept); - printf (" Call Accepted Rx : %i\n",stats->rxCallAccept); - printf (" Clear Request Tx : %i\n",stats->txClearRqst); - printf (" Clear Request Rx : %i\n",stats->rxClearRqst); - printf (" Clear Confirmation Tx : %i\n",stats->txClearConf); - printf (" Clear Confirmation Rx : %i\n",stats->rxClearConf); - printf (" Diagnostics Packets Tx : %i\n",stats->txDiagnostic); - printf (" Diagnostics Packets Rx : %i\n",stats->rxDiagnostic); - printf (" Registration Request Tx : %i\n",stats->txRegRqst); - printf (" Registration Request Rx : %i\n",stats->rxRegRqst); - printf (" Registration Confirmation Tx : %i\n",stats->txRegConf); - printf (" Registration Confirmation Rx : %i\n",stats->rxRegConf); - printf (" Interrupt Packets Tx : %i\n",stats->txInterrupt); - printf (" Interrupt Packets Rx : %i\n",stats->rxInterrupt); - printf (" Interrupt Confirmations Tx : %i\n",stats->txIntrConf); - printf (" Interrupt Confirmations Rx : %i\n",stats->rxIntrConf); - printf (" Data Packets Tx : %i\n",stats->txData); - printf (" Data Packets Rx : %i\n",stats->rxData); - printf (" RR Packets Tx : %i\n",stats->txRR); - printf (" RR Packets Rx : %i\n",stats->rxRR); - printf (" RNR Packets Tx : %i\n",stats->txRNR); - printf (" RNR Packets Rx : %i\n",stats->rxRNR); -} - - -//------------------------ END OF FT1 STATISTICS ------------------------ - - - -int X25Usage( void ) { - - printf("wanpipemon: Wanpipe X25 Debugging Utility\n\n"); - printf("Usage:\n"); - printf("-----\n\n"); - printf("wanpipemon -i -u -c -d \n\n"); - printf("\tOption -i: \n"); - printf("\t\tWanpipe remote IP address or\n"); - printf("\t\tWanpipe network interface name (ex: wp1_fr16)\n"); - printf("\tOption -u: (Optional, default 9000) \n"); - printf("\t\tWanpipe UDPPORT specified in /etc/wanpipe#.conf\n"); - printf("\tOption -c: \n"); - printf("\t\tFpipemon Command\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: xm = View Modem Status\n\n"); - printf("\tSupported Commands: x=status : s=statistics : t=trace \n"); - printf("\t c=config : T=FT1 stats : f=flush\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tCard Status\n"); - printf("\t x m Modem Status\n"); - printf("\t l Link Status\n"); - printf("\t ru Display Router UP time\n"); - //printf("\tCard Configuration\n"); - //printf("\t c l List Active DLCIs\n"); - printf("\tCard Statistics\n"); - //printf("\t s g Global Statistics\n"); - printf("\t s c Communication Error Statistics\n"); - printf("\t x X25 Statistics\n"); - printf("\t h HDLC Statistics\n"); - printf("\tTrace Data \n"); - //printf("\t t i Trace and Interpret ALL frames\n"); - //printf("\t ip Trace and Interpret PROTOCOL frames only\n"); - //printf("\t id Trace and Interpret DATA frames only\n"); - printf("\t t r Trace ALL frames, in RAW format\n"); - printf("\t rp Trace PROTOCOL frames only, in RAW format\n"); - printf("\t rd Trace DATA frames only, in RAW format\n"); - //printf("\tFT1 Configuration\n"); - //printf("\t T v View Status \n"); - //printf("\t s Self Test\n"); - //printf("\t l Line Loop Test\n"); - //printf("\t d Digital Loop Test\n"); - //printf("\t r Remote Test\n"); - //printf("\t o Operational Mode\n"); - printf("\tDriver Statistics\n"); - printf("\t d s Display Send Driver Statistics\n"); - printf("\t i Display Interrupt Driver Statistics\n"); - printf("\t g Display General Driver Statistics\n"); - printf("\tFlush Statistics\n"); - //printf("\t f g Flush Global Statistics\n"); - printf("\t f c Flush Communication Error Statistics\n"); - printf("\t h Flush HDLC Statistics\n"); - //printf("\t i Flush DLCI Statistics\n"); - printf("\t d Flush Driver Statistics\n"); - printf("\tExamples:\n"); - printf("\t--------\n\n"); - printf("\tex: wanpipemon -i wp1_svc1 -u 9000 -c xm :View Modem Status \n"); - printf("\tex: wanpipemon -i 201.1.1.2 -u 9000 -c ti :Trace and Interpret ALL frames\n"); - //printf("\tex: wanpipemon -i wp1_svc1 -u 9000 -c sd -l 1 :Statistics for LCN 1 \n\n"); - return 0; - -}; //usage - -static char *gui_main_menu[]={ -"card_stats_menu","Card Status", -"stats_menu", "Card Statistics", -"trace_menu", "Trace Data", -"driver_menu","Driver Statistics", -"flush_menu","Flush Statistics", -"." -}; - -static char *card_stats_menu[]={ -"xm","Modem Status", -"xl","Link Status", -"xru","Display Router UP time", -"." -}; - - -static char *stats_menu[]={ -"sc","Communication Error Statistics", -"sx","X25 Statistics", -"sh","HDLC Statistics", -"." -}; - -static char *trace_menu[]={ -"ti","Trace and Interpret ALL frames", -"tr","Trace ALL frames, in RAW format", -"." -}; - -static char *driver_menu[]={ -"ds","Display Send Driver Statistics", -"di","Display Interrupt Driver Statistics", -"dg","Display General Driver Statistics", -"." -}; - -static char *flush_menu[]={ -"fc","Flush Communication Error Statistics", -"fh","Flush HDLC Statistics", -"fd","Flush Driver Statistics", -"." -}; - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"card_stats_menu",card_stats_menu}, - {"stats_menu",stats_menu}, - {"trace_menu",trace_menu}, - {"driver_menu",driver_menu}, - {"flush_menu",flush_menu}, - {".",NULL} -}; - - -char ** X25get_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** X25get_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - - - -int X25Main(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - - ResetWanUdp(&wan_udp); - - switch(command[0]){ - - case 'x': - if (!strcmp(opt,"m")){ - modem_status(); - }else if (!strcmp(opt, "l")){ - link_status(); - }else if (!strcmp(opt, "ru")){ - x25_router_up_time(); - }else{ - printf("ERROR: Invalid Status Command 'x', Type wanpipemon for help\n\n"); - } - break; - case 's': - if (!strcmp(opt,"c")){ - comm_err(); - }else if (!strcmp(opt,"x")){ - read_x25_statistics(); - // }else if (!strcmp(opt,"e")){ - // error_stats(); - }else if (!strcmp(opt,"h")){ - read_hdlc_stat(); - }else { - printf("ERROR: Invalid Statistics Command 's', Type wanpipemon for help\n\n"); - } - break; - case 't': - if(!strcmp(opt,"i" )){ - raw_data = WAN_FALSE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "ip")){ - raw_data = WAN_FALSE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "id")){ - raw_data = WAN_FALSE; - line_trace(TRACE_DATA); - }else if (!strcmp(opt, "r")){ - raw_data = WAN_TRUE; - line_trace(TRACE_ALL); - }else if (!strcmp(opt, "rp")){ - raw_data = WAN_TRUE; - line_trace(TRACE_PROT); - }else if (!strcmp(opt, "rd")){ - raw_data = WAN_TRUE; - line_trace(TRACE_DATA); - }else{ - printf("ERROR: Invalid Trace Command 't', Type wanpipemon for help\n\n"); - } - break; - - case 'c': - //if (!strcmp(opt, "l")){ - // list_dlcis(); - //}else{ - printf("ERROR: Invalid Configuration Command 'c', Type wanpipemon for help\n\n"); - - //} - break; - case 'd': - /* Different signature for Driver Statistics */ - if(!strcmp(opt, "s")){ - x25_driver_stat_ifsend(); - }else if (!strcmp(opt, "i")){ - x25_driver_stat_intr(); - }else if (!strcmp(opt, "g")){ - x25_driver_stat_gen(); - }else{ - printf("ERROR: Invalid Driver Statistic 'd', Type wanpipemon for help\n\n"); - } - break; - case 'f': - if (!strcmp(opt, "c")){ - flush_comm_err(); - comm_err(); - }else if (!strcmp(opt, "h")){ - flush_hdlc_stat(); - read_hdlc_stat(); - // }else if (!strcmp(opt, "e")){ - // flush_global_stats(); - // error_stats(); - // }else if (!strcmp(opt, "i")){ - // flush_dlci_stats(); - // read_dlci_stat(); - }else if (!strcmp(opt, "d")){ - flush_driver_stats(); - }else{ - printf("ERROR: Invalid Flush Command 'f', Type wanpipemon for help\n\n"); - } - break; - /* case 'T': - - if (!strcmp(opt, "v")){ - set_FT1_monitor_status(0x01); - if(!fail){ - view_FT1_status(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "s")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_self_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "l")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_ll_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "d")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_dl_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "r")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_rt_test(); - } - set_FT1_monitor_status(0x00); - }else if (!strcmp(opt, "o")){ - set_FT1_monitor_status(0x01); - if(!fail){ - FT1_operational_mode(); - } - set_FT1_monitor_status(0x00); - }else{ - - printf("ERROR: Invalid FT1 Command 'T', Type wanpipemon for help\n\n"); - - } - break; - */ - default: - printf("ERROR: Invalid Command, Type wanpipemon for help\n\n"); - - } //switch - - printf("\n"); - return 0; -}; //main - -/* - * EOF wanpipemon.c - */ diff --git a/util/wanpipemon.old/xpipemon.o b/util/wanpipemon.old/xpipemon.o deleted file mode 100644 index fe6ca0065ca585fb5a64e4b7e52dfb0061e00045..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26780 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 diff --git a/util/wanpipemon.old/zapmon.c b/util/wanpipemon.old/zapmon.c deleted file mode 100644 index f4501dd..0000000 --- a/util/wanpipemon.old/zapmon.c +++ /dev/null @@ -1,627 +0,0 @@ -/***************************************************************************** -* zapmon.c AFT Debugger/Monitor -* -* Author: David Rokhvarg -* -* Copyright: (c) 1984-2005 Sangoma Technologies Inc. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* ---------------------------------------------------------------------------- -* Nov 08, 2004 David Rokhvarg Initial version -*****************************************************************************/ - -/****************************************************************************** - * INCLUDE FILES * - *****************************************************************************/ -#include -#include -#include /* offsetof(), etc. */ -#include -#include -#include /* ctime() */ -#include -#include -#include -#include -#include /* for O_RDWR, O_NONBLOCK */ -#include -#include /* for log10() */ -#if defined(__LINUX__) -# include -# include -# include -# include -# include -# include -#else -#endif -#include "fe_lib.h" -#include "wanpipemon.h" - -/****************************************************************************** - * DEFINES/MACROS * - *****************************************************************************/ -#if LINUX_VERSION_CODE >= 0x020100 -#define LINUX_2_1 -#endif - -#define BANNER(str) banner(str,0) -/****************************************************************************** - * TYPEDEF/STRUCTURE * - *****************************************************************************/ -/* Structures for data casting */ - - - -/****************************************************************************** - * GLOBAL VARIABLES * - *****************************************************************************/ -static int zfd=0; - -int echo_detection_state; -int is_call_active; -int ed_enabled; -unsigned int num_of_echo_absent_calls; -unsigned int num_of_echo_present_calls; - -#ifdef TDMV_SAMPLE_STATE_DECODE -#undef TDMV_SAMPLE_STATE_DECODE -#endif -#define TDMV_SAMPLE_STATE_DECODE(state) \ - ((state == ECHO_PRESENT) ? "On" : \ - (state == ECHO_ABSENT) ? "Off" : \ - (state == INDETERMINATE) ? "?" : "Invalid") - -#define TMP_BUFF_LEN 512 - -static unsigned short u2s[] = { - /* negative */ -0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84, -0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84, -0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84, -0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84, -0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804, -0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004, -0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444, -0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844, -0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64, -0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64, -0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74, -0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74, -0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC, -0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C, -0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0, -0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000, -/* positive */ -0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C, -0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C, -0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C, -0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C, -0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC, -0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC, -0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC, -0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC, -0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C, -0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C, -0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C, -0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C, -0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104, -0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084, -0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040, -0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000 -}; - -#if 1 -//ZAPTEL table -static unsigned short a2s[] = { - -0xEB00, 0xEC00, 0xE900, 0xEA00, 0xEF00, 0xF000, 0xED00, 0xEE00, -0xE300, 0xE400, 0xE100, 0xE200, 0xE700, 0xE800, 0xE500, 0xE600, -0xF580, 0xF600, 0xF480, 0xF500, 0xF780, 0xF800, 0xF680, 0xF700, -0xF180, 0xF200, 0xF080, 0xF100, 0xF380, 0xF400, 0xF280, 0xF300, -0xAC00, 0xB000, 0xA400, 0xA800, 0xBC00, 0xC000, 0xB400, 0xB800, -0x8C00, 0x9000, 0x8400, 0x8800, 0x9C00, 0xA000, 0x9400, 0x9800, -0xD600, 0xD800, 0xD200, 0xD400, 0xDE00, 0xE000, 0xDA00, 0xDC00, -0xC600, 0xC800, 0xC200, 0xC400, 0xCE00, 0xD000, 0xCA00, 0xCC00, -0xFEB0, 0xFEC0, 0xFE90, 0xFEA0, 0xFEF0, 0xFF00, 0xFED0, 0xFEE0, -0xFE30, 0xFE40, 0xFE10, 0xFE20, 0xFE70, 0xFE80, 0xFE50, 0xFE60, -0xFFB0, 0xFFC0, 0xFF90, 0xFFA0, 0xFFF0, 0x0000, 0xFFD0, 0xFFE0, -0xFF30, 0xFF40, 0xFF10, 0xFF20, 0xFF70, 0xFF80, 0xFF50, 0xFF60, -0xFAC0, 0xFB00, 0xFA40, 0xFA80, 0xFBC0, 0xFC00, 0xFB40, 0xFB80, -0xF8C0, 0xF900, 0xF840, 0xF880, 0xF9C0, 0xFA00, 0xF940, 0xF980, -0xFD60, 0xFD80, 0xFD20, 0xFD40, 0xFDE0, 0xFE00, 0xFDA0, 0xFDC0, -0xFC60, 0xFC80, 0xFC20, 0xFC40, 0xFCE0, 0xFD00, 0xFCA0, 0xFCC0, - -0x1500, 0x1400, 0x1700, 0x1600, 0x1100, 0x1000, 0x1300, 0x1200, -0x1D00, 0x1C00, 0x1F00, 0x1E00, 0x1900, 0x1800, 0x1B00, 0x1A00, -0x0A80, 0x0A00, 0x0B80, 0x0B00, 0x0880, 0x0800, 0x0980, 0x0900, -0x0E80, 0x0E00, 0x0F80, 0x0F00, 0x0C80, 0x0C00, 0x0D80, 0x0D00, -0x5400, 0x5000, 0x5C00, 0x5800, 0x4400, 0x4000, 0x4C00, 0x4800, -0x7400, 0x7000, 0x7C00, 0x7800, 0x6400, 0x6000, 0x6C00, 0x6800, -0x2A00, 0x2800, 0x2E00, 0x2C00, 0x2200, 0x2000, 0x2600, 0x2400, -0x3A00, 0x3800, 0x3E00, 0x3C00, 0x3200, 0x3000, 0x3600, 0x3400, -0x0150, 0x0140, 0x0170, 0x0160, 0x0110, 0x0100, 0x0130, 0x0120, -0x01D0, 0x01C0, 0x01F0, 0x01E0, 0x0190, 0x0180, 0x01B0, 0x01A0, -0x0050, 0x0040, 0x0070, 0x0060, 0x0010, 0x0000, 0x0030, 0x0020, -0x00D0, 0x00C0, 0x00F0, 0x00E0, 0x0090, 0x0080, 0x00B0, 0x00A0, -0x0540, 0x0500, 0x05C0, 0x0580, 0x0440, 0x0400, 0x04C0, 0x0480, -0x0740, 0x0700, 0x07C0, 0x0780, 0x0640, 0x0600, 0x06C0, 0x0680, -0x02A0, 0x0280, 0x02E0, 0x02C0, 0x0220, 0x0200, 0x0260, 0x0240, -0x03A0, 0x0380, 0x03E0, 0x03C0, 0x0320, 0x0300, 0x0360, 0x0340 -}; -#endif - -#if 0 -//YATE table -static unsigned short a2s[] = { -/* negative */ -0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80, -0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580, -0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0, -0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0, -0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600, -0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600, -0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00, -0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00, -0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8, -0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58, -0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8, -0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58, -0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60, -0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960, -0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0, -0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0, -/* positive */ -0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280, -0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80, -0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940, -0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40, -0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00, -0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00, -0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500, -0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500, -0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128, -0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8, -0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028, -0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8, -0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0, -0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0, -0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250, -0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350 -}; -#endif - -#define INITIAL_LINEAR_TX_SPIKE 16384 -#define NO 0 -#define YES 1 -#define DB_LOSS_THRESHOLD -45.00//-50.00//-60.00 -#define DB_SILENCE 80.00 - -typedef struct{ - float db_loss; - short linear_power_value; -}db_sample_t; - -db_sample_t db_loss[ECHO_SPIKE_SAMPLE_LEN]; - -/****************************************************************************** - * FUNCTION PROTOTYPES * - *****************************************************************************/ -/* Command routines */ -static int zap_do_command(int echo_detect_ioctl, int channo, void *ioctl_result); - -/* Echo Detect routines */ -static int get_echo_spike(int channo, char sample_taken_after_echo_canceller); -static int send_echo_spike(int channo, unsigned int collect_sample_before_ec); -static void linearize_spike_buffer(unsigned char *spike_buff, int *linearized_buff, int law); -static int write_spike_buffer_to_file(int channo, int spanno, int *linearized_buff, - char sample_taken_after_echo_canceller); -static void summary_of_linear_spike_buffer(int *linearized_buff, - echo_spike_struct_t *echo_spike_struct_ptr, - char sample_taken_after_echo_canceller); -static void proc_sample(unsigned short, int); - - -static void analyze_db_loss(echo_spike_struct_t *echo_spike_struct_ptr, - char sample_taken_after_echo_canceller); -static int usecsleep(int sec, int usecs); - -/*****************************************************************************/ -static char *gui_main_menu[]={ -"zap_status_menu","Zap Status Menu", -"." -}; - -static char *zap_status_menu[]={ -"xz","Zap Status Command", -"." -}; - -static struct cmd_menu_lookup_t gui_cmd_menu_lookup[]={ - {"zap_status_menu",zap_status_menu}, - {".",NULL} -}; - - -char ** ZAPget_main_menu(int *len) -{ - int i=0; - while(strcmp(gui_main_menu[i],".") != 0){ - i++; - } - *len=i/2; - return gui_main_menu; -} - -char ** ZAPget_cmd_menu(char *cmd_name,int *len) -{ - int i=0,j=0; - char **cmd_menu=NULL; - - while(gui_cmd_menu_lookup[i].cmd_menu_ptr != NULL){ - if (strcmp(cmd_name,gui_cmd_menu_lookup[i].cmd_menu_name) == 0){ - cmd_menu=gui_cmd_menu_lookup[i].cmd_menu_ptr; - while (strcmp(cmd_menu[j],".") != 0){ - j++; - } - break; - } - i++; - } - *len=j/2; - return cmd_menu; -} - -/****************************************************************************** - * FUNCTION DEFINITION * - *****************************************************************************/ - -int ZAPUsage(void) -{ - printf("wanpipemon: Wanpipe/Zaptel Debugging Utility\n\n"); - printf("Usage:\n"); - printf("------\n\n"); - printf("wanpipemon -zap -c \n\n"); - printf("\tOption -c: \n"); - printf("\t\tCommand is split into two parts:\n"); - printf("\t\t\tFirst letter is a command and the rest are options:\n"); - printf("\t\t\tex: ses = Send Echo Spike and collect sample.\n\n"); - printf("\tSupported Commands: s=send\n\n"); - printf("\tOption -chanzap: zaptel channel number.\n\n"); - printf("\tCommand: Options: Description \n"); - printf("\t-------------------------------- \n\n"); - printf("\tSend Echo Spike\n"); - printf("\t s es Send Echo Spike\n"); -#if 0 - printf("\t esa Send Echo Spike and collect sample After Echo Canceller\n"); -#endif - printf("\tExample 1: wanpipemon -zap -c ses -zapchan 1 : Send Echo Spike on zap channel 1\n"); -#if 0 - printf("\t\t\tand collect the Echo Spike sample BEFORE echo canceller.\n"); - printf("\tExample 2: wanpipemon -zap -c sesa -zapchan 1 : Send Echo Spike on zap channel 1\n"); - printf("\t\t\tand collect the Echo Spike sample AFTER echo canceller.\n"); -#endif - printf("\n"); - return 0; -} - -int ZAPMain(char *command,int argc, char* argv[]) -{ - char *opt=&command[1]; - int rc=1; - char sample_taken_after_echo_canceller=1; - - /*printf("command: %s\n", command);*/ - - switch(command[0]) - { - case 's': - if (!strcmp(opt,"es")){ - /* send Echo Spike. Collect sample BEFORE Software Echo Canceller. */ - sample_taken_after_echo_canceller = 0; - rc = send_echo_spike(zap_chan, 1); -#if 0 - }else if(!strcmp(opt,"esa")){ - /* send Echo Spike. Collect sample AFTER Software Echo Canceller. */ - sample_taken_after_echo_canceller = 1; - rc = send_echo_spike(zap_chan, 2); -#endif - }else{ - printf("ERROR: Invalid 'send' command.\n\n"); - ZAPUsage(); - } - if(rc == 0){ - /* wait for 1 second for echo to return and get the collected sample */ - usecsleep(1, 0); - get_echo_spike(zap_chan, sample_taken_after_echo_canceller); - } - break; - default: - printf("ERROR: Invalid Command.\n\n"); - ZAPUsage(); - break; - }/*switch*/ - - if(zfd != 0){ - close(zfd); - } - - printf("\n"); - fflush(stdout); - return 0; -}/*ZAPMain()*/ - -int MakeZapConnection() -{ - char *fn = "/dev/zap/channel"; - - /*printf("Openinng: '%s'\n", fn);*/ - - zfd = open(fn, O_RDWR | O_NONBLOCK); - if (zfd < 0) { - printf("Unable to open '%s': %s. Check Zaptel is loaded.\n", - fn, strerror(errno)); - return WAN_FALSE; - } - return WAN_TRUE; -} - -static int zap_do_command(int echo_detect_ioctl, int channo, void *ioctl_result) -{ - /* set the 'channo' in the user buffer */ - *(int*)ioctl_result = channo; - - if (ioctl(zfd, echo_detect_ioctl, ioctl_result)){ - perror("do_echo_detect_ioctl():\n"); - return 1; - }else{ - return 0; - } -} - -static int usecsleep(int sec, int usecs) -{ - struct timeval tv; - tv.tv_sec = sec; - tv.tv_usec = usecs; - return select(0, NULL, NULL, NULL, &tv); -} - -static int write_spike_buffer_to_file(int channo, int spanno, int *linearized_buff, - char sample_taken_after_echo_canceller) -{ - FILE *file; - int ind; - char strbuff[50]; - char log_file_name_buff[TMP_BUFF_LEN]; - - /* 'fir' - finite impulse response */ - if(sample_taken_after_echo_canceller == 1){ - snprintf(log_file_name_buff, TMP_BUFF_LEN, - "/etc/wanpipe/span_%d_chan_%d_after_ec.spike", spanno, channo); - }else{ - snprintf(log_file_name_buff, TMP_BUFF_LEN, - "/etc/wanpipe/span_%d_chan_%d.fir", spanno, channo); - /*"/etc/wanpipe/span_%d_chan_%d_before_ec.spike", spanno, channo);*/ - } - - /* trancate and open the file for writing */ - file = fopen(log_file_name_buff, "w"); - if(file == NULL){ - printf("Failed to open %s file for writing!\n", log_file_name_buff); - return 1; - } - - for(ind = 0; ind < ECHO_SPIKE_SAMPLE_LEN; ind++){ - snprintf(strbuff, 50, "%d\n", linearized_buff[ind]); - fputs(strbuff, file); - }/* for() */ - fclose(file); - - printf("Echo spike was written to '%s' file.\n", log_file_name_buff); - - return 0; -} - -static int send_echo_spike(int channo, unsigned int collect_sample_before_ec) -{ - unsigned char spike_buff[sizeof(echo_spike_struct_t)]; - echo_spike_struct_t *echo_spike_struct_ptr = (echo_spike_struct_t *)spike_buff; - - printf("Sending Echo Spike on channel %d.\n", zap_chan); - - echo_spike_struct_ptr->collect_sample_before_ec = collect_sample_before_ec; - - if(zap_do_command(SEND_ECHO_SPIKE, channo, spike_buff) != 0){ - printf("Command failed on channel %d! Please check kernel messages log.\n", - channo); - return 1; - }else if(echo_spike_struct_ptr->return_code == ECHO_NO_ACTIVE_CALL_OR_EC_OFF){ - printf("Command failed on channel %d! \ -Possible reasons: 1. the 'echocancel' is set to 'no' 2. call is not up.\n", channo); - return 2; - }else{ - ;/* no error. do nothing. may print something but don't have to. */ - printf("Sent Echo Spike. Collecting sample %s SW Echo Canceller...\n", - (collect_sample_before_ec == 1 ? "before" : "after")); - return 0; - } -} - -static int get_echo_spike(int channo, char sample_taken_after_echo_canceller) -{ - static unsigned char spike_buff[sizeof(echo_spike_struct_t) + ECHO_SPIKE_SAMPLE_LEN]; - echo_spike_struct_t *echo_spike_struct_ptr = (echo_spike_struct_t *)spike_buff; - unsigned char *spike_sample_buff_ptr = &spike_buff[sizeof(echo_spike_struct_t)]; - int linearized_buff[ECHO_SPIKE_SAMPLE_LEN]; - - if(zap_do_command(GET_ECHO_SPIKE_SAMPLE, channo, spike_buff)){ - return 1; - } - - if(echo_spike_struct_ptr->return_code == ECHO_OK){ - - linearize_spike_buffer( spike_sample_buff_ptr, - linearized_buff, - echo_spike_struct_ptr->law); - - write_spike_buffer_to_file(channo, - echo_spike_struct_ptr->spanno, - linearized_buff, - sample_taken_after_echo_canceller); - - summary_of_linear_spike_buffer( linearized_buff, - echo_spike_struct_ptr, - sample_taken_after_echo_canceller); - return 0; - }else{ - printf("Command failed on channel %d! \ -Possible reasons: 1. the 'echocancel' is set to 'no' 2. call is not up.\n", channo); - return 1; - } -} - -static void linearize_spike_buffer(unsigned char *spike_buff, int *linearized_buff, int law) -{ - int ind; - unsigned short *linear_table; - - if(law == ZT_LAW_MULAW){ - printf("Using MULAW table...\n"); - linear_table = u2s; - }else{ - printf("Using ALAW table...\n"); - linear_table = a2s; - } - - memset(linearized_buff, 0x00, ECHO_SPIKE_SAMPLE_LEN); - - for(ind = 0; ind < ECHO_SPIKE_SAMPLE_LEN; ind++){ - if(linear_table[spike_buff[ind]] == 0){ - linearized_buff[ind] = 0; - }else if(spike_buff[ind] < 128){ - /* make it negative */ - linearized_buff[ind] = -65535 + linear_table[spike_buff[ind]]; - }else{ - linearized_buff[ind] = linear_table[spike_buff[ind]]; - } - }/* for() */ -} - -static void summary_of_linear_spike_buffer(int *linearized_buff, - echo_spike_struct_t *echo_spike_struct_ptr, - char sample_taken_after_echo_canceller) -{ - int i; - - for(i = 0; i < ECHO_SPIKE_SAMPLE_LEN; i ++) { - proc_sample(linearized_buff[i], i); - } - analyze_db_loss(echo_spike_struct_ptr, sample_taken_after_echo_canceller); -} - -static void proc_sample(unsigned short linear, int sample_no) -{ - unsigned short val; - float d; - float db; - int neg_voltage = NO; - - db_loss[sample_no].linear_power_value = linear; - - if(linear & 0xF000) { - neg_voltage = YES; - val = linear ^ 0xFFFF; - } else { - val = linear; - } - - val = val >> 3; - val &= 0x0FFF; - d = (float)val / (float)(INITIAL_LINEAR_TX_SPIKE >> 3); - - if(d != 0.00) { - db = 20 * log10(d); - } else { - db = -DB_SILENCE; - } - - db_loss[sample_no].db_loss = db; - -/* printf("sample[%04d]%2.5f\n", sample_no, db); */ - return; -} - -static void analyze_db_loss(echo_spike_struct_t *echo_spike_struct_ptr, - char sample_taken_after_echo_canceller) -{ - float min_db_loss = -DB_SILENCE; - int min_db_loss_sample_no=0; - float first_db_loss_th; - int sample_no_first_db_loss_th = 0xFFFF; - float last_db_loss_th; - int sample_no_last_db_loss_th = 0xFFFF; - int i; - - for(i = 0; i < ECHO_SPIKE_SAMPLE_LEN; i ++) { - if(db_loss[i].db_loss > min_db_loss) { - min_db_loss = db_loss[i].db_loss; - min_db_loss_sample_no = i; - } - if(sample_no_first_db_loss_th == 0xFFFF) { - if(db_loss[i].db_loss > DB_LOSS_THRESHOLD) { - sample_no_first_db_loss_th = i; - first_db_loss_th = db_loss[i].db_loss; - } - } - if(db_loss[i].db_loss > DB_LOSS_THRESHOLD) { - last_db_loss_th = db_loss[i].db_loss; - sample_no_last_db_loss_th = i; - } - } - - if(min_db_loss == -DB_SILENCE) { - printf("The line is silent. There is NO Echo on this call.\n"); - }else if(sample_no_first_db_loss_th == 0xFFFF || sample_no_last_db_loss_th == 0xFFFF){ - - if(sample_taken_after_echo_canceller == 1){ - printf("Sample Analysis conclusion: There is NO Echo on this call. OR\n"); - printf("\tIt was removed by the Echo Canceller.\n"); - }else{ - printf("Sample Analysis conclusion: There is NO Echo on this call.\n"); - } - }else { - printf("\nEcho Spike reached it's maximum at sample %d, linear power is %d\n", - min_db_loss_sample_no + 1, - db_loss[min_db_loss_sample_no].linear_power_value); - - printf("First sample containing Echo Spike is %d, linear power is %d\n", - sample_no_first_db_loss_th + 1, - db_loss[sample_no_first_db_loss_th].linear_power_value); - - printf("Last sample containing Echo Spike is %d, linear power is %d\n", - sample_no_last_db_loss_th + 1, - db_loss[sample_no_last_db_loss_th].linear_power_value); - - /* suggest something depending on number of Echo Cancellor taps */ - printf("\nYour Echo Cancellor set to use %d taps.\n", echo_spike_struct_ptr->echocancel); - if(echo_spike_struct_ptr->echocancel < sample_no_first_db_loss_th + 1){ - printf("It can not cancel the echo because delay is longer than %d taps.\n", - echo_spike_struct_ptr->echocancel); - - }else if(echo_spike_struct_ptr->echocancel > sample_no_first_db_loss_th + 1 && - echo_spike_struct_ptr->echocancel < sample_no_last_db_loss_th + 1){ - printf("Echo starts WITHIN %d taps, but ends AFTER %d taps, it means\n\ -echo can not be cancelled completely.\n", - echo_spike_struct_ptr->echocancel, - echo_spike_struct_ptr->echocancel); - }else{ - printf("Echo starts and ends WITHIN %d taps, it should be cancelled properly.\n", - echo_spike_struct_ptr->echocancel); - } - } -} - diff --git a/util/wanpipemon.old/' b/util/wanpipemon/' similarity index 100% rename from util/wanpipemon.old/' rename to util/wanpipemon/' diff --git a/util/wanpipemon/aftpipemon.c b/util/wanpipemon/aftpipemon.c index 362142e..164fe6e 100644 --- a/util/wanpipemon/aftpipemon.c +++ b/util/wanpipemon/aftpipemon.c @@ -46,8 +46,6 @@ # include # include # include -# include - #else # include # include @@ -1406,13 +1404,13 @@ int AFTMain(char *command,int argc, char* argv[]) }else if (strcmp(opt,"regdump") == 0){ aft_remora_regdump(mod_no); }else if (!strcmp(opt,"reg")){ - int value; + long value; fe_debug.type = WAN_FE_DEBUG_REG; if (argc < 6){ printf("ERROR: Invalid command argument!\n"); break; } - value = strtol(argv[5],(char**)NULL, 16); + value = strtol(argv[5],(char**)NULL, 10); if (value == LONG_MIN || value == LONG_MAX){ printf("ERROR: Invalid argument 5: %s!\n", argv[5]); @@ -1420,7 +1418,7 @@ int AFTMain(char *command,int argc, char* argv[]) } fe_debug.fe_debug_reg.reg = value; fe_debug.fe_debug_reg.read = 1; - if (argc > 6){ + if (strcmp(argv[6], "-m") && argc > 6){ value = strtol(argv[6],(char**)NULL, 16); if (value == LONG_MIN || value == LONG_MAX){ printf("ERROR: Invalid argument 6: %s!\n", @@ -1430,7 +1428,8 @@ int AFTMain(char *command,int argc, char* argv[]) fe_debug.fe_debug_reg.read = 0; fe_debug.fe_debug_reg.value = value; } - set_fe_debug_mode(&fe_debug); + fe_debug.mod_no = mod_no; + aft_remora_debug_mode(&fe_debug); }else if (strcmp(opt,"stats") == 0){ aft_remora_stats(mod_no); }else{ diff --git a/util/wanpipemon/atmpipemon.c b/util/wanpipemon/atmpipemon.c index d6b2a3c..ae72448 100644 --- a/util/wanpipemon/atmpipemon.c +++ b/util/wanpipemon/atmpipemon.c @@ -41,7 +41,6 @@ # include # include # include -# include # include # include # include diff --git a/util/wanpipemon/cpipemon.c b/util/wanpipemon/cpipemon.c index ea78c94..d822c80 100644 --- a/util/wanpipemon/cpipemon.c +++ b/util/wanpipemon/cpipemon.c @@ -50,7 +50,6 @@ # include # include # include -# include # include # include #else diff --git a/util/wanpipemon/dslpipemon.c b/util/wanpipemon/dslpipemon.c index e038601..5454938 100644 --- a/util/wanpipemon/dslpipemon.c +++ b/util/wanpipemon/dslpipemon.c @@ -40,7 +40,6 @@ # include # include # include -# include # include # include #else @@ -50,7 +49,6 @@ # include # include # include -# include # include # include #endif @@ -106,6 +104,9 @@ static void router_up_time(void); static void adsl_baud_rate(void); static void adsl_atm_config(void); +void write_register(int argc, char* argv[]); +void read_register(int argc, char* argv[]); + /****************************************************************************** * FUNCTION DEFINITION * *****************************************************************************/ @@ -134,7 +135,7 @@ int ADSLConfig( void ) if (x >= 4) return(WAN_FALSE); - strcpy(codeversion, "?.??"); + strlcpy(codeversion, "?.??", 10); wan_udp.wan_udphdr_command = ADSL_READ_DRIVER_VERSION; wan_udp.wan_udphdr_data_len = 0; @@ -142,7 +143,7 @@ int ADSLConfig( void ) DO_COMMAND(wan_udp); if (wan_udp.wan_udphdr_return_code == 0){ wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); + strlcpy(codeversion, (char*)wan_udp.wan_udphdr_data, 10); } protocol_cb_size=sizeof(wan_mgmt_t) + sizeof(wan_cmd_t) + sizeof(wan_trace_info_t) + 1; return WAN_TRUE; @@ -465,30 +466,36 @@ static void line_trace(unsigned char trace_opt) /* frame type */ if (trace_pkt->status & 0x01) { - sprintf(outstr,"\nOUTGOING\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nOUTGOING\t"); } else { if (trace_pkt->status & 0x10) { - sprintf(outstr,"\nINCOMING - Aborted\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING - Aborted\t"); } else if (trace_pkt->status & 0x20) { - sprintf(outstr,"\nINCOMING - CRC Error\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING - CRC Error\t"); } else if (trace_pkt->status & 0x40) { - sprintf(outstr,"\nINCOMING - Overrun Error\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING - Overrun Error\t"); } else { - sprintf(outstr,"\nINCOMING\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING\t"); } } /* real length and time stamp */ - sprintf(outstr+strlen(outstr), "Len=%-5u\tTimestamp=%-5u\t", + snprintf(outstr+strlen(outstr), + MAX_TRACE_BUF-strlen(outstr), + "Len=%-5u\tTimestamp=%-5u\t", trace_pkt->real_length, trace_pkt->time_stamp); /* first update curr_pos */ curr_pos += sizeof(wan_trace_pkt_t); if (trace_pkt->real_length >= WAN_MAX_DATA_SIZE){ - sprintf( outstr+strlen(outstr), "\t:the frame data is to big (%u)!", + snprintf( outstr+strlen(outstr), + MAX_TRACE_BUF-strlen(outstr), + "\t:the frame data is to big (%u)!", trace_pkt->real_length); }else if (trace_pkt->data_avail == 0) { - sprintf( outstr+strlen(outstr), "\t:the frame data is not available" ); + snprintf( outstr+strlen(outstr), + MAX_TRACE_BUF-strlen(outstr), + "\t:the frame data is not available" ); }else{ /* update curr_pos again */ curr_pos += trace_pkt->real_length; @@ -508,55 +515,57 @@ static void line_trace(unsigned char trace_opt) } count = 0; - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr), + MAX_TRACE_BUF-strlen(outstr), + "\n\t\t"); for( j=0; j40 && !(count%20)){ - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\n\t\t"); } }else{ if (count == 5){ /* - sprintf(outstr+strlen(outstr)," %x %x %x %x", + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr)," %x %x %x %x", trace_pkt->data[j-3], trace_pkt->data[j-2], trace_pkt->data[j-1], trace_pkt->data[j-0]); */ - sprintf(outstr+strlen(outstr),"\tVpi=%d", + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\tVpi=%d", trace_pkt->data[j-4]<<4 | (trace_pkt->data[j-3]&0xF0)>>4); - sprintf(outstr+strlen(outstr),"\tVci=%d", + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\tVci=%d", (trace_pkt->data[j-3]&0x0F)<<12 | (trace_pkt->data[j-2]<<4)| (trace_pkt->data[j-1]&0xF0)>>4); - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\n\t\t"); count=20; }else if (count>20 && !(count%20)){ - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\n\t\t"); } } - sprintf(outstr+strlen(outstr), - "%02X ", + snprintf(outstr+strlen(outstr), + MAX_TRACE_BUF-strlen(outstr),"%02X ", (unsigned char)trace_pkt->data[j]); } if (num_chars < trace_pkt->real_length){ - sprintf(outstr+strlen(outstr),".. "); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),".. "); } outstr[strlen(outstr)-1] = '\0'; @@ -965,8 +974,77 @@ char ** ADSLget_cmd_menu(char *cmd_name,int *len) return cmd_menu; } +void write_register(int argc, char* argv[]) +{ + int i; + unsigned int offset=0; + unsigned int data=0; + int cnt=0; + + for (i = 0; i < argc; i++){ + if (!strcmp(argv[i],"-offset")){ + if (argc > (i+1)) { + sscanf(argv[i+1],"%x",&offset); + cnt++; + } + } else if (!strcmp(argv[i],"-data")){ + if (argc > (i+1)) { + sscanf(argv[i+1],"%x",&data); + cnt++; + } + } + } + + if (cnt != 2) { + printf ("Error usage: wanpipemon -i -c cwr -offset -data \n"); + return; + } + + wan_udp.wan_udphdr_command= ADSL_EEPROM_WRITE; + wan_udp.wan_udphdr_return_code = 0xaa; + wan_udp.wan_udphdr_data_len = 2; + wan_udp.wan_udphdr_data[0] =offset; + wan_udp.wan_udphdr_data[1] = data; + DO_COMMAND(wan_udp); + + BANNER("WRITE REGISTER"); + + printf("Write Offset=0x%X Val=0x%X\n",offset,data); + +} +void read_register(int argc, char* argv[]) +{ + int i; + unsigned int offset=0; + int cnt=0; + + for (i = 0; i < argc; i++){ + if (!strcmp(argv[i],"-offset")){ + if (argc > (i+1)) { + sscanf(argv[i+1],"%x",&offset); + cnt++; + } + } + } + + if (cnt != 1) { + printf ("Error usage: wanpipemon -i -c crr -offset \n"); + return; + } + + wan_udp.wan_udphdr_command= ADSL_EEPROM_READ; + wan_udp.wan_udphdr_return_code = 0xaa; + wan_udp.wan_udphdr_data_len = 1; + wan_udp.wan_udphdr_data[0] =offset; + DO_COMMAND(wan_udp); + + BANNER("READ REGISTER"); + + printf("Read Offset=0x%X Val=0x%X\n",offset,wan_udp.wan_udphdr_data[0]); + +} int ADSLMain(char* command, int argc, char* argv[]) { @@ -996,6 +1074,10 @@ int ADSLMain(char* command, int argc, char* argv[]) interleave_status(); }else if (!strcmp(opt,"rvi")){ remove_vendor_id(); + }else if (!strcmp(opt,"wr")){ + write_register(argc,argv); + }else if (!strcmp(opt,"rr")){ + read_register(argc,argv); }else{ printf("ERROR: Invalid Status Command 'c', Type wanpipemon for help\n\n"); } diff --git a/util/wanpipemon/isdn.pcap b/util/wanpipemon/isdn.pcap deleted file mode 100644 index e69de29..0000000 diff --git a/util/wanpipemon/prot_trace.c b/util/wanpipemon/prot_trace.c index 577bdbf..2b425e8 100644 --- a/util/wanpipemon/prot_trace.c +++ b/util/wanpipemon/prot_trace.c @@ -1523,8 +1523,8 @@ static void print_pcap_record_header(wp_trace_output_iface_t *trace_iface) struct pcaprec_hdr ph; /* Write PCap header */ - ph.ts_sec = trace_iface->sec; - ph.ts_usec = trace_iface->usec; + ph.ts_sec = trace_iface->pkts_written; + ph.ts_usec = trace_iface->pkts_written; ph.incl_len = trace_iface->len; ph.orig_len = trace_iface->len; @@ -1749,39 +1749,11 @@ static int decode_ppp(wp_trace_output_iface_t *trace_iface, } -#ifndef ETH_P_LAPD -#define ETH_P_LAPD 0x0030 -#endif - -#define LAPD_SLL_PKTTYPE_OFFSET 0 /* packet type - 2 bytes */ -#define LAPD_SLL_HATYPE_OFFSET 2 /* hardware address type - 2 bytes */ -#define LAPD_SLL_HALEN_OFFSET 4 /* hardware address length - 2 bytes */ -#define LAPD_SLL_ADDR_OFFSET 6 /* address - 8 bytes */ -#define LAPD_SLL_PROTOCOL_OFFSET 14 /* protocol, should be ETH_P_LAPD - 2 bytes */ -#define LAPD_SLL_LEN 16 /* length of the header */ - -#undef phtons -#define phtons(p, v) \ - { \ - ((uint8_t*)(p))[0] = (uint8_t)((v) >> 8); \ - ((uint8_t*)(p))[1] = (uint8_t)((v) >> 0); \ - } - -#undef pntohs -#define pntohs(p) ((guint16) \ - ((guint16)*((const uint8_t *)(p)+0)<<8| \ - (guint16)*((const uint8_t *)(p)+1)<<0)) - - - void wp_trace_output(wp_trace_output_iface_t *trace_iface) { //int num_chars; //int j; int trace_started=0; - uint8_t lapd_hdr[LAPD_SLL_LEN]; - - memset(lapd_hdr,0,sizeof(lapd_hdr)); try_trace_again: @@ -1880,44 +1852,13 @@ try_trace_again: } print_pcap_file_header(trace_iface); - - if (pcap_prot == 177) { - printf("Staring PCAP Prot=ISDN Reference=%s File Trace in: %s\n\n", - pcap_isdn_network?"Net":"CPE", pcap_output_file_name); - }else{ - printf("Staring PCAP Prot=%i File Trace in: %s\n\n", - pcap_prot, pcap_output_file_name); - } - - - + printf("Staring PCAP File Trace in: %s\n\n", + pcap_output_file_name); trace_iface->init=1; } - - if (pcap_prot == 177) { - if (trace_iface->status) { - /* Outgoing */ - phtons(&lapd_hdr[LAPD_SLL_PKTTYPE_OFFSET], 4); //pseudo_header->lapd.pkttype); - } else { - /* Incoming */ - phtons(&lapd_hdr[LAPD_SLL_PKTTYPE_OFFSET], 0); //pseudo_header->lapd.pkttype); - } - phtons(&lapd_hdr[LAPD_SLL_PROTOCOL_OFFSET], ETH_P_LAPD); - - /* User specified Network or CPE */ - lapd_hdr[LAPD_SLL_ADDR_OFFSET + 0] = pcap_isdn_network; //pseudo_header->lapd.we_network?0x01:0x00; - - trace_iface->len += sizeof(lapd_hdr); - } - print_pcap_record_header(trace_iface); - if (pcap_prot == 177) { - fwrite(&lapd_hdr[0], sizeof(lapd_hdr), 1, trace_iface->output_file); - trace_iface->len -= sizeof(lapd_hdr); - } - fwrite(&trace_iface->data[0], trace_iface->len, 1, trace_iface->output_file); printf("\rTotal Captured=%-5u (Len=%i)",trace_iface->pkts_written+1,trace_iface->len); diff --git a/util/wanpipemon/trace.pcap b/util/wanpipemon/trace.pcap deleted file mode 100644 index a082b598fde262e16a817ac0242b4d44063a150e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3528 zcmZwKT}Tvh6b10vSv3Vy3<Tq^0GSrTnS!vIQGGIC|1{N<;=gi;X%74%4`J9!V(noQy+4nL-xL8v3#0^ z?N==K@%-6h>Pwf|r8EnxRIGsdkh@Oj-6ZCwS=dR%im4B|57f6!%ulnhe#Ly$hg{sS z{T}QR`$Ds@ImNoD4>=dzzdd3J53Ijo$ol|Rt5_fPA(uq^xy8b078a}6AoU?vOZ!!c z@x6k*qw~VXsSlP-`<)Q0p;_2@#gh80`+|QT$ep3S2C-h6g^en?70(N^Z_LX*lg;5`@g!*8==>B~a<6U4y)CVi0K3ERzHzoFi_Jb8tAFPu4VAUh` z^G=Jsp;_33VuAkov(Kq-PG%#!tQ?*%Y?)$jsSi2xr8SFZ6w)N0WwZ0D%MN0u-A&+pg!bA>AXI% zCYps^Q_N3&$VJh9x5WlFIE`%iE`pcoC@l>)4Kp;v>219g=WK7RPc*%a$qTy*4px=B zm*-Y{4pdegja=bfmzj~7m6^6NE$vun`&#)yRd%T}_$3ElW#qqC7wn4LX++8Ico~jT zSGegl%{b@%#(G@skgG`l{qhr>7_V{~i^T9U9IoKRg5X4=S>J%E&yt9ci+Gt1R~c50 k#)alOt4>1)) -#endif - -#ifndef LONG_MIN -#define LONG_MIN (-LONG_MAX - 1) -#endif - - //extern void decode_pkt (unsigned char *data,int len, // unsigned char status, unsigned int timestamp, int protocol); diff --git a/util/wanpipemon/wanpipemon_api.tgz b/util/wanpipemon/wanpipemon_api.tgz new file mode 100644 index 0000000000000000000000000000000000000000..6edab762cdff729b72e161e416f465a4fade7da3 GIT binary patch literal 5952 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 literal 0 HcmV?d00001 diff --git a/util/wanpipemon.old/wp_trace_pcap.bin b/util/wanpipemon/wp_trace_pcap.bin similarity index 100% rename from util/wanpipemon.old/wp_trace_pcap.bin rename to util/wanpipemon/wp_trace_pcap.bin diff --git a/util/wanpipemon_legacy/aftpipemon.c b/util/wanpipemon_legacy/aftpipemon.c index c98cc29..859fe9d 100644 --- a/util/wanpipemon_legacy/aftpipemon.c +++ b/util/wanpipemon_legacy/aftpipemon.c @@ -41,13 +41,11 @@ # include # include # include -# include # include # include #else # include # include -# include # include # include #endif @@ -210,7 +208,7 @@ int AFTConfig(void) is_508 = WAN_FALSE; - strcpy(codeversion, "?.??"); + strlcpy(codeversion, "?.??", 10); wan_udp.wan_udphdr_command = READ_CODE_VERSION; wan_udp.wan_udphdr_data_len = 0; @@ -218,7 +216,7 @@ int AFTConfig(void) DO_COMMAND(wan_udp); if (wan_udp.wan_udphdr_return_code == 0) { wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); + strlcpy(codeversion, (char*)wan_udp.wan_udphdr_data, 10); } return(WAN_TRUE); diff --git a/util/wanpipemon_legacy/atmpipemon.c b/util/wanpipemon_legacy/atmpipemon.c index 41569ea..969bc2c 100644 --- a/util/wanpipemon_legacy/atmpipemon.c +++ b/util/wanpipemon_legacy/atmpipemon.c @@ -42,13 +42,11 @@ # include # include # include -# include # include # include #else # include # include -# include # include # include #endif @@ -160,8 +158,8 @@ static void set_FT1_monitor_status( unsigned char); static void read_ft1_te1_56k_config( void ); /* Other routines */ -static int get_cell_type(unsigned char* data, int len); -void decode_user_data_cell(char* data, int len); +static int get_cell_type(char* data, int len); +void decode_user_data_cell(unsigned char* data, int len); static char *gui_main_menu[]={ "atm_card_stats_menu","Card Status", @@ -290,7 +288,7 @@ int ATMConfig(void) is_508 = WAN_FALSE; } - strcpy(codeversion, "?.??"); + strlcpy(codeversion, "?.??", 10); wan_udp.wan_udphdr_command = READ_CODE_VERSION; wan_udp.wan_udphdr_data_len = 0; @@ -298,7 +296,7 @@ int ATMConfig(void) DO_COMMAND(wan_udp); if (wan_udp.wan_udphdr_return_code == 0) { wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); + strlcpy(codeversion, (char*)wan_udp.wan_udphdr_data, 10); } return(WAN_TRUE); @@ -853,10 +851,10 @@ static void line_trace( int trace_mode, int trace_sub_type) printf("Cell Type: "); - switch(get_cell_type(trace_pkt->data, trace_pkt->real_length)) + switch(get_cell_type((char*)trace_pkt->data, trace_pkt->real_length)) { case ATM_USER_DATA_CELL: - decode_user_data_cell((char*)trace_pkt->data, + decode_user_data_cell(trace_pkt->data, trace_pkt->real_length); break; default: @@ -890,7 +888,7 @@ static void line_trace( int trace_mode, int trace_sub_type) }; /* line_trace */ -static int get_cell_type(unsigned char* data, int len) +static int get_cell_type(char* data, int len) { ATM_HEADER_STRUCT * atm_hdr_ptr = (ATM_HEADER_STRUCT * )data; ATM_CELL_STRUCT * ATM_cell_ptr = (ATM_CELL_STRUCT * )data; @@ -958,7 +956,7 @@ static int get_cell_type(unsigned char* data, int len) return ATM_UNKNOWN_CELL; } -void decode_user_data_cell(char* data, int len) +void decode_user_data_cell(unsigned char* data, int len) { int i; unsigned char* puchar_tmp; diff --git a/util/wanpipemon_legacy/cpipemon.c b/util/wanpipemon_legacy/cpipemon.c index 6db1ade..6ec3da0 100644 --- a/util/wanpipemon_legacy/cpipemon.c +++ b/util/wanpipemon_legacy/cpipemon.c @@ -47,13 +47,11 @@ # include # include # include -# include # include # include #else # include # include -# include # include # include #endif @@ -269,7 +267,7 @@ int CHDLCConfig(void) is_508 = WAN_FALSE; } - strcpy(codeversion, "?.??"); + strlcpy(codeversion, "?.??", 10); wan_udp.wan_udphdr_command = READ_CHDLC_CODE_VERSION; wan_udp.wan_udphdr_data_len = 0; @@ -277,7 +275,7 @@ int CHDLCConfig(void) DO_COMMAND(wan_udp); if (wan_udp.wan_udphdr_return_code == 0) { wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); + strlcpy(codeversion, (char*)wan_udp.wan_udphdr_data,10); } return(WAN_TRUE); diff --git a/util/wanpipemon_legacy/docommand.c b/util/wanpipemon_legacy/docommand.c index 95ba96d..d6ac4ed 100644 --- a/util/wanpipemon_legacy/docommand.c +++ b/util/wanpipemon_legacy/docommand.c @@ -125,7 +125,7 @@ int MakeRawConnection( void ) soin.sll_family = AF_PACKET; soin.sll_protocol = htons(ETH_P_IP); - strcpy (ifr.ifr_name,i_name); + strlcpy (ifr.ifr_name,i_name,WAN_IFNAME_SZ); if (ioctl(sock,SIOCGIFINDEX,&ifr) <0){ perror("Ioctl: "); return (WAN_FALSE); @@ -178,7 +178,7 @@ unsigned char DoCommand(void* pkt, int data_len) udp_pkt.wp_mgmt.id=id; ifr.ifr_data = (void*)&udp_pkt; - strcpy (ifr.ifr_name,i_name); + strlcpy (ifr.ifr_name,i_name,WAN_IFNAME_SZ); ioctl(sock,SIOC_WANPIPE_PIPEMON,&ifr); if (err < 0){ diff --git a/util/wanpipemon_legacy/dslpipemon.c b/util/wanpipemon_legacy/dslpipemon.c index 0d07906..1736eba 100644 --- a/util/wanpipemon_legacy/dslpipemon.c +++ b/util/wanpipemon_legacy/dslpipemon.c @@ -40,7 +40,6 @@ # include # include # include -# include # include # include #else @@ -50,7 +49,6 @@ # include # include # include -# include # include # include #endif @@ -134,7 +132,7 @@ int ADSLConfig( void ) if (x >= 4) return(FALSE); - strcpy(codeversion, "?.??"); + strlcpy(codeversion, "?.??", 10); wan_udp.wan_udphdr_command = ADSL_READ_DRIVER_VERSION; wan_udp.wan_udphdr_data_len = 0; @@ -142,7 +140,7 @@ int ADSLConfig( void ) DO_COMMAND(wan_udp); if (wan_udp.wan_udphdr_return_code == 0){ wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); + strlcpy(codeversion, (char*)wan_udp.wan_udphdr_data, 10); } protocol_cb_size=sizeof(wan_mgmt_t) + sizeof(wan_cmd_t) + sizeof(wan_trace_info_t) + 1; return TRUE; @@ -465,30 +463,33 @@ static void line_trace(unsigned char trace_opt) /* frame type */ if (trace_pkt->status & 0x01) { - sprintf(outstr,"\nOUTGOING\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nOUTGOING\t"); } else { if (trace_pkt->status & 0x10) { - sprintf(outstr,"\nINCOMING - Aborted\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING - Aborted\t"); } else if (trace_pkt->status & 0x20) { - sprintf(outstr,"\nINCOMING - CRC Error\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING - CRC Error\t"); } else if (trace_pkt->status & 0x40) { - sprintf(outstr,"\nINCOMING - Overrun Error\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING - Overrun Error\t"); } else { - sprintf(outstr,"\nINCOMING\t"); + snprintf(outstr,MAX_TRACE_BUF,"\nINCOMING\t"); } } /* real length and time stamp */ - sprintf(outstr+strlen(outstr), "Len=%-5u\tTimestamp=%-5u\t", + snprintf(outstr+strlen(outstr), MAX_TRACE_BUF-strlen(outstr), + "Len=%-5u\tTimestamp=%-5u\t", trace_pkt->real_length, trace_pkt->time_stamp); /* first update curr_pos */ curr_pos += sizeof(wan_trace_pkt_t); if (trace_pkt->real_length >= WAN_MAX_DATA_SIZE){ - sprintf( outstr+strlen(outstr), "\t:the frame data is to big (%u)!", + snprintf( outstr+strlen(outstr), MAX_TRACE_BUF-strlen(outstr), + "\t:the frame data is to big (%u)!", trace_pkt->real_length); }else if (trace_pkt->data_avail == 0) { - sprintf( outstr+strlen(outstr), "\t:the frame data is not available" ); + snprintf( outstr+strlen(outstr), MAX_TRACE_BUF-strlen(outstr), + "\t:the frame data is not available" ); }else{ /* update curr_pos again */ curr_pos += trace_pkt->real_length; @@ -508,18 +509,18 @@ static void line_trace(unsigned char trace_opt) } count = 0; - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\n\t\t"); for( j=0; j40 && !(count%20)){ - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\n\t\t"); } }else{ if (count == 5){ @@ -532,31 +533,33 @@ static void line_trace(unsigned char trace_opt) trace_pkt->data[j-0]); */ - sprintf(outstr+strlen(outstr),"\tVpi=%d", + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr), + "\tVpi=%d", trace_pkt->data[j-4]<<4 | (trace_pkt->data[j-3]&0xF0)>>4); - sprintf(outstr+strlen(outstr),"\tVci=%d", + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\tVci=%d", (trace_pkt->data[j-3]&0x0F)<<12 | (trace_pkt->data[j-2]<<4)| (trace_pkt->data[j-1]&0xF0)>>4); - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\n\t\t"); count=20; }else if (count>20 && !(count%20)){ - sprintf(outstr+strlen(outstr),"\n\t\t"); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr),"\n\t\t"); } } - sprintf(outstr+strlen(outstr), + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr), "%02X ", (unsigned char)trace_pkt->data[j]); } if (num_chars < trace_pkt->real_length){ - sprintf(outstr+strlen(outstr),".. "); + snprintf(outstr+strlen(outstr),MAX_TRACE_BUF-strlen(outstr), + ".. "); } outstr[strlen(outstr)-1] = '\0'; diff --git a/util/wanpipemon_legacy/fpipemon.c b/util/wanpipemon_legacy/fpipemon.c index f87d75a..ee4b54c 100644 --- a/util/wanpipemon_legacy/fpipemon.c +++ b/util/wanpipemon_legacy/fpipemon.c @@ -274,7 +274,7 @@ int FRConfig( void ) if (x >= 4) return(WAN_FALSE); station_config = wan_udp.wan_udphdr_data[0]; - strcpy(codeversion, "?.??"); + strlcpy(codeversion, "?.??", 10); wan_udp.wan_udphdr_command = FR_READ_CODE_VERSION; wan_udp.wan_udphdr_return_code = 0xaa; @@ -283,7 +283,7 @@ int FRConfig( void ) if (wan_udp.wan_udphdr_return_code == 0) { wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); + strlcpy(codeversion, (char*)wan_udp.wan_udphdr_data, 10); } return(WAN_TRUE); @@ -890,12 +890,12 @@ static void list_all_dlcis(void) for (i=1;i # include -# include # include # include #else @@ -51,7 +50,6 @@ # include # include # include -# include # include # include #endif @@ -144,7 +142,7 @@ int PPPConfig( void ) is_508 = WAN_FALSE; } - strcpy(codeversion, "?.??"); + strlcpy(codeversion, "?.??", 10); wan_udp.wan_udphdr_command = PPP_READ_CODE_VERSION; wan_udp.wan_udphdr_return_code = 0xaa; @@ -153,7 +151,7 @@ int PPPConfig( void ) if (wan_udp.wan_udphdr_return_code == 0) { wan_udp.wan_udphdr_data[wan_udp.wan_udphdr_data_len] = 0; - strcpy(codeversion, (char*)wan_udp.wan_udphdr_data); + strlcpy(codeversion, (char*)wan_udp.wan_udphdr_data, 10); } return(WAN_TRUE); diff --git a/util/wanpipemon_legacy/prot_trace.c b/util/wanpipemon_legacy/prot_trace.c index 57b1ce6..98a2c8b 100644 --- a/util/wanpipemon_legacy/prot_trace.c +++ b/util/wanpipemon_legacy/prot_trace.c @@ -19,7 +19,6 @@ # include # include # include -# include # include #else # include @@ -27,7 +26,6 @@ # include # include # include -# include # include # include #endif @@ -112,7 +110,7 @@ void trace_banner (wp_trace_output_iface_t *trace_iface, int *trace_started) date_string[0] = '\0'; - sprintf(date_string, "%5d", timestamp); + snprintf(date_string, 100, "%5d", timestamp); if (trace_iface->sec){ char tmp_time[50]; @@ -123,21 +121,21 @@ void trace_banner (wp_trace_output_iface_t *trace_iface, int *trace_started) time_tm = localtime(&time_val); strftime(tmp_time,sizeof(tmp_time)," %b",time_tm); - sprintf(date_string+strlen(date_string), " %s ",tmp_time); + snprintf(date_string+strlen(date_string), 100-strlen(date_string)," %s ",tmp_time); strftime(tmp_time,sizeof(tmp_time),"%d",time_tm); - sprintf(date_string+strlen(date_string), "%s ",tmp_time); + snprintf(date_string+strlen(date_string), 100-strlen(date_string),"%s ",tmp_time); strftime(tmp_time,sizeof(tmp_time),"%H",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); + snprintf(date_string+strlen(date_string), 100-strlen(date_string),"%s:",tmp_time); strftime(tmp_time,sizeof(tmp_time),"%M",time_tm); - sprintf(date_string+strlen(date_string), "%s:",tmp_time); + snprintf(date_string+strlen(date_string), 100-strlen(date_string),"%s:",tmp_time); strftime(tmp_time,sizeof(tmp_time),"%S",time_tm); - sprintf(date_string+strlen(date_string), "%s",tmp_time); + snprintf(date_string+strlen(date_string), 100-strlen(date_string),"%s",tmp_time); - sprintf(date_string+strlen(date_string), " %-6lu [1/100s]",trace_iface->usec ); + snprintf(date_string+strlen(date_string), 100-strlen(date_string)," %-6lu [1/100s]",(unsigned long)trace_iface->usec ); } printf("\n%s\tLen=%d\tTimeStamp=%s\n", @@ -329,7 +327,7 @@ static char *clear_code(unsigned char code) if (code == 0x39) return "Destination Absent"; - sprintf(buffer, "Unknown %02X", code); + snprintf(buffer, 25, "Unknown %02X", code); return buffer; } @@ -556,7 +554,7 @@ static char *clear_diag(unsigned char code) if (code == 250) return "Reset - user resynchronization"; - sprintf(buffer, "Unknown %d", code); + snprintf(buffer, 25, "Unknown %d", code); return buffer; } @@ -760,12 +758,6 @@ static int decode_data_ipv4(unsigned char* data, unsigned short data_len) case IPPROTO_RAW: /* 255 */ printf("Raw IP packets"); break; - -#if 0 - case IPPROTO_MAX: - printf("IPPROTO_MAX"); - break; -#endif default: printf("Unknown (%d)\n", ip_hdr->w_ip_p); @@ -1528,7 +1520,7 @@ static void print_pcap_record_header(wp_trace_output_iface_t *trace_iface) fwrite(&ph, sizeof(ph), 1, trace_iface->output_file); } -static void get_ppp_magic_number(unsigned char* data, int len, char* outstr, char offset_flag) +static void get_ppp_magic_number(unsigned char* data, int len, char* outstr, int max_len, char offset_flag) { if(offset_flag == 0){ @@ -1536,7 +1528,7 @@ static void get_ppp_magic_number(unsigned char* data, int len, char* outstr, cha printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); return; } - sprintf(outstr, "\tMagic# %02X%02X%02X%02X", + snprintf(outstr, max_len, "\tMagic# %02X%02X%02X%02X", (unsigned char)data[8], (unsigned char)data[9], (unsigned char)data[10], (unsigned char)data[11]); }else{ @@ -1545,12 +1537,13 @@ static void get_ppp_magic_number(unsigned char* data, int len, char* outstr, cha printf("%s invalid buffer length. Line: %d\n", __FUNCTION__, __LINE__); return; } - sprintf(outstr, "\tMagic# %02X%02X%02X%02X", + snprintf(outstr, max_len, "\tMagic# %02X%02X%02X%02X", (unsigned char)data[8+2], (unsigned char)data[8+3], (unsigned char)data[8+4], (unsigned char)data[8+5]); } } +#define MAX_OUTSTR_LEN 1024 static int decode_ppp(wp_trace_output_iface_t *trace_iface, int *trace_started) { @@ -1558,10 +1551,10 @@ static int decode_ppp(wp_trace_output_iface_t *trace_iface, int len = trace_iface->len; int inf_frame=0; unsigned short tmp_ushort; - char outstr[1024]; + char outstr[MAX_OUTSTR_LEN]; trace_banner(trace_iface,trace_started); - memset(outstr, 0x00, 1024); + memset(outstr, 0x00, MAX_OUTSTR_LEN); //print the data (including PPP header) print_data_in_hex(data, len); @@ -1587,58 +1580,58 @@ static int decode_ppp(wp_trace_output_iface_t *trace_iface, //pre-decodeing if (tmp_ushort == 0x2180){ - sprintf(outstr+strlen(outstr), "IPCP-v4 packet - "); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"IPCP-v4 packet - "); } if (tmp_ushort == 0x5780){ - sprintf(outstr+strlen(outstr), "IPCP-v6 packet - "); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"IPCP-v6 packet - "); } if (tmp_ushort == 0x2B80){ - sprintf(outstr+strlen(outstr), "IPXCP packet - "); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"IPXCP packet - "); } if (tmp_ushort == 0x21C0){ - sprintf(outstr+strlen(outstr), "LCP packet\tID 0x%02X - ", data[5]); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"LCP packet\tID 0x%02X - ", data[5]); } //common decoding switch(data[4]) { case 1: - sprintf(outstr+strlen(outstr), "Configure Request"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Configure Request"); break; case 2: - sprintf(outstr+strlen(outstr), "Configure Ack\t"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Configure Ack\t"); break; case 3: - sprintf(outstr+strlen(outstr), "Configure Nack\t"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Configure Nack\t"); break; case 4: - sprintf(outstr+strlen(outstr), "Configure Reject"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Configure Reject"); break; case 5: - sprintf(outstr+strlen(outstr), "Terminate Request"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Terminate Request"); break; case 6: - sprintf(outstr+strlen(outstr), "Terminate Ack\t"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Terminate Ack\t"); break; case 7: - sprintf(outstr+strlen(outstr), "Code Reject\t"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Code Reject\t"); break; case 8: - sprintf(outstr+strlen(outstr), "Protocol Reject"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Protocol Reject"); break; case 9: - sprintf(outstr+strlen(outstr), "Echo Request\t"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Echo Request\t"); break; case 10: - sprintf(outstr+strlen(outstr), "Echo Reply\t"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Echo Reply\t"); break; case 11: - sprintf(outstr+strlen(outstr), "Discard Request"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Discard Request"); break; default: - sprintf(outstr+strlen(outstr), "Unknown type"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Unknown type"); break; } @@ -1647,16 +1640,24 @@ static int decode_ppp(wp_trace_output_iface_t *trace_iface, //LCP switch(data[4]) { case 1: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); + get_ppp_magic_number( + data, len, + outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),1); break; case 2: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); + get_ppp_magic_number( + data, len, + outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),1); break; case 3: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); + get_ppp_magic_number( + data, len, + outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),1); break; case 4: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 1); + get_ppp_magic_number( + data, len, + outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),1); break; case 5: case 6: @@ -1665,13 +1666,19 @@ static int decode_ppp(wp_trace_output_iface_t *trace_iface, ;//do nothing break; case 9: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); + get_ppp_magic_number( + data, len, + outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),0); break; case 10: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); + get_ppp_magic_number( + data, len, + outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),0); break; case 11: - get_ppp_magic_number(data, len, outstr+strlen(outstr), 0); + get_ppp_magic_number( + data, len, + outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),0); break; default: break; @@ -1680,47 +1687,47 @@ static int decode_ppp(wp_trace_output_iface_t *trace_iface, break; case 0x23C0: // PAP - sprintf(outstr+strlen(outstr), "PAP packet - "); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"PAP packet - "); switch(data[4]) { case 1: - sprintf(outstr+strlen(outstr), "Authenticate Request"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Authenticate Request"); break; case 2: - sprintf(outstr+strlen(outstr), "Authenticate Ack"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Authenticate Ack"); break; case 3: - sprintf(outstr+strlen(outstr), "Authenticate Nack"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Authenticate Nack"); break; default: - sprintf(outstr+strlen(outstr), "Unknown type"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Unknown type"); break; } break; case 0x25C0: // LQR - sprintf(outstr+strlen(outstr), "Link Quality Report"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Link Quality Report"); break; case 0x23C2: // CHAP - sprintf(outstr+strlen(outstr), "CHAP packet - "); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"CHAP packet - "); switch(data[4]) { case 1: - sprintf(outstr+strlen(outstr), "Challenge"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Challenge"); break; case 2: - sprintf(outstr+strlen(outstr), "Responce"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Responce"); break; case 3: - sprintf(outstr+strlen(outstr), "Success"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Success"); break; case 4: - sprintf(outstr+strlen(outstr), "Failure"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Failure"); break; default: - sprintf(outstr+strlen(outstr), "Unknown type"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Unknown type"); break; } break; default: // unknown - sprintf(outstr+strlen(outstr), "Unknown type"); + snprintf(outstr+strlen(outstr), MAX_OUTSTR_LEN-strlen(outstr),"Unknown type"); break; } diff --git a/util/wanpipemon_legacy/wangui.c b/util/wanpipemon_legacy/wangui.c index 9911508..3f367d6 100644 --- a/util/wanpipemon_legacy/wangui.c +++ b/util/wanpipemon_legacy/wangui.c @@ -161,9 +161,9 @@ static int wan_if_ip_menu(void) return -1; } - sprintf(current, "lo"); - sprintf(title,"Operation Mode Seleciton"); - sprintf(prompt,"Local System: device resides on the server, if name needed. Remote System: device resides on the network, thus ip address needed"); + snprintf(current, 100, "lo"); + snprintf(title,100,"Operation Mode Seleciton"); + snprintf(prompt,100,"Local System: device resides on the server, if name needed. Remote System: device resides on the network, thus ip address needed"); memset(data,0,100); @@ -216,8 +216,8 @@ static int wan_ip_menu(void) return -1; } - sprintf(title,"IP Address Setup"); - sprintf(prompt,"Specify a remote IP address"); + snprintf(title,100,"IP Address Setup"); + snprintf(prompt,100,"Specify a remote IP address"); if (!(pid=fork())){ @@ -241,7 +241,7 @@ static int wan_ip_menu(void) if (stat==SELECT_OK){ struct in_addr *ip_str = NULL; - strcpy(ipaddress,data); + strlcpy(ipaddress,data, 16); if (inet_aton(ipaddress,ip_str) != 0 ){ ip_addr = WAN_TRUE; }else{ @@ -251,8 +251,8 @@ static int wan_ip_menu(void) return -1; } - sprintf(title,"UPD Port Setup"); - sprintf(prompt,"Specify remote UPD port"); + snprintf(title,100,"UPD Port Setup"); + snprintf(prompt,100,"Specify remote UPD port"); if (!(pid=fork())){ @@ -374,9 +374,9 @@ static int wan_iface_menu(void) return -1; } - sprintf(current, "lo"); - sprintf(title,"Interface Selection"); - sprintf(prompt,"Please select a WANPIPE interface using UP and DOWN keys"); + snprintf(current,100,"lo"); + snprintf(title,100,"Interface Selection"); + snprintf(prompt,100,"Please select a WANPIPE interface using UP and DOWN keys"); memset(data,0,100); @@ -418,7 +418,7 @@ static int wan_iface_menu(void) close(pipefds[1]); if (stat == SELECT_OK){ - strcpy(if_name,data); + strlcpy(if_name,data, WAN_IFNAME_SZ); ip_addr=WAN_FALSE; return 0; } @@ -443,9 +443,9 @@ static void wan_main_menu(void) return; } - sprintf(current, "A"); - sprintf(title,"Command Main Menu"); - sprintf(prompt,"Select one of the command sections"); + snprintf(current,100,"A"); + snprintf(title,100,"Command Main Menu"); + snprintf(prompt,100,"Select one of the command sections"); for (;;){ memset(data,0,100); diff --git a/util/wanpipemon_legacy/wanpipemon.h b/util/wanpipemon_legacy/wanpipemon.h index 08097b3..b29b7a7 100644 --- a/util/wanpipemon_legacy/wanpipemon.h +++ b/util/wanpipemon_legacy/wanpipemon.h @@ -341,7 +341,7 @@ static inline unsigned char set_wan_udphdr_data_byte(unsigned char off, unsigned #define ALL_X25 (DATA|PROT) typedef struct { - char prot_name[15]; + unsigned char prot_name[15]; signed char prot_index; unsigned int pcap_prot; } trace_prot_t; diff --git a/util/wanpipemon_legacy/wanpipemon_legacy.c b/util/wanpipemon_legacy/wanpipemon_legacy.c index fd2e4b1..ae396ce 100644 --- a/util/wanpipemon_legacy/wanpipemon_legacy.c +++ b/util/wanpipemon_legacy/wanpipemon_legacy.c @@ -138,7 +138,7 @@ FT1_LED_STATUS FT1_LED; *****************************************************************************/ void sig_end(int signal); int main(int, char**); -static int init(int, char**,char*); +static int init(int, char**,char*, int len); static void usage(void); #if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) static void usage_trace_info(void); @@ -403,7 +403,7 @@ int DoCommand(wan_udp_hdr_t* wan_udp) } /* DoCommand */ -static int init(int argc, char *argv[], char* command) +static int init(int argc, char *argv[], char* command, int cmd_len) { int i = 0, i_cnt = 0, u_cnt = 0, c_cnt = 0, d_cnt = 0; struct in_addr *ip_str = NULL; @@ -435,7 +435,7 @@ static int init(int argc, char *argv[], char* command) return WAN_FALSE; } - strcpy(ipaddress,argv[i+1]); + strlcpy(ipaddress,argv[i+1], 16); if (inet_aton(ipaddress,ip_str) != 0 ){ ip_addr = WAN_TRUE; }else{ @@ -486,7 +486,7 @@ static int init(int argc, char *argv[], char* command) return WAN_FALSE; } - strcpy(command,argv[i+1]); + strlcpy(command,argv[i+1],cmd_len); c_cnt=1; }else if (!strcmp(argv[i], "-d")){ @@ -523,19 +523,19 @@ static int init(int argc, char *argv[], char* command) } if (strcmp(argv[i+1], "chdlc") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_CHDLC_SIGNATURE); + strlcpy((char*)wan_udp.wan_udphdr_signature, UDP_CHDLC_SIGNATURE, 8); wan_protocol=WANCONFIG_CHDLC; }else if (strcmp(argv[i+1], "fr") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_FR_SIGNATURE); + strlcpy((char*)wan_udp.wan_udphdr_signature, UDP_FR_SIGNATURE,8); wan_protocol=WANCONFIG_FR; }else if (strcmp(argv[i+1], "ppp") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_PPP_SIGNATURE); + strlcpy((char*)wan_udp.wan_udphdr_signature, UDP_PPP_SIGNATURE,8); wan_protocol=WANCONFIG_PPP; }else if (strcmp(argv[i+1], "x25") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, UDP_X25_SIGNATURE); + strlcpy((char*)wan_udp.wan_udphdr_signature, UDP_X25_SIGNATURE,8); wan_protocol=WANCONFIG_X25; }else if (strcmp(argv[i+1], "adsl") == 0){ - strcpy((char*)wan_udp.wan_udphdr_signature, GLOBAL_UDP_SIGNATURE); + strlcpy((char*)wan_udp.wan_udphdr_signature, GLOBAL_UDP_SIGNATURE,8); wan_protocol=WANCONFIG_ADSL; }else{ usage(); @@ -564,7 +564,7 @@ static int init(int argc, char *argv[], char* command) if (trace_prot_opt[x].prot_index == -1) break; - if (strstr(argv[i+1],trace_prot_opt[x].prot_name) != NULL){ + if (strstr(argv[i+1],(char*)trace_prot_opt[x].prot_name) != NULL){ TRACE_PROTOCOL|=trace_prot_opt[x].prot_index; pcap_prot=trace_prot_opt[x].pcap_prot; } @@ -626,7 +626,7 @@ static int init(int argc, char *argv[], char* command) if (trace_x25_prot_opt[x].prot_index == -1) break; - if (strstr(argv[i+1],trace_x25_prot_opt[x].prot_name) != NULL){ + if (strstr(argv[i+1],(char*)trace_x25_prot_opt[x].prot_name) != NULL){ TRACE_X25_OPT|=trace_x25_prot_opt[x].prot_index; } } @@ -962,8 +962,8 @@ int main(int argc, char* argv[]) { char command[6]; - strcpy((char*)wan_udp.wan_udphdr_signature, GLOBAL_UDP_SIGNATURE); - sprintf(pcap_output_file_name,"wp_trace_pcap.bin"); + strlcpy((char*)wan_udp.wan_udphdr_signature, GLOBAL_UDP_SIGNATURE, 8); + snprintf(pcap_output_file_name,50,"wp_trace_pcap.bin"); signal(SIGHUP,sig_end); signal(SIGINT,sig_end); @@ -973,7 +973,7 @@ int main(int argc, char* argv[]) if (argc >= 2){ int err=0; - if (init(argc, argv, command) == WAN_FALSE){ + if (init(argc, argv, command, 6) == WAN_FALSE){ return -EINVAL; } diff --git a/util/wanpipemon_legacy/xpipemon.c b/util/wanpipemon_legacy/xpipemon.c index cdcc460..58285fa 100644 --- a/util/wanpipemon_legacy/xpipemon.c +++ b/util/wanpipemon_legacy/xpipemon.c @@ -458,7 +458,7 @@ void line_trace(int trace_mode) { fd_set ready; struct timeval to; - char *trace_data; + unsigned char *trace_data; trace_data_t *trace_info; wp_trace_output_iface_t trace_iface; @@ -526,7 +526,7 @@ void line_trace(int trace_mode) DO_COMMAND(wan_udp); trace_info = (trace_data_t *)&wan_udp.wan_udphdr_data[0]; - trace_data = (char *)&trace_info->data; + trace_data = trace_info->data; if (wan_udp.wan_udphdr_return_code == 0 && wan_udp.wan_udphdr_data_len) { diff --git a/zaptel/zaptel.patch b/zaptel/zaptel.patch deleted file mode 100644 index 7f29279..0000000 --- a/zaptel/zaptel.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -dur zaptel.orig/zaptel.c zaptel/zaptel.c ---- zaptel.orig/zaptel.c 2005-10-03 10:52:42.936229976 -0400 -+++ zaptel/zaptel.c 2005-10-03 10:46:57.123801456 -0400 -@@ -1760,6 +1760,13 @@ - } else { - if (copy_from_user(chan->writebuf[chan->inwritebuf], usrbuf, amnt)) - return -EFAULT; -+ -+ if ((chan->flags & ZT_FLAG_HDLC) && chan->span->ioctl != NULL){ -+ if (chan->span->ioctl(chan, ZT_DCHAN_TX_V2, amnt)==0){ -+ return amnt; -+ } -+ } -+ - chan->writen[chan->inwritebuf] = amnt; - } - chan->writeidx[chan->inwritebuf] = 0; -diff -dur zaptel.orig/zaptel.h zaptel/zaptel.h ---- zaptel.orig/zaptel.h 2005-10-03 10:52:43.094205960 -0400 -+++ zaptel/zaptel.h 2005-10-03 10:48:53.974037520 -0400 -@@ -611,6 +611,10 @@ - * 60-80 are reserved for private drivers - * 80-85 are reserved for dynamic span stuff - */ -+#define ZT_DCHAN_TX _IOR (ZT_CODE, 60, int) -+#define ZT_DCHAN_TX_V1 ZT_DCHAN_TX -+#define ZT_DCHAN_TX_V2 ZT_DCHAN_TX -+ - - /* - * Create a dynamic span diff --git a/zaptel/zaptel.path b/zaptel/zaptel.path deleted file mode 100644 index 700d63d..0000000 --- a/zaptel/zaptel.path +++ /dev/null @@ -1 +0,0 @@ -/usr/src/zaptel

    CKMTpN0&dMu%J~WnQmL{4QONVbJ{SG z-vEDw(d1Kl1smP@8*atyi>jDTU!;$lnQHM4#@d_beVfK^Are{iYBb)}uG2FP~ zC$tDOz6OI`?S%2UTyTN3NMe~tknn85YY~Bx1Fdutcr!ic;DkI+7~G~@Wt{-3V-j>3&dR zg)InxF6-mP2@Xay-8z8fxgBCdjWhu}0$0>Np;?lV47#ReM$RT!3!}u9ga|8NWllIDd76o<->zPSa3aL zrU)uR1sx7+BXqfL5KW!!X?IE_o8J?$cWI*Dc; zrfX8p0GP_bF%exH=7^6f?txzkQH}^J6zg3Hkyt1Cabrk8bpRT42~acL5w!??Bl5%8 zG&f8sD?Kd@5v~V@K)Yo}ltX2Tm~twGL&5YYKYW#85uTPyU8V2US+JNKFCE%c>PnY3 zEhL=tI&K-f?li1(YL8=LCSwuDUgr!jvRz=^;axCo-u9qny^WXwJMp5# zWe2(zEg~y>^a$)4lud(Rl7%vTUCp6GJ9kb3VBP@i-w#X18^2G-apJ7A^ZM&=z4iL* z_h-MwU3z=8xs*#av-+HZ%HkA%_b#2(N zC~?%<)Xz4U5VCdn{xjgh3pcdDR-0XytLyIq;Gml}to-tifBDDX{OmVBTMCwzHgs+J zWLz<&;I$V@!Jco_Z9Q-xyMNu4b-R|9vVXfk>%VE!x~q!CT=6T}{h`fhKRsO9uy7rY z9v^xdP}<4Yu3e>_u;-xc{pm2qX;I4I+dq)qe=Dplu{`woTpVVbP5skj(tP5%^U zO{2@cy`Xu{g7Ji#oVFTc8c@AJAU-koxAnbkiVDnGhd~j zqLCkVQx(aHaeaPthL>rO&cHTQzSb!0J7N zUMoF)=+K4@U5RYVp;F3Pcg{U^d+5zKdA6!a7&r~4(2|=rq;Ug!de1q8uM>DbedA-- z^1M(waQN{4A5Z>Z|Buz-H9wpDfjVC5-?VAdC%Z1#qsKZ+%Pu+af~K7;=@b2oTbH|_ zrngsPF#-0c8F%Zg;p~O^tMiq!*=D+~3$tBzA!Z=8ZPTX@SpHk|O6hEic-~mol`=m` z`%7QgWl^2=!_o@Ol&~CcShNVU!fVX0bTq5K1C2LUva45Twe^=Rzu~E0tzM)6`0sh+ zX`SbNrKP2j~ti}s9xm{NM%c!*sEl`KL{#+JyE ztLUzb5)RHC?~@$F!4!7&llO$>$Y7jsqG)wMR)8FO5*L>Byy}ITpbNgedGJ;1QmvHa zj11~AD==ua3ZU0>6Hwrl%Rm5YFVbN4y#{>L6611I3q5}@6-co9j>6IBAn3JvY5com z66M|Z>gPbtr+^jxGG2^P?1?7WaE(Y~No&8XCFP}#QR57uHUl8hn}n3>=|aAwiWNg<9}Lx`bX z!BLV~V~81W!kZm7VGu@k4I=iWP9F}VV8a=d&f)Q1pAdcZ*43bKtw1aI$-XKFk z1oZ{j7ef&DM4>Rp1zH8uNskD-nfd6-U}6|J6UA=KgGQjFEe#Zd!Jc4b+gpoC%en0Cpb0F@}5`fZx3)Nn%Ix z^Nn;ZVn#>u{$aeNd&E1Rs=xYQ&#E`?xwg$*w(Irw+}`HTpKbrDqrUgrTyg8szzjaI zmW;_2Xd7&g9ZbU1NKJSDqv!JPGTv=nEOGk4-}^uB3?(~#Pzr`!UKx5`8+V-)_hZSL zXw7=ircEG0BYEeYh1Lo_qsYOj2?QI4FM?w_b=1@GSC4^wOG|GHwq|JC7_6cVii$^k z+;OVO{>Oc&dMsytP@qK4>`SsxvUzVzHBt^eUxwQ;@@512YSA^hWil{4C6d$>ypEkm z6Sf0x1f<%(-sc=Ps;iyXWy(6}&>y^x-WY9>d3nFhF0RTDEyuy+0m=K(;A19o(9ddw zSQFcW+?F=mPTfRKVoLoq*g~6^q>;cYDBHNaA&83h@$3md6BK=cv$41hc>d@9)!V+* zXslg;vuLkA+PHlfMxhUM=Y@G|rf?njKmR-A4da}XxC!S}Bp8ads6ec?13EwX%w&?5 zWJYW;K%>qM8Xn_b$(r#~xuOUi|4V@0dn2NO3Bd~SiF-`m>*eTGoq ze$S$yx*og8^*lQarYJcC9uwrBo6zD4E-Dd~!*-3G&ID|^pR+nlDWE2UB!BCx9StL| zqF(5tNA@1sn0(*FrzkZVAd$=D0Z*NFaEpuPUIsfqwml2TrbHqjDaK6cQ9Y{Jk@do( zNuz=B8In%UQ$tNCGp~bh`2LUcU^5FS7w=#w+Nf+Lpk^8kOs0fGz`~SJ1#7R9tQwY{ zvk05es08!Jy@II6>~^4<%I8rw<z0tfFDW zU_fCP3Uxym)iiZu;%C?e1A?O;%nE2Sjhf+n^LHoiXjoc5u+p@=WiP(GaaUhM)jsvl z8_#`0ebTKu_?gtm{X4w9|9nw0Q!r>PU6dU8kBZJOHeNsrcer>B3P#8CvC47&UrUn&c;3_X2T{E^)>-D#&xO5OFP3$`%7LPc^d+7I)xc6%d9p-?!#wkAVa8uA<;LpOx0Y$78eA+SiXU4(*t*6sY+F>@1h#Y;p zx#N5^J~@we46Pp;Y8o8FJUx-&PKEBn>y?@ocnEgjUI808>?VjqoG-bxlrhOs%xRy} zeqG!lLBULeBjUDxXhB5e!MN4bf6mA> z75|ZvcBYDg1-c@o#IP{0``^%glAde!vDmtk@=RZ(^Z(_J4|&0N3e?K+-h0i}f|~YT zdLIRMC>*ovcnq1I3Ji>5S}#-NBl?r8C$Pw7a(#4_n+mfcY91402h_+B(mBx#j64FQ zQg(v<7!(2uU4(iNFol%4j6Jlv{12-{BF^EcVI#34^<;qBm9o&V;5TehKqFKpCTRL8bza79fPB3BmZbG#? z5?@3iAr!`$FZu-L;$>H0UiF<9dS@JYPG!^puXwFux4= zaIIbe{u#`Rm^4so$N4aZZ4XKhv$`P-39QMQGOGww=sPH%{+u!HWQ~3e%n=2u{w9jY zLonlx(w!KL$z-QnRnz(R9^T)m9?f(t!nAy*kj1kvaWk#-$PDG$#c_a7nX9Q0A zI(~aAHJssfpqs$p>^5~?)LiYZX#Ij{beo!5n|%B44gX-$rtP_!Ca0<$ALjl%f1tb8 zcH3HMB@h@2mW7~Bdgpq;{n1h&V&$Cm+ zze4Pwn95)NRnJfUIh^A;0?H%h_M)qSP<#rBeN?gWpGZQxVZod0Yirv z(W*mm%w`TLcEDar5)x!)IJ{aIjj&FmW*x%hD{Npylp;+I0yJ}lfWQS->?qx>bUwjx z4U+WTFDy-r1Znt~#|T|g5hW=JUMO2Jiie&Frd&V(?(Cs(9g}c5$J`*aa-xES%fk@+ zVN44UkTVMi#%U+48;-ssc(YN2%>yZ75XrvQe3%I}wbD41VV^q*tFDW!u%uMxU|0p{ z35u&73IRk)10N*b)U`FQs0tP)Cbtra#aYPtldJZaF5wILU zS&KNVPtS9Tu!*yQjy(wnOMr0U7^x8{qFFFa#7ry7B=|oG#HrK$N_|2`5et2CB&zk3 zaGgqGzI-u+byvwd#A}y72N!{e1F^sJC>G5C*h0TjdTsJohfA;uyt$B$t`*t0-YRWM zdmrk;wtw1KS$ak74EECpZG1=d^|u$%0%KGEZ%Vv(#5NVsXvor%ENm+YM83CZS%a*f!+^61lGmb*k7c`7bp@|omc{p*`_~>h639dU=Pvt;-!TU||ku}yR~8!h8vdoSBk`_%3DuJ7&mrY|nK zz0l_`7JRWLS~h4xJMkQPFpucBe`8%WePup`W83c!p88XK{}{GdzS{q^P?m#$wqJub z<`et+8`q4VB`v0*==X#x?dDTqmID1}v-x62ko7Gzz}9^d+b?s7?UNin6;QBaGI0Kx zJPMfQW~nd&$Y!nc1aZ#L$JpA05fzTP zoln2HW0!HDmwVRn_>I!Gg8MTR$IxEx1&|GL*t^88eR! z8&>ykz`$ODkXn&lyY}~g|H2C|?61rAuV#FgzXxBy??04X zSY6%O8K0uvz54!VZ+VhAzJRwue)F3{CEAa_5zMXG-|)HQnOlWAV}6J>R%6QQB05`8JC$DXd=2bjK2Br&%roXL<{Voj-ZJ>-;y5ym@3(*MUQu zHtogPXS~CM$*i>J@DEGJEVFbdyTrmzqBH$x!5;i91ova&(_eMwuRG)KcpdD*n4vAU z|MvBjN~u&fjbPW&(uM)f8^iUTrP31*Plh)R=rQ|k$Hq-(j?SpHpUdHVZDeX&>B!QU zYCx|^Jws)%1%mrNby83fuflud=oY+w!zKIPw8(QwmDq7|dT5c#mJH6@qP0O(<} z!Uia4rPg}~;;jEjNWrc?N8D;g-;mxmdXd&g9JOpq<%A4vzYjedXDGyh3LgRhtreL0 z1;czceJ`V+<=%yHE*X|gw+Xc0rUX)8iw)@;&?ca#^Nm2~lUu`hgAvgoEn2wfkgfoP z1V!m~gr-3b7!9aD1z#rgWQVwxAK88(cgwxaOt)nllQSrG4EziDfOz02jsUMT{S=5r0HOy?eEfbHvCQLa2wG_4!2@|5Wd>3&?NAY#dFU(T z1wRN?*n4sKMs4Ha2pz&eWiS|uUBO#-NK-5f0XBRzJ0_y|BA`u{;>`?LRgi`tgS3m- zQS?;NbVY_mnl`WjC*jdY;)w`2VZtIK@Gy#|Y(x_Pr65q?kL)6gHnI0@a3-LzZNntt z!;1i^r-%!zB-6thMcgJ1Hm!!#FeWvbNk~CP!sbH|c;`CD8sKb&gp1ILu!vC^Qq-h` z#2)nK>u{##jg@8t&c8mtptG-FV7uoH&-)`!6}G` zthJB50wx_2PPfFS-_~c942~>l8#a8P@CDj{XdzBSsFw$HF}Ikg>Xys{XB8V|ez?;k zAz>B<9Lx)Bf$8wUW6DiEcB90z74BBlJ@lE+)CX3tJHGZH-X7`b!w#6=Jh>5P8O#QC zlH}hLQ@_x)@ zW}brI1G`4g+-spjNgi+@F$U-|+?mu-?hF~)YK>5WMtS=2{_4htMfsIO%;p48m@F9Z z-BI>xZZWUO^ab+9&DLFoUbg)I$K9TK88%IGmAPf@s8FAxPNUf@e%V+?H{-LGLsn1Q z$e2V{-H&SJ|3djKDb$jVr)r@|(YT9u4b=iQV)#|JW9!}t&_`-1|3{uB4Z;Y<@ahoE zfpQA^DwRZCs#jsM73(P_fG?7J@SodxmzxUX9SzuFbiO<;X<`Lug51YOB`OGlxnTg0 zN_=Di+y5_-K+GL`8SP3Eq;Qj{!$8w%XVmZwbt(COFoEx{j^&eo_G){>((YcdHE)dm z%MlV=ztujtV9c*gz1~5p8}`zAnxw=TX-4&t6Rr@QG5|YB+|m(l-Yi8UZ=|iKa~mgM?1)}#;a<)i#6)v>l;y8BrbMAnPg%;QN5>jJVl3*R zrklV*kcnv@I-x=E`A6QuZ6w|_Ejrb1=eI00(m3Xn3sp-Wy6^&pGU{m)nIJd@gIXb} zX!i(`4f5>PYBGEF;bFy2Vy{^x+~z{Bz-UBn+-MXHKZEy9=<+@YqpRt1U!=rPk-Nii zvWS|*hB1f$upywdI3O#}R8YLfp&l+bX9GCO8?vRSs2BIo=*ot`955eR zNDWJK8%Ht&qYd9S)Y8TzJ@OAl!|i+3p{@VAvGLQY?$4lZ~|RyVM|Z z=>B+z0nQam{$#XaNpaxvPZV$yG4Iu{D zMJT?B*RQZPP7d%d23UE_i*g`-~1866M zX4F$2XY`E`8cq*nEn;`{R0OOz`cQazZi&N$dNR4_(W z9p>7-hIcWHpxn8tQux?9?r8>1s@h;}ra?8E;%0o);M-s7b}c(c+p6N?cr>#|mw z8M@%I0sP=9;?3BxV6gL&avbn7TkoJN|GX!EF30NRP!er2g6|D*tEgzwLxU1s#ytUb z1TOxvN4;b(edcS6A3M_0i_#RU>fKbHnv#WUzp2TG4p-~#W5kp};PG<_0&Y^w>jWsy|6LA^` zCR=dGvk$Wu4A!AdPnzg2Fm92$t{Q6vCxaC-itY7*J+}bcTnJ!m`0c+-M=8`v#wKh7Y%&&p-ytElQ+1dLezRy zx!OOugq&qg(QaM-c+wZkiwS3$@2tPX-r@f}T?d1sZ(npaTBhLpXXfZSkGsdHPldZg z4L-o|4d2Z@K>W+N1s07Div#?cGkw46V*X9nHgb#5a!rRfDo69aycKtwYrLtE!iicm$sTajx6mc-MvKK-A_qzyDFg3*1b@2dVQ{4$k|!+v}*X zqX{?QG)exDwyMMYw!6Vr=+D)zSYY_vHhwiauMHi}C0`=mZu0`nDT;EdlCWKzk3<~)7ECtT-rmH_-C9rrh3dseTy99({M*f(U%TumT+BLp zJpy?;Sh(a7r9py(`vb$@Y0}W}4D~dwJ@j;Cps^i1`Jw|O`>=;}0a?5V0&rA^kikXO z>oPJf1|~on=Vj@ra(K+8kw$3Lalm5E{>7VT@-n zQvV~sxueAJj({~o6i12+Iuw>wQLF-BDiJk`ITiKKJR(qW-~?Y!QU1*Iu*#F%#USBs zUU&(em0cm(W#QZ%E2T({M4vcMfxy=>3|!MT^n<$AkyE6C8`?tI_i%CA32Ja61565> zJ~$wdml4D+E2*H4txIa4{t$zp2tCCgh!CLJR7GJJ3a;}hDDZ)?!Fe3jBRod&v+N9De2!ZK>$hj% zi!faQ-%X0;fdSeiM2Bwp%pNh*B+Mm}z$Cb>Gw?(qbO?cvwTKan)&;1@#yBC^4VCA> z5Qrq}Ct{>77bnfgsS%*6lrTlb34n5DW?2cv%E*lHo;{m3VaY@raDJEf`f*hDL!}Rv zK9;hw#^L_s_Bo~FM;Cf;m)314d7tjTpzeaY4`x4@eH+vUeq(aRS4E#L?Yiy3@$uMZ zP?zm;KV}_*Wp}Bz8^F5Z@o)4p#AmaK7YI`(d92)dVuX4rT%{YLTdP{p8frk zlUZ$7-XGeEke;nuy}HX~%WVk9aBdj6xZoQ~do0?s$D^YFP7S}c%HLbvzkg(;cZ6~8 zqm=o=4`29UDKg-!?plpAeWgjZ_2QHu{O|veT|B<1rS5{#2VrI1 zl-iI=EX^Lr25*1%fMpO);-$({5jxk;uqZPRix8QN(Lc-sa{G0>AR(8vayLL-&8nklka zcloU&psk4ZBpo2dic_dA_;%Of-`WLs4amD&1?7em8nwQ(vcBtYU0wopS6%lbL6(IV zT;}~g=guT)Mf6GLo`27I&U60WbI)_0bB_N0bL}e|RzCnq>#M`VubFW}(YoMOTPdrNK`;QQ7rsjMHV2@5&R=SdXqQoYS3+`S2=NX#c0c|8NVgQuCh!iHW)qggRje9ZB|A?=RqT)HgYJNVGma-Ra6`ZK zeBjeT*p5v-vr0$|ZZt5o6x`g>5kTjOm*HCSGz)7biH{AA}3Y zh+cswTGeEf3BM0*5FpXGSSmXKPNpZZ+dJz{PhV(Hc5eJBS*@L&Lj4e`J}HvGY6Xs% zPKB^WXE{&GBd}q?$$WGfZ+>7!odrNO&?c+s6Dea0n+rpg`Ws91Ry*12#nou zlNBq2wl&%M;)#$Z55Fkv6aPUI{!LRGH_o1bP4<(aJ;_W!Jj(o?uqQV{q%59#@~0bP z6Sp{_{Euht!?D&WU_uBDvd?bp1m+(D3fQBZXP9cNWTN;TWtb>DN19sclURUBNJS1> zn&aj;&zeV=1R?^>fCL3uZP@VBWs)XH06QujcDh&tFhvYI16J{?W)Y^P@Bnm>r3_&O zM-?|jV&v_5mQI5vfuJK}7Ei9TyDfR#vCQ&3R zXApp^fSooWhoL>n(cP|AU zl-exhb(em{mmd=rotZUlLN@sp-J6)9JsprqM2Nnm)m_}IwRi}+ZHGKwM8ZIZJsJhL z>8~k&Eim)yXP^`IfnGPoo@b5aYbd`rFV+)Xo2g;e-U`wN7NZYs+KG(Gua{Szu^HS4gY{ z75{JJyjY_H&I{`9oXoViUf&{m(6qKy$r~9F62yvA=B+9fI<9rI;;|YXG2LM{4-zEY@kY|glyEMi@0l+COe8LiwcL96&m*IIxk<_sv4t3(gvoaPWLuI}xV0i_$L=`}X{DEiJJ#SU`6mfZZuWXP^<|0L9Bl zB!7*>1B=_dcK`)r4=$pEH>CV&H+c};Xc3_AItV=(mgEQMn3(=|JC74l@q)s-mo!_3 zP>6j~&Z;)Oz@I2@7fl*cF3O{p1(cmaNBN89ir4Y}T(w(fJLMGCJg*JdWh@bke4 zKyoX=cAz@2aY4LikxcZXR7t>nCk6*mjG^lCjmc>X(t>cjj~gdGx+OmufER~mWqTay zFWWu3`sbnw^@+&E*iZo;U~lQ?MmdF}+*6tf0+T&zUl#|ypsMCr_b6M_Ez3)WW@^t&5F z;E|vu27?~~1|iRtXuTJ3^E2lSzy4(eq+-;S9JBL{IF*=C?efTnT9de7mm}3W<7iYT zILHOfA)R+M^}j)7>NyvJY}CZS;~)8@*@u8Ay?AY4F5nhUJ9eFwtV5LnQ0;(BgJ_gm>bnPSl&q0IY>zUa1EQdzy(>nM(F zUX`Y-l@^YtRKIk_mh7*0`Zuk?l-;@1YR28VX|jCbK-!~_H=%VJ$MO?CBKJx3drRW# zWEre!^Y^oa8j>fU(2zT1Uo-a8p`d$E^nN0nk^LnB(QaZD?N#Z%4!lqMb+E~YMt-J0 zUCh*{(;aSCil;LYYM7F@>`Bn^liYz^4C)?%1~Q2%;6?8aSf$EkP^DCoqfWAiCs={x zW)t{`nnNwREq&-9{($OUyI+!O$Eg-=P7+GR7}ew|>cT{HY)b;Y*=mUfR1QEDXQrLDHR;#1e+I>|&vY^!iXykcCy}e2BoHF(re+CppXlgtA~YLAeIhBt!xA=OC!f zfBeh>sP;5KhxF052YUZ3?l_-ryy4tf{1K#mP5j{f>)jg~6Z~e~n(!R@h}#=H?k-LS z<7gwGa9-M>gHAhg`nPCH4g2YUgwWB;uQAv7Uh7Qh3}NNz|r z41DG@ezMCOPdN=`z9z|O2yQI0tfe3t&}zpaX1vcqV{IsSteEY(%W=-e9-ui;{B<#E zLGzgskS{ue^f->wR(M}y*HNR7jE+YcN91vE55a100Y1y>C2emA5>yxuu06M*ZGB_I zSN+C2sdoheZ*XoXpnb61!mIzQ1_#w#@D6ny;$o8tu0=Y)Zz?4Ep}2%ejX3oK$Vjzb zu{f25ze8YwyGl7nA4iN?$kc57X`Bz>QvC3PGlNFVs3A!24%%~Td@nYRO$;g+{6yQ% zwqW^P?Vs(*2X1fUPVb)}-#jg#u0(ILyZ44bw@qzwgRiZ^?v-nj?oEf*cm2ibVyxZy zxcke7q?p(Q_8kwm2iLjp8-F~v3>&a8K?@);b1>XuZ`NXB0a+qo1z%JVwfkMjNse3{ zj5XuE(;J+IyU2aC@*eU|YwwkLq!a|$<5CaB;9loEH+g4}>pHM^fwKe@1_OLLH3iKm z4wueG(3^W@fHHu#x8$MiY)DeMOwdncpv3=bTtiG=I>7Ml5Vp`^#D#!vJxrE6 z&Fc}S|1t$6UIh)-@SOx{csYs8az_Gj#mobX;|kBh1{e+7TAaZR%(T^Rb!((#;p`PF zjgFXuFNP;eT8=F80B>P~0wOqTy&w;l;+Dcm2KY&h?hlg-h}{;Rf-MHdH7IREx_#`= z7@%DR_*Unnv*?V0{t^_F3M?*nj=@|bnuFIoA!UW+sBam?u09_Ap8Dc%vXW z=yHaHd1s*9ByniZ`|2~hID3MgX`@lb3*W#Cm?1qahoe4^pI_Q}96>GImn)aHupD-BGP*;O{fBeE{`E^gY%=msBVlbi>n!Gg!`N(Y=GDJB z7>1}}&PDXVJ&)m=5%{sD%GK+>5&PiKj@17|*JH9a?yhfq!?v5AseItNYoWXcaR;A` z%5vY@J()GV-}y9a_BY=6?Qf4lRJ+S%?Y9SJWznBtJvjg$=h}NU|6S4B1dd-`H#o@t zeE##d0Wbeooz0rXEE#6muv8ad}Y8St$CJe}E-WSx-do-9+Q=tXK+h&uEfHz&KbIn$X#;Xf<$jrfW7 za71xdaDJL6^QNm~j7Fa{zqAFq7^&slnavynyGW&p z$-1w_Jmm7YL${bWc^&}vY#fdcTI^?jIuBj!JanoCnXv-{9!!i@CqYgA%QEbm{Un6>4yIQH=H2iQH`C{{ollj68yT=ko70U_E@6zG zl?}5_FMc&z19SKP^4-AW>|eV(*d!ZP6Mq|{)}K!8Z?(N0yW|Dg%P)WRa2+^2UcY(A<-3e5c1L#Q${L-eOCM|Ak%dM-MicJiJgzh~J@5dt zP^sK|*=Gm7u<>)5FRoovy;*6pkK&x_9j`^QXRS7D zsPVrG*ZyKt%Mea)zKs3ec;nSqn;y9AvbV{y@mjg^HEWkzhtZU=BjA7y8!os2J6KNI zZ(>6EynBptPdw4wM@O?`jN3F*A(jlUJK8j}gDS%z?V6QPN7~Fo5Ae;vd^a%D;PVSO z-X8)i(W6tibZy3g%yR7OOQmBgT$+=IOcg?AGb2zEuWspBN_MG73|{(HyMNj zIG&X7CnQ_2$(#*SPr`AiL960iuHs*8h&#U^!gH=7?%`N6z>&_Sw zG5~&mFW~zO0NHOwBenL)J~qiw+qgt{9V-I^U0QUo;gll0>@94%;^r^Z!Z%5c@U$Dr zV#7Kz_%x;^yrBn+Cu*K(n&}Ep#Q9Lf_5DDQykVoNOIb-x<&&0FZ0`fXz;k zns`Q$>?FF(;Z4rxI}2_>eN1=8vYqrSl$Put#O!D3$VU4IlU&ePapibea}A;APay;- zh9a-SQp%Qe%!HfOS_oBvxEqn4y5oCCpR&Wwsi}VsC#Q(YKxTjy{~`X$G#QqSAL*>t zCpH?py*mUGI87QD(=qnqG+jNZPTe+WMz7(F%u#YF+mH);f(+nG{*GfNu-?{HacoC{GGg z&|C5;HHp|yKKnh=Artz;Ah|vnTq#^*kzgqD5~Sc``_dsS^+~Lw`TTI2I>^6-&LW(u z-e*#P=m{TCfVwttkT%;*>4t3o{UCMqO>N>co-oJ?VpKIYN)W&HfhwjpN<|?E*2uYp zp)rw%(u&q4;aeSov=2?tDi%ty19=9PB)s>F3PdpCsZnHTtc?TyFvuDTpUn*Lq4z~& z(7o6xG1Ry%1<29f?DcY)`XtQ+1HU*?*y^r0o4&NoqCL+(64x}g5X+%lFpAy)GH1>r z%J1wc!+sldvy|q-Dq?{yDh7oS%nCc5_QbJ*T|#5v{=_oY`Jg|9JVMB=U&h*+6yJ4I zqP>2mC;kD@hh8m>Rmj(c}QzjBnN$!k_x=!$`STxw)X-5ehnIq?A=qz|{WF3gs}J$jwLe=zJ% zgm#Y`msbiJ6?*TazVz^?)@0;FAZ6Rm&GB3_#kQ~UwQv=Z^$2olNt)0S4n8%rC&xxbLT^a5HFJ;rbMe%s0p_Ec9au3!|FSUz*_$c8q838e1UITmgaMNEw! z-2_hrP^L!LLdMIcsct7L`wc?B00|LAPMH6lQi`a(n z^!G5j9(f#ZVZ3s1Bv_tzjG!2s%R*w+T$|N%N0U8GzYnaI1xnRTUx~IyTA^Q5%V-hw zj59nBvGpN86a|HDozze;8<>7Ks;+Ql@Dp(xkWphU9|vLpeZ|k{W)wNsW+{3H@Ugbj zqERQb=S=h1rQ0>={&B!XpyyDfu`63{%KX2=zvS4TVh#0$eWW^|zZtgBpZLD_i^(PJ z_ohbLzqIMoUOwsXrI{AGid+n+*cXLGbd5JkZc|S$7W3r-P-foit_Q1bHJxL`Ejg@{ z%_#+|RB-Mrz^jB`)R zjTeM|@*G6Q)ut9VQK+!LvJK|j!e|;zcs1H}3|&@>Jdl_rI&%!?PlT^R9_rv7UUxll zXFz^r9j;d;XDm)RC4Pcw7RF402ZP4X-Hk^md^}lYk33D8WichFEZiGAh|e_WIU`J% zG!V>CHqVnD0-{K?Gp$r#A1}4*UbWBa>l1f&Y;s0AMmLMB=t=HVDxKbMjf`}U7Smfs zO3C%IySMvN%B9oY>ExaCq1*ighN_mfv?Cz(b@~#?VlZ~8Wwl|m7)~M?89=ipOOf9k zBsJbHQu~&$e7`S;{D{q$3af)83270ZTSE8`xS0WslAJ+-*&va^Ab@^{*$u8$poCUh zN|hbVVDPazQb3?pX{~5={a##f?Iu#LmBCO!5C>yiWe^!um7$X+CrjE{Rqr~Q9E^J| z3KF=ML@<|eQMrhxa0M_{SynZ>0r<~kZnZ|7wq%F1b}{sLX{>p1Gqve~F&9EeM_kl} z?Jbf^)7gxy`u&&kyfh`1M6LNwvaM||%eHuJ*8=U|2eUJcMxG8qM$#yP@t~n`J>+_R zV?B*`P(AgoA#atnq%H2mp4)7&v|>t$HmUo2V}QjDwmeCiu7XY39ebT$}gbIfhQB*#7l{BAV$ zR|p!cJH5r=75cHz;DMGi%Xa%9$+ z1otJ}Gn}5i*x1(F=wwFIX&lDh*p-Cne>HV2E4crwd2H(kdt7hl*iRa|+|BDju)%8_ z+=dnrI~4r-y_9zY&8KjG_lhRH=CAW(1IYYC{(pvl;+>lr^Tu-i&0|h=Ey)I5IiU}ujnRmyH ziK~fEr|rp{@AP_ctRM;pds`3%B03K{vpAU?l2(me@0-B}x|u{ptoD0oy;JY?xV%gb zSvl^d&Ouo-AnzmG6(z+SX$WNyu@P4d!yzHQMcUk38*#pYljA0XuJX2kjb#RzBN&OB z7{P#zJfN$s<(5YHSZb7TVmZn;B!Z$s0wjaH6!DRKw+a++oN>&hcxJnn1G!uJ1Df$A z#&*U=(=02d!vNtUw5&<6-9=JJMPVwVvCu9^aV`uf_%kqG7MR^AAB-{N01LnsfG`zd zbGqF8F$O6ZOomi%M1b7@(>pjuWZ}#))NrJ6)p!KGYJjdWG&+mGNy><^$S-m;54HHS z{;(MT`5y0N_gJ7GOP425rm~Cgx!lQo)Ep5;&+#gd-S6 zU|!G>gB|eY`oe=OJ`W-Q7AgokkeWFHK5=01j~f7hAJSr51aL<#vq~BHMYV}GYe4hU zJlHZ`t#m^viiy`s71&*l(x`cHO#IKIz>WxX%`#_df6h)c!a2sIB{FA2&|VF2N9Teu zyWS%&j*bp#fX!|syfz(i*ye^9m7#@TS}kStHbz4(fd?pG8~JndHeA?*B{&mw5>q-Z zYwkUtG~v?V>we%$gI_HI5Yp_H_&JWgayA$Na~%wJh8j&+CA+H-@lgsK$|} zl+P@7jVRD1DK+QMHhHph)}>9JW}V1Gx#pO))I8>ymA5KyW$`+cp`hB*{2!G?F>2Uk`rXT6rzIUwSE09-hLn zstoM+`fnciF5l$)wXbam{_!6#gA8T3T=_9XwFosx)d%AOHt^#$>oUW`SwkzEcFCnn z@3>>=%SQ*_`t`cjS2iU|kjBi1rbq>DL-;kL3iti99$o(Zvz|Wt>9ZfY%(9y7rkQm| zCns5&a@Sq=-@oqYZy}u?#tGT?-#_#Khp-mjU3aZB4Euta`6Kmyt8!l>&#mgwo+|6* zR%y;i=GHk+-a9~^j9M&S4=hKXl_6IP0|w*F539*X8KWj2HsR2@jev(4{sF48Uyd`I zel<+5n0Jq_@k1QeBQ`J8YW#@GEMJBWt))qXWUL#G;cs$VUvW@;XM=E14%*&t3EP}9L>K6sRxb(>IxL;u(CV?NERp4GTj zm&wDdj&O}G?_iq+&;?&Sp7Ffa%x$Y-^Yg>JnzE6ITb2Dn=8HR}`3!4wkMYAM9C1(O zlfo*&w=tUWT5Pphs)<|2arE=^r&X-?G`(+K(`gmK`%+%J{I$!YF1!$3jz=x*HypyD z@VH9%Eqamf5TAt|m+yG*TV%b($y8o}-YsC+vXv{1`#JPv_J0QZLY}ESfAlD{d|#<< zLV2uW?%hq{WC8|*hdnTC*5H4v4LBR%EgThn&RN5iVctJ-`L2rZzXZW>Qif565Ee|<*uut`+G&-=w~Z@y23Y>#+JVHl8-W|B@&rZezUbqpa?x-mi6)& zHiYdkQRv6N^5rk@(v>$MQu*TmJxM`==U^_>wc=Msc00A=5zB!L^War}D~V9*tMI`G zlkUYU7I;yo(&(TcGcr~Ob>*0brd_lhw8R2tNJ^@aQ(4ffummB2gE<252(vFsNjHR* zlqA}{-myZ-H^cW3%knq+9!7LzKMXr)cPNI*2IdDB+tBA0?m{ z+HFjy>q2~XFx^j&Vpb1KlLv*{%P_q|{vZ7^r^9-`Jfq8}DUQ!THq}gq%fsLOiqZGI zb95~sF}ibpQYYCXCQvwk1SnH7B=#|`aI6>DEsFMWsqxX4Z4Nuw?cNb)*sQ-}1ZcpE z!v&M9NY;87LI?(3rAC%weB6)AkNKc8aA8GOvnLpBmTW1GnJl5Y_N3Xr_yGGFkdZOM zCR)yjiLXn2;19Kk&HP*s5>EyT8>ThP!!*KTQr!C+|-@7z1V=?L7@8x`jxhJT_Lqw=7ttT%aL6I2Z_)32sus@6nl=5H)~ z0W?z@<|6$5D6mOQ{g5#&+wOFpwIJgRZRoN7Dr~h=W&6To7udMunKs(f_C`(Nk?Bcp zPKHP29KLKqNRHg;gk>1M%?^x~t(#+({X*n2UWmai8!Z=>P_kzjZnQ0BhmK+wVj2A# zmYOn1qzVX)e`vlS>F|+|?g>N32?c4I4(pf}>L5ZC^nLik6_TAzk-Bh_{rL-L9)y}J zvlEg*`viOA7T%2}?J(qoEk#PFC{&?XJq6<@vHEb)RHNeD;;I;I>Yi(0f<4y8W4oE#jb29|6I zEf3cgWy^0PTQOP4uq3InFs$-tIfHRvode)#rP-VX4I77R3Ccyda!NuyLpe&q7ZFI{ zsjY}2tP(%?I>rhIf@N5CO4=bQNyDX3SiV9y3R8f%MP*|r9*ZQ#9fT{6HwQ5twFrs3 z=QO+_F91_mo7Uw%SR5%Nye;AP5f(SVTaM$iA3$&c`4;o!3-%U}6&c1D39;d3P}&%9 zCnejoqz=U#S0P`syp8#_TXyma2oqv)CiNqtaDGGsbvUE4UPAYEhJu^zL-L<@`Z4_F-W{Y>;2?ahqU0PuSwF3;W1ppFrz}W)$oHI? za2bcKgl@}w@}hLfv1xMKHgr8;ZP($D@3HLZ874c!SO%6$3X<_qou>XfC9cr+<=lDWP9~8TpwR?=Rce zN>4a*}hlRUQao)(wYHR1MJD08K z2sD;5P@w@mwNN!2JKd5Fb${hH?yu7U9#~4nnR)<}4_yPht8IVLf{@}Gg^vLMEx?2U z9~cJqgC6osEiE;1G~5B|1o>+l?;uRCcFgQ5EcTZ?}&}E|Wh9Qnd7Ql~RC(Oo^dNyZ%i$SFIa-XzVXRXWnddVSPw*M;%G2 zn{cLf>e7;v!Qv3g0LL>*DJ13igoyk>2l0>{%9DTl0z?Ksk_#QuTjs~TiR`ujRfqvG zNg6&H5)2p-aBSntPF}MdiTv4;)moe9=ut!m2e-?%dhPgKHm!grFV0r9BR5sH zCwg0sby18At|0AWbcr4I?}Zvh|D$r9C22f$--MR(?!uWxsQvw7A`!+4 zW1hD2D*0*ZQa{S?;RSayR>=ZH7PvkWlM${Yl*R#M-IJ(AxR9HY8Fw`D&%y9Q=D1HO z?pz@Az7}_09u8@HFQQ{yYw>J9ktipqt4_I|v~(BJ%VhKGM=rc)Z9Ep_I+zsCQ>Z*m zWf*E2?i!r=IG?hbB401Erxj{vjbAs-2S_z~vW$fDIHTZuJL5p#8sepa+V$!}TK;dP zhv?aIVJ|v+=H>}foWv1P(oHj%FEhVqQ+W!rPl*_yPp)p>OtgSx9x@2acS|l5)I!a; z47td7+o$)Wfc)5cozBO7@H$2Gl+ejoXnA9h!@jhM&ZMi{cNImO)U5^o8PVNt=UlHz ze0uOt{%mLOVbMZ$(7>elFDUy-jQd$vqSY<>`2sW}=wPEhFb4G``9;M7JvKtYxuI5# zJ`}=7vdgzff7Dp;fPP%$-9XX%gacellAs^?DUvha!BN*Kuy^Z%W6h}7jQ1W;I4Y9K zn1AEO28jzj1u1Hwt`L-Vi+K^6=k{Q42OTJFeZR1>Yf~fAFZP|YPot3c1vCxt7(Gtm)LEPKX zoLsVo{99=+534Ogj^O(9#obuBPg)q~*J3wH(PFhlH;4iLhM zgLkRB1k2VQM%Ga-g`zBSV6cB`=SWs4(sx$bHrO+$V4Jzo;Ov9N*GH9XB>4mM`q_ZfL+p zF850Jksx*~CBC7m3`Ktv!pKahwA_eg)3;-3kr@XpRRvar=AXP;jiOK~16sC%T%Upihwx4zU+zRnF-V+?9OQ!DeQ-lYSRTSS#kSzQlEfGk z(DKL8aWGE3!_-Mc9xf#4}@B&0BZvllE z>$9fItXKzsXe@j6XZVjd(DrkvA^$iUWXXs4jOzc2(Ut-IF*Mlh( zYr3yLo0fRXdd-{6$DP}yMc6t~a2g5-1>~SSTc3v-l_d(B780Q?_kc>gAG+ zy64@}{k-e@ZChf=E~j^q-FBd-eNkbYmdO=eUEODF?ONY+v2!1kp$8!vbz$N%;54?m zY)OR9SYvl%5qnzc+ikHep8FSg!T4n~SMM77s(VhU2^Vv?k1R=^_dyhL8)U8R^#W(} zyWUm=fEZ4QICKpfEPMlM-@l$j?zG zEJVj%IHpn8*w`M&6%e_wzTOS$u|bd$fk3e=k0;L<2XQA(4Ru-LcbE(q~I^U5D^c&;I3GO9JWLd_%PYf(WO`L+fbD@q48&M!cN0z3iW z3|dJ;FGteYy6si$LYd&20uq;w`q*XbRn|F zo!Aq-V`!MzZl}4;aEyS<$Vp3}yL2ZPgK`vRFdT@9?KvugphpS0P=wbu{BL(eR?6E4 z@V>_oT_V#=FeHO7(8IXQ;4@Piltm!WC@kl3_9X1DK)s_Of*LazRVI9NfPgNH<6JjbgcrieU3#RRiHRU%d4G#Fq&;@Vgkm$xQF-t1NNk3xyV4MePj zzzcy+svqXba5s)8K@b8Zw=H)R-4`E3lx9DdBtMZ0IRanlUM8F2CHWi;;KGU=DfC`; z;bDAWhc9wCQe^_?j8T$goWl+6Q5fC8=gqGXI90v^x+y9I3ID!oARCe&z=jFR_>7T; z1#BuZnT4P6kCI?l6(r2aiNOZn;1MN^q{ad_atgZv2|pRKRq?;!O|p|A;*>K09yFIL zSHT=a9L!7E1f4&J5ZO$gxS42iYS5hfWGMi<-nR})ahF5dYvd<e3C@&mA8+9Eo08 z$t}`cdv%z}Rx1B9j0fut^Y6_!najwI3v*w6?KMWZ|B9+y1@a3H-&LtR&;GM8ybH2f zk9IX}Ff!Vj|Esa4=5?)=A+he63zjW=>A^L@@ZgZW>jOKo{$|Gcdk5Nq0F&kr^z(KM z4N*;%xV&$p^=)$%bcnsLGsKw#>iz zdcEv6dcXYDJ1>uX7Bv4Dm|l%0n|x1kO>f$->I54^euT{H?}4hU_XFjs9`D=8emSO2 zbAKfx_cfO4qpHvQaLrGj(tT_3YGw_uX0pHe&5L&`4aS`x|5W>YH_L=IUcUo8#&EnU z-4aax%?FmpvVQNWI=(fW`SM!U1+KZ7Hvc$X9>Gi+HQ6uYA)Ojee8+FJN9lq4jmEAGP0uw9w|>c-)m~Y-v@+E6Y7AoEr5h`! z`AxAe)y?#N_j9~oWb=^o){YHpjjXe=>1Q)T=v_6-I~mxym=$XG3tB z4`UbGD?84rd?VJha=8ARt-IdC+i5CqK19#|>&nAs&gP`e|lkzqHT~tf6W?r|-u|xULkw}KQ_hXN&VfWPFugqD;2RAdGlKe_?&{5Ln zWfw{s(y(^6iJhebpi#In^w+t1@@xWgTWX4Em zmK@FSl%1U>{(%@W-9Qp^dspn*$p$>3R#Sb7Sh-Yi;f&$xiioU4&~8jSoW(a zS%woe|fw^V{Y8_h2!1q zE`H&K6uU3H1xYa|WE9|_Pr?v%TlFhcYiZmU;%T7SJc~pf#-jISV2a|c``8JYaV?%g zdYC2c>62_`N17RroRUJ$;4j!UAENl$io(@w_;JP;8Dc*2<3v?iG|CHr`SOS~<~@BG z4a*#amgaDpF!7UhaIrhZZH?n;7d}GW%XHy>u^DbfuIb0{q0q!5`#94@c^zljuSnJj z2{+Dq-iI+1?pyn$3wLrNlw>Jrq{3l9SIxII-rYKN!v1GTC&FhZ>!yf)^(17ytttD+ z<&zs*ClSS>a`bIScI*gdp{{M$JxP=*W0f&Pc-C%?1e_WUtRgrt&W8-Q>`)4y6?KOp zVYMZ45rQKdft(?SYx$dXS-PWc<78PJJ_`L{ZQEANgi~u|ocy#WX%Y$Zv8*V}2>c0p zI{aSeBpCNYECs&^Z^)hRRUC}OLhQ7`*~}(cJDhrw{WZ^}Lzoc%wtjy~gouc=83(?z zPtxIKgcGe#)WORYotM)zN}>i+p*^LMY8d_?%+^hZs5ekJj9|V(@D&6ciBLnDY-Rsv z!;)=(f3g<;513HdK*`G%pN}<0ol5CK(O2R;KguBq2hCSWrU5B1j|>AHycYmR=}Dvy zKf@`CNFjj%_DB%UcNAl`YnQocjcT$bxCIUdPxzo=QUVL zOFYMCKsFhy7Rk{fJ{0@R2S1@T+`d#;)JA1N@El>v2n%Iqs6j@<9#~JcI$S4=0^j*5 zLVM>K_?TLR7S+8%k;sow=FZlhOa5{ZmFhC%){j2(UhTdP6}n9Yq3&rp8}|}=jpbk1 zT8_K!jA-}(4j7A{ZFyf`);NL6;+O z$FCf7Gn`>LhH&Jn8M<^cqp%f7QC{JVgx=54LxMl}q5(}?xayV*AV%8MZH(dt5Xa11 z!yCH%w02RJ3e8P;x40Nd65iCmrv^* zP?8&a8Ocff@HX6yXVUFip=aWa&VT3I%MxoCviG)oKZypgCO$?~Y&7yzkk_`h6x1P{ z8M2gg+OaB0P77Fm{aVYpD&slSJAjqDQaxUBe+0z28nMVqW#Mj(hj!x;?q0d9e~Yk| zPxx!f`lCT|Pv?I1%{^<92!g9`U1*b z_K@C#w`8sxB^6lFn4lraq(;3UhxCLb`u0Zzx+ zOEZzq4n`B);cRiq^`Ik=Le@QHUSIBBM?nS(ts)nxlI=dkOXFp{96;zA+1Z_pQ{UKw zvZS*P#Y?}Sg->U@5yZOZklhh|IL>*O_>sQw4m=fI^+DV7li5pk*WQv^L_bmfZUI?x zX94=-J;@`?xx^28$8rg`8^0496WVPk9MGu0ESzW?A*dGqz`>QYq?beSU>>M>_LHnU z2&IvQW^zq?6@FWzgJH(^tT^tyv<7hHgr(XvSs^4mI28fkN7~LiBbbV5Qa%!Q5_`}$ z1=^PDmT|}i#=t(GR65pHr{ahMY5<4JiFIvsKRUA0hbZt@=>3%Da7>IatT=GH@Qs+) zCcud8(V9bk?ShVpwH+oq4W>ka0@_hT_aQ?T!ayq{%Sb_ETmeBfvIQ@2fptr~ckpKS z6|*%~CW!JR9ujd&lC!8_W3Em|Qdkl~ty=IN83j5fRWza$hxg-C^~rl#rmH(0ZBEC? zfjOluoDIDM2|C$jsBkq-omeh~#ia}=%!gB)b3t*mT%V3ni%w+z)t;jM;&u$7!Qsyr zKl*KP^Uudq?(_T3aFtRYo%UpY?HbbSu{~}2oVeDj+HF7U-YE*a^rj#BWy?XmemjQn z%@j_6ovV9r+Q|U4yHK3dxL`#n(x;P^&r=u41WtW=cqG9uzrrr9=mFvWGd?iZ1Y!kX@hLC=| z4SRswH#Mwv|Gg#CDcqe>j_9esyAre!(MF4OO9#RRPK_aHHRX}6^bb%yZ>+*tDTO)9 zIvc0&)b-IyqD1n)P!?p_{xAd5wKL!+X zQ#S)zMAyd&uRN>|4@@Zf*(R5o!Y4f^7Z5#p13kG7nMqC^OZ!I*b`pro$ zIp5!TE|(~woV7(YKwNHqxFVeO4B2iM4tMP73Y0UH-jnM`5yiY527L?-g68^g?AXf+n7kZp@jV*bMWFJZHUeP3WE=fBFY#UL!~>`NV=<7+>{#F+FvZD`y5GL5i=pDS$IK9M^+_o z9h9pMTq;G@>1cMO6scrVoTH&n56N-A8XT3v9r#dt%Lw5Vj+C-GNOrdmEKZJ;WJkc_ z*gko?Nc-u;>U2j6qT71%nx$V#`VMU_;(Y%i#y@9M>Q;eDQGTj#y(JW6mR4F)vBR<~ zB`zY!cW~jZuxPc;U=bQswZtkp&Sob)pvW2P8}JfYESGOCI{lV%6Rt#2VZa$ctsmsytqoggkBE;u-Rr;l546^Ec3$6}_^VH~e56rs`bax1ZeL#Z z8WZ1jAKwZBC12)lblSaTZHw>od)-`pLXG=9gS}EN_DhLE(3^;j`>A^O!hwOp=P2in z_mpuIEvDUPLcRLq=!=xVX1gH%5Nx^epmcv52B!l#J`j2wXRMd~zr%~6jG@l?%yK@_ z!*L-RLA1a3opLi+=T35k<374QALqlSfw7Zk!wD`72eHsI<6K_o_D~|;f_np&JM{-} zq;@{XohAOi5(>oWP=QvVCqQ!=`&b%0FD~I*dOY~+<&Q$`HUW{iOAU_iwl{njbH_%n z_tPb6us&SBf;w>Y@wYsv{R&JiP^e(25!VkZ*+|I*sNvOWHRR*tIi$u6o&;blhzGrN zP9cC|BTvGEE39*}Zd)LO-k#nTY)c4|>kFfwaQrn}J$K8%mUp|EwzHk~?&fq`lCs+A za-G%tt~zkB%C;@17GEWLdLQX|eEh>#`0dvWd`B6Y%d$)LP$u8H;q5RsD?U1yJVD(nq zpX>ErgKd-$>*C00yuA0~hz3lQ`!@tvqP(GG+&kC}Emx1aah1^-^uZf@Jh!_cXk>BD z*>1kkIj_+XUD&rJHCpHlj#7}0-`$>x;U;s>OJfB$hse0>8_iebppuTdgHk#6TMGa4 zrr`&_#Xj6)Ir=jkuhHS)VsES2p>!YtAM9GmOQlc!C`623pd$7XT?(cYq{jj{7?M;=2IF-B z?|1OehpQu^1TMLnv%oeKv;l011x*IuJYhPZQ3K?j0dFK|$12!3+PrYQ-o~+~s_G*V z$oZOs08y(cRY#^MxJH5ptT}|ac)w#a5fn0~2v5*5Pgp>~iLsA?k{s03K|PNK7$F@^ zMN-X5VmiJF9|kG8R|8+KDWF)qlER)6?JEqu7Ixq?GuzxQ5T)!`5TbUdM>LKw*O)Kn zZf^t5qgL=pTLzFurlIaGD+XRRIEi*m!CTj*FNjD-$41E{&BR+};5^96IB^v7=n7CL7YpE1sYm z(EODAh@uf`*!$RnL7VEd*gDRS8W|De;ymTMDePPBI2y{)3 zrO8A@N2b{{!fENqYIM*u5e!O|p9mdo!<3J%I$?~8$R6dg=5I;>QDx0zzFG5>ENed* z@GVpID4!f)T)g%_M0K=u={I7JHNRpH=N@ZjJNq;6J-C-$_NsAngqI$C{_+hAce(4D zHU#{~IM3l^R5my4SW6p%2$$X8c<{L&vi>ih1^wE4Bbf@ciJy7thflnBY;0%K)gS!N z)@#;X{lTlxo|&nv+fjE+*CY;=WgH*y21{32YT7#d+_AbHL)eU5d36``8gec%|T13t>M4 z(V5MrevO}|%q2R1sQQ~%?_}uI;@8X?{aJd|fK%P8J{`&It`gE4+4@W z{k1m$!dLKC?0I>BTVs$k^4(f~sgGP9{tIS+Q*U*f~@wrvP z^h=o9Yj#!L2r)2eWUB+1!#d~yT{Ult+||YiUrgyC3)adqGGJa^VSI;}j}WhFupy8V zryxQs?T(tWryu%f4SnTMdWTK$EcH3dCX+w3?uhPO!0)kXWLaabWzcPgI3IGB*I`fCT`~GS4|2zT)1`(--P1vvhgoM7Rlh4 zCqE*0de*Hn8g_SIv!R`4(EIQH0`KF?n;3=A)JTW1`HB5N^e!vJz)v*|~j;on1r0|PPs&8@iE5`9EF|Hg4Uex+i0HXPnc(?pea8TkH6J*S*de8| zHlE=W)})cq&>)3KrfzZ)>)0v`IXUq3)C)0E{=~D4FnJk|$n0cMF3^~sM6FHP z_F>M~JA&j;kaVcbHrO!;!N9^Z{1jvg%&W%FfFh+~aqy7DfG3)RgHH_O#CM@kY;$yn zBTe6iJWvRiI#dQ!$<@UHG@2^OqCvKzxC+%Gq#;xUT?bq-XR!IQ89z8tV~C-Yg?!=j zQTWmlW6r25f?sD82y>i*1$JrpN#vtwDcH&ulY<4GAPo=(!&s}2nm?S-TY<}k#ssn@ zEKSNXNcd_JDpzkSlm>pB0&v-AM#q7k5tL?VOcQ*#EKv-j3c_#5eyI=RyYa#!U$dNK z<~5u++^tXqV)nZmXZDbirZBK~ndn~^;>_dU=mt$zHv3@#_;>4J&t?ocy+upNfcHMR4eKWZhvIi^%ZXdg_s4GU z^4tI6-X8S{>e*X-nIjmmkU&yf1!&3dRI9{P&40OzN}(BzirBsvYdckcAMQ(|r7R=| z{g=Vwi0%f%`uw^}Nk2%-n>OPd_YBr@gKhzXYBvIm&Nrq03b)VL2sodX4Hl4)< zuO~(&4Cpfi2O)pJh~@eh(*8ildNTzTAgE{5Rs&M%mPf7{`PVZ_iTf@Zi0l9N$Xy*J2dGnkfZq5l%me_2AjN9chr3`?*h1>Pl+# z!QUeo1w*|4W5=|2*uh$?>u$H@l_ar_hT$R5c2DN!3z&+5Hu4oL`NkMn`5GRSM;7sj z-hh7QN89%AKYZ`HY5iHK@~-)e9JO;)cO)q_bSIYH4>XfHw(1iteAe0N-(sUfJ*!NB zdDwK|un4#SK7328_IZyf$}}DPnHdETGVSiQwiDd}rBo~u9^5Vd6rN`v{1sS!M=-%7 z)UL{1M9GoeWAVJ{ZjN@ixmsdWgbv9NEXA;r<*I(GOe{Z;_dzO$YIY=q@fo~ycnJ?%{*j-i3l&y6S7l|Ou`KI>f*i@4zHPedTq{C_ zq|4If&$p6qL2r09u9cK|9?OiV9xFiDZ4o7b_QQpw1a&ywlq5q%YKdzPfUnUypxZJi z98^++ySfkDsJ^?Qgh?4OViwd88GvAnnIuNJdd9GXBiXkGSeTW_NL+CNBVoK`Nt2{3lSblnjzU&ey2Cy%{pcyrv0st6=FDf(8@ALWKaVKOb8d z;@*|A@Sq=yPv!h}G3X5B?7Y?fF0mc-Q4QGtAeoi0{kD1t($BYOl@K`^9RJl z@y~&4)7$lzrZuRpX}d{UgVc|Ab!Qib9)-K3vEQR_JJ{X6h&j^RqJFZ{EC#q#tYej! zPoW-^tP{#Z{?|6<5-6u}vma%5;vvtO5GXiQ1+Ro_+l`a6yp9f8`_b50vyd=o=@T%@ zJB9n%5q)!W0bC!V$-ea?_xo0L%~Q7=`B^L#=`@E`jCV57^||_RR%%_YJNYlx8VSzZ zkrkcF1W9^>mA!K0h89jtJ+yEdcl9~>o_2}%03d@5yR>DBmd^wkoCV3BYi{W;^^GpZ zwwwImiyNmf+EbUSF?nBESVQ5xJzYLEoO`RiSbyv@$j=Osx{hv3ntQ5w8(1D?EqbY( z*PH+{%9Vigy?a{hOaiC0PkDsil;!|h-HUw$eY;T;KYur7WRAOV3FW&m#-AIf{F&fw zOmi*yD1Y)1?ftzN4;sg|W&C4rynbPJ#%eq-aXW1+^mPCGYu8c}mH^C|6Pz$Z2|q4a zu(90L#)1bA_+9i9484Fbfj*IEo538Re=>H>&lu=U*Ods4foW{SSU^JYQ7yj@Lcfe8*KFbb;(I(;CO1EbdZ8}*> zSeOwy4g!T74g7Y?NjbX3Z9(hGqM^$Y=L=cn679FVY$_|MOQf|kMjBqyQ5{ysk*NU- zH^gR|U31AQuFSBol1+pzhX;W~iT;1u-ak&Rs>&B#`_$>`Q^l#y=}sk9LM7~~l%c{j za5`y1b*v=2o04=igO!j#U?M3s;|)F>3q=z!+Pf=dXkyd~1SWW+ulVIeE=c1rPJk#U zBqL$KA;_B<=QAP=nfDoI?)yjp5wD8Jl=*4Ur?rTW zffF49(66N`);wLbS2%w6ysNun37-yN*8TXLJna~FMQ)ttZmc><=Y~&K602z-aaHV3 z)A`1}FCIwr7sX%9zw!G?yO5)$?tS*%_Okm)rVib|x@!(3a)2v3x4#3k^{i(6D!=*X z}#xxtpBN z_E@Q6Mb6*H6ZnU*a~=Zo@p4=T`!>kO(s{2$oPfaM}llVIyIz3*oBa9YmB;) zR0SoYFi_)JPG6}iXs6PhU+%x!>8&j6@gD5HLYfkBD}w7u-5 zy-m?{f%*;=VqPkhx!6q~s6xPY;pWu-IsI!^q)%N(>Gb>O_N12Om$~N^u1d}IoO)r; z(qhqf(_LNeY=77CM6p^d`>8!+XMseFOE(7+y?wNF%uS>=ImPtav{OjU*F|Qp-RSrQ z-*wJ%Vuz?${7KYz{4yRdf<452+x{aY%C4JqzwTC?Jy9xf2`$~alH5~VY@-lp;1+w+ zR83)4N=QsPJ8^pBr#Jcb4|;vb)v;%9jiRz3h#|$}H2zJCb_EK!8%2Z;2%Tm~hfUb>;zxL=Z*P4&@1-55lI&G96U6w;BXlMXDj$o=s2C{}U z#)}y%bixY&6gH!g%*qV2b@8_VP|XsU5)TG zl8sF!u!RPWn?U)()o9>#$*QutsQ0e`cFX9(x#N zI<491V1$6X34u3-#+Nk8*bt^iYity;aXsQDs05zow|bb4tIU!UHcBBLPMsO1O=cX= zS*yAk%OSm7hv8WSoEVWOZx!y6J)u0|uL9NYFy zQbPz&vRUFQdF6UK47LVH^PT>IjlOHT#XI$&?tDk(X=LT=r&hM!x$WpUr;E?| zuUua&KD*@O23Q^WjNLKvz9%kT1?Zf7?njH4ymD&gHVZUk@coWJ`g03jdTFJh5r8}H zwYOe>>vbb16*OB&Cf)GFcOat_#8F0NMzlW;EC09?ySzBkc7JihKh6NnrwtE*jIwz% zs4t*gFfbivC1}(m>fCcV<={SU!TU=OExitQ-Q6o! zPHx+5SpJ}!WX|ZDAHl1_NY&|jz?Ad{z;Xxf8Ynve#8d@#+J z)hP(3>8C7DYcx8z&SBGs4$o>xQ^j7V)dP)P3!U}+o9@;&>z4mEPFrQKZT%T4;%(%@ z;bzLdAK`O2_!)n!0%gjb({~22|1b<=EwQV^PhGY{|-1klMT6Yh5~FYWJfG34>bSDy2# z;YUUHo7}u4q`%I7j>M+VZ;s4=C>jrzT(GzZYK|8R>g-a`W0Z%srR4&pGEMymyW(FRg*` zrI#+cXhb1=w!+;STxXe_Jp0-^W}MpmI4IM2-S-La36JICgYLWJiO0hGEt3zK@oR)5 z=COxM4mWC6nXxPW>`x)f*}%$Kph3@=-0&Q~oDNFwVC}bWF%LAjo1y;{F1SoCS-SLt zFXPqY$&Vet$oTQ=2HLeStrfMcrqr@osc713Xtcf2no$ofY$L$0Kr3wfi_x~q!_G}$222QxQ-nMTFx2kRZ40M9n&gY+55lGe26+*QJk1Ty)G74ikI|4f3- z_1$6kb-fb{<3QTc*9r#j%MJ6sFvUaKu+&%(kdjE5!|r>Y=B@&B@EKz^{K}RxiL@2ya2cM<90=Q>p~i^S8K=HXlvd@Ri?Zh@jR>G%ROpT6?RhKhwcjL3*maH zq3OleEQGbjToOS>b1H6I%l@e(LNy24Aw!)8TlQf*y^-h7)4*}G-?}Pn|#BYK-~c9^gQzCh=sRtdBC$cB5eUFaVHxvD5~Gjv|^Os zE83*fIZ41{nY7)YNp1K1vYVZq;#q)Qguqd|RLaP<9=1=a$J-1R@7 zfn($d{cEt`NaUHwGk3p$9z&7RNgFipQs+rJl6?U|KSh^5b8;s5aIq5(|DT+B1k$K) z3xe#?2vZrYV_+c8MzH;W_m7H`G%)h`SOJj%H z$yqcI@VB`D?oS?r9uoT40?sxC=;uwGx6EXl06)8QoJMEPMDm`#?QGrgul(HbXen|G z3IM##>~SIz(1L(#@%RxwHam_mIQnNIPaO|H{oP5&k2CsdKzj9Q(=;9Lk{Pt8Oj%2< zJs=w}$%Jl@Y`Y+{UhvF)5oPb%ao;;Ov;UF$Z^yJ%wa>>n&pFMqmOuZKB6U=7 z)MF_`;yuev1kcJQH7615K7klVxb_pz{X*~p&RuaVoNtrR^)2ZHw!ZTZdCc{_gz3eW$#)XGNvzDiJ_|0e7i^d_lJyfY`_ zINslG>fk$_bU0p(;&AJ3JADE6?qlLC(15A8F5-L;=GI<6=&09+=UJz`<7i?|z1wAh zTkKie5Ty5~$TKJBzk<$*HE`bNMuP4|KjecXM|q759xisOIPN5;`SXHm3|>N>)^0tb znrG>y-qU4JAWroqmDPWl1~2WdOhr?r0Cc=MLfdCWp+ngvD)`!(5(+9Ece_-;^aKkA zzL_0@7hWU8JI5d!H`%U$X`5jWewvzs+uL+_1dSaqlb4pi?4pW4BxGE|#y#4^dE?J< z%p)!Nm;ZB__sqQ?C6b2_6{>rJiqWj^bkv+#(We$mate88!gAj;(L=YarJ(*FkGP`| zzmhyTM)GM()grE|FDKC2aAsqnTmZPo&*roiRbyu638HE`80_f@XiVDyeez4ep+&*q z4XzhG*mW#Ym-mkOTbZ_l)2IHYZG~&-xEgTCcyE2wbOUEuQia)bMO5fG)!>RFAQY29 z%Y{u9DY5f;q-Zy2_DB&~nz-w8(Rlf~>aaTs4b=TvHiFv;jq!{D&O#=r7~F>MM7*@crq`=JDshZ6!77@SyR zON~|@mISKZ&O~gC?KlIHV%S2mdoIx!$rR>wA_>e05+Xm~je4+KjBzr_(OBL%!Vvf= z{86d|-4vM28Ium}y1qPXJL|qXgZA9<6HMJ70y!HKr`F`9;0cJgp8SGycrb0rD$+7e|2=}M40j>>6=X&D zKslJ#Z~;GC5&>I=t}0<2Rshk&9`sYRkcbx^i_`Y7e^43m0xBp;+8SxbAmaenF3?)` zeFOvy`jq<-%sUv+YRv%S2JONzJLZHL8YB+6Rg8Uvn=0S2Ko}Eb4ez{t{ZsdC{m}YX z{_^f;?^%55`j7Tf?u0<=1HuFdRaL)d*dTMH3UR9JLVje`qrO-Gmt7*SvI9ttW`wep zeIR{&y@b0I)b`mVwO zEkdktY&ZqnKiKP^rg_kKSICqa#sFR%8TqhW-l!_Z4%Sp1jE?k$IQ|SuK zV`z9#h-F7JoHrb*?AgZ}YAI;MW{jcLi;YW?cMoW`@Z#}@X~?J?A8Q}a`XokI)Vt(w z2k3$u$e(?lnB|r$j$4lvBWS`GRgP5P+S?nPjSQ5jTgA}jLYRp+MAH{yq(Gg3rLl)P zQ0COJmjdC_>{Ha$I19^*iH7xl^oxa0(swDp_6{B2;=Es?%upN%U!#A+QyXMkL)mjXt#obRSkx`h9YzxAQ?NMhKE2}v#1oqSW|;_ z3_k0$^y`_?(Yz%OctfHtR>z#tVJj<>YgA4Zlvca_nyuH;`mC)t`h#_)?ELVej1rzV zFn1B8cgpT$J|i&tc(RWy(Q7Zx_x564<%nFyS*)_SzLy*oLS*ceT$G~^*csU$hm01x zd<)6lkd}}k(a2J%yJw#_SgJ|fBkLb6;anc2s`2x(lBAs>g*$NyTTTItK{e?5dAvlt zX^ln7)=HHKqYY@H4KRZOO88n3dTA*$s%jG1IKqNGMkZ(^SxQRBQy9*GDut98ziv~v z9>j{8SELxo2={U{WH$pWXOtBTfgH+z1qp0Z@eiU^f~pojf%}-#g=X&ASJNYQ|0e4H zddhpWT1YRa+|{3SA?tXKeUn>VapQ;MAMU$C=Bo+U>!SI~;@_X^uK2Jwr<(ZOgRV0k zbKF=z_<#4sQ&zmoT?FpeW#9G_-+wUa|ILkFNK z@V@Umk0y2;T=BpTzx?1$2V^<6ahV6EUwrAnczV3pb)bCsh8w?0{sZ56pp35FTXARWy#blE1JH8N`(J=}!~gPvhu2hrp;zG7)t*x(A)| z!r~6PvCB`ytX{hFn||twYvlSwR3zer0T@M%Uo;#)aeWCxMKp?jW-6_#at%0uCHKK{ zSj4f})B$Y=c$wi7BMB5nMHu`=6&aP6nr$%E#Rkjqf#R3FXsTQxFTL37yER5}wQT;L z;@{rXx6%CxUH{o~DmwdZAslBpgdETN#Rz)px#RG!=Es+JlD*~4zK|q3< zZj%-xl%5apG6Vyo(`VBbOuF{N!!_4(6<+A@oHe#p{ z@%4t-X)i80$w6JC9Qckk7*2)lyS~!y5MyhIBDQhd1UUkrYf(>$Q^_#smK55bB41Mr zP&zqS*_@sbuxlWaZBwZ8k$5g`lux^jpH>;y6oi=oxJDSO1u!tI2^D-#J8^LD0>@j{ zR(2S4X0$@_H||}FIRz3zG)9mdmxLfupgpD>xCwX&3(ZiYnwg-FIGnChrd2QyC*@^0 z#o$c0Y$KzB$B?h!$1SD>R#uiBW3koRi-$*u?;%7(xW3bH^AFr)xtJYNT zQ#eSxsUN6k;@5CK6DFr=5Qrp!_ZXGKn@!$-NL(6~&?Z5vy#({T2|=1Yfr6d^yDE=6 zs{!c^@4A$UvC`J$)mmwh#;uzai|j!IK`dk|MCtMN0!$9b1=5mFBKBLt9NB6v>=2*C ztxx6Y4=AiiVZ5qCqJ)OKQkXd5Sq+wA@SRVpq*<=nPR+ryGLEu5%X5Y;R^ZEVci*LX5?5xRGe>C#GH#=6kiP!7LgtCjd|6$Mavl`SDV_ zPB7|}r}X-|Z+}RK{I+fSX`3E9MPF^vRoUK*rcCF=3ZjkQ*0XsEr|qt1*&?z-_tBraZ#9nTBn`25p!5et&xJHIIV#cbx6FDs36QW$2mb_x}su zuc2Qe#3_*2S54#dW&0_bEB9V@pJq1K@;WxcV( zhOzAy#t@D%x)lc>9vFX68K#HX4$nAn+FR*=Cm!3k^U@x}j2{jU@o+eXM$EL^b~vrD z8l2Wv+zo7B+I+(7-{@OzCcM)FB~f5(%x7})cfUiILSJV7UIvyu|LUtR0hTP8JY_jQ z`~0sy^(hc8uf5~#*Fs+25RdO)Jk;^(kBls3WA#Sl%?`eu!iKIH_U}h7?3(K9XHP<& z@=KFv&~9J)=|#rh$cMl~{OS`=7{hZII}!A`=Z52mv1@%WZhn}x&%HRgiq(9iQhYn{V}+GGj$Yai)wy4e_q(NSzXdc~ zP0oUlCTz#5yaK{1T^DRCkoN1SdY<)!j=&b37?VD92Z`pODM<2OH?-uy*@^X$#!XRd zHK5w@Q{cLS`#l;5Do}5&f~iSKMPrL?&~i&pMHZRxn=vecmBcG*@E=aKY)>WZyAe(= zS|-OgCafiF?;aCj_*k@Y{y1^$4`~BUSW^zTL`sJCnn>ag@wO&-b~O0X==jqZfZq0M zi$mHoYyw=j+h2kPUza-+uTAAOB`PI@wfS4IHe{L3n&WHX%|1zvG5-&<%M!_5aOa)R$*F+fsZp@d zpuvXJatw%EL9_~lG%Qz@;k<&5Y{iK^j^*{v1>70~rmTVHE+}x&TwoJfMaKgT)D8+z z=)k5YEA$NgGn`I5MKl4?&XI_KTx4Jek%^}QU@W)m-T7gvBvfDcl@z;9mCq;N4I3=N;QlsMGU zXyCSFwo+xHvXMmi)-Yj@iZI9u*b6?Q8P<=mU_U6~6MGS@34t44B**GNt~fguvM>b* zmKceIw4rH1OC#H6s3-tq8&R^(8rxP{LXq%CNDJ~NIjJh;HFdL&jww|h?1VBrheQAt z3W{S=h|Gl_1C^F)lt^Vejb$ppvAgPM_>nDs|NiVayXmt)!_<)U8^u1Rp2~N}pBz(X zRmQ=Or08RW6$IY7wX4hZ%^g*ok8bZlne0N1B>p3AcYV#W>Dbd;s-COQ+TxsuII;7Z zhy{NEN~J-MNSzh>pm1hk(~sJKC@OqTMEs--keu?EC+QTD0hS|93?;G3u}E*nzINhe zw4sN4^xafm1ymjRHQjpyov%$Puf~$oN5nXXm84M?j0c~F{)32)_Xc-)Wkm7IufC3i z;9fWKr*K%%txnyLRhE&}JbYWlyRNg3Ordp9N^=?z2!D`F1aDLAC*TV%e9cgC0#^eP*_eXAg~92Za~Wz` zBC^_9XhI;_ar`|9Isv-I?5^XW2Yf|bA%i}Q03OrVHRv9$e4dWIHC+9VvY;_w)t@h-EM11-TSx~7t7xQ6{X@OCWXu?Do` zJmjuJ^}~fv1hSox@@D=J@JW3aM+lIbAoZV%-cH+B`_Sl{N0+I{MC&{d>EuvqC{~Y4 z5wj4|4H|MDT1T$p@7*XabJ~tfS4Mk+d*hbw9B*P9_Px$V%>Cioq-?ijlusLY2jXGq zNWUz%fY~q~wNvxQU?fAH91BeLJhoLlG%Ku(DCiCpeU$TO!>ssR z2Kjay+>Y#FpGvz2C3F={8vPepfJktdTY@Kmi$;%ctl^AvY+>1erU9+Si53Dxa6o{< zFav8UHu@k?S`(siU1)> z-;$XL-J#2}Y!`TR22G9ba85vq1%?SE6K9#I#|cH!a=NhmaCSY9Uh3zuR4$=l4{5u} zC7d)&(Wx13Z}4ptoHLe0yHBA!AK`N>jXN_yMoE-2sC+|?nteWG@6ja{ zi-MOSiM?)7M)Fv-IIp{7WF!e$L_z0vJlly5N?tDqfH0Fyfr5|?yd&=Co6Msd;7Iz8 zQ7lk=bF9B5|)qFmK*1rI> z)8;>74O6Z52QgaeS>(<@U}quAOylh!M0}7}-}&XL+qwYfkh78VUM;8yXS9h$`ydAb z32N{ljruPnNTM)6YeoIimE8pjev88AR+~Mw3% zg{22L)0qBVGvV!^6OU1)N_cM=(QSt|-EaJhV1{oImtU6<29?{*cQ zT$q2)wQF_!fBlB2g1BQPMr^|abb?o;ad{zaaaNU)#uJ<-G=&aM#~GkWkW%;zB6`${ z#%LkuNV4RRTwN!U>l*H8jzE*h;26~tgIT(|P|J{&+Hc!?X^yixCGB`OI+d?ii``)1 zs`ucjg6@*77h4(W;nuM|a4Q7iin7-O@guTt(CROxay@RJNUld=S^c-}U1xO<=DZ%A zEAg1%jY6EWQlcnntiQZ(@1ERV$Wh7EvWuPiz8*^qt?Mo2C{qR-U0n3j+FN=QXa}R+ zqLkZY<+3=<$o40t-6wLTF`O=ADY=*|+&xjb(Qc=^+sZhQMeOd`IJ!H>qMbG8UzWh1 zC$WU^>YlwA`%)fX2oQo~e2nqfrI;vdEAU`PWp zghP9384Izm+l%Uy)x6V17-VCwO7Jqoj8niIf}st%tua9&5Z|jFLYOhXzcFrqU&h@A zT{XU}aA+>1@zSFhhrUp_--}fX#YaE9Xds>3G~VZ=$0>K+H*N3RVQM^m`k!|NGTX^vc+`^S;-$9NBZy8!1t2oIjp%yafFz`TgKc z)%Ibq{bA_c?-Ux%Zy&r7We7rU)6t1+eyKA*(c9GDR1hZoD8v}Y4yM>0Zv!_e*7OA> z2Jk@fVX`GGF{?Qk)coiz(4$(Eg*f?2jfOf-`=y(MhTLcw9Ki&dGFD5x0yCs_C#*tP z_-q?Oo)sSZmMz5^883<)zrr8%oJ#dJmo86W$W3)qHBx+^z26m1b^E|Zbbfb#ii#_W z=~H{ik2$H&Y{F!ImiueRaku)o9O?gX`Nln)Hf=glS-wZQ>*vg+$0pLTqAO-@60@(^ z+LbsyzgTpN#hb>RpC>=-_IK^t^V4*G);!laP`Jrm+FP(YyLLrq4cN}g@44v}(Z$}1 ze6rA&yL3KCz=i%RQaN|EeV|bA{2A%@x$(Kqb@O%?iXGl!D)e7lFC6mh<*BnL;;H5I z*RGGJf~9j-{OV3zRv8oj;`+r$++B%8f=Okrb7+3PFz_WOTKSXc3hxtC=yROeU34QY z!sL*d?^M%^id$#k-m4o!tKg}`FPm~_p(EI<**Fw(FdhLUel~=iwE784;x>aH<*2Wh z3w&M`DZskK5Q;!>L%+hP=oGrRpYTx4Uj}U=g0rbro5HyiD;*rmAb6~r94!^omGC9> zZY7lqK?EMw{jP0&$rJv#t(5X~davz2OsVo>M`=uq0>az&?k=q$?H1jxui`2tMf+`C z7%r>cs=nKg`D(po$EDUy2qYR>fiV;9W|&rZHAM7jQt7T<&;E#9w_A<8WxPMCMZIRa+^D8Eln$!~fv~)ds8OmB#9c*}< zlC6;%8%2d%-6_vkG??Z)k;*@Wr;?Q-`hZji(tWrTiiF1JvWRRKZ(IyXiAK|%B6oc6 zViZ*Q0oh!W_ncjrk3hBUrdx0Iq3fr@Ue{9eNV5#N8@8WRp4GI5x}#JYr@lwJvE6j* zxD~{hb#f)qz5KRA*0MOdO4mhlUxQ|$LOl593}6ADBW}Wq3mwZAdRU_veT*&G`lFH( zHRPUjhCtE>A^;l)O?}9ukDMceaBtYAYCyC0#(*)*Xf}VK;C3^J-(i*V)`97)jEyqG zXlDGuggB-FoUoM-Lom2)w;J#y3^l>uP!BX`7erx%GM;IaG)dle%kq#kU5&$$m|LLS zD#AcL+kvf7?n!GX=w%Wn_PDrp-%MZouEX zm3Ul|X)A-ZCm^eNI*oVR%55vzZyVnJQAq1$Gsgkt@s=B2{wMYc-_nsrjNLU3?=1q`%TH(%! z2s{*Quz`rQPX~~N-vQ?Wwq*_f?+m7$oIBacWiSF}!iP4$F%R0`fcX2+L$6WChUX$L zVtG9NSo+GmAJ4yTVDhacbVo6Cc=jk> zAO78s=ihPXZ9kj=8p`SVI6a)TX`QSNQ(77`^RF^}5Aog>?yjvk4gYY9o;<8W8Q1MF{+Oz{ zESSa%dT$$td4EkjZJM#60VAGw^8F%S=JRFRZ(G)LTkdmMR`>>-zB6HpE{Zk9G#SoQ zvYdyJBF15u!aXwx9%-d#-bcLgesPWwH~IE>%s z&(*-w%y-LbE8ccIj5`Gw#SO5EUpwxWtueFyopPev?hS<9=Jn;cSVkCXoI2o zVz$&wcq(|Bzdv{O&BWk08c?Mr9)rK)Ze;tI-mdj_tWIF&)yH9$?*3qXqYR{ znVcE+zEJ)%>sO(tzjP(@|4zL2_G@Q%Uv$w*|Lxb#oswyfk>kya0Kcd3j*IdC(&URQ z`92IQ{6f6+hLy8;+zQ`3pK^Qai5X0J=9@1+`}_~S@Uzd~zu^f`hF|*W6X%R9L3&<= zbmw<~y|crNAFsYTG6JW!Uw!rWzyIxTpLl}N@W41L?*I-Xbbs!-%`4gQt+(F#B}Ta= zzq|hzU7I&|cXxD5UbwCL(1nw4y(XB)cgdYIZXUUC^U9GAohifm_WN(zfSK#<7bmlH z#TEBqlsXL`d-}jqAEWlQcS7#-(Px+3arNY6_b)#9<91CO(@ANKg(V*9~@dVasN@D$N-t8^u{f3r% zZ?1}TV&y)HbP(KiD<8WfM#i(P)_NTNfjQR?n0VU35f(zNhOVaUrfb&nn#J3%aX}dA z!sSCl!#?f`DX|zx?F6nRqjsqp6DWs9eLRnw<#gbOZ{!6sd;p)gt;+{6`LoRD{XYy< zwhy7v*07p42K{_SBR5-a)>yYAfn!)7vN{D7E^*idd8oqKdy6q)b8sHpQV(odwMy(x z&Zy=b!i=whwZ{Jzq1gocqZV|c6xo|&vt46rhNn&Vy|-=1X_$_U@fY}{Ih|N4199JFpc~jTC~2; z=Uq$r$&-i=X|PA1H}TaYpap{)A$fAIL{`B|9!LbWnob_cYh03L8gbH6`Q*t#32%aB zJwr7zpF_1BiEe9J>PfN`vxk$W)e-nV8hmq7!@X(xj@`A^KzgaRm72iAUjIW1jix~NK-apFcw}5 z7B4)N1+y>U?>`hQU^PJSuu+r^@QGkG8z?&2dGylG3B+`zn1GaOpr{BQ(LGzdyo&uy zbXZ@a$XVHlTy>O*zIJCbd-RpgPI~6#0ued-pGP~7Up{(C5C9cDogrAzG?_j2cL<6t zn*5;-{1~Glj+O$bfq44;&;IZT$tD*_z#$yFS^g(zz?`^%j?6s%1|NeRr9dwTX5JH7 zaQxUzjidp$^O*&aATm?v30^KA*Ab|H1SHuKp(!N80*Y;SWbnbfB$;yx;5iDeC}bEl zRL>Ty5typr3VRE*1N`w$X*#grJp z!sLK8E9{32667?50KbHwEF6q-)HvB7M2+wi22y_hO@^t!-a||Hbm~%baJE&KjEB9g z@Ih>`AW@;m!~;iw=Fk{GE;1bwMr|xi>MRujpA=jrBImY7o>nBah4kR3BOR8I2!iV{ zuoU{KU4wr)$f0W9zDZ4rl!uKryims2Lh~+gVva9opHf6yZ(M_BO6po3Iena8Zbgo8 zW{oOPmI5zQam^{~6jHT)Hi}5yCv>m=8*cF@D0hl3MHPxIhd4HE7-=Se8QeumZ$Iwe z^;&}>)hI{~hrHvFvKw@R9*M2AMg{^g?84I(GfvoUkU0e{pXec!3~E4%`Tqmq8hTn3d&h(lJJ;J=5B>If!gHW-(r~la1um|GNwiRXbK7_|{?F$>lN`$;h;n%o!XdrU1O25Mg${>7$i>Furo8YpZ7s|LE08z*T0~ypY-Jbx zs%Sm5Y2sg?{X>ZAkBxgY0oK3@uizCh#<^h0M)3qg^p78N=-ij9XeT`5`Z4RcAAd~_L(j!S)O2(={rm$G`L{U#RzSm1u>-DPHMA;7 zfS2FZt#AOSsPpBN;-0ok;4=lPt;^~L@Q`_83752!2LTum57L6vDL5c=mQ^^VkWo09 zA9955S_TzM*&31t>4Q;19bnuBg68-dmNJ*85PG-9K!{_YtcIJye9DC~8@GVU0vhVY zaVcpDoul}RdwLABQ2!d-=N4M(Fl8yCYv{&t3$zQIp5gQyfpOUrh>HLd6p_NfIwnvz zESt%ZLvV2haaIRd6^1*7I%d2Gn(amW{Xh%g8NJA>p$Ve|?v`kn5+7uh53#KBFx4cv zpUNQKp%m3>wV8R2pZVc9Xq?^?I>HP-S))RVI-GGdn;bPzCu%Q6asp}BkjJWVBt*`a zP2%CN4ejKC)sr5;JrE>g!b7{M5Y-|`E4H^dyo^#GHEt0Y5OhzcKB&h!F@zzx{E0*g zSaecU<3KOkL>9nv`_vIMf6#!rodB3`rA*nbq^pK?qFNA5@o)M4RHbL4yu8^S&Q_5^ z8n`kU>2gCF@))uNIE4Z3;HNDu3hC$(E^_~Y=mced9;`mB1;*vCi#>X980r2H`c;w6 zp?y{WZ>b5@8`wIf7tkm;WiJdmby7$;{G3y*@oSiVi1K6gf^Yo$IO13II% zp#Qxb^Uv2sZ7bWla6(Y0#4>nvgIhwsbZ`v4>qu3PRlKClBhbWfmi?=LhnyS_w>?2% z5dmFh>BYDMhJhbru@t)F$u8mmEu_Lt6L8twzM5Fv57 zDZ#X3AuA^^pLkKokzhvTMse3&+?VnRLg`l`xR-JQOwCq-<#5&&G($y88YRKqPIP#dzS3s$92Q#_}A5-hEkeR$I69D|fJ*$?i#^C4u^x@f*1T z2`Wf#aB;WrY_(3N*4nkTd$FXTKA}~2U(fp0gLv?vuU4b(eWmgsty?QcW1!`B=k~4_ z5;JMmv#$b0b+09*MSEo_*M|cRUC&`N=-73U?ZN7(Z*c8i(YK~FRH9sI@7fHNvYCBl zNH><<{kbd+4hefSE76Z>wAYd)1y;+F(!z1~L$<)EB}S#F_hcX%v}6gT9pMdpAD`DBIo+FXr4hkf?6$_vM3+#lP=* z_71YIoAu!RbBeUyTjAg>+vVp;Z=gI-J}@BH(?D$5y!`gLsqc8>38k;fgI=Ce^*_@<``XP78q`oO?JC(*kHgSTwUI(()H7^d*Ry?%iSg>!WKLa~*4L>@TkFET%T)W2reGOt@W3>7#Z% z)=7!&DKA}d{EN5kSn+2&y7&LtrKz8Ksbw4cm!;C_D-OK!i4<+`@Xs1Zb^d9^O&uPv zKiT!`_Z8j~P5$y5sbX|#d{y!31#{Q*?-F2$y>Dqxp-@mK{>e$Y{o5;!NYC@mcZ!b`{R5(R zR=Sv=g8!(Gw}hQ#*X5)eg{)~e)$8H?->xF0J*WCmPU*j02Z|RthwX<1uGb9# zZoVx%CN#2-8V!|4$GcN|B}QzgCjEnIR$;h1tI4}dtwXAi@+Q{fP5ZkWY9%z+Tq!F* zuJOJIt__bX65~VN-C}QUXwbK^*w58$?F@B@*&ZmfWz|zuevdtr7^0#4-Gl*7f*8tM zQ>VLMXbjd#p|7X(m{qj4$4O!k68$|%YV-`>g?vaiQ+@4z9I6EJJ4+9LyncxhiU#*Lu~GO_qWmY>+Ip9<-oB1uaNi$M{1jHT)6C zU(W0)6)gH>p+MufGLYc;S+84vL4Qwbe02179ilqahI@B(z&iCAFubGFXfB^?QRTS52HKm}yVVY1)|s zgl1$xCaZu$Mhcziw^U7NEFngLZQGbkOyftzjxr8L9JWy$0RsvQ*HVyoHfXkQgRx!In4{b=>meY|v+R5c;el+BU+8G?3GuZtjMR=- zz>;MULGwjQ2WwbZL)7V5kF=8@f*X4jfzw!PJ9>ALZ#Fpc76hF~x+E6dUJa{I&+_sC zRNKL%j1;U#w6OJnfhbU8A!u$(_CMg>ql5-21P*@K@B)}7-UgFX3zgG`b_m7{S9q6Q|(hYfV8^jciFMNUV7$8~n^0%&BWoX8sP5b+^&$o5pn`>)9wLOzYvN;~g zUEX$O$ZP!8TW`P3zbOyUy!hPY+2F06)!ogs+tB~Ei$|7>ECGk|l5H0ozf8C_uyPhF zo6lK^KV$K3pOH5rU+a7$g7=E?vghR+Ch>mp6W^J!VZ;GX8^=AeVHWswFPePw^2;x} z=%J3wFBf9-vn(f-feX)5zyU2~!<|cRTQc*x_XofG_Ek*Fy&v1U4fntK=I!4Kaob-| zbAHWw=Kc*!Km2M_@vL_hf4xyOM$mFu4l&PQOxv7Jhh;ncPPaB6?=%{)!E2dA`fHa7 z?|-Lf_cm>pX}QzmZu|WMK3`4~ry2Ouf9*81RpSPF>r^=KV`#ptA`H%RJKvlJ{uy(d zehVC9uTRs48}J*J2ZG=*KtJYq4DT`cctaV^u;=t4ZpNAZ+p4sY`OLoC(5@48gmKS= zchW+qTy+J!)Rl2I4TTvhaNIx827F4J@FatOaJiJ#UmfGJ7SGc=D_dC`~9rRH;tTv z-@bOS&CdZd{!3Rrgns|q*Xs0xFZ}9LpEu(bzhlmB4?Vtl8>!eS-LQL@x@n0 zF7CLv2jIB)PK%LG&4xdO5w?0RvSf<>{HoZnVFY(i#D*oE=GES}9?HJi2R`NBuk=6( zw!6hIe({;fXP4Z5`-o=0rs$eSmu$FiL_fRcH@~H^B@32BwwW?qawlXN0PflJh|E;ZXYAyR{n2#iAvak{E&7o?4EmX(;TAB3F=n={8xN(o*7&L!iP;3u=<1n8v z8y6*x;6kVJW-sWjz*T{U%=RK084YQ_uN;wBv4N&LigPJNv$J9Np!J$`Bu|=f1T8RC zi=h*toB`!l64-JAr*|iUS5#Bo1yb4N3#@=`oBUy35y`2V2=Rjw+mWpZSU-U*XBYi@UhlW0CUBY(k5JbS$K~~!YnlD~3&8|}H zW*|b@3Gnw$5M@_|Hb5rLT8`KXBAr&Gbd*+=E}1YPg7zB;@E9-1tytSdUa(F+nLYaS z#Na=#TD5>}Uby5+IvD}4o~Y3?-jSKj$PoySHVMFbSCR}kY`S~qGeh(w=-1R?a)9d} z$6*LGXt%8EoPY@t1_7-86)Gs#S$Kzfyz}VYbo8D8*?$sz%E5&ASCG1Ac1A=AevWq# zT@IDY9IgBh;lz{`D4h_VC1oJv3Jt}!TP~&ql!szq8~%A*>;UM^qTNM9$zb$gTTn|i zV@ULC>DBP#@+J?7SL_X2>~f@T4c6cX!~>iPK(;eK_J`yJ>=9~RDo4Uo2uL2mPr;Ni4-czI7*{OX@yX2QAdb_ zMD=ow6QB^Hg;--wMNW{2d;`E#17gLDab5zL=#cg zNg$#OvWCbwgTTX2UOlfs<$zxq7eeC^_Y=qaK|~MrtEOyEA@QkkP|P zj@PgbTg^*ImDai!sn-V(!-@46!-sO7ZGAl0+NB6%D#B4@%|c61T8#J75Tbz$DWd+F z4KRd&^JcJ#foDb)TzU>KBx=@6GLlGA1M#;G?a21C6*y7A-~; zrV+4X8)UfOG)CyXbwYlQA_3=TTm}pL2VFIe2OjDF3ZfNnJ%Z4fLFKJmdm-%Q^LB49ZoWomh$l6YUrQZq0;AhS%piL z&_~_bAedjE7x?r3>6d$vN$-dqFn32kM4DQhKJOQziUgEftJ)h_jZ#G|MWgNNoS=)2 z*cH=$bq0rd|8v>x*M1imfarwNy!kAg^ZDw6&WUaseue2W4nO+fE)Cb|qXOiZB1%WP=qmD*EVbAKt(n=wE zH{v!eRT%2hDoXJRh)y_1<`nH(3S^I-gccP<7!v-RFgy$?r&)`@N!zfM`0ubS-Om{7 z@rmjH$0%{`NtU7xBTECPC^#ZPBjU#JC2f^8+BIY&bFlD6elyh6xSchxB~PQIktbkb zuTY}sJ`t0N@!=SXfjTT2<7@ML9*zu9u2qjljX5 z3~*M8%e*r1&!xIX{t+8uL?$OdI7wT3ZM+!FtUxAoWX~B)I*Z|+94vV?(2=r42jM8G zlH#)))B_(ZG33!dkRbkGCeld!yF%vDrx7T@OEOX=eI#M{l(-*k&;Lqbiu^};)rwY=0 zSD?-E98$(zrNmgLH!J#cSi9A9v?bwl7{@%;dgm8l}@? zlj{Ad;QWtsodUQ9(Au;B0owuXaVwaSxcI!ZUZiwTzkiQ+4-UTBK5VW?R*e(^bD$Y{}qa9 z;VYyrxqhn`++(3xT)-!jg!getee2e!0+}wahyt;07Nk%kT4z>p6bM!P$d_8s@;vDG zAEXoIOYgE!ZOisz9+`oZ>^+hpcO4bFkH>@+sm$)iSuOkNnxQC5)%>hwz^>CGv9#H< z6$wqu#mZDy3$uc!({7y_qr>XaT{m0h^^j|U)z`8NDPck8r`I$+WX!ZvvoUS%h zY2pP7wO$yV5uFw7*yvb4>uA*(S~AmpO_k6ggb1i=(4jSbkm&pwCVyc#txgPsLW75c zja7(RlgAk1p;^%wl{AR+@;rz{P#W{nFzMQ@W7-z>qETfn(xa=<2j}#SihR#ty#QKB z$=)p_Xumb^%o|qo_z(AG}3b!Wm6lJ)^qpqjY*C3U=5QJ+-x^ za&1&5wX)Vry^nIM`)oVs>3!?#xplUsRChKvv_3gRqoY|%AMkQA=ae#@j#IrSXAQ0; zEZ)wu7YpUd^}TDshE;FqnkeZZB{O1?2I*glIEoqVeh4cpp&KJ`{ep&g z=EA5Tu-v0=H3%<+flX&>P%KL%vnmJ4rA%@FHm>N5*%ks6SZ1=n>7YYHoP~F|d>IAj zXO3`V<(P+_?l|jWNk|zcXWUNsczc%~-4B-QB%2AH_`(hsaedu8i?`h`@g&=-V2Hf^`+cNOM8X6GAs7PIG9)88ELdxX*h)kWkry}pae1C4<`bcILf7Q95+xqdu> z1AVaHx>qNtoQk0%M=@FV(nhzD!3+fPVv_s=nCc%it@_cc$~(T;)uek5^F=3gGzr1N zg4t6y@<}G2EJBvGbrZQ)z<}k{jd;Qr6vl*w@tiF6$!G%SpY+x8oF7zy>w>0^g9+N? zjsuIzhcUoGJrg9lGVUdzGF;q;iQYt&(f8ODFW&F(DWf|78y(&|d&qOM^qxYoA%-_? zmt#wv{ZTj7S%^Ze_8t#U`(E(D-g$HW<$-H^CKid1I6Me(rIVj z_}&$NF}&{V)ZzKx>;1~14fFc{{+ePc@yP@G=iG3?oUiZkwm0&z2M*6Ww&QB;6mFVR zKCls-#QQ%x|Nq(a@%zuc?y)=b^FRCK!e(FZvf&-O9(I0GD)=*(J-hCk8+WgYM!Yq9 zoQG4r7kFVE@w9_u#LVaN3bHOp0DyG5vdauMw>K@9I=!NwRvUG!cX(T&BATJdumtTm9RkgTq7RE0TL}uzJ3W$7FYl zZ<110F`cz8=upBPv%9mx?@P*yYQ25-;{MSGtk{}0HMI22GmnkT9X4=9+$|r0_)RRu4V{%cN;}BlBQj6_~8Fb z-1~q>Rh|37@7l8`*)#5hJz-gi-ZXEu_|rG>sCM?e^}6Fb{+?=)&q(QR$Y?4X>f zQ_AjtVt6mQj_s^0_C*N7K>*#tERQC zjqDb?(-elnxrCM-U}ZLZ8dRCP*_KSA$`>fPNjKD4bK$4qbWm2P{|?9j*&2oMN5 z%B?BE-4;gE6!~cbLnsrfBB)J`Tj{mHjL;__a7Q>_1>S+V;s%>9XI!x}Is9B_vjFOw5nSKkw3{G9G>oO%W6ZDlf*k zDa95^ogDA4Do*CcvA$!|tzf@@_~$!6J$-a^`k%@8b1P&yUjt5HaHduBe*Xk$jfLBR zs~kS?t%oNADGk&t3NY9^KiW#IvjUmV3nv7)EA#L|3hQq;ruE1t}WQEZa#$GrELefGYEdkcTI0~Cq+0l>MtD+yh z1Zv?pKK3AJlV65%mPeUCZ{Y;y78bM&7Y;)%EX{&iwhYjQZ{jCQY6h56y?XVZM*}`# zmJrSAIzT|Hv%m6N;nhFPx)-P;Rhwk{=tB3A*-2b)RQT(8NY*@yGhcknyA8dB`^#rZV z|H~L}aOW`GDt<7rn*%$JiTXeGTc?2i!u@@+o;ezng!?dU(_SSe(Zbc> zxQF`I!+e=Gkk0Fj(4DJ#sArks58U_OuFxx-Lzx`NR=(z%)meDH%Hb#DX77cod+0nM zwI7X!FuVim5@5L%`ofgRr#?Vy1H^VUF|`V4R>k+a(71B!N>~p4sq7!0w^xn23m1ZP z00&t(Avoj06o~&;k6(TMojwj7(9YH4-+lMhS0S-})9Uf#P&THgmEY(npSod`dN%0R zbWkmpD9==k6$sBL`|(eVyE+6>1>fQ_`n82ujZPf(W$?4xGVt$K&avDN^S#Hv|FJzc zoyBxH%*{9Rt?upZ2bSG@^FsF>|7_3KuAOq|i`RbTD`#6EFrk&)iW|P2LP_rk+?Y=K zw37W!V}7ZzqC~(mZtQOOvX`4jupDFmvkC!~B#)%8XZeGud0v3;DfA``VD?w^f2n%? z{CHe6$~M-^s-m=8nK$o!zZz< z1scnod6BJDL!RhnOB5Pq2eG{zMovN$s1f&DTTKM^y-3j>bs> zY?FKNSp1}Tos7=cF(Rt*gTnk0E$bWDh~4MK)fviF8H?8}Cgr>Q2OdJ7I1$n>bABcI z7D2uFkD_v%OmjWhG@JffsYtMr}@=rm=mNkO&)F0j0rz?0(-CCv9b5} zdLy1DdJaL=$dRL5m7ZUn;QvK}N8tWJl^yFK1JDC|wUV8Ykq*{TFoSgz8cO*YB#p9m zP@G#^Vc`Z3?fa{+G)Z`f8z?Nl@P{O{16kpLTi_`fS2z={68`^GS9qoW+Dhj9H8;oB zl0LMrhrlL!6PfTc!Q6yk6$Q9E;e?eLQ_^rEVbs0E_KC)-N|sAp&Z9$885+ekLRzA* zSUf?&6Nzh}4;CCz8&Yy*oK*n75m=BydLjSgFa54!k`$K4`#z+QNT3Yr{p>(J7HGx~ z(qcOG{^RnuNQ>X4yDiivcIrMEI$c*+Th%502@vkK-?@n8<91geTlP;PH29-P%t^l8 z8_AtEB6Fy7oOfN?iptBegm4DMi?m=DP$ZQSQ%X&)T1yR*p50a@4jU(`tv%*3MEj8P-^H$yMqKde zwsqBw5M;e7x)dZxsLn>Ltq*2QWYs%Niy$^wf25VXYcfP39Ff9o8()&xVt*T~SG-(O zHEK-@;<<*-S=Uyb$lw&vq2`;Ld=7%RkfK(MzvzB@1!FRAR%2&pX{-K1|C@8zc+sz=}K$atBm>2>Lv zfr(_FGotiWC0GCRjo8s1cCW(Lj+HHaK{kyb@5kPtl8^I=i-IcXZTQDftyo-ot%~hc zrQX2#b<}KN;%CE=y+S5ug3tH*A+}=xK!~WoR$g|lf`ygC5j;`!EhM15Ngbh5XJGfA z8kNkLs@tYToWdFmbp8nJZm>?y9uux&RDl7r70Q8&jbx|PMNA-a_>dV&lZSz1)+`~) zgCf!AkycjDKpfPnHO-*44Oa^ZrGher8SbNfo#Dz4L>MH;PYLgEtJ8=Xv03< zpyAUY3SJhP4!#<)h~;9PkUkYupgd5TA8KcaTnIlbFAMR3Y`?}tB!#MQA|(t)elriK zGYW-89f_1s$}r?n($QgFNFjHTGEY9(4ybCm4I25xE>UzpJe z*z&NWkfU+E%`G9(Q2XD+f=>4}fB+WryZc+TKU_<6@xcB0{q*{L+q<<_hUCveI=|lt zEgx=3SzXT0OTyj~J{WmA2@-0pn-Ur(we04!6N>ecQ8n!LB-Hl1w=bZr4}R_|&DI8* z<*ucpBNwOU47b>?(@bi7eJ$ytpuHme{Y6F{d8XA}JK3DsNXJX~uNzh~590C4zw1Q;=tc3r-QVNy)EnW^y z5}SkM^(OAZGHN4~1`zs;hD_j<-I%Kn<~5#F|}&e?AC z71w4VR=lb0fy|PEt;M9o$P%mmYNcwQ`ncP!MMrfF-8%bXuS52qOtt@{wIk*2?Zec* zQ*{c_M*mCGIeo)z<7lF>MYc^YRbfD)9?*+1)l31TD_UQTEp52;#E7M+ubocL<2ulw z(^YIh%^`FfEs*IH%hpP=TQ5J*b~g%P9rMRJrkZfb5{*O<$XBS2+;Dp}zpJdYuN!m$ z=(~Oq??A#jGyrj;uBx`qwp}GW-T-4BKQR1iq=R1EsI8c`26h_O<>r9a5l28N88K6_ z&Xk>MRGo3`3a55<#`O${OzCgZ%2etK651*jWKSYx7}~*|8Tn*Wr;0Bz`ddil3)p`( z3T-_Qo@6v-zNo+hba|cH*(fP5vB;~-7h_V|lMuBI*~vr<9qBLyZp`dpN-DI%K<-pl zerH}#(rE0#oF`^trd0>2s>0~WYc2#z04k#+0)z)c9y2YC{;M4$Ul(taW|62fZi+^o z#5Bk>G&Pwqvu$Zzyc;|CF{drj=w_^?a%YS(DwD}4F$tB}5f)~hU~()#ZAo2mCDXVeucf!5bMHFAyAw8=?=x^}UKaDn#z zrzIm)vkrcG{z}VTVI^Yu!z;fz&|3rcXID^fzE2FbiOqeRCqZDYeXDV}p=E(t*chez zMTkMzSdvjL|*OuC{Jv9%|k|oX_2tbh=?UH*D%}rh)cT?l;ITWdR;ttv) zi<4r2#OLzm+pN1${v;Y~0R}J$JVP5(#uuVcr%+;#00&ou$_3U`*Td77tVRio|-V za;@6zV0QB)+Pu8JW)F^l3_LQiuS5Qk=00K1O51b#n)hry@6rVe64?_Aa?YOfvH7{q zn$){8wBDZhcw)}Fc-I5&@Bdq|ecLA+mhYYK9GRB5zMhT4CPR0r+ zf3v@nF9Jm~3&OjYF zr={8DeJm$|(+->(a~S(dmi4omK4Wx95>8&S-6G7rLIYO=+@BWxYdhBV@3*@QCCo{?ab<;lMQTBVTb$JWNIIXpK|8~p zcCBelwg&3D>uh1~>S!H+B$uw(=Gx`dDU4VFM>zT!*#bl5RkgBp$^6VJqZYfb&X;R( z9MsON0o^hBos83|6i(%JPX>E&oukZ}ew?wxPJ~M?ipadOz*M2fu-%JVZ(}zo9A)#* zXC+)FNz^8}iUVbmUsGjUsbUFqZK49%OH|xdIiR0T**sR$XDr%Kh^Gj12d0Fs)dyS^ zsvo&TRe@RxN7XFD=`@Icz=0(PtD+83fUIzn>PYoc%Yy8ckj<>nw)YUeAfhG#UQ(w8 zXEY$08B@QE$~roQVs>REE)G}J6N%gD2BS9Z#8lsMNC9Y~4c)5S=yENU=$O%AcG~>| zx5g=%eWFQe97cdF|EL^v4q?L4>1kQ<;@E+^ZuRnz4v1Ln23tEK*=(rT#C`VCyQ zUU*cKkfv}O(NRr6i#Wt8Q)DRYWsx<2WfTZImlXL_lF;Qlc&P=|jXY~2{6o2zx`V8v zb`2gD2&*M2HaJ|>sNTxJz?XuZ`I~a4(fo=8^zzqKrE&j~KlVO4O$K&3#jVhkaTCHx zKkN=6A@KupBp|yYLAvBS;(>()D;~+JOJM&*(p|wYw>#j7MF-~L%yA0^QVSOoLP02P z;*xT?oSIRO*JEoH&^tsua}Xn%z-<%=od99R2NQuU)rl`7QpG7&tXCX-w=H@Wp1^ri zXc!L7HG`uXzL6`);saNfDf2P*gUAQ?I9;9W#kGce$+?tae1(yw;alL0eu?t<`S)QH zyn~etDjE4e99CRRUr8B!txYemb0=mc{h#KLe?^r&yh;U^gO$oUW54fRQd3j8>zDWZ zA?wsfI`3S??ocnh`s#acUt&U*=zBmZCiE6h>Y)&8na-;G|o| zaoN5Js4wF#AB}#)&RqR=(m+SM-`2~2@e+~>(Z?f&x*Yf??Emqh8y?5+k&2(Mb31sP=KEC_a>PHzNBLJ#WjcAr ztztjp{};l3(65r_2Xzit!EygR{I>GmzZUMVxmWTs_C1yN{-tsjgYN>`f&4O8-djm$ ztX>JrZWu|Hrq|w#C;*fyN$DPFjD+!`m&l&?$SvK+yTYY}k z%yfrf<^o*ol=pmxL$jtG)PqVqjv= z(!|Ey0L}7soSyU3;rS$|hZ(f*-i5G#Sw+h4zbQ!PL*asSHI?~^F$X-Wlw@;I4xn&& zALep?I#{#^*zU6i%HhdmXQiA=eST$3w0x|)oL2cu&$ggkMc+dkRKWBO<#RY+s0T;; z9(Z`*k7i4`KIwz9v@78_$QZM4)Q!+^&o1xGF!L0iY&Upkfy)r+1+HMm?ks7M6|Y%1=Yslu`}-eytkrLR#l3mNcRn)p zCFmi~pZbMiqL4b~`-Gli&4Y`FKTK97zrdRs$^qBB)M$FgpFF~mMvgoi3WfCeHC4|n zHlFL(Vk#s^YTWxPfFy${mZp;Q_~Kh6bc|B~r|uTI7f!4^{~63gVPsa-5J`S`5ZHW- zMNj*g_MipD4ZS41EpX4MQxrORG~|0z2}zAC%7jPg*i!`VUyqJ?N4X4B>EFg5Jvu%Q zCgSR*Q%GWjLZBxj)j@Kc=6ElJeSJD=!q4NA#vf28uQnM6qX=_>wbuoutIrnG1;b?H8gq%qOsbT?vj$+nXz8gPGG>nwQKcAH@Rlqw?D5Ay! zS0MHXrAE?7+fRv^L<5tOzQ2jc@J4hhdq6KMEb`eeP=cZgq)&2Es_X{M?;TuulDB)| z4L{%QY!H}oWB7j6BHYc?^$bn%#2~;N0dJFupmi^q>t?)&`q$ZBI;nJKolfZ{LCXsp z&Q+z;*?$sO+`an>LD@A_j}Cy$xY#8^zuE*0@-1vWQC~OP&9!D78N(=7+9B-X81W4? zN+{iri?KZ6c3pO(+g$q#(;Am_vl+^ruQo2VGszKU=$NanQ1-UBPWs1ez90MCcD}p6kVQThztE6SYF6qJ0^_vc}UI`Jb;KrWB4? z1C(4Uf-hD7{!z9=rR^!$k5UYblXb;{XsdcO zpSBnMCT?^B$LUy_5Y>7vWJ>qd((Z^su5%+KBHy<&7HNo{n0IjK%Fl+XQ{eV%$*KEZ zgfJ9=4FWyac>(F@d*|*yhhU9CKC+dT=s5AJY;Pk5M)_nAZwwz|LT#%rD-_FDgXf&E z@)_jFt45WS&a?@8rmFlP?|aBF4R?raTGEJC#|7$Ptdho9n;|6lrs4v0%XCQNB{Wc# z#dfsDt4zf~kMJuAcQ;T;;Y|F1CfVd_&CLj<;6rICNS@?`fv71QX5fxs!GrRKG89iq zv0D;xj2sEgqlI%_Rpq8UgTjvNPaz5cTmgA*LQIqj5fluWEwTS9AwLh?WFV0`?jZ;K zg)|_KARTHj|5`aa>0B(w;Av-aAay<1X zE!t5`8b)4)>o9C3*E!zDFXjCr4P%uG5sIWbe9D3k7cBS>RD7L`&|Z=nwPX?6yZy-! zym633Sp$_oWA&Y+z`~Kg9DB}MHsKW?QmFMHeJi0|7PoK_g%0}{3gQR`#w|UJFUp0- z_aS%hk>P;=Ujo_QG?FIEBS|l!3ZptMkD%&C<|3nLAi0ipB26H%{m3^; zw4yDCeye`fC=d!+K)*yxQlmy-={?KXdv zM%5#z-3%ZH*mCZkCq z3LS%%(9u|-dx>lYCb80r44O^^G-2k%e5^6quQeEcvArDIiKcgw#^s{eI+TxQbY6Fu zPGern!44zRC8EWh0*G%uZ$-dOoTr`10RwSC@QkKL$8O$b05jRO$LjA$B{~awk46PF zfk5UH3e%^gtt{$SjaICq6|^2VtLN>)_JW~e@eUmH!x(B>D)vZfMk@0}2W3RFBO6Uh zn#GQIN758s7IioPCv=lEJFu$cM!_wh1zc=F_`H~~N=c9=gW?<1Pa1#RLKEXg($Z1O zuri>0yxE+0l|*QaBm=pJ(dy*7X9=wsYW|Oj#u+1d2wb*G0Fv#H)M0Io97@XhiJI=J z}r)7Wp zMQ-YA4Ul@jX7*0G^}>z2v(57ki-}+AscDY&UU@?*UP?IMDGm>nKfcbvKVKTdb7qSAsVCBjzNoJ=kF7HpwM0%fa+|n5P2LmE;s_Nx)0c4IJV= z2fGlUs5P~X5Z26X0ti9Mfuq-t@tEuw0HUG}-36EuaohMkp@=cw&{>G;d%)qL3+SlcsPw4z!h?-J|0^tzg!_#p7~XifNE*Z;9Mef15K?y$NOn-@kB`+j-< z=TjHOSFM;B|A#93iS?Psy4FpLeEi2dcJ1H)=gcH4K76bBgueZ}9b3P5%cQ|Xc!jk; z{oh~Qd~3qGXJF5lZ}|2@kF_88^Z8pFPM;Hr)E-zm=dp(FIlp*zKE%2FT|Dx5+s$)r zIbb16z`iW&m8R{rc6D>QrhRACp_36X`=$+dFh$e8Zc_WNs|un$wvO@Ec2)C9=c4vn znjG;#uPD*Hc7_@y^>Fpcd~ZXzh+A@Onv1W7>-X;E0%(qlZXabDhqk14cL5UP0f9&+ znuyxC)_ERvR+XE>cNne=9>hKKIr5oD;b9I)Y7|Hi(%D^OKQ-l<;M%F=E_;s!USO*; zrpcQ3_|3vWKHIOfA2GMC#6e28zgx@wb;`)n;^tCIVa{+}G>ot3R}RcGE*P}4>Y-ZW zVCU@CFMc)>qpNVK?Be@73$a1{Xw4x$8sZL!lAF-GS`KP(bt@ykiUxO-)B?<}o9mnn z4S8D8EgYF@?J`tp*NpD|yaA>sDmH1%Vs+iz!FwjIsd94W#H%_s8=YTH*IM;e#`WTg zMsn}2?X{I#Xu)O3^M+e(;ndl@E+%lgD+h}Yq(FsOl|3kQ6V(|sMWU8KfDB1>An@QT z4ysX+VuR7hPww}=>JK!2qULcT5f3EGYHXb|4Pzz!=La9YtMVf#$~#(f0OfmH0cV`!4e%d8Hf9%F&3p^gFE|7*H6a&S%6 zJj*@QdMV~8$|=&a^>#zeB-)Uj7X|0;u!?0AT7GBOhT6#~Ai7S<_@q^X8+~0f2k8tO zvl?+kA`;(dI1Ovs4=c#o7~F8U7Iy(RMXykugDsZqy3ll6CVT;?TU&LQthQ#{5`jP|cNcLDyQYKy5Tjdi zq0K=JCrue!bAt&z3~NQX*u$%s1HJjI)r65JWvDJ+m7Bpg?<+TumVw{nR5^o9GtH&x7ei(UGJ?LcnN)NKV3v@80QX zP~e6*e4IpAM9O2h2SUbx_&$lc#$1fRp6g`6p)3720tv=40xzq=vIaX3coV-EKd=)= z6xO^JlFBJmElzY|)`z{6?fA?A50(gIT72(tHX>6Eq~r_}I505b0P_V>?7RA$!o-*``(GDg ziK>hvud;ufeY>gY;)Sz-3eRGk1n3Nql!4#!yZLY7gmHA|GRAE-RkN8f6%H|49Y~3O z;rY>5r;m>F^Ur0N<^O*RI!u6dm{U05x_kclO0~|Jv+WRvW&60%aied(dF7+bMSLdQ z^LR1TX)@@3sAUHj1AcxMyE(oO_X(&x0ZU^l$aX9^VD^7LQ4HLCzcH9-CEQrOVyTap!m%WPsf{Ohr}RQPJ7Gg5R>-vYX7+bbcFrUJ#wwt-dS-Y0#en&;KZ+ zuRLDIs_g2lj}uqiK*1ozo$1=@tnc=&f5O8*-@%lF-Bw@o2jIQ4KtswB<_~>uA6UW{1;Vt=6nm9)2*a+jgN6Y ze}oq?8q1(#l7QK&f2jDQ_y*kZb>w*q#vh)rC-E)x-63!?M6{MZ=VH|^yYeHJhQF3; z;I2_)<9&bZl;H!2c)T;@D{KoOB@<@W{R{~VV7k!{k4%)^{lH@$0rp&>17keO#sJ&J z%gQQ-^w3m1_eJ`Z_rUC9*0R{|%ceG?xYmWsBk^rFIDEN2h|}}!<@h5ZY~@*ds+@^< zhqGr3LROTiv&AshC@9o!8un#AV=0p|Llv3N95A>i7S7 zzBnQ^?0nxZ>l_X`OjuRmiGIR!YQaEepy1kDF~h?PJvhFJ?IFBxgnB}kj(^AR&n37i zzt%!h!F-I+^*zisJ>QXmPdG37w|m3lRH!<0@9|UjY9OEE{Wy!BzW14_ArAvZL15ua zc>n(-y@(T}>Jb5qbd7hs>d7hwPmfOZc!=l|;sm&rHGop&1iugvVJPVrlTGYM*oT6T zDLD$IJb4Zsm6$3^ll|ccMNdx+EGF`Nw=dP*_tTN2W;%lXb%pMPP9hamtcDSYrV@${4Az{0n} zAn}S4vZWbY(iB$G)h1GWpF&iHgi91Qv_G#ID;eIUG#HV`Qt)ed0(|8V5zirW$TwZubZalapc2{%l z3F_9bxzc*E%Kq4|ap#tiQ`e0@)a->C>^jVe3UzCSU;b1yt{0^jKlF|}gF3-$cA6yp zEKk)vz#x9;q`GEok0ksZzqc0zEd1W=MIWS8;gU1B{wVxkIN!73p>06W-XN1T~mgt^|s^K=6*h zsf{hUc*u?4^AzvdI5T1Iz3(Hm_ekpqzFBT+JWfH6|2eQd%H_5Q8ake#(mA2DEki!G zD-a&44tkpfp1UiT1P`em0q*K(T|XSpD#U6r_K9G=($2Cf4&((8b_H!x$tS#>y0 z9e|+_Ayo1QT9)3hI9xNG#HJ>P|0y4kBgx;6Y92dk9v&5?Dh9aoXH0sU_O}fXWQqq} z0DA{WSJP0+uE`0*>})C(0eN*Mm8sQ}99w8vm1Bd$FM(3f3>?r;C3(MPygy4LgH9T{ z3K}xoNgxEnv{yH+>jZZyHn-uJHzOSLF5oJvWX-^9OO8Z%>p?4w@5E8HyegX$Ch0B! zVqmw%OE9c;hYBa1XXDNqV_w4OCZj7wRYG7+WX{wErHV&HbO7SLF-u-ydi|Y{a=6>0 z0S2-F)D0k!_Dk_9A(J3Ay#i#EG{x{*q9Kh3D#5ZkB%5HwRtupMjySba!# z4^*2lnlxz_XtxI71|Ju@Iy}8IxfKw};k`xEfH-@Nmx9z<2DX#_qH?k}s_%Q?HKwVr z@ocwmMio)h@{v@0`bZ5xp(W%^97bZj_#WR@yG`^>>B9WASnb-vgNSG9#_|a2bPUwO zx(I`55F8=s51ZSN6K#*^35$>{M4)$t;BFS@+M$O?ZwYOV^P=fTZ_Tj1{cXC_TW^Cq zf|}Q$%AW_~u5H^3bq#*LCEa>_-|J0V{&v@6Q<0vzB^Gf@U3YK0sr8o--E+fTJA9IsYn&Il`bZru4dIT0FL!kQJe+RZ`s~`;qcL2&m~yPn zUbmf|)Kq$>K#SWXO&LV$)1u;@{+Q5ui!v2EL@wf=2QU{OCrH^hBRQ zIh&@_Vjdlc*Uw&>9~|$pe?@&@3#R%_KY{hzsy`ig`OlK(FodeTpUf_dQ&XtM-P=*e zJ0ksEj!cR{@b~72Kp-s{ovF4LWNN3CGGcLaNu4>f-==peJD|8k=zp~c*! z#33(H5I8vII+@=>d;n=GsG_n3(?T_4D>LN6owUn{&gv=P&;Tgny+{X8JJeHJk$gn%KXjm^+uREeIuS9@zN7h}biBB1ZhMc8%_{;ci;2C% zZesWohvzls#h@JA{H1x#R!@4cxH%!B8+-MhJrg6hPMX}j=iA8Zyxr+(6Ruxy!FG3| zJ(pT~n!mmB9vNv%&`b<^$HcjTq7!%S--VU;^{$-gOl&A+Fkf#UrVHCv9)7&RjpCN? zZ`;>XFNKFEq%c~BQ;`}$64X8_$p@X#;#8=?>;+Q;dzkE^tN05r4S|eEGgcinrgML; zL?q{;N#TR=Je6WP#WqCqb+oQRb7cV-w1={jaCgP_byMsq7`1=fe$uYbo@cIW+XyD+ z3F(!0T;=8(qUre;Iqg->%80VsSJ{a@f809Po%5vy4g0I#SRikkzaTN)UgGZg&HAgN znM<1L=cnEI8~^4B+l)Tel4_`G-k45L_{kF!oZD_O6X!Pc)kh|`KalvRp(%S;)=myT zabx>88aDim{L`{e)y#aL{^zqknz?*jc>b=H|FHbYhK-3oHr)02te!V(B38ow$f^^U z7Aak;RDz6WPox)%@a(p(gz@=hZp$UhHyM55?n^|?hJj3C_wQzzpF3$?d*K6zZm{To ztV`kw-`=WEAGfR0U7I84bPovIPCqjDchLoQzTox^;f$h7dt3sib~fie;!?x;w9W@^ zG1(Eh2CLm}rpH#I_RytKO_;|vK(9%`h}v$jTG-V}n3!C_@LzBc(8U^L%JulPT5h4; zP60_Cv`t)3?8gWm*)e8)#_R+n3{#qU{e%yzQ<7#vpLh2Q_MIZIZ?#7d)m1x7K904yoN@TEErl^rnR9Y*ux3rjhJyZkYC1 z?uyAWsonM*7;bY`t6eoe7JXo%?tFVWYcEOi^`4 ze+E<6B939$hj(CoXyt8c|5B8$b*v4lv7h2~uF10kXM-~IS}U4fuiP$brCo!%wPq{m z+i-2&peRXlRb4mw_Xgp(JECf4L$}5(>|uR2F>D111%CncXjYrSD~IXm}^O5 zQX?>@^%u2Vd1x6ZxPq{;atJ!&`9^*Q&M*Wa+3BpCZ~MSQ!wys*N~7Ts%Q9qlnnmsE zk~TUep?Q4e(h$C0t!lnGBLjIcSO8L|(x9L_i!jEuZL~qkeVtBse9aZj_Ie0_o`@?- zRKsu<-vh8c@7}Cu=2M2UGLE}gce;nQlg@5;!rSkO7F5?=@%{1E{x4lI5ev$7;Np$V zZ2UM`3m|OUUKcZrL8mM2GeOJlFzTq?R(3wwZK%bK@y$5+Gt*9*O{zJp4oX|cUCSMm zwSbPbbk>>&a0uG|jAKGhJebluQHVzW5W{{G*InT7$P(9~Ci)CDaxoP@Oik!qq=e#X zY_tMbL5-#cZ4&6`sFeK_baQPa5rwIc88|4mF(oRe=9}H|8yR%`5sJmcsTs6*suQOSH7IkSHCwpJqX3f=X*Z3%Xmu9 zGUv}1KYa1S?1%NU&o#Dsd?>W3dKoy{fQNv$b{sKYT6qg&!tB2qcr18wA=h*|cza(M z7dwB{=lf+8mnAzh9t=zurU1`{7-#tNZ=o;kIgq!?aRNMelaB%Wal+@H&*9FGy%n=p zeGm6(LUt-b1^5ed2IJkpX~2b7&G^dd>ox%c21~*rw@NuGb>ZtgW6}*NmR0@2zE3{>LSg+QB$;Oz zczKyeIKY1YLO7%u$czr^n9VHv85c-kumx)DeZL>XHoM9L^n>md+_Rj-`!qk!f0E4S z3Re5R43sTC&N~K=U|2lK^)mP5~m0P`g{kzP|VMkf`K5$>AQB1D{m44~dFVNf3@sMLK zDM&wmMV{`WJRFn@QB^J%g?xTs!Wl9%q)OO;oM;*-X9oPm0y-5V9?HEZ?;w4|qkwOk zOgRCzkaK(*Ha1n6yU0%;*s%6xL;JFy`{}IG72|f~m_*W0oD)u0@{_j4*oN7KN@+H1 zf01{)L}r_B14hgf4=7I~GYH>Qj^|Iue4olAVAqdTp=?)TCtFco)_fJ@Pe*(`S=8)^@@cj34|6(|_S*0BDC!RpZ{?;~?tH`s-QX zQkLlG_a7C(*Paq_I$L+(O;chXt}&I(h1&a}{I0A;eP zFtCG%B~}mus|?LSOIQtHxNCg-94{1ZR8e+4s}S0hQkES6ik$WGjecq-8u_gIzh^>F zZ4}B8u)0Q`vA%~J+_`aKQ5YBSAjYMA7vH8)o&n0raDRtCxZ%z3l@jmAt_3jga*-`g zge(SG0PSc~p+l2G>dJ#=B1NoOBudQjU^7jL`hZz*TT14bF+7k=Uf7VtMkxG*BuTiZ zu)wP}PQfz523*e6R}TB;6evM=2|b%i!Zx#J?9WEd)KAS!p)a7?lYbxGGwF)Qo2UO8OW3dVo^R~RleNU{y7V_>Pp@;&9fx(E zS@oK2%ED3&fagc&)7{}rXK5Q2W55d5fBpg|Yo6}Cp}#R5FTCBk_2^Ai(cOQ@)zC~w zmi~Z#k9tN;$xG4Os)9=5!bAB-r8V`gi|e{{4!n-F${Gl~@Bym+wN+C%^$6^kOuu9( zI^DN&E1+2;+qF_*A4l?1+9NBx+>E16#E!akWRB!2@uiQ;u&soTlt3aS66ZN>6B@+` zcIMM{Rd8Qp*bPp}6(rjanErycoo8+s)NQpp!$NvTvBi?@v$lop6c}g8sYSl?y0WC=HJ(8=dZc6E6vh}K_&$bv< zPp+XYjk8-8g9k1uyJ#`qJnm=1PJL;JOzk>ZcZhW8upN4`Kv-=@AlF~qc=8~BsZ-?6b*To8&BUgyizagvwtqg`Q8t@WN&LMb|Sg1 zKIEiR+gjG*9$|`aZET}$p|*7)bpLQjuSa=7zfcFhI@HWs*h_;mcB64FrBi`Bfj;vn z(Dw5qzDo*qPZ%obhv>nKpHWVeF^A~{H#759TU4w`H7_YQw;v4;9T$LRfzEWnDoPFbQ<#gey;RZ}yg->F;Bj-1W=COv7H_wVeGwIHG7EUmy^5?H zXb;5RVVf`~C2!FZc;8Gz#w@V#W^HD8>yo7;iM&o=Cgs07%E3Gmj+Iu$NZ80VbZtkK zV0(VcU0}L^JQRAFq>58r=Sy&I$2@r@##$VW3d<1 z4!UsDw9W;)44q5@du`fKOQ$=~xFhhv833ZDyUg}DPQ*3a@3hlVr*H6Rb*kBU13Sei zj~W)!-W2IvuGC#azqmw9E3K<9zSdoTSwh!)rnQnvbkV>shdp(2C{^6@5BD60OyY8&Gr^H@8^{yMOhGR#RH4aUCuZSPtauf};tZSP0M#z>iw}BFe zv5QglvOe;+@i~oK$@oKib9X8FSk1cH8U?w;+d}^0ErptBz$^(0t8HI(OV)-$t>D{j zK@~eG9m>IFos9>+XpdY3a?uL2tUiG)UacXM0bLTjzFKsVG!R6%8q*P~YU%~G)6#pb zS0j8`p#pP(aRRVfd~vKWwxX+z0b7Mq?NuYl(U6jqK0S@3TRVkJ1om4RjoCXN^9uXq zr<>`a9~Q+^Vkm{{;6;z1**}~?^@|*{w(4}u2!nndZ;aLKGt%9;XwL9N@3*Twqt%HkWr+k1Wh1g*LeP(l$G%QJD1sQ zq?7D|yO@17FpfN?3e8k+t%XZ8hDRPaymiluztu2*=_dl`B+QxOsWA37vuO-)hr&7d zV1`H4NELx|*dyl@6hq(+LFV!LR{4{6Xp5iyHGP>bV4W@wo&h8% z?7$_U{VUNUF~LGhNacWjL5g$}p%#-q->_4sbfV5lTFueqJQ10Mf&)FzV()~KP7{O6 zlp$k){2gwjfDyoLZIY%=G*h{^lZKJMKj6Ql2HOMx=~xp}m>g_OxX#QcBCgp`*XDlK z-nbduX_0HCt=oZN+L1^@V$~OFOw)|ShZhW6Jqu8Zp(0(M{J4eNRoiQ#_P3+rhT9Jf z&eZMq-440Uw|6HKJ-6OJ@z8CP;_pTh-`HC$l}yIw)Z2_$_`um& zszNd)II%Onzkzbv(>SB(I!n?kmbb6m_ypxZZLP`ncU%{D0H@Q3eyh^w*2nDnl?{pC zwy#?;#S+s;CJi5KSYXYMCEUm6tXw~5)f4sSro+AQNx!q(C$5{;Y8lh!v^P&l&7mJV z|NE00#xHGan(@GY-F(Njb(i#&{@2DIpOZ)rmm!Ry_yLwB{>sR4Yqs?2#!HEsDds(!E~Vnwq{B`y5~K6+O* z@33_g$8w@qP1OBU9vvuAL%gkj-q!x@g)c8JgzG!*zNMQc8CP}J-Mz2jLI|+f{>gAd z$5(dL_CI!yr4L%owW>claE~!q7eOB#*z9~owKlYBV_?D1(AHLCO1^HDEtdDEzgQP9 z4u-Ae{Y@*~ezF=PX(~;U{hihxyQZ7J>+WNAyMeU zP&Z<}p(r(gB42^RW|}ZZ0>Z9ghC;zz1)V2bJW8N!2lZD`hU15?SQV%fE5(iTAr-`9 z%2iQ{Lqgf5z%>Di>Bn}Bn8JJ33ZS~JXd)atR>%l)M|L-YNSmh__HJopmAq24S|GQR zgzTlriYrZp0?((e+1)ET?60q}7B9b$WKAPJrf#>}z1*5`x!b<`+e}~gECEYtS8}Pf z*`aH#3wqj(J*FiGrnz<;OSSmzb;HTl$u`YgN$EyGkyfi_e!Jy%MKBpjx8!diTV+8w zuD!8;URNp~>CO<{+Kht;9mBHCS~{i6F=e-r!K9ipRy=L=8XzQfpwBa+MF!9~0F|UAteWt-<2rRwWn*d;hb`eZ zMhW6jWu+?yGT9WwGhhl*XO~V6Zqb*aVJX4kI^cl%CY-ZiOkj@5ho$xDJ2R3 zd|u(O4JG{RxE%@RUMqo3zROJlgo|~iiPL}*FahYSwcXBf0?wO6*F$)`#B`c0<=FQ` zkQC^33ZO4Q-i9;+Sz4y7rDz<)M8*EUyuA&aQ`Ma}{yR4}nVWDYb29`C7~mvC3^eMU zVZcBKIT-^4cho?ciasb2t$*yY-N9->7v&^G3^>{hQkVMBZhUKzr8;(L7nMHVVNk|u zE7t9<`*gbw(x=;Q`>FW0`t)s{@3~2Uy8C~5KF@!9W^&K_x##@O>pkD|`<*>-Qu8C? zgDfUiYcM#d2L#dd)c+2HdLDsD^qJ*VlD# znv|}{S~}yv&lr(H(NLJ=R_ye$t?wEFVsA!KJWM^6`Jwe-@Wpx;#X7dEiIe2DlRyMw*HP? z<@sw*XvQY+>ozczi<{_59sgA}#lu_o1^1eZ|0-0aj`b@4KJQgmDP4tW^7~#CfAUH5 zTJZa}ZJN8OZ|j?ag9rI-_5P>49*^R|Q-6xz7f!FZ@}Y4}rplA@+uF9ZPvsEoZ|`lo zc(KcIr`#3iol0ZvxtoB0|7N_&<4mX8$hKeW3pFG}uU&f@Y(eO^-&S;1@y=G8HjVe) z-2I8a`_zHArY-i|e9bF;4g932Lc85TEvg&lGk9m+@BhIrH|)DYZWwBYYw8Lg&0zv- z+M9Y4M{U~w*jVq!-+wm7dpb{`$Jy@6+_WqG<7p_nD+gM|!#OY44lMjM_S>Ydt1DWA zo|v?&2xH-%VD(dc!s_QL)WaX#_dC>{JbmA7^WNL0j{9%xk^b=6#5|j>F1`s%?sWfd z`cNJFJY)TLre<1Ao&Lxeauf4adNU77KN}}*hWU4yhl9jGq<$ag0ajsMKcwZRhatDB z!kxx`mHAAH(m7*B-y(H8x4QLK-FsWV!CTpt`~LmU&#*$9*8Z5De{$_nOx90mr&~}c-1_evZ+tqWv+1KO?`D)2Ed9pO`O;m+b+K9s&QA+0d56u!w8Cz z4Pn)Jn8rDlwzcE=_p|xWt8frLFtNe!3oKaW3CQoo^}IHolg1}42F^ULL^QYHR7>C5 zxtliqxD^iSAkMGqKbL*E9sz97jJbTtuQaLKNXgZ{b~OlnYSNrn_W#KbZi1}n2lhfp z_RVl>D9lfG)BJhTJ(zXa=eh2I1gs(^cG$D5vmx`i8O~i}aBLG|y@M8jx9gb3aIUUl z$Mi;mV~YEjVhLRn+^Bxc`Lq?Q9K26r1*-H>r2YT1LI#nqGpftAi+cWb6h@UJLH%y| zjSQ}@@kr9WA-DV$aeOv0hu24Wm59WeKq>=w)2TAG*z%Y^Ww0Y&wLu3#*xQtZ-cz;}lyFldxw8>-I8Rk(5}Hq;}Lp;aOi{$by@r z9<^+ON|12vC}Q3J-_btA-EdMp|07j@-%)n6n@;)cJpM<)|M%TuZWM7kB6m$ywMV7$ zU)OOz7Rn2Za>r{bAM9vL-JTkBlshy25}vM->Zx+spvP-Te7}jrkx()Y{<-iYaJS&= zIBq(|%wacv_<>!yiFdPuv-0*soC$b%axDB70*SGO2F)jR#tki=dj)5DT>o@O36F zJE`tF66ENXj|$lQ7vvf7jKF_Xj!cwvHDUL}z%S%GOBsfrpP}Cpyl{Z!MFfaRhHFH>4*)-G+kQ%+z4VKh9Vbr5aBr}4GVavF z;)#mPH!WDHBll7fP=gy@l;@HprL0+W9k5oXlkf|%~YJ#f*V#Md_Rnm2H zADG$=1`|?)4iB&JYXS~}13%HV9Ny`6DL6sN2DM;BtSx9I%=TWj&_DiGo z&PGtBg;T9RQ^IX;#~|zV-bp>;SFudt(U1kxBvy0WyfwWp$GSuVc7iu82So_B0>_`FW- zuO7F$jxHJM-gdo7+h4xbblzDR@`--!?lMho$%xVqP-N!Sa{uHZ{@p2^MtOxs7k*$( z*UGkWp38K5_Xg>)&9-+bwSD9^HpX%(kj0#-TdlKyT>y0qfd>?5B(Mh$6Ixe|%Advk z!f1%DvhY-&ze<4#6AUMuW3S4g6@gDHe&6l^I=&K30pYj`quFj(QAUnFI7aAiNWahl z2^>dZf%sO2w8y}$GbWd!l~{CMf4g`ujV>d;*+Qjnlv$c)&XuUlEoO@~lr(_V(ve%& zBfr62+XPBo=F-!7VeteO@BhO{;>$WHoc#vN>wMdZPV=H+!?@?f+~kYLGvp}@qU)ux zb7X)=-Kbz=fZwFq?WLa&g@rcO?wknB&WskcT{CmZ7o7>yciD$~ml|Q&Qc)PL9ju+0 zf4}qM)3o#Fq9_cSF0>(WX>BB^Iql#yy@AG<5%4>H^PZoXRIvP1@^pol9+3vT_|})YG(n;yKceV= zy)uI58Z;WC0ey^A_kf$kuep%QDKp6!-~y)~e9`G-k|{C!xNCC7Pv8RzbJV)}m#~7~ z7IuP2ku8U`uxnzmmRe0Yqt&C=S=v&~qcQkfomeuM#WdA5}88z*vf%xV+T3)Qf@&zXcu$j_$+nq4`hdUor=1u2 zot)+=1d11;t3e!?Nh@=4$V+^Xz*xzD-NCVA6`Wbkq(Crg^?iZD_&}m{a<6BG4C6@!UnUa2=@=*H96t!#~|vnU%l~U$8O(?*5}GQ7L55GTQBeP z8`9uI+qCWbcMrcv-}9V*=t1IQPiaOK?Bo5jFZgVy6?1I!zH_V%!y5IpP_h)J!WHpR z4}BuP#aD35A%ll0{4b{U{ox7QB^uxtAEjbe1H+TH`@pghIp7&Xxg@j79?T8Z5bo5q zT1%jcuV#YRjKcY!(7;=0HuwGuO+F6{Q^@f8Nq9(%CqSM|0W&|HxR6KHAK$qz?`{C;t*;M`Wvn%qvM5LrI?mF z?}&_3zG}@nWdUPd5ZZJzJxL6|K|EWBj{`hDh)4zz*OLdBD_3bYuKdOhFT@FH`pBE?~$G#c#}a zi+qpiElANu-uSkD&HVcb_J&Ji2Khw=Sa8lG-(@M?vXjQsw-aO|m~BVKCf^;h2Yl~X zOn|l+$8(;|t^3N~#l?4Mo!o!3b}8j!ZO210yxQM=B`{?SWmimgHy>A?145M^8MN6i zCSYu({#z&iK#ONt9so$d=f!qDXh`1U$S3%r5mp@wCCaD6|NPqjgrTW0wYy3ULTWIA zI&SY0H_?WRuyVZzzS6gl(0rBRpr}*^66o1^T^dO%9FK6B$!1sV2nX~P-5o{!>J@Te zr5TUM1TD`Ji)WR5*t|Rsf z+CjTPSw_YV4FelXWXeV&i&CaZXr&}Jax0cUP6;VumcPANEJY($d5TEw*6|9ib#=*5 zNUtuJrBYW|4@3BGduF8`Hy|w6qAzEsh9VH>S+3%?;HmAqd#ov|tZG<_{EC>4o&Hh? z>#}TqRTkK|&?Oq3#7H7A1IAHU%Ehrct`nw7Aj>fjMQ3p#P*E|?(Lp3|Z;X`>(2qlVlkHj?`qiR3rABl&6wtw;f2PbY31+e zy)1R8bqdilcRU0bYhKE@%fGMd*=Mw_=&j%J1{dtJ{jJk@gf8!zw_88tW#8B`&;KMn z9-6jiMS9UZTV3sbcy{`kNjs8raI@vrt;QwS#HJngerw>m^CFSMcIcV|9f9vW9^La$ z;=H|y^uqI6@2=gxZ|XCBkMBINFuJDuj>L2?@kP}qA4_+yiuBcJUZCsha>AUnpPt~~ zSd?FMaNj<=tK(3Bc0Xo$t*%fYkk-wqTWsvz8|==*!6zfrsbkSI{yqIu?hLh0Pw$x& zUXWgB?l~eY$&3hq2y%y62`FhdwgqueUmvJiE7l=%YK*g`XY%lV4mrb-Lx> zi#upn?}_DK zp?{mU_paRM=HE4R`+&XncKOg-ekaim_hH{z|_Hc=gc1(DxSFUfI7uzXZqX zEjuuf>efH{GmrKObFjMtL8$_WRdm{VkTOOId$pD})=WzUjdb8#47dx!;NaT#i|g?VIR{|4(y zMeRU1q^x9Jp!$go?nI=jdI&a-RehkxC}+jwouolb7*HBIC$Va~gp*Qb@>&Ba8y%0@ zb!Nr|=RI1W$E;cT`58<4fYV+Q=)A%Q&eDXzVp`5$Y0a9#I%xZQY_ClcH%PrClRE^b-?N~o_8Tmt{ zuLfBAo=f7>wP~HHoxRA;S2}twd&n~EfZte^Gg(hDHl6$1KXb{>=$Eg5WYROcM7!t+ z+QrRP+PhzabZD8E1+lW1F1O^0D>?;=oA1`6ne&1jU0y+wGaAAOW$;X@6Ov?d7UTFR z=Q_xRf8fHhWXB{b2r>Sc*56BHNBOO z5Z--B(@vsTH==^1o3^0GEW8J82QMPsM$(L_ByI942wFr0-mhDN56Q6J>thAclSQqe z=XPG+n(Oe{nB-Wt-D@x9Ueq7uhm1v5W}sjN%&_0IKd0R){HqM(@*Ig)e~0Z`)gM`o z^FoF8feZF;&h_`t5mr9Et}4uR{j_wQ*3lawZ+XK*=KNI~bG@ymVdn2_N7inOc2C>b z%K|}Wby}JM7JZGc4B+L~i zg~bp?Yc-}zIHAN>lyNkn69rWSWxDH#a&U8~Vhag3qK7$giP=O|3n~gG6d5iqb+O}! z#B>~)qIvKlrEK*O>hT{aMWm+cXd3GJrBuY!*+>_Y5n)n8&w?k41rNZUz+YhoL2&bm zfFlM;H!gr%b)FtdSk}NGMdBESaUP4PqFcuK5vvR2qAmb9>VzaW!kBX~LgS_=0Jtg{ z>?z{~=)YKSV|}Uusr0V#;^n%r1NlG;R+)gXW-Ey@OQN}ObPq2>zzTvPXSfDjAmNCG z1F>*&gIiPC)tFEtHkMJUEPAfT1%Fp)csE!!Bj68K?7o=qkp@-5NYg<@>fB9Jg3NAG zstY*`ZpfPY=b*FB6G%}h6$ECa166+!3=H8LO1=7Qg>3$zGTe$Ku9A>VFX>{xXK(Yn z=DBU)g=^gVs~q0`>#OSb_kt$M-q+R#4B?;uLYaT_o2^@a_q*T!{`_&shIW<0c0UD;)X0}m|c^S<^0Nz;}=0H zYiMoXrcDaR1s`3X!gAevG~XP5`*~oxG&iXIe*6>x(Vhz^M@dMXsIsMST_xLD;kkWn zTZQ7c8=s`&;|@*S!wIh68Nh$r!2A5ErvUW=NIK2yJpNly!xbmHX%moOH$5QAPhAD5 zX8c3%+OFHuw#xGnvklT>)$is9AHU}2o53Bt_SLtyf_g1=Nzz+Y*tS3e zKS4cU_!DlmNYoE-%#Z(?7;e+uoq`Y!GA!J%XZyQDsoT*o{Hid2L_XdoM%%<`RbHBT zBjBs*cQ$t040js0ZD71-r*qm5Snb*6ZcM4a8S79fAq_t29&!}XX|H&ZOVggy19Wr_Gn_LON1|C3fr9Nv3upJT3xe;)rV+ZsXp`{ zsaHLlfa8Lz_sKVBDE+DDE_V5XmAR>iec*lSx#yp3+S@$Og%;xiZ*=tcKKSAI^9t|X z+J-YAS1E2?C4E`()~;3K$)v#Az$fb{u;SmXE7xys-y}$hUhK+f1~0D)yA_g|H(fjq zna{wCF}~nF-Wf<~hO%QIMTl{@Bc%F!6Jv|w?Zt@Zj!!KOOcz-0T30T8{e9{iRN=i4 zaJ}g{@bE5n&#G*l`~34Ce(1gj`E_&k+uuTSuQ@&q^tw3l_x=|CzZzfL``jlx>{scz z5Jc0{^NW>q=TmcUa>udm?)`l?-Bf=f5mqmydT!dp$fI`Pv4106%{ns=(KlV0#IL*> zaxu#8f7od29>MpBAs4%}Onfmh!K>A5gs>s+e6hpzKMWD53L~vB8`GNFyC}N+v~Kc$ z@W5)sL)b*T!PP5-rlQ_{ItK;UESaZ)C1bj*H?&47n0XOD(eT#^pT)3a$>+*w=3qF` zfvpO47!B^PAU{e!z_u;WHHVu&{Q>gp@JjZio8Nu7QHq$vJIAmQC`rzgN#vf>uFot` z;YNEg(2(Fn+tMmN#uS*9y^(J^9&z7Stmo6zt4Rl_Q+0_43sZ>&u_VmgmLcE|`rumz zI{1Pax#g^q=9UlX;$$4p8%N ze77Q~OwDva6uedU4L9@Uh685Z2)`qt{1dxIW=iNs2Y#;HA%nVJE`yG`cHvQVf|qW8 zEus9&_hJp`s*$9`b~O@d*c;`f*J3Ih?NIL*RyqD!Qe#qtPpV}i+~Y;?i$R*)Tf=Vp z;hDo+g%6)>#0OZWRG5lM)V>vdOWBxe)PJa2j*gTj9#z#f@<0nJ-C4r^0a&Fb940JB zNE)M23;eC4Qh$qH@X)a(@qZYmA~`R3Jb*N1Yf1kbRo9-QxW~8P(;RE*4SC}3OALY( z_IGFLV};t`ZHsu7%3V&RIw*%{|wRZYV5Lpq_>~DiO;5*qCaOO8Db)@r_ZM#MYu^7P^}3X4NqC?ZM1H}&|L3N^$$-tc3y!Dm_&zD z9E2o(2R57gvD)hjCsde1e=Gc@!)!+HYPq)eb@7;1kYzd)l^XTR;$StxJFpeb%tIYL zY#W3NUud-#UXM|9`%9vC-%m8!{zIDhvxyx^Ioml$E6imJHG!RkL0iT;L=W2h_uru_ z3Y*K4X5V~aZ5_6WerEUlNzrJ}wtq8IDzG(gzf&OZySJzGaC@+1=>_>#&zH}6m%_mx zWHs!uvfNwJy7Cme;GUOHENuhZKnt443!x!V`FpX!#AoZ$K;c2HoYst=)01OuG4upRgioBL!Z#8Sw1#sXC$Z1=t}F;N-RB1oBbd#u}=7>6JgUC*S`b zMf1{brBgP^SU<`45Sm|=b&08JU@;~iu^_Vc0HEPi89#sXA+ zA$r|=_*VZK8)`p?<6h9=LaH>D{$BZHLG!$|QyR{YPvI?pj{}}Z-VwMh5j*fVtzxoI z*vGgL5^?N$%Gj(g@von>M0uuxdq^oPS%2`_ zB;0+TnZ*oE*TLk#a8n}6D13CZ*HgeI0J^M2>Dlr%`t+k7i9Q58eu7LMoB4$cTDt1Z9g-8@ZBK|H7d^BD&Bzmb-dU2{;)otiS*{-SlTLfMtex!&&IW8U42+2H_B1O_A$B3gwM-&$ZRFsrp z-VXx}g*DU=rV0x}u8vg!;BEdY->f^r4|svrcL>O-X7az<6o7*CH` z`|57a9DJSWLCk-X@;aRlM{R=3FqVt^0HEN$!ujeI>CdhhOSZXF0&5Dr7u) z0k_b;N=`y*?W>!PDTi3q$9Dnpg_k~_ER?YHI@a~p0J@{Ht(+XSoPnnTyA2Zvx zKP;YlrA6+(|FyfH`0n5N$r-!e^z53wYtR3{h8=C5R%{_(ZP0I`L{NgO=c9f}PK{mh z=&+QK->%&_X0(?Xa7=ATPTpt90YjRzR6yg|sAL->-pMR=4DAe@7^d{vR6T(f=n_xE z0^cT8*QeEKbMuR`(&hRUhVZGG{@etrv|^9fN4%>7hHShB+Tt?-p)_^y@gqpGLfSoL+S>bqQH;fs#gzDmJP)_y>_ zmqXO6AHl-xdPw~-G;7u8eW@60kBU|Op;>y>T#`@k{_pR!V{YvFB{8bJFdO379eES@ zV0J$U=3{Fei5FkS=4)Pd(f)-4$3wv=#WkN!=~XSN{8kqlqH4ni$CxL# zF+1ffV?GFbNCi(>)31D=M2pcMrGh~%@&8GyYQ*>{B1v?CB8->vLHUp98X)sm(Z?Y3 z8CW>BU)|b3r~*t_&*4`Q*icQjvkdO21*&N#c8I7MvzLd%cDb6)WqW#)(jUuddL|^~ zoKr zmapJNitmbpCu)a`_r!`Ni073>Ah}tY;Zkb6!nhUEGU(l5mJMjxWD$duZ1-~v9>tIj zz^*42^RvN7WcHjnJ21^!mboGQXnN*~6cRar{l)KE% z#xuGpGUbR?sT4&e+pdA}cR3SaVA71`J4ke+jaz~0a*F8!i>Y*8_E0_wrsj4^tQ4hC zB*98FAggNpmpU;H;$Z~@jzz``6gVZ2C9oyvLR`MH9=;&FdZltZ*){r?l(rTo4`?t{Mz@e4q zL(^7Fxei-stG;vL?O;H~B-Q_n5wMcxDl+aeqQO9S4IArMe|ff__uU-3^*nFX{EE5Y zRzBxYblPfe9QaoE9=1Cbv8&8~_rm@An0dgs;7Nl`e>~Dx#;u6c2n`t9I^LWe)|PIZRX6nCZK)amdU&7JcVd zlUA)Xr`T)0WIk5YCfQ%uv3pW@_J(iVIkZ^|9ty|&(JQRz;fNW9to zNY4&@xz<`U7kGmla91_x!;uxp6oiR_Yy5gEtki4v-_aWGH|U}q^}OmoAOz0i#h#R^>}2uKLqv*Y$P{`?fv>NY59 zaN0LC^|gK;XZsb+iF_Rz0BxeH~gP#JP zn61v1K^dqWR1Y4gEA^;JHP8uV<`SAjKSCEWjereTA8ASBo5glx1qMNTDn6eiWD8pX zV@Jm9wX$n+MlatUzlF9$zGjISAjVjaPcHD2Jg_mgCspat_V!|ez_3Q8+!flPTQXZj z{QiLWYGw9@;>xHUtoT~Dv{xSfih22;?a}#@1Jc;_B?_-8EoD26^;utFaJH>$*DMJv z|Li5zeH4r{JL6Z9Zv`bFXbPgga1?uvK!3N1)WAmZa zy+ktzZ+f^oCsVox;XY9@n0W-cjD|6rw4z(PIgF0|-C6WIL1H`$HAD!ed^CiM zkK1=UkA_^|IihfYFh-FYtvm{z!W1 z9X@@9S7b_(nHny%o_@uD^TzM&iWCjQY`>mg<~6n4XL7n0^3GrW+3w4{$*+)Hz^8}- zcELV9VP`%UXf=3$cYt?rs-m?*YI)Z|ohpBZqteNe?Pr>|gG*g-FD6UNuW{WwfPp5+ zLFq#jqrJb~h17F^q51!z(ln{+1P`}n8r}^}xq|5Kv;L6Kw7M_WNU(?= zS5vV$P93RwEQSossH&d9TnjrslPT*>!D|{2E&~Q*kr|imd zow!vrb(m(=W=0<`DVMU@jN_J3md7&LG0VnJL3hO9o0A&vwRu%6sf%eKI9C3n^ z_LNrjBosP~>5eO`moPEw4hq0jb|duPA)pBJC*WnU?>R(iEiUCGNZk7r@(?0939F;K3Z15%c35@5&)e z0z1#DL`{Wsl(M+1spJp{^hI#IUm4x-+%+{rxt6mZnKLO6NmWLuGkf}wnTo%&)hnm$ z#l+U;AtZSfF1;L|H?F(L<=nQuwz<>?BpCNk{(38LRfhLN=JN;RZ_?ZoGThw$Rgae5VC@7Ar8`jE=Ri!S={j}>Ozx5))j zemi~@WTvWHMNheT-4vn^p6>2`??XB@{^4TtDew3P&jSQ*8=nNJt%?J&e&g>eueg4% zYy$R-xcfKtg?{zM`SV}8>85%us3&mEhNX#by11=!KMMRNHB!4|&I@%?dC6xPQZ~nWwX{Sr^l7gl}T3XUG4)GdI&X zJATuw{8T)Z_h$axbQE@s<(eB8`X8iy7EKh!tNax1dv+Lg-!JY2eg=2`4!M}H;`_Dg z;S|rW;{QFZ9F<00DLhlDre1f&lVdK!PvQeosk8l0-(jo5D8E_tG~76UB)(nu#s8ZR z#b?{Zc$>OPLYbQ?hf+7o+H{xoVM=|TxT;ALmp%=*YC~_Pqry~m%jE}F^ipZ6FlvBP z_^`?gM({JrQETJ6LQfihbH-MeKljb6e)rDXe|^3eJiedY|4McfW6!yAlgH1kgTpGR5)i66JYd z!&~P*H9mf=vcCQH_-(FxgRvRrwefhf?Bko%NuF1~xcGUs=7rx@6&B}KNZkoM_Z4-5 zWqiE#$8E2!2({5u2+=&((yWKGtEU*zHDH`K*6+X79jva&0Tw#wV!@Ozd6YjFm@&{9 zxT^{j|eJ3e@5JjqIoifVw|ElWPwP;}5slj(t)>z7O)YZW~)ldaxhmTWt_cSo?T|&`= zjG}1x3l92o8peJKT*6vW#R7MN(vH2F3%S z&L}jLtm0SIvvSO#G1o%?=|!_dqjqQ=UfO6yV&;fT2Ty$BTU1ostRpiei3dg{VtJPq z8LdLA(X^f(rg2o@!}nxSUv(v1jZ4S7teo{e3U>`JAg$)rykmEJ;H`PN8-^SWAS}R1 zu;U>RP~0QR=4eh9+$f~=^iVvDt!3vpHpRU)t{)X%&q(dkux|6(m`x(b(aI{K z2Vo64_M@woIi4}6RQiV_FRmM#S?|CFJ;ge!?WQ;s= z?AXi4tYawUsM7-I{ER}NhSF5VRHH9T=ARdZ@lEWQ=1uk`l9~1{$hSHUC9S{iXR=9DvXjXe9B2`kPb2#7~Dj9)!LY@0C z4C$}7R}nMP4%%=_*D(~}bH?M~i5F!ofk>Qin+=s5!$G1t7Zi{j36wM|hOcY`w8JKa zR4>7d?10w?S5)Z&L1UVS>mD86)pj*tLkUtJK8`Y?@f#(kXFv!`V9&%Y2Uk7_;VO+{ z4IK{Z%UjV*!pW9gg#pK+2WQC1sv(Od>3;G9AVlxdz*U2fDpjov;Ssj3`kMwd!1pTm zD$^!G4>}$@7;s3f((sb+(vjQJ*s8b1w%M93-#w)Xq=P+}8fnY~{}uCCdWzvowC#>G z^PRG5Ke%CIm{wdr!2d1ZYEXMftnV;=$L-};O0W&Y?C9}Wz?j3Cam0foj|&*Z8l=jMWQ-tS*#piP(_x&uYeYUhS2`Y*$$G>>JoZ+p>3sMAbn>m@#= z-E-0)PI&vfs0zZ7Zq{#N6PTQgzW#iq@nVcr`$CX@+Z` zj8PczdbNTF%etdM+I}$4AI5P7Zqx9Kh3>mgrdKlOOF`+SK2|%ZogXK0;^7ZW5#M|T z<1$|I4)xA@R5P8=r{f+H+M~=0?^$8AOMiMFt5M2B=>haqV**dNj>haOW@`PpSx=-* z4OsE4*ujXDqUT?J(HW7~)AI82_J}vX`|t_fWjy`9LGsX= zS;MykEi`1dvfpf(S?Zd7vg1PZi_3?}nki>m6)>a}LCVyyF6;^pfymhg_W)bo&iX;2 z9J>MqZ=oI`bWDR1oe2X3=mg&4_tF0`Q|6iCC)Rwb!=s1O31BKP9Al6%;iGAEYJCjd zH7Vh)Nn_|J_@WysPj2%Bfw{(|8vUli(XTTxR>@7(mon^LNXqI`Fst-Vj=Vf%aVLk>Nr73qB=0IC zi~Vh+Qby^LMtnDy8q@Y5X&fV|&~VaY(IfCr6k>gx@iya92jt6JxLkaRm8%ZYBwFGR zCkFK^Lz>aE($Z)qRy9Hu?Pu?yYCtkCU<;|)U?U{Ttk1-8Y%opoC$lxJ5E-de_klMK zJB{Dhw%4i#FXHqbr9_R09#cc2IHBu_ob-mdl_eJ7aL=5ASXJoQWy<1YOb4~&Jc=$E zL(inhMO~m7-R+T@qxh^9e9hJF)G}Sh5y^JXFF-bD2uzqDUjp?6|Fe~BS|s?zQCP@W zZ{?_*plsV0^*Pig$ILk_AC>F-Q(?!SljiYssvs^8A}m+$6eL#_PxuE=8t}27G9rbi z$v6S&2rn9we4^OW@~fd*MxgEZy6+eH?rQn`q1HBU8F#kIuu+?v32Xh)+M`-rCYhw# zBL98&<^Y3>izsklfC)11_8v;LjM6OnzPc{6pUU?PvGX~x%Ig$ZpUrTR+20~+IOjA}G3Av6>!VcyV{w^Bj{MY66M zWBDzF3U)AdlQrf6t?$FyJUDg&EBaFwm1Ai^qq``34yB~x^G(vwRC^Cn#_0ow3Dh!z z6AZ!2Cy<7}{nPjI)TB1YGFvu3-PQJ(4T57e_EsU7{lq7XuMM+co{UAh6E%*q^rXrP zqT2P+Gg*X!fBjmrTdr7VN=6)4S3?GKAo-`Gcp-B2;xmVGVs|<`zugzSbfToA!|Oy? z!)^w%=;-ZiG@O~F;e5!Ne|bH8?Y(!RbAhcN=YX&qX&Fn#EYY@NopH}*YJX$Gm@0RQ z55HyhgeYdbYbB4el)Q3uf%%E!5c_wEf-P1Wd8n9=Ur)62kq~(>b^`#M3}WFpsiGyh zlvd->izhMC^%HP!jA^(&y7rGHGhRU3I5&Hmz6f7Zk-o=L!#2HJFiniM`c%ex$;^iH+2UYtkHPeE2%NurcJZA8g4D~JH8te#3WpI{D`rC^ER0hW zN2}rBUkfZZ!c2fts2qW#dol7`d6$W)U36jrsK@lGrpK#wYWJ`VWk^?@18in^nivRG zTs6i~t!{=5cm0yFm&}9DfN6C;UfA!q19#fdNFcDeHE(sb?qv(7Ze~L}wmjCV0R-+{ z$nKAJmTUHs-z5Djjlh67i z({QW66JOmDxbCYR#?|{Gk?6+O!?>CH>E3;2GBlKmrYGI^?2g0sC3}r0D^mwqI3f?x z<9qeVYphGI4MlhAU3clvGCR6(s&~Qt9p=uOwcx;l$>-@y@5&}_=}$zB<(AQ|`^ zhSj%EGrG5IxFXrgvU*qQx`$fLYxlLz^Ixza=>Mi^?hUimUmo1ty?0UnVZhec8BcC0 z)7~wY%zK79y8Ab*^jgt{#3L8f4lM0npSt>xZSp8LlCrh6b?6D)!A-RuqyNcoUxCSx zqI(ZRx@^AY9(}_y(|)#wWwA|myUtaeVRA-;M-N-`j1O94&5gRiyaGyVx3<>n!OR!n zdl{&YTh{xzF?+S3D^n(mpw^<%G$zpqewZXC{}*cCey3enm9BJvVK;caz31)7BAf&? zY2os2Q@1~3cj=c|q15N1m+U!*$82XqH2l?X(qF8a<$Hhrp7aG9?(lwN`k(fuBk4r+ zfm;EKi7yN#7l~U&=PaG@ zmCv6ucXMK*ZuXkS@$+(j`$WFIGuX1LH}P0-L$K0ie$hvPgxtwV|LW8zSROm`<|$o9 z!>xA8{%Fe4zwk!y1{%`c_mq)JXoV^2-tNQK-DNC_8bd*x^J8YnNKachIk?)`f(u@Z zMOoY4lRUJ*XBg$H^OkOhXGNzPj4Xie#z4e>GiF9TonFQ@ci3!x>mOsas|! zh_T0?I~An?Oc_B12|)@7T015rb2VY{r<4iF&46LhiQO)OK(4d)1A~ zVK9^Uju8vfngoCFI=hO5r8O_!5i}s~odS;-7y@x>ZBGwR+zuGu)HdSM^vq|?uuS!6 z`B~bnQX5J>y|5TJw8B(VM|YKv`J}yKJAEr^mljGXZE;CjKE#5R`@a!-)VtfuRl4TW{yY7&G16Jo2Cr+? zy6@6A`!2L%nlIaV<2tXkJ{${cj|H`$KSLdpZ_^%OTj;@_L_9FZ$GW-}7POwFmlIBl z-G@c!ee-)#lkd9w5}faRcqlfY7rH=Uh;!+|X%y^21i^y<1a1jNC&9Z8YM`PtFvwuF zDa1CUZ9hN1wVYlV)#aX zqfX#y$Qwi^cjy(-dAag0i6um38WJod@MS0%d%Rz;S%X|KN+Wn`b;mqgv!aDgV?hTl z8^U$80=L8DY;`dk*^{GU-y*t69!y`}X>|+xK4Gny|bT{K|jAQOm$r`kJ!k_sv#DbzIJ zD%gs;T4(Y4C%-x-RIexX1p?oXDe2mI!?mts-iH$SY1?&xw;b}11?fpDy;McsIo1T| znDB;dXu}XWIAHyObDM5kuq>X0Db#;inga1I9PzU?+Y0NrUzgH|CfbdpsiW6LAe=!( zOeWC1@o|ha)!VWGfUw<$=}P)RF4W!Q3jakW=%{r$O|gvGD94(qwylud5=vWA%Sgz* zLNZ|SwQM7y)AD)5lMp08v956R$c;B-G4BGnUA_~6oJqUY8EJ6%TA486w1{DRnV7^3 zi?K$tl5a4@j*MKP$E&j>cn!oHDNGwFgzNnR{u~4nh~kn0L11sFhDia%O5urI5{Q)YYjK0GQn;2^F^T z8vqa7EcuG!wj&w6*AH{zTX@-RgiHdW3~@!?%Y>i0U6%|j{Ms< z)jOenF#WSvtNVWU;@02s-+^Cx?f3`yADQSxMorRukK7;GQn#*)U7@R6gRlcxD|(b+Ow&A|J5IcN611J3puK z+Xlw#hC`W7yQBQ4<2A~9HU`}EJDWbLYzo^2uKNt|-68COV4_ez(BR|u0=vUl-M@-> z^&fC$m`^LA=zd1Ygyv$CXIx<7;H^EYyGd*!DW$@GT)lDdmM4_l=qss!fv=(dNEone zP$lIQ8|_WksJl^>SNFun{sP&N2$7RU50^*qg++!GqLL!@VoI(esb>IwaA~!&teQONLU3zX!{J52bw{nR1t%9nhCfpH&sBam-vDS`T_>C$M?O=3uURTT zrudZ0_d6>7vC}QjDl8N*uT}`(+$bLwRr6H%#4aooRXP9u^DbZS0K=w{J0Q$;F=CpD zlAxT`YSVpeVnP#%s{V_47N&ymF+~>`8p~MeJ&yE%4IiuX1@Fn$G4l0HQG@5HWD&69 zyop8aX(gK`hhSvFqt@NntaP91F%pyR8cu@7D6nr(d9m`YL1@rXFG?q$;I3&flvFti zI}}qMr?FYLT&~N1(!(tz2!<6s6b=d?AH?+Sem5Tp=e49%`Q0(>>ZyBHsPa;Z{m?C6 zm08UT74Oa-dtn6Ge#>)`A053^WoFcK z@}zTwMn>LR*79P@GDvMcPFd%L*B$A2MjiAFM}_i?Y#Sv8Hs9AFs}mR*and|=RBEqI z9GU2m(*5ADBL82fYjm4d1G^}Ww9dYB; zAIHy_wH%gV_=rb3T*n)AgvFbclCYCTVXmeqodeg0oQ8WDfw~!x29|0w#ksA z>zctS69M-LXI#ryDHPE-vS^T3w7WB*;dDnzKF(+f8znJjMe^*RA>ZwpE|2HICvZJWf=}Ry_v`}|K!NmrKMo5} zYL=Fj9*zkhF@MIFSTeQm1Cr<5u`wKehoaI$trLb6wcPL|bONjIErKGn%IgJG1xmU^ z#xX{0BMN1su~VR-RS-tybEui{*gL2gTpTxth0(0Be~B{~E&Ynh6nyC6!yu(*dNeys zr<9YcP(jIti5U74sn^I8sM_QBtTk>G4_-@r=B^#`rF^)8JPv%?4Snlm;sqM;20GxT zr0TE#_DlWWY#9q-PoW?znQng!(;x?Xcmac_)YH?h9lyMww+r9Se z;besV_C!A|Tbao{0N%pCsC{wIz=RE)Rzts)|c} zAdjELn(ubc#SNz??@qhcmW2iZ|MhMeESfG|dexHR`gE zt%qT&ftxUbSD^1?;*V@6;?zOh;Tkqkde(>-ZL5({MGx1lcGVtB!#p`m+Mw{P$zIAZ zBbW0LVFdKCFv)6-5~N8AUz#=r={Jh)B_#Jq?coYqNyyJKm(_ILm+(m+*Rz;GeGz6# zWHE-sL9o_sczcG5x{UCOQT>_WyBeo2l+f}c8kT?&O&5|h-ovBm9U5^>lc79m#8$~k zl51Sc>A*6C?XRU!t|V?_Oczyg1tcM2e~&~i&Z#J{8wSM$h41cx0X4f*qWJ2lBFMnu zL?{Km7zHCPV8EDW)HD=T+L(>uq7H;X{4Hv`3nX4=31mW1`m|bIH`O!~?=>CRwrw-H za4d>@;#zZhn`=rN|!$YZ-2gv#y$%}Z>4tnf^%$V8E{g+1Aqn^vi*L8|K)j@L^ zw%~Fovm9O!@dS3s7e_jTLutc_-J_1W-LD8@%f*vvrJn|_Pr5t89)uTa8Yy%mo`6l! z)K#oypGK)F1BZAyX!yFdmN6{?0S>*oZX-YnxaE5EPfgZ52Qkfbi&>+cc?S%vn5h~` zC=KU{)9jlLKt1b6o9)CGeH@DAh1Ig zd%`Q2QIy_GniAgAnV8Kx^q4GDEM}NJ3=4@a;&GFwcEl51 z_%78$tdk{*JwoSkth`WiFzBgegT@Sr_Lz)Ofa1xlJ;!P%u1lFPN@Y!Fq;XSXr7GeW z2{mh_>K#x4{3I|h1zs9!e3h?mzzwzCWcnAuVVd50r{CDT;4AuJZuduHo27+ut{ z@P10OkZqW9hu4^jQLHh3 zzO`jRYT%j8;RUg(;T?*|p)H|9`;rS22foqwY-IMNp@%~I_OWkW{pAC-Xrz32&zBAi zO)>|gD?0YD;OzVW-ESS(6G#rN4qul_+xyb`;GyY$6X>3G?W8-IvD(}`Wq0|Z)_K#? zrOKzxoBjP?`s_E``_~(R{vAMf?w7tn)A-iY%oltnIQ4(=_Wp5BRd@dI=iJ=P+=M%s zJ0Xk#Gk6jrX6T4_h7kiD;LH#p&=CUNnf7y!@Wr(-#OH>smnUuGI_-+>zKW+ zoQX`$h{)0B?)_h^EBtr%owrR%Zdx^;&)IjNsVi~+;r+(EA2$74Z#wee<&&=tZN1r; zZw?$jdV{&Ct#4QVrsnHsKYGz;X5HE8nYX`f`t!M4T2p77x{Vht{(A79fBXK`9j~r? zrs3A5-+O-L;>>f;$>#P#xC9Bq=3n_<{*z7Nn5loo+?dSG?6SMMQkk%|kEh#SdbT+i z=7w*L9>QI=smL0`UozS(z4eQx|K6qXyYwq2{`5Q)fxil&&z& zJDM$lHa~dxO!G%|W++5cLxvqbVq*(ahj?9F1Zqc;^QkF9ajb5rAK;{S6|FO}c9`mT zTXq8uvRumBK+=>tx zd?XOOx?^`cj^t>C+r^VRXZlf2v4{oGJ$c8jWiNL0cH0jx?hthaS~@4y zwROs3qnY*vd**lde(TEH?Zs0?@X%Ay+;XkZR?rsv9vjThEOnV3qTQ!8VIEgtt9M^% zlUB_1qFg#H5sN0N$;;)g<>2_;HB;LKs%aDT00!;^?rLc$5-v%ggwQ8CELBPxmZhW) z&uIjwRkaJ6aRpiiH#MCq>kBk69^xO{UHAps2dYd#ctBkaTCN?ZN#N*JBNk!aXV5mB ziw-gC82TBm0l@^Xo38c=g1FEtyR2w?AqF@U)4HUUwgN|k`^}~&yka5y_?94Vdzlv%A?Laws7MTa=Q`F6 zs=1mdXSC2dDFvsB&SB)1JdjZ{UBI~ERu6Tc1Wna^RiR5jtT3-CiE-|eN>yZ4p<*c~ z$2EAlA=k9JBn(QnFcBc|SzKkGpeV}SB(A0fSkx<*M)$$8pBrG6wIE;_SwJ!g{S@Fq z4!|y$eG%PV?)||X;G>W0*O9@)`F5AH*H-R;>8kmpy3rTJgv>Ys&Kp)biSXaBFfSzz z>|5nW&0UO)5ALw9E3n6FnE;EqreZ|IF*RAlbqoP)^kE8v6JADGZ&RsEfO}rOk$_Md zbY)7|CS#}Oo)DovA9hE>ZFMZNby@C zvuYZKBwKWv!4L_BMwqHj;7U}@(0YYi8}Mi3t7a+)H?&XaUBe3>G7lZEnMmaeCRfd3 zZ0tY2g9`t^^ZT(t6-Q7P+m8MFnDfCKERF54RI;C|GEzS{1pKmL!K4O&C2#Ij z_%Gy_{&wsguUGN*R(WcHfT}+r!kg=>9KF?>brq(ekc7?P1OD`<{bR@svR1QGIL1}p z?|E-974BO_T*k(^?;v1#9Q_4q3^~&3Z|&+?=kEsI3_L~QEI^k%n`r?gNh{r2+_b4e zQn*X%niuS+%mr|_7TC(zM8z`)qy*_h`jxcRaSTPJuks#TOak}Z>aj_R&+d)Y{|1a0 z$cp02gZjy3w_J~3*TbKE?Mm{1{~7SHGGG1Iz@QtE^FL4}0#*ZM821?teG_pZ4!qs^ zP&GqFR;rgbsV23H-NaR&%5B?z%y~|7&cwD)YI9m*ZI1`S9Fu5ucI? z?PBA#a>d(KsvaC114GF8u`;@$i-oH0SW^mbne*bzVWQ%-kOgFR(d} zm%6wqENb{E{gE(Xl_#YXPqM;aRs6M|n>VE&cca|7>BEetrsRd?Q8QHehd-rM*(f(E zY;4$kjOktwX3gGpqY7udT-95dx#n(YcsQ6EV_J}NUa(_Vyzs(mP_VUYL373|l8UCd3bLm!Q8$pQ z_tF2r!hih#QF=+@-EhF7QdOFo8i8)TB3(Y? za;kdY?}33?win?=yp}s(2@QO6nsOKF9`~o>{K)-=@o^3vWF7D3Fk$gsS!Ii9&8rsP zz<7@*)Z6?sH9?2@?mW^6cLm4wXAD&Rrv@D54^n1f>#8b7S|nhtI>VH^Y7uushdZ~v zYHt5eyle4w1MpM%S?b1|Vm0jd2X4OF_Kt7+l~+V1+@0K^o=9I^-hCG}RVUEz8P8wc zZs;W`SN!!bIob&cTbjmCoCJ8=XNw{0jdDSDoMqnZukVvs}>coXC#GqYYN4eQQsQlYIxEB zrbvw>bu-b8Xql{%7Kt(vXy!V@N}kjT6YeQWTtaFO)(;LGKxsN6WN@KUtQ7Q8y)~)n zhydSZN%+!)rgVs%71Bgpxr7Ws2vx-fWHrk15Zo{j!hc60HpE9oH!YHo8ZMYbE+lt6 z0$CDeK{#m6NvLQz(nd^Z0z0nE{3TEhmDy9mn+rDwDS)5?ep8obA ziDb9b?ZmeClglj{BIo^$8d>u|hjKLXxpbudBkVL}u$OJqQfv(Oed>KVRj#tyW`1O+ zPktfkNbPp-&eS%BB0iN?D@)2dzUVCU#OKx;yskjm3b}n!gk;T1`5zXpaoG(V>xY z;ilcYx5cmtd-K226RqpE9s1B}YmQ|FMn*x0Iz(lX3{mU5kc4}#4W*I~-kfZZ2Msy_ zS)PA-j&&~z<(i5(uCsoNcA)s-!;pchH-jx~>Ih3T2V$xxo0h`_d9oJOb5{96!Rp)g zera(Lgs^!ROR-I8SFH&-LHe@cmpU0A5~sbyaSt-$Orn65N}B3<>L#7!Z_45w z5A}`y>u*s037Df2xU$u3_gmG8gE2Up%Ou0t6fg;Y-YgWarHdVa=FDjkjW*}1$afomf;_=ito zXzeiQPRE&A9^FKcvpR_Ta`&0>p29-@Lerds?Tioj?YfmooR}FLJgFg1S=RKI9@CQV zT0@~IrWjHg4n6A0vK{GPg7s?poXBOz$y#y_R|~Lk^WZOR8axg()G-sUqIr8goe9rL z6%GZnc<`ICRT0f;+p)?hU#ihXl=#J}iWc!Y(imZ&0NJv8bp8}2Lv<+5tsZn0uUdU! zM-#zdFzdiWzPUZnJbLEYx_XBNjMT?FOwmO&&}5t!8ntMUEdMW|Qej z(He=!IIMlrXLM?13QGZO7aWwJN+oU^+ekx6Yi-EMxQZZtC=`$TRKAshY|jf6yhEMC zFGB}P>ur+Jq)d!V;7%eaghUl^Pp_OX9~(khT%2MAJuXsebK_^d^J${>9;UeU2_s;A zpJj1raY4p;f1NI$HZSWjj(GOAhem$zKxFIghQviJmg$k73hrXgbLQusGV8w{F!p#l zBk}j?^7`$0KOZ%E-eOz!9q0f2)b_o$IehTy#>+qF--oW;_H4dGP^KKaDx3W5502YE z7qNsB=c8@=@=Z7+5zzj;{RuKE&ze8qC`11syob2co*(8-^chrc`Y)Qxh1?*|jSB38 z9Yc23(aJBB=#{#pSja8(zuhs9Y`3DLjw3%vXmz7F@sY)i85%@3nHDKtB}nRhg;_$K`vHB@yaR(F>-0KGU>w+X@YAZFj7xDj z=GM>QpP*fN>?=yYod;S7Yc9A;-&Ad6P-9S9Mm@>AEUUG};~2EFlyELBsokf<>)LuI zVE@GN5slVEi~->&!(GWhosHqe>d@-WNnbi^lk>a`NH)}l(Wt&~6J7o(1byv9$Yyxm z;>8uY=F1LR8?XgxjQT8u;7e4Vu=<3@X45$ZwsU(@GZx05TW5Fu%@lBASe?zU`K*}8 zrp5gXa1;)g{$koF4Lp`J{Bv1gA=}+)oSSVrcQyZ;HG|9nONx_!q8A2muH$c}`K|4z zX_fGnBTLZR{Xx68kTD{a-`q^zO$N@JWW}PJNH(4pbnQ(nkVXMZ5ANLcu(}@XHO?k0 z?a@oxHZ*ZB?xDN?Ni^wo=g~^FKGlkGFI%^0jfRd|MlZJW)vXiTEohk|E`PiwVCE8CzkVNtf*V0}7PJM|n!_MX z0;S(e06!w6cbir#weDc4c${`Xe!Nb)C@qsXcBKi3CTSO(o9z^j7rX79xCTAmt#$W= zfPhYp%l2rDipiy|tQhZRG9DF$cub22i+Ps7*_!qh!BP`j5fj8(CGRQv;;A(~g}g}Y zllj)7oMP?ah1OV}cI-&()-;m5R3d9fOxwXNjYYAu+nw6IREu&Wj?sKZo>&jdhk99@ zQLCk2pWk2Pa!0w?&QkWOL_A76)P^$;wYGNaT&9|UV#k?Y(126(coCWM_oaIBxY*H` zXYovT9O)5^>FtI{?amW+O`;+^857CgV7{=!Z}@i>TYWxuJu~$|9Qv@#P^xJAQwWE( zaWrHc-C7o%K{^RLHKS-zAxb8W>-))+T3qvK2Cz1+3;cRDowafnCp{5`WCsP2KuJx# z@Y4*{6)GnA8_-J{e0o0w&(gk-qysbs?L1)ExZlW_v&A&zJ@=URXM*0=DSF&9&aRppynOp|S$vwHQa9SM7B*VImL%b?YjI2PSG zW%q57hxh4M&h>`&f1}gq3qQqM_DoH#Om}s*T)CxfXl}$jynkl+TL))uIehq$_O@f* z!z(83TyyV{1Bah{GMuz7f5A9>&tu;RXYQb9!ka=?dF~Ur#FUb?2?tmXgOd?L$T?s2 z{Ll-VAjmqz{Ca8A^Vh8rGdn8>o-A8KgV!H0jj3B+%pBkk+!GM#1PXg~EIgK&u#`_Rkd_r!4uBtY@ZWbV6j zOYVTrPtTeM8t73oqru$IQNDK>;PWybddx=IViXDJnN>hQFjMuvNc;T^H0oH^!1TzV zx=fki=pJ+wI5cxv__oO|0F=!1ai)I;n*sH0I7>5_JeJ%U$-ei-IySgqu1)=2H}+ok zFGeC#;WG^5*SKmqJU8jTdPgNWGB1*IOd}I&PweMwkIhYV-eX$_u4_t$%U#s6;i0AW zGo_cmBya6(`TYDGnUVQF-(WO8_hRCW_O97oZQq#ta$^3_VAo}R_a)`zVypc9k*=Wi z?_2JCu4y{I{Z2V&4Y#lFy~$pd_+q51eg8*8Q~z!rY1XmOE$=7)I(qesH@vvXzt4YH zxHS+CE-264o&2bsI;V&1EdBDIlG~bTzdg?cS9>lW5pBIC->un(Z%sJr+vvYzOIKIY z=)HHn*?N~g_W-d=9o*lM3Dd)&IbAsOL-vdSvB8EmA2;^*pE0|1!!*Hg+h-o7V_o$n z+L4@yo>{;+P^a4#@tlnVba!NI7B@O^S$S7L?^?qQT0dm)b*Ay9gkfBDomJvS$Y3U* zBij$T0ReDgx0q^x=Y49Pg5x$AU7&3DNfH5Ixm1U{hP65!?ku4NgRr%tI2(XI#l7fv zbaSEeYTJK^1T`=BQM<)NXEC<5L!$x}R~~7CAdIAZu`V_kTiWsB;L45%7cXmGPBdlE z&iA|=%)L-%%Q8aK_N2|yT+vXcH*4GcLt1gpvZferjh=2U_M7W(#5n@l@1M_B82-r* zEqcWA9qqNW03=ly>Gqu+et%baig)tvIWKtie9M&Z&Mv9Z)NX4~D{kytIoQ9ueSHvv z*0wnv>0lwkpGX<{VvW`5LmI?Q2h;usR-|oxzGl=JyV|?1E(YuaLSqrp5kCq<4|m#b zlBMQnNN{0*fEp5Hr3XWb0lHyemXI?Gu|Q8&*Ek3i>cUk3%-l9kQfaY`mjMw{pG0EZ z2|g_~u(*c*e-Ex`mkWC^79#K>i-?!d!q3KqHw}U6 z56%EJg}mJ%MpHywm}W;Lqg&k0&n=t19b!(}j$Svo$lL0*x^dP=gtmkiMb=n!SI+k0 zAVPP4Q?f10CYwfjb>0*&c88WV4IcK*F~!OQfH$q1e0LdJx@q_HK(CmSiGj}?!(f2x zlLozJx~->YOYZ8InwMMtP3e#ijjQCx6g?Kd{l%cYu5SwDgIoRS!6u#BMSBN@o@~%# zjGK{^-HS0Ji)<_fi0N(CgSl|s&`uN-rqsD6E-}h#(h8)zh!JO90J*UuaUm3J@gtgN zDWhTV45I-HY$J*?f>KJA*LkHA9kk(?E0d3_1fe4y{A!BVK0bci82pv)7%gU~8=Vg6 zIwlfoGGX9voGAg@1L&C0Ch$}TJr^D{I8JG5oZ~o{y1NFV{L#U%kU&GQ4x%wAc3!Bo zT0aqHXRx+#^Z`g}$XEprUdt#$ineXy768DqhR$*DgY075NIZa3;wpBcbs!CG3;e*yTTNl#A^40A9J*RooyVM#m>L0T#X)!qw8fsGU>`*Eeh zR?3ZpqnnJn+Vhpdotg{RTzRf4IHmE*;>u7ey;6Ci7oL3Mr(>68$Q)g}wy|EB zD4yCSKs9bKuZXGJf7RbrSB<$iEl}BOt31IjwtI=fZWTvx?Z#jCHeeSaxuj|H>WLFK zuU5EMq~=?i;(WQQguzah5I`>y=KW%S}0u z6J=MGn+kc*xPSAvgu6Pw^IIT4$Pf5@oxfiDj>`Lj1*MM~8^(UWdJ*sw@C(25CfI!e z?z)N;->;JE48Gq+g*{c}p^lw{z|?aO`DWp&&08NF?z;6>#anl64To~Qu6~k1oa=>r zzow|wiNZ87&H(cQv2yuP6`90O;gaJRr80Mk9dJ*@PkWxHR^g!P2lq95^C*}3V1-G%z|?#9!v^fe6lLc7|xDwA=(-(yw2-|_o?$N8UC z-c^}gc;7D;GFq*it31CdedEgc_*>zRWpv~k4q1D6GdTbbA5{KPlnuJXoSfZKv#)xxX2FAPh4Uub?lPK9It7jf78*8I3` z#&KC?Cs8gne;4A!HGdYCyfyjP5^1aDgW8cN_{Dv{;MKn1zTa`#&u+TLziVM(6`QGj ztB#b~>~^QI(nm9As;|m>zsm@MT!IB-?{K_c@{44UcDOP4Q8QpK0WpwMX#d8 zKOK8|5Ww(%jD5$&eBn;rhYMa=&nGaR<#;jYQs`veRpyLaw!eXn9wcWta1&d2xqBG6B$?u3Lsl|QNc0gJBYuZ`96r)*(f!*q96-5H*Z zZahUc?D{k7tNE+4v8lSKmW!@@yUO8GVY}0+*l+V$6_0?-XOWN+yW+=>t8^&rm#cT^ ztiY3j8Rq>&jLB5!?23dxPa<^O4XpYoU+|5acqf9KInF32;kXuT8ciEvudtK9q!`to z^qiVD;?RhM-Lzp%jE)X3QqEpe{bYn>ijWFSp3kDI$kR-@^VFYRG?4O~^s0bgd-eER zC+V%lufJ6g$dv^u!yQ1QIK?>p7D>kg23i^ROnBQGK;t>7LgfgThR@20a%5!MTQuOD zd<#xhWM@5lM<9rF_ax`ms7Y1A0tTSqJ{KhYVE$>CFPFY&0IWE7&R1y&KGm=PoS&WOiB8cB>EAD&3B zI$lD(0q=F35TxTaM&${HSF1c&%>Bu8i@g|vhLcWDkj3!yywSw&+Rav(^y(K%*$xFF}lv+~EPQaVft$*~AOydAP1$!ts%2tWsD2`@Y5zI|$)c=n(f8;p_L#-|q|R-RA2YUxs9Enx_Le`SNd4(6abshd-UZSB@t4~VENeRU zvJUCZ-~aI8%-~&CLn)@!r=!^2I>&l1E>hxTYcBJ%n~;%z+%Xlk+E(`D7Gr>zfD$w5 zpEbLg9TOuShzsT7k{@}{3e&3KJJG3gs^kwcJ&-9h4XC@Sj_t-HoI zXgY$1OlRE32}~G=v0wQamiGV)^a?sygB*0a{iiR}l6>2bg|*$LM}Bmg|^|r$Cpi|U~*saUE3_Y+qsH*#DT5vlBhc@5J<%(EZ-485ID*g|$urk9wFqDpn>K!d&Rq-uVxT2mCGq5W~E&daw$e-Uy=^?kW)sIl=K0`%7CP#b?mcBN`%1H!P_``eF%Fmde#T2dY+?yJuV z>zhm$(-MJ@UCGPGrzwG!ka-y$N|2Bp7iHxP?g+DCeM7}c6ohWKhMa>#kql&YUNlOr z(o>-NQGIad$=hl18M<{MB_!&*E`3YSj3ue;j?!c{=?i?6{XGA5bK!~g!O@&m*?!#i zTqHLJzL0t5#!0W(+;g!13M-ds!)c6}xbIi?BHxKKgAI(*`N5m)60Vxp62G)jMY)+& zCrxtNQE*TwOZ}W=g0gkwi017qhel~}hvmXsC+6w0QPBVFQ|L2UICkqH28QcH+#R@K zZtNt8mB(0_dT-96qx;VDQm!M@_ zL7}>O(q2TO0(w>_elBP{cI%aG_56g{^CM$t{YN)b!AsHN@n>jJ?slTTRs6Ji*Ea20 zBc5fr24yz_R%ukMT88;`kK5Q1xEE1=w+ZJv{x(bUat-I@n8In1E^LtZQ)qk4sT&A> zxbN1kx_XYAtOr$4i zpUJI9B0o}vH?KA+Q5rqhid9fx6Q;K|NG~ zp8`erSP5wa(_$%?HU~aANKI)*OJ$75i}8e3FZ%EzI0zxAy~*$DH;vt;{`#)RPWVyHW?BVd*9L$*9$C~Z_4)+ zI7>$}v3#B@!2>;*FoC63&-3o?cxvaI9-{;y&!W&Hs6Du>sZH(!GrwLe=-qKZu04g_ zF%h*Rf*uaWg`Za0-AoV46@p?olCWac$^z25dnwBg8d3clTx6VE$+ZQqXBkmt4vKXMB4Z!S+jFm~!;BXUFHHuACQExD;JlriV~wlL%2uK9L@>0e`ZPKnQ%*JaMzbaeI# zU!@%R#@$clGG7fHG3LMEqt0Vy_>sHs>UyDn_RL)3(JA{5PL8~g>1vJ!<|X>f$Mh~* zWjuDY^75q1Cp|h@&O2gwAGv2!$uM4iWcU6n{hjw739kx0#X8L+FNLpf%~#|DN0Zo^ ze<)dQIOOZX)XV5N(D#jAX${V6G3RdZMXA5-t6&56f(Mp|i z7!TmUS7)ksRoM_Y3$dnP-_}=5G_$6)BOksvygSrnSYNb(`aYImlDANC!eM)Z83cph z4SH8G)>v2WT=QNe*<^gDYi`|_!gKBC-Uyd$Yj$$}52FXxMxNRKSYWGlUBZ|;GPtZg z+BbXCzP`3Z%MG))=+_W$pPZ=E!%P4Ei#J@EnB8+v_^y4A-TTui;Vt2xd@sT;6^DEG zeZw=q<)w{}%=^~GYd!siH@?4oFu5f#A=PJYO78r#^~R zm!{JEKqPHk}^v2zFVwZ|;LxWD0%OM`)padZFj zCDxNN(~}$OFvDm+awsncLDzLwx3j_A71%bDI(o}My|s2w zc9T-1cSv0Z3_h594sBkN)kD@kD-S9PrD1})h$&gjC^D2FN(@iC!?h%ww2|sdb&CrX zqJx%SXr#X3`45zUUSh+hh_}!M7`1!U7v=$`#D~UiGO$=Sn$m`j)uI4Q--Yu!-j)X~ z6Vkq~4)e%5((cst-r1dz<+N^+-Js)o?W>#oeUUwN!2?Z)CEaktqgH6w^bP%*(Phm& z1lY0bcI_q6*DW`ML#bwKYdF4$4pKiCX76)FQ(UP{_Ohh7dnu-!#vX5^&)iW;+E|cx z`)Pmh+3;L5*>lW3j2Wm2PR4x+3N5SLiMctdrVeZ*~) zq$SD~CihTlb$(=orF|)2mlW(#c&e;XC!&M`gObv)B;Hu};#pO~7UNw(){MsA9G?F` z8Q}g_VPf2*l8%e9@GTJm?YxnxVFw#6P>f^6gJB566;?lDr$wAwI2A%+`%pA&rGf^X z#Plm~*g#%&a0XYpQDpgyPhJfUUm`4`U?KDIa3>F!;ToC1r3FS9_kY9vdN2CC3HkVV zg_ljTva<=-HgRg|MVAhPb!BNfj6iUP&cswi4T?ICM<7iATV@a(odSXn(3fy@5l^m5 zqiA7mZLP<|i@0suDP|?%(CGD|04;qh_bn2{=?fNocv4{-jjI*zyTHb!zfe_70Uz%G zg#ezqc4GU7iW_a#v;~t~-n9C$dWCW*6k_Z?NLmKJnZka5y88X|vQw)Zx(dBjJh=+b zb$Q{&x#uovnmDoQLSex!Rt$IG;w6O)t3PF1^>t0k9DB;l;9g;%!?P5otE4-RK_04# z7wFBH!d(_z1&OFt?%sO1aWQEIV&$fB5?lc9RcZhBx8Hno!PwZh)y5Tk0uaG1p^b_M zcx+V-O~RyEosaNeIBz4wW0K zsuQcq_p2(z#eLn6+5_09QVO4}{nDrv^kY}A?EVk~R`Qc;%Ed}~HH;djs`y-M7;4R3 zEo}AvgtDPmKPcC3JUy=e@o>taaZL7ta4!tsjd$FQ`>k-_n%@gB;0yhzxLiHlNsu4) zbJe&%*G!d(GFNW?Fx}(M)yoZQ+`k0I>)!XP%E%21VIXZvse6BGN;*`jeK$hBGboUG z+1SLUv6hR+N{7_xFDH8^v2o z`iEXuR)L~l>J-R*pcX)6tF9O|zC#Vw(5g=YRX0c?Ge(tOz?ei83s$FIls|>^BAnIZ zH}&GiafJEK0z8$yhZG*HLQ!t3*fZWPZ!i2oI)MsD@g5_6kXc_%iTd6QDmJ#-`K3yU z!jfHg)noz3t-J>r^pjMc#*M14UnvUtN%bUMMWAw<8z=nKwR`71(D=1u_t6`(-gxrc zkN=f&4H4B(KJ?IUf9?AG_eN5PajhQE=Iz=yhIv#L=o6Mc4yPYt=H}{GaNQ&LVGM7& z=3qb`f^<^6yN6tUR_g=lVyQ+Q!eS1W+fc5`|8$55fxA(4fe{m2&|X)D@*8iea3J#S ze6&kR$3{v8C8*3lR!dy-l3HXjWm>hz!CBXQkbS{@k6`>&{tu7aV;jy52e;VaiVuf7 zdt=j7I#OSm=B5Yh6=2XRT?4aJeiR6&!grJyMAaJn*SY+=ZM=##Ltv>-cc-?HMuT|X zV0(b^ib~=~IiCtgvU6~crNqFq2p{4`7LAwazFN8=?TB~=^KVRR6?IaOu*{IOi6d8- zgg^$vOA+*^%5#RjV8 zifC0X=U9!goR%l zFy9^@^@Q>Q^@@gZ9G0$wyaEBnm(` zJ;!Bv#DO5bh2&J6dXMH@yU;oA8Gd&(~v+!Nh?w6&4;pbu)N9 zUb(r>Q#XuA-6n#a=aay23BL4UXBzP^fwi9N%E2_}_{a#c2^V|zo}K^~ND*;13|3i{ z1&7YQO@K}viEZZN3i%o4}r zP<|BoTmmc4FoS^SX+W--ihhYR{BF$gTx=P8krp@96pY!~*N^X|%0!Rzt~W&|9qncd zrTJs;u;gNdM#l@oEtL$Mquvp>hRKDdbntJ5xci~QT-m99D?r&f9PlC)a1EWrG+vj{ z1ZkXe<}G7M;`O8jNC^|lujUcmz)35_L70FAK<2VX2(N>cjfRZ60V{WewuvWxBI*Dm zaD9^QC@UGogK1bdqZxB$f?P(6&^XEmClVyN)Fd{;buM5lxT07^^~P$hfJ503Ehr^P zhImu*T6K?nLci+sZv@5{ojNZ?zOPW~_pKB7}}b zi`I>MA*q`jG*De{>P9NLr3=A`AR5%L!Q-u?m2zcJ zQxaj!TWcuo7?H<@be zS+&H`1I2-^OyD0k_6pRw^S-xfdsa3)@xiM+t?QB3emG_Az&#Wc?|-z-v#Mmi7VYf0 z|E6ScN}`F3{$Q_Uwp^AuXFJjUroDeU6u9iwrQ}&x!X2FgIhi-~H$H2z=k~mx{*|;p z&l-KxQIP3%82i|0Zwb6vPyfs9;XyArZ+}A#hw>j$se8z(Z=-$TQE82MC={3>v|r%p zLS2HEpSsVmU-4-T1M5(@zx;*vlWAlY|3uVf&L!FO-=s+1UIxCJQ!7)ezHWrPszm>V zz|(c~sD8*sf#@Xb3A-C8;d9WgX}er{6dG6#2}5e)|4oRJ$GC>pcUjn{5{91WlpiD^ zWSA^@CM!^sz_2Ae$~IuW&G^85((0*{swb2w{!vwtuZ=>kIG@e8Gb=H0+~sV^!UoEZ zI)PwHe<&m>&}JE(B6}K*CK*GXDVIb&p#lDk^1G(p72Pg#>+|1Di&eQfTAbNI?=KT# zTDOvcOb2eUbJU^ri)l^WTt;V8UC(i9$d(%fNs7&-wk(IEch^(hiB8h79pM1U(?>0O zg^rdzoypS+4=oc~E=iZQXQyhT{)4xiv90aVe%z+8PyBq;n(+^w+oqOpYVWSkwDa=M zsM!ItaN#VNE@yq0Nl&1A`*i}jACd!X($q%eY5R(7y&N!}#J#(pMf$WR65`NV33`p* zfjO!mp-8Ec{>2wfPny^KLXt-249Q??STpey^-gDKl(xWA0=zva$+IHuu&jx4((17r z1?*SqqbOw$S*P_ZNU|1kJT|GmuDUn;$l-TYbWq~_Lw&#o-A?C^Ny-dTOtl83$|{zK zTYu?%9Yt`%HC$G-l!ROhoS_#Sy%Tj-(L)lcrya6x(k)D#b{E*Lk(9@Enh66y1L>`4ost?zGj47o(~Bs}bhv!8g_BTX za@g1thp4ou!!-1E4008wEK)MbK!Xq3n73kM#gd)O z5{J}q_6en7Cx@0uU(WJ4{ehACa;4JUPM@ilast{YIjgwJl8`o+2P4cl$EcpN0m_<# z0X0>%UyP_a-};XkGk$R{_O%Jg2VOaD{$+!ed~g?AIMX4sZ{Q#4KT>;lQ=psn;E1#D z7F=ULD3@8Ucyyef8pP<8lAcjXJgWDJ?d_o-Rnp|)SDOxXuAG=_2Ru6Z)Yi|X>6)Ix zv_C)oDPy^|k!kX_hEsnb*sOmF@jz1CE}L@v^fNY<(bx~3T^Er9O?+2-|Mn$c5c_y# z{S%dmN!k{*pOPDg%hpB2ARYB{u zM98X8jQ^s`td2sj^2N1X|a|`Xm7s#ySjzeIiGkws8N>K zE_O4C+}w;aVaT8i_?KX~gnnVl_gRo~Of;TWyT+IRAm2!|Q0Ex@{S#oc>w#vGHw+GbI^?ZVBDXA*k@l+D;5hfUntT} zt*}C8d5CS@sppHj*a0C*#eIwlskqf$02sVREB4^BPk*NrMZs8)o^BI8IB16j+z!zl zYfb3Am@MS?g{(LklO+h=juavPdCdr$`A|xcm57dW?Z=CytCR4S?gkup$sX)30Oi=q;136hlovdGl#nWm;&?$H(mk6z)< zreK2EAytl9u<~I898(6!!6e_ywt0Ydhy9OUr|_DvFRTx(*+(~S0oyMIJOBP%hUOj1 z93?y8H|92k>5(|(rtnomUwrVfqig&J{9SxwL(_|^Eq=h;*^z7Tz4ZL#OSL16I`uk3 zn|ff*OE)}n#C+MFbkzUAK2yKp`K_f~XT#(zW- zdThgy_MsQ%M2s$W!;!$@d+h6z^LdN!*z;2j*0<}Pm;CocZfNk!P{WjFcC_J!#DRtb zLBM&I*LT==<(!uvec_(FyUOKQ&Koi8c@I5vUEAF2&Ha6STkf&uB*R+{v_JZM*l67k zzULRB;dvX6YzbdC`;Mvmz)yNzL*K^!PIHSrb8tC3rXMg`ryC8+0Vo*0=M6K*G4f!v zw~zI$qBYo`ZMaU|*lQ9uDvXA3w#u9W9b|&yD&wItZjz)M?=lYG;j^C41p<`0hx7&< zlX}s7j*jL~Cw;1mU?A;7$3!<1u(J|h+6=L&SpOSsxy%{_bj!87;;ft3TA`vF#BV3LA4<-cQyC>82Tcy1xF4>w6=WNLTX@=OkqF zlyKL2Yki@2ZqhjXpgrZ@Gz%vHlZ1^3m|0D><{8WEyLih>{d?Y9pKiS6@Uvn2u5f(W z<;MJ5H!V$0`AH&j#TUZ=uxR!#Hl27alH9PY%PfUQ_B;Q~_3+@1gl}e-vH$KPY1?l2 zUgaM)eAG2)J+biRLntVX=KaJ^>CUo*9AH~2$yH?^+1jf{5v*fQ=(2((LGaZDj4&3X__P!?49kk2Iu;;q7;>_%bu~*z7+51(Uw0p zKh+UuMgOujw@ocP7HoMicKF4`IsNg%++y>x6b8W7WB%(B*`BU=DwNa3R~O0Ua^t0` z=?7Qkadd3)0|9n)is{`GnIp}hrcP^iQb9d0%g;}2Hdj>3| z6`Hrp$n6WJwfsS0AEnY93Vt=WEj|d2(p6n^GDlP!Ote?D=f^~#KHu56A?35DbOq@LUFFtL=GKD)t! zKzO}(C9{W24J_>9OKQfrynPa-gQ@mC5MSSRAZbU4)}2tQ|}JVkhQqFn|qLukcPR zIzV|T3{7?BEiqUpC^SX4;|R|1;u7?gTA1tzJp}hS;t4SJD5YBs$ZXb)wobh*gp;gP zoD#Cadbd{eV~K>b*f)nPgm(}L4C6d1N+PX-mjcrkOsh(3reHVPFdv891~jZ8>kb^M zS6`Se8eSu}ShQm62f_X|mf(@FmCs;V;T8k#{Z&a_1wC>KdXCjM-b(3V*M$LD(W>oo zw*h0TS6QK^)Vrp*+s;+Fz+6p@tIBp?DvST6>R~lwm4<2%>LX9|+jEdiIyMFl)lVu& z9=-3p31lCuZdXBGvY>DhB{LO{-vG9%{w99#%{T7{(mJLjkt%Fs!K4L1 zU#q@;kNbZ;*M2$Ua_$1pg;Z3R*BAKiwN>fPiobWWD-{)-z@D{KmD#MMqr$Dr6})-% z0#g2~{J%xHyQCu8JT2fT6%lVKVQ$b02V#$D^*h@keIu{|;WLpXBCvZ0!06tEL}# zJV1J@s_9oxT&Ifvyh1$?VKt(Z`X1-ob+O!WY}3Uz3E1bjUg4EBGx&w4>aT`lDm{q8 zc?{LnE4&rIn%ndK|410{e~NcJjWzQ>#CtEyqq_gt)nAaO|KuKa3LCDKkqTE~yEQYV zSKq1(l)1vdU3<4&(ETq|svew=DcglsH9XUOW3^gSHH`EV_T!c=wmRP7Ywna)?c22n zxpCjXT~!zt{*>Eld{uM$W66XbPm7Abrq1V2Wb# zRJCwxW=kNG;F{FeJxaELI>~ZPY79?Bo4)6*ncZQJxo1}{Y5M!jS{k>%_I*%6Ma3>@ znzgyUUfqL!6=WaWVPAEXI{9)*(+9I&uv6FkeFkz38Ue#9Od5*OYUIS@snTVoU#m{K zj5Re?D(cY6SUu=Ae)Tz}R|Yk;U_n(T!L7IA#@|~myXZ1@T<$u2({rW; z$oedG&+mh`eD;Y~_dcB&?sBcpV^9LA6H0^1ocqqJ+FS~^6ReKs|=JqcC?Uw*_budtV?=j^?qYg z*shX^op<@4>2D@lDj(SJLU}mcI*q);-YQhFXHruIg}SI7g64+ZVZwGv#ymkVlbP}f z==Ch$-vfKsE#6gyDO&9l(;`=mCSb&jz2n&Fj@`9J@$V^)hknZM67k) zuD*zLz@CY{h+8SSdj_7sSZmnn5@k=td`wSiDqqSNzHjS6|$=qFN5+@pAgwajx8l&MFLAK<2aL z${)oXgd?y)&s=@z%nHS|#ej?^40HK#Fj9-laZEqD*TwFvc# zW_%WP?l3WON-KkxZ6w9^!kv_GI}ty40zUWFNk{WkD%R^~je(1S)h^PUB^-WFIit?B zQ=Go*nRsgA>t6ZxlHspSE1b=;5$6?#OhM#xc7d9bjW0nS5Q;H@fBDaHub-QcY>;s$h|qI7h9g9q)7vC-dJM}d zBl9S^9c^SdkK7+@eQ(Oal>JUCSSXy)%)Ta?(NT>dJoD9gS0Fq_L-wzoA~VYL?WQ6O$6A> zv*wW>MYG|eN2ALo3ZIOMKF{e}&Fw!M3d)0%fZgLr63=y^+K2S0->Bq+Zlu9n(h@po zSFV#IeO$NOV^hK0+?bU}T9zKm-bo8PY;%AK`ka=W{%3PAGvY(W;AO|I-Zm>c^Djw6 zD#OBvX`Spw(H+Qk&@)Ric0hV_TrZ`y~#}7`4BUo&Pcg|svV|ijp^JV?eRk7Y zt^7sN?w2z;nbOTCN+EQF&t^=X=>SY8+n-$#h$anQ#-v^EBzRgr52G^Ms)tH^nff4- zA_SeKl~{1r5pHS<(M6ON-Hv?K0tN z!IAL3e!XmKLarP~^TGCavxt`HOp-k>*C8aTDgdw1wKOG^i!e+Mp;!?;lnR3U6(wSd z6o%*=CB;ti7acg_Obhu0SFvuAW%BhZ1Hj*e%$d3p85R-hMH@n9k!|ele@o9{l_sPj zS(nb6(5h-#Srn#w)iMOk6=e1dU{frHbcaBuAQro@qtMN`GAuyGD0hMkMNkv01YzXR zfZ-yKpc0}N6X^YtGK5mVjp~$^y@9{kt8+&Nn`DlrP=`s$$VTap2p^i2_1mh7X}~%u z6OZQslgoEt*$nBm>2xAUoMK$X{tpxVRcvVk_8U~$Rsm{vUucRdy9Tl4K2O=2D>yBC zt!gBfdxOu6mjHRrNp1TFPITq_^b1eZ7hcNE;rAGA&T3E?IV*I51aGdaYquz#a$HXC z9|HF1sP%bjl-m^p9{H6s&lbb%7RAig%n6l6`sbKghzw$REMPiX^-N~_Ag5HNLZ8Xz zxZ_73G0LHZ>u&tfz=So!!eu$K;?*J1r;j&GJ$#?5x<)+Vs-EpD4aUgnQ@)I{WnX^X zIz3MG>JF^Eng473KZ=X{lYWw#^khGgvn5iRn`!wVsLbK6d3Pwg?iL{@NIE{3kvu?l zC4Uu(feFWCKUw(RKzVPHqr!xZi4!(y!g%;BIlEe;>vuhy+IjIZQZ(2v$;E@1z%9`} z@aC#~L_!0n=#y3kw==u(0QR_80uBe>qqwpv@pa0&YoSw>hNH5@AuC=gs5w&mu8^Kb z9#oDc$0()Iyd2rD8}QPz_&Gjn180s^~{mm3x8k!SR0QpWICF zevY>DR$P)#(uji~3_Snzlnba6=IVTT#X}$w* z=EM}z5N*`tY?~uFsWw6_fUgLwbC%(q#-s={r3}~A2#=(wldUqtW<>1_sXUzyM^iDk z=yZ$Bv;qrs^E9W3p{Ipe0^AafPb*ZGyE_@%S5P9!MO;mmL{f|OcIbuj{-_>Zq*GW3 z#ftC{WO+ix?B#ZCg#wZDQbE`C!<3KRP#yrv~IO-nJ#at@OE+*-x0;*D|}hu`4IcB|8yi4ac~ zpf9cyT~D{nJn)3)Sl;+X`-XYefo$Hl z{Lpi1JcxrVH$U}q*mBvv)e^;dQ44^kS|U#x zt_jp-&Y(m!>RlCxhpfb0Iykdy>%&Vu{!{*tzG2Vtg`)wx^qTcAJI z6F0YlO61ATgr;Y>^#Myxp*aG*1_-lP z>FJ{Ed}*U<8rR^KcHPP^7iMljGD!YXR-u_~cdpdTmiQw^LHk71V|)-#tZGXficTq8 zAI$GsX>}ZU>dBmL#plxg9JeMV**abMk{L9@OiOs2@d@jIB!9iC-1Q|_KWZ9GI81JBI}CVD2e4H!-Hg29+CX55$BFfHJl#1dcku2_HY$XD7X zCE8iw)^Gjey~nnEWbzwB`)_FbMs(|Y@7#8J^H*Pn~9XstZZ%E9EtNtkO zpSw30f1~n5=83(NyF2GS{?1lwvKk3OnMGToSDD>@Y?hhWnpBL;p4Rt<_C7TCp38~3 znfLQ+#)+diXc<#hr*meL^8JZmGFF@C17{0PcVe8gDW5ow>l}K+J9!m|oR8-L&zCVRu&bq$kb_7p^tQwG9@Ks;!havoh&4iZs{U_NY=F-tL^hNd6gNKU;p)#c@3K6B2@tyFFo zs+zc|M5g$|-FH0TkKC73p9ru|z0l3n3S_fx9JN-kf#u{e9r^y4RYM|YO@M)qotP*b}w^K(aY3@z_xy5adnpy1uP?gUE1GEMBG(eVXO2+& zirIlVMmJld=6hMkVs-JPy`i)xMQS)dPr3a_`yQ)e;S1KymBK(K0Diymi9n{*2EpoPAj2$8-Xcz3@_m6a=+0c(=;HxioTiN1%+`vze>y zWzvEt0|S^vGzC^ngn%_mPu^GcX=1`EfAk6Z)a{00-DK|eZ&U@jqRGYB2^6pRC(`l` z&z?KW8iYde?eM%_(*4Dt_|)2HEZD2|b#dpC#DO`tTj@C&H=pZ^9*vM@@carbMM`#g zHkzBA=zf?V%Ep4ax%Am@@I*9No}XKgrXXhC*9N7yF+|k6Xd@@cygq4pRHol;@NVK$ z(sNv!jrEG2Y0@j*#zO{82@Rl-n#&Z}a-#%2YW~=wP$o>Q2#q|XVn;Vkk8(^@b;g&2 z%J{F$MkDtVE8!lk5q*V(6H3&jYqXWalPF07A3My_;-sVMFy*!l<~bPX{}a=Pw+My` z#xSMeA8Wl4NEO=43FUoeiB3T_@EElkV zOne!>BLW$wk2fP{vC|F1U6e5N>9)>i=o^Bndo!?`nGC!Z8=s;9^Qnotxl%4uV96Nc z6_N$aYEWbdYPxZ21*5bQk?S8$(HpVV#XN>dFk!5Pr%XpCg@zL#BM`;NshL&NjT_v; zSHoTaXon|#ND_)Fi%dhH%S-4O6KTNdD2V|UEnn}!0Is9k*l8jKle>@~OsO(qnJZK5 z#uT%rm|#r6rjb(wt&yq1F#9@s!Ju9@Ok+Ev*gERAok#?=t$`Z9$)xJNNXC(=2?f8= zn2;FTRzKcR;v))u@WDIpK=Snlxx&AC{7v75beWBfN_+uW3FKoX209|o#007$Pr}`{ z;)jH1w@E#zQt}M)a@$5G{IT~2L&~>F#6-rE>Dh9)QjQMLsdSGub-6W}!VPuQRBBw^ zwnFMawbO&-8|00V8c-T3!)xo5zFOv3V!6<_ET8)JNON6cPWt226ZnIWrU2Q2fwT%Z zzJ;BHd@b99V-G9@?C`4xcAt+u3r7MuYDJRug*#&>Y7m#Ktv$e z2UzA8Bdvc>*90xKK_3T_LP9?4{#VEZGG|jN~Aa2W-PhzK|0B_Eo@Y{|J9l_q@bkM{pLew51MtxyMA_jR1?4DD15c zoGVTvuz}S=>pbGxSnl=LH#bY9R-W#QGkZtT-%XpUUk`um-4zc$h+Qk#KZ4yblK)Kr zA45*SS-`uXDIYwx&O1lOOa09f)5X^?I9nZyUJ70YEe7DB65VY`{(|#Ky#_Fn3)lG? z?jIbP^^=kDt0f;^xbPiELsx^0Hv&=ThWU^G_~*I|FDTgHQPOU0m3p8D2Ui>)9F(%X z2M>-wYXR`&fBMAtKK1l-Q?P%gRfZ1^KJ`?iCgkAr>qbK(h{*{BMjNiEw$5h#PxDN3 zaAwp_Lhe^k?HcUm2G)6O({>vhjqE!IT%^WIN5PhfGqj(nsB#7u<_iLR9J)%R`_JU6 z8|;;YIGj;Uj%RRJWIkZ46tVqH`F1>qShkywKL0Zjw&VTiN5GJ4Y^ZyojoltwUdLQ@ zDta}w#xc`fa$W1V;Rzb5^alH={Dw9~fSFBX(` zz8076zDF@xlcs`+7u>W{NEg;>N8P=nc5yUb`AR(0A>!?=*8&M48w{S4bp+E$uQ(ci z-)muk@Y18N)$_5do^R-^o{rc`WK`}ry-Pkk)^Hgg=M|6jllP5sIYQDEsW|H8sMX`s z?wVab$S*Si#7ZNA4Wrlz0psmw(nW8M(oM1;m17n2Vzi|4P}`-XoJ}d(RL*pQIrEZy zUh#kZqFs)*OVU#sVPD5wBps&Wucl!#jc3PmyuC*1)WP$^HC6o0`Ip`##}MlK^-Hge zSH<~eW$@ga4n90sJAbP~yyUo)eu;A)P8HFvG{)0XPPm3PN4VN{4Tkuz!x5%1C&J>I zgU;e+kR;xU1w4H73{yIMNd`J_si`jwb82RAQuBiFaE+Srqf3s#0;G`FIvm4q4xT^% z(@Q{D&pBx7OE)6OF+7#doqhexpPZe#aF8%BWyFcARl;Y5}& zjn3TY7#egqhME`F-aJp2!fC1j%XWzLPhM$x41&EB9y*VlQSB9~T?FxUZ59?TA#Lm+ z6-AQx_>IGi@C~7Wu;ZI#p`piGkmFpk*8Ix(p-VJ$9!Rq&Rcny*rNK8HXI^hcdPkJI zUT>Bwy}!-ab%-`#hwA||q)5OYolPa|Um=w-C5cmd0ea|MQ#ptFCN;!Vw~rAdJ@9F1 zDh%0Z5+DLq8PxPiUgiQPKq3U84}3Qubv?voqml;S8%(i3mjEi zn2c{*NDU9;)Ujlf2%vBp6ZT6`PnxDMgfaV@fshycetsyid(~-rK zDH7HPuwAxDSVQ%3lmbXOM+BiVjUkR-O@^dApQ$F9iAcZ6RB`;7qW_E|(YQwsbAzZ9 z>s50Sq1jBA7vPk@7wEdCGSP4;Myi$4FUQw?6^AuDex5%mE_Rv}iN}nl~7u*;o{@t>aplz@X|HAt?Ib@RE&9Z-E;Q)`a4Zds0+!!#!i(0t&I zRQ|mjUqRMxp-?6l>1-Ja-E(Jojp;x2`hchPXV7hVj(=(B?ZV{G{cLFUD@qCa6;*zI zLzK$zsq^&*L=d_x`yW^0!IxiCE9c%OXyd*6mM^@U=e0%Ut8Xk3rb}g<2V97iK1$)t z+um63+vFN|xoNnhNMA1`iFY$UGrlSB))-73q!sY3UC!}H@MWwx8fYn3sbK9*NxS< zf$dp1j3W%PI%^*8Jcj+(2(#8*Qs1IsDKW~pPaDpXQw0woObRtDc@a1MP|29rT_W=p z$GWOM{Hd5z)jhS>6i@O4F|&l{gc2lim*vXVCiui#d1L3{phpaM4r|qRSF>6vEU%@a z4H0-hq7R4lz!Y6ccqNyyKoyXNXIk`}?L@H0Zo54d&XK50Ka$D(Q4roIGdZp6!$ueJ}B1K@FRK$%*UWT5nM}>M$1`wAkEePh)frT%bo~oyyQJ|?=!Dl zFj!FcRgv>Eol3|lcj7VbO5>^^F|SJ~7sNUAeLYn@W2j!!AK`=N|Ydr=t``^HlZ`Q%-@U#IcBj2Eho6JzGhklrG}~)Fs+a ztxPCU6;lTk&V&!;<;7}j76LKQ?_f>{nS#xmK}Cf$OgpCQj9g9NXJE>}#{{~lR%ipW zF()`EM?i$}PP_(L{m__5$To)KvjS^5LYbPYp9<{A)jMu=1JvhM+s`|Og|ZwgYih0= znH=bIuzCJjq&rDGeWB{GoW-e@U*q?-=;0+42=s{Bb+mlfEA!2TpIO%(I-@D)f80Z#vBb`h^Q+GkT!zIn#w{Sv7YoZ8@3d==_Zc0I1k*cB*E+f?qS74(}+Xf4Bq+PZ*EMQ#Mbw{qpZWY2OKMi`F z&Fi|1>o6FrJuZ)M*PhpM(EX~=M_Q_a%5M*Qa(B5}FNS>TLPuPbrd6Cb4R>Xy>t+jI z_d=Gx9ampjbBv~=AS|~O2-+#hUsdO1OxoU5it6uYf;-gCLMx@%`HMo$=}u+W2K*MzaYoFZdD;atrkPgl zyZ@l5sSVh`HDX} zuQbgIl>=FjS9J;RG;4ZR)t5Q6zS?0)D!WbFV(8MfU6Im=0^P?<)VIq?vZV?6hn{j7 zLk8lq)tV=ijh^nca9l_`!RyrTDt3eujcs-^9ubqT;8Z4PT~>hVbPG-jdSIvwS2BXN z>FMF97A`X-tf^`@zb&F`teX-gKU?Z$-a`de$d;6_(ivV95gj{m2(pQd1Tq$Zc|E*8MHc!4@gqTo$oI~OZR#m$8z4?vYN*klQk*pN#u zk~h*$RNyM&xU~XT+Iwj!6j6sFI^VB=bwaQ#73ud=AsH=bZt&uEfhnUt$(6dz4C)6k zM=GTJr2=>;`jHPiS4@p2;+R4#Ohb1*)SP5kFhnq%B9h9w*6md%qNHki8fgj`w=&JE zuGCz8n&z6Opx_0QI(!g*Q&yr`qXrpP7f7v7*r;k(yK5_)Qs`6DTLx°`9HZk{qQ zfursk8EDC z|M+toTC}ZGP7JgqX6|wAoiu46R-N5{s&mydTO;@1KKF< zXP_o}Z->PvDvy*Oo-x02+Y6n~mG(Q`0C$+B*IBjdcZ#2`5dO5n_~eMNinH6JdOm#${jS1#Bye!#fSi_5|jSryoQ9 zH_?`VM8r=mu6C7;f&U#d)vbx!R^@4az*xL)ZafGOW+oG1fu6Ro@o^+a+85^$NwmR)jI6*rLK3U7gWwLPU_hN5ZekC(BJwdJ(%eYTq zxY1X|FgXKe+qBZa1_~3iEe~u1J#VIlr!;%B74zrt}zENolkjM zd~S=Y>S2zQ1&OfkDH=i{Pdd!x4yX2%Cb^3QVL7;q@b83+Ym#srcXflV0y^0QwC@`J z9KMiZ#TB-FZG@PkE|47m@@e8%!f*qYidnF*;HwEMO(_|uD6G8`oDefbH)Z^quI1B~ zVuACSH-~gYNaxxGfOCQnr9i_xvU0u#wxOK|pe)q)gjs-@y zUpLtUV(!)yABcCBJ6x8tTdewG)QF(CdwIv{OrqqTl31I?bX(mRc;N0+Jqagz|Kf=r z|0?5Kys2mY-hE3tGkg02B6v{mo=p84olSgsz%aM0Gv?CVayY1`2GZ@BpvMZfrCe&* zXm5MAWQe637_ogjlfm9_A5h7(r%e5o6u#DstQnw|-6*1=Z)GZ#ErBIc7f$-s$eh;1 z!8jg!KxFCm&-9ZX}54mTsUNOvKW5&Zjtwjyfh4}-|&VT zbz#Y;?bPalr%)fG2EP0rT}7%8s?`;f;T?A&Ok2uRZ7R-Hpn@Okp(dlVDh?Ewh%<6{ z#+ryB>#uzhfyQhKTFHzk)bzQ~a0t6G+|g(PPsrs9oYpIqG-H^QKWKHtVKlwE&H#Yx z=#zB8rLE&_js)6M03XmX0-a1#^Xn1F`mP5h%m`K~;EQt+xKte=zpfM$Ogn%zG9bU_ zH0z)NxnB!gtZ+~u?FUAoU@G}P7TpMx9mEo4O>smiioG8aJVr2zBHxXFQ?DsFkPp}@X7`LV~t6* z`tyxCsg4N+X7URtZ~h^c_y4_)3;YM9=<0e?fB3_H{%48T0<*YY%E*q8JTX)LE?=HC zG7C6G9e3CUOro^~nC-WLwgQ)xSca68mFN7*G`Ha_T`55)Wo;$y0z9{ly+9+gjr9WO zm9~r{KXpeS*G8=)-tRPh+%4sOCF0UbtL>A1AvNrfD2&8jR*=M5B=+KPv;wD*Qo-^n zks0~-;4Jt;hORCjJYwTIw>m!dG3$Q!$FrN@2Errrw|YGC4tZsuGQZW(C~WfH=id9= zix0o}usl6<)+|YlR;YOf40XffkIRSG-}Tm2>%0DR_WHX{+yYc*^{j)fQaI6;laqGO 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℘+-wL&)z+QmQ++d$AEc0jQ5!iGc=K&BqegtT) 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 P^)lvvv5jBaDBu4NTmJ82 literal 0 HcmV?d00001 diff --git a/util/wan_aftup/A200_0040_V08.BIN b/util/wan_aftup/A200_0040_V08.BIN new file mode 100644 index 0000000000000000000000000000000000000000..c6563abcfc45d348a82104c055ca999f8f8a2a2e GIT binary patch literal 212392 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

    t-z870$LoqPTLz3><4*YxZ4~ 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%0D(dSJwk-*ojJ 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 diff --git a/util/wan_aftup/A108dm_0100_V31.BIN b/util/wan_aftup/A108dm_0100_V31.BIN new file mode 100644 index 0000000000000000000000000000000000000000..de6e4d17576f5c220e729b23f06027007440da48 GIT binary patch literal 402936 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

  • 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 literal 0 HcmV?d00001 diff --git a/util/wan_aftup/A101dm_0040_V34.BIN b/util/wan_aftup/A101dm_0040_V34.BIN deleted file mode 100644 index a21f73b2326a40b0109d0dc9ddb5eac7a2d4a901..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212392 zcmd444|p8Kl`nd#r$_1;x1^Rl_KwZi)W`w^QL-&dz?jIWBoA1y4jBUqPCm09h&O9< zy@^5~cCsX{kp&3iz!YO@Nb*j4lp04hxR;$(F&+Yz@OF|RTw5uB!x4YT~ z{>_(N9n*R=_AQrUpvkGpm0hx#rW&nXvM5PMnDw6koKOc({3p=mKZ^=Op(1Uu{~QVh zB%z3`-KqZ^I{hEfLhDZCTeRylzm;yQ#Jg!xYsf4_^l4$5O(#mP9_tn4ak>%ad}s5a zN*wW-hAM^nc=hzGe5m)S(owomK3wec*r|bvJpY@ptmPBo|4rGRL^kO+%ao2|Mf9oS zR&IxH4|c7~+G%NoBTTI!P2z3Ri1ez-+v7F)i2rstO8%I9+=y%Nj7~LfM4v7`Ch<9l z6V-`V3M(rLpChVaovvO{yeQpc@(GTs6Oxfwm}iZ)PZ=MR%p8P#%k-lN#|(H8vko7x z7bXi6dOZI`bd=OF`2-Qy;AFAXP^jZX^r_>?x>V-$HYl*~+!#AM#QV-(Yv>RY1)w-w z7tf|@rmQ;Lm^Eb zM=zC+srp)yvq)gc$Pmeu$_*68594V}IAJ)ub3!=*HsXhJUc6x9dsa;^yB2QM^lAvh z%Qd-K{c8HonMc6fbgl8h8_}nWk;I9?A*nbN`31*eCQ-3bxFP3q0%pz;|77_bok6iP z$8^JNhBr4MZTLjT;#s+4`H|dgcrE$~kdd?56@t)0#7sUWf|x_0V^Rw9(Z^>O(Z}G3 zKmz)hMCK}Xoq#${39AzaH(ntXtxd}bx)_Q@JM$~VGA=0o2|?}#6j&xEtgNkXMw4(SFpTGg-w_Hacw zfS+L+vh@(u6K~;Hh{x$MW>CoxM{dNA=wmSAMB$91bRzv&R@Nd^YUwlP@Z&+&!jI=O z&4YIYI`RP9xR{O6kI-W*suIH%U zqr?u?_z_KW#G475!}F&2HJQR3vJs2*h#;tWBE2SRH1i`l#!+}Jcm`Ewe8+n9vE)oz zQ9m5vaFo?xc#Fr;1*QS(LUeL2(u?Gy^iM8gZ3TmID~eyKMU3c3&q%L`Hsv|~o*h5_ z)o4az#8ZH*o}vQFdQr6?3`x$kK@bK|OAsm7s0s3uEQd(aAUGi%Q6a9}%yRB&C?#UIj0gZ5q8iHmYS%uu@E5&K00 z>9lVq2*=;qU{ZAaA~ib=lyof`XU=HS&EVcRNjDsq5hogfIflnNO3 zVA~7Hcc|HRS-@}JIbB32b(_hB6fDTdKJ68nJ(={^gVE4gu-#%~pVRF0fxN)69oDOl z+yaZDvfy&e=$3fKf2s}|ZUn3rMf53R6E{kz4ns!+x`yp`_Q=6OM#@wY`)VK=Yj&b| z?5_cO25X0cGr-57YuKsbkUQ(DS?^o;j+3foF%u!8PZ6I$CE|iGNaJFV*vTGkcQTR) zjq+g{149Iyo(hTRUe_d}6eGzH&&`eUJy!Nqs1x1mQ%U30WIghZsgpTl%Q?Ak#Z)J% zp%X;X%%8m<^hVXDb6RY=aQP*94Ci!4%Xg27+0)a~Ql;VH5bxg2fq3X-pr@tZuU0qT z-`{V=dWO$AhnZX355^WOsDfXu_6+y?jV&$x>_2++$dOm7kM1rMh6DQQucyBDwZD4f zt`=(9P03_FfA`&_s?{Y+`dyYi_})wMmxy6+>-K8@wd<=Jc0XNh=^0M;4EH2^&Nw69 zGkv(ZSMYu&C*^jlwao0WmnoaBndp`Zx%X>ckl(~98 zUFHyNyQDjs(K46T;_kHAKf_}`WK4MEM;=4;U^~%+7USqDvmC-aqr*AEHYyynlsLu5;-v=po(rN7+W2;Q5Nhu$HOH|e>k&Q zv_$+Uk?QtpOSOl&)$I|F@xu?FfBuH#!B`~E_>41JLP_{H-`{iKi8#WK9Q}6=3t{v9 z2QS&Mp}*Q%J+Sj=cQtVBYE{$G>hRSY<{vp+J-EGk!aOo{G|J5RjOX|bnDi3=GW_XDt@lAhgEvIB$3nKW2qfe3(gtt1&suf(&l z&<-&Mpg!O_9(6E<;YAuuVLVL(q`~N{(KM6qB=dzfp`3mg>*QU;4mV8gVM%c3p$z`L z!5HIE5AX~D6vC=kS}{MMSZcoj4S1OL z!L`~SrspZPZ}oX!T!o};a;CwJ=~8J~Bl|3xmI2ZAoMoP3)4@CT(SGCt^d5H49u28SJqOKTRiH9MY?nmx)w zbeoG7rsCPs&>Td8CS`keU~3h#$TvVLft(vQu5os; za8N)FI}Apt(0humq-5ooD9#rp(QOYcC#wkl;cn9ibf}#X)NrHSBBtLN(C{@J9)Sx@ z#fX;h=_6t5)nbIyT0}d%5ZrC1f-KahevTUM!{@QQqPEq=kvCAbP6c&k>Jcf z+yuz=12zWtX>M*ed85*yMs*X7#?c8n{f4uoMUJE_B`qpVQZwwDFdPi|tio+#MExG) z@7`$5EABx4#R~73g2xu$Gj9i}5{Bh@sFQNM2&tJ{$NrOr0&8o4*GVA+y$;{oQJRmm z592z%4NjBbHsDLN2dKk<%EMTPauO-iowTKh?^p#Kq1v&LQ4WH}K{`mUtP!I#MUwOm zYK0c)s|$8GHler3`;aGTM8UeIVJf)^$tzyr-1i|&1{u3yP}wSNjSq5mw^3FN#xc|j z)FRezmB1gek!+#18HUK|0qYRVM0FZFE!y$W4b;>K-a~(_7}WtwQ^QQ2eiUR88jl_1 z(BWCc;kxwoTKI}Y(_9q@7l-<~xN;OEcI=yvE_j_cbs@pXuz6K1Mox^n2V>8n5&nq0 ziG2d?!f96j3&MvS@9zJG`ppjYam6-J@m-cA`g)1E7TFF-i?m$JSMxK0z4 zK%F)fj)~p=9vmwxq&ym&2i;J1+)@hoL1YaO39+=H8fzGYiz!UUX#wtO4F6sj!Z%a< zXyd$vV3r4UJLz^PzO0CpRk7jVS|PstBh|eBc6x{g_nLOL^arB3v5Xk|m7~t3&PMW@ z@BSz?|9e(hUq+fKD~Gh!q9JXJ9oj5N|Lt<7H@;o$Vp$COk;t?K!s2gD^DP&TTqEag}JZ{oLVvr+PpvnVx zAUb&^@)wb*U!;tNE~sF%zI^#wX%g0El1Dssaqif z^j1l`M3&l7ZK6c&+HTJ)t2I%U()MM3RJ2Qy$`W2S3u7rsvIpP@wn?&UK%(^;s9{+n zk3(T7j9cjEg$EPV#G9x!wC%nL8v`6Y= zJ({5m;(vjfn#)dt63$2^8|)k&aIY6~ zQ36ZD50wi|x@m-5_m)3yZu%6t-F=CxJsd3cNl)&?1ma%Y>iUkSFM`R^;trO!b+e1& zH(6e@_T1dgX6JdzX>SY0LyyK5?ra`fH|~<(=VFRNEskR+J=&M-UJTpjNUu*4CQEW) z^X$7i%{D|3K4mBgy%&34b7o!Yh2D`u!}^Zx8ShXg=eg^*o#%V5=l6BFeLl5b>^cp7 z89I~`K7BujGVzV{3G;>lBs0@yn87qU$FWdHt0)A?07?;gJoaW7$Ozd*B=cv(W^U@=$oGe+eZ;Be5IiTd!lXy!3Q zav@cV91#Xbov#-Z3eAAdp^OI(j~x*}kw`jXnIa<-V9h)q9?70smDH6_gR9x$d~`X) za5Z`fP?4R`1W;k$ESNlwvm$WSF=*q~-7COZ>AT>hxGs%DQBKXn4)likr%=?IG9N%3`ZP{_L%CJFY(vO z9Dp<~3$c%}i63F)X=q?9Q4Aat9?8{V7Lv!&Xr8msb5*QW&@X@Waut7;N3T`GKb|-+ z(a_PFg>l2nvBno)>{-q>ik;NIpt`%|;DzxG8xH?s_t$^^`~Uc-+vSG&9QM`uA-=mY z#LV07Y?#m1$(LG}EU9jwm;3v{eC_3zU;pkf4ZoPQUV3Tx#bI%{P&gECI(qYOe%K02 z%CD{sl*m#^X;^t53AkRn=DNr)vLuuh4SChV4~~pMU-nan8fQfmp11;3Wf5 z343U`+Cv9nqj)>ObC3vT?1tPm=e~3b{F+?kFEbDFSLiK!aZRva_wuwYbIC+up^Xv)Gut#_|E$j^lz}P+qB2GF39w?hQ-d-$%s1Kh zute*y$k-oi$<_OZ5F@e^>RNn_MJ%UPhRxC7T7&24kv+1O)SKvt&vCgE8J!{~QAdbJs5j;H)HNEjJY3OHN3WPW^6rfB5|V1xuE^)XH(6h_7DFxOMoY?=n8~ z%>MrVcR&5~v;9ATrLS_!he3WfT^K)) zR@3(FEj@nw)~y>hcvRg!oJYPi3>`M#|Mb(b7;K)y)x(@a2(zU;b)S+aj)V0wX|t2C zV@f{$0*_9Cqz~anVKW*8BgPi^W6~JeAZPDL*p?=@9o1{%VKanyiVzedIv|8(TH^^i z+X{D{13rd%hmeoZHLJFg#1W8!xp=)%eds&1h5OahFu1y%&7#9w>HZm+8Ho%n%0_l`-4fQ zMJGfUH0B$o6;E{xSOjPwRI~)DgNQ#VwUO5nftVX>`oOdVzNu26(*~;@H62GXUO*Hl z+)awBTC(5+0-hlit&+ED=qSEP*viH1a-bSP&!@?68a)E6x*%tN6N14q;*~$`llkCb zLJAt`?$csb2{>34n*#a{5Ij8X$0zz=mefh|2?>VcQiBJT;KqcC#q6g9-s?EVn-(pFq2FNq$RsjMTBHT9rAh5VWQt%*kW%8FqZDt9tB)mj|JCZTxZ?FbYWU2#xb3gl@B610 zuv_XKv2I=KQp0|phnjdaW5fd-VCuA9z}TPf1bQg@lg zAW=m~R~#N6M-^x-Setq{o~{owehKX&aP-HBHu}Y;`wml3=+(|WKQh&O_ai$j`h!4? zvLMUP8x=GyZ)xVY2^(q1CD@?cX-~z9-9(Sxz|&wVz`fa#pp>f6ntNl~{RfGN5U-oa3GYJuPx}|CAhcnL||Hlv?zv4*A2j_t6rUA7bAovk$?KW@W3^kWV{@(`|&G$cEo(H;^f4;iP(DlKTXZ?|Zl z+SF!`qJW)4nb8u_rPR$T(f`8bXq4@rMq!}Dy`Vl3|64)h4{aptzrna6yf%cU+zRP0 z&LjUmK|9BBd-o%r)^HA`sgm_m!33%M7JxTN3&(|}_CM0sV13Y(88sj_9a7HHQB9&8 z_x0U~f9dx{vxB~L=mk-6ehiBxYSux;2l=9anxJpc4!W-3QRbiVCNFCcQkiQCz z0|+}QaPQP8?_*B${zh^{X2pwO8BG7IjcC7-gd`q;yDu~WOMPZ9*(V;Thxll-oR-v!zd6u=~I*b|9 zZ5bsH|7&P)W!&#!D~7Uqw~1a4eL^<|IkDqGVCFLY@m7 zJlS%PivkeVpq;esLc367Zi)0gWvR32q_ol96+|qX3R!CH1uk7lC0H=qDCJ0rT2yT$ zc46j{AIRgtR-$tqwwIo*bjeD!XEVxD+HRv{t|NQp&iuJfR(8lSEyd2x((=3|?vUt` zu9Om^h^4PA4@nxc#-z1a5t{0`=aq4sjPTO1ZiKoshKhu=U!6*)kV}Y)ncnY3EqViu+KV_FH zlJDp(#iw93yNp!E{bUmrDvwP}xQPc~rk8FXI!FP=yNP1wVv^4^lyNW+w#Q55-m;?3 zBAh)gi4mTz72^quY>wd;ufq>)_kS{vAekcxg?M}$A6`FsM_AY2xxpb$O!M5}AH5X(W8ZQ>G z7;bZ0X&t6m=;^zu8(MAef~6~y>-~+%3!KH|f960FiFe-h{uOKfq>%0!eKcA4f{SNh zem@4oi*89e=eHJJugh8c^h)P0vc;{!Zk$RyP-u9fJhLf(YAMFA9ggz+3(W6ZK^mkAE19)BjYsWJ4uoWV(Ay>a*!o5p3X)2JVL@jPn6EH3k7HqxQ3e7i{7GdzaJq0s01d+! zy52YdVh)H}$s9p5EOc@9OOoS;H)>pETz0g{F3i%*bvB3LGD`7qra{j_nF|MASxdu& ztJoufI2B;Ybi1i+a9Bx+KgJrD!c|k8NmNJy2r?Ruiadmv^rTs;i!E?f3iL zCn_v+6js7&mCsJ{$;sj2@C@bQ!$)6ijU7A~1l4C7sb~In*h_}7Tx)LTG+ft>zX%%& z`>SsptZo=?#ktE^tmWWO-l%Seov{jQi;ts_fFrThtC8DV-v76%hnZFiq3FC}$m7;q zyNEGtHb3C6|k+qd_`&N*j8ftz$c0M__@+&`Gc`NfGB z7tGr1_w9@LTepVc)$OYRzTXdneg*xi`r3j0I7?|STXqy(({+zjX?c6k_SzxKBlIF2 zq~Ux#UVSzm?|*jqD9%OBz=rB?e#3nzJntCc+0vc7uddcjBqisL3%;%o2_*d;XrW1; zV>@j7J8%#O(QtEY8tEVrNXH2#YEv)t)GxjvFKL{QH%erepm zxNx+DgOecvmsmKlNy%6{JbUo`f%;&+r@8sU2D#73DLc;?&uwe*8g#n}zf)svh26rP zB!SUAYU$epMqZv#}H0#h*9;7kju`+EVOiv%c~Ux_^z zo4;R(##e*=jR^O?V^%%%ubkEI3eb@GP$Acb#*L6>5SItIU3r- z&?sq~*BY3$Z9)wEgXB^$C~V#xW~s8#5?gs@qbVqMrNTQH5FwdT*n*OfwgekAE{zMu zO3gM)fMkvZVNW}tJfVfCkPV|O2}#nnfgu1PIFJSYoxojdMu_e@XGH#26v{sQoV)6y zNc>mjAudsH?^1+$fr#;ur7d3LFw!tNj}%eMH$0&M?36to!FgW zP$v2WPGS@(sxw~k-xUiJa1N7FkobJ;N7k)i-TIDgGA6fC1Kr7m1eDikL8Zm8Va5yC z%Kd5tGv<)~v$#!Xac~w&;Rf6mCP&JGa=$$+-SID^zUhq6XG)}Y2zu!DaZ5GGZP^`@ zu<1Oa8rpCVY$~b+0o42vJ%l^PEky#Q_Cc4kQ2vFo$ZUW^pJ}30`7DdgU`(S8l71e( z**Y-+rp#h`q?7wy;SnXKN`i#neZ|L?3)MhKzi3+Exp{=|S0we1u$ZjiKuUn~AYur1 zESJnjEO76xfDD5M@AN@MQPXsVPC+_WfhpRjF|l~6zXN&O&&P#pt-_5rR$ zy7166u5<-?0-ru`ng({>eI0Cg!BE3@G0q0-`#k3ri=KaBljR&1>QWcBzJTa?QcKYU zXiN;n?0qnzSA0HUk$RqOuYBxZY3$7za_%Zrkv>aMW07!6bF^5}K!6aG#8g`a9ZU-p zmgz|hR-51%pq)-&Ir-;&r?T1V(hvCv*C~7*C2hf1j*C%@ZZs~2TvQR^{3FykmlTNy zp@*?GVz7fjun*L44PCcyhOz27b@uJ3n?QKYe|#ef8&6rEEx-o+kQcMp;pYB%o^Hjg zn@*G)ek@>6cD_c?O*cYKg)XdP%b`dL<4KC{#9e%TK!6@ekzHx+wasld4iY#WsAw8<^p#q54Gk)LymO5lSU*UK0nhFBtx*hCLsv_C z)EZSP(RO*e@bjAP5WDi(HOiI+QbVNQ-q`by?RegzJ^Nvo4&mb@-s_6j?d>S$A! zCq%dHSz@qPl=Dt&@1VE?s@{_urFE&bLS3c@R7tGy2FNb0!AH_yI&8;@W0lt(otNn( z=}|{X8p~=u&?d7To{fGxSh^$U;{ZoWb?0&7&Bb%CJ9H_JE{tJo439`9>dOV@+PC@O z9M|i~!hKC-^UJ%~d(sv-dscX9cysPznHX&N+(;+wb*%Lt!n7ity*N+!Ioq9Bp%Q!P zscVo0m4*G_gGKpyN&8Okdo3biy8S8seFBlZ_67T((?U zs4S3eD-um{tEp+IaHE^{A8Gm|eSN{#n)Z6zn%otcc=A0~o7?*}a(maiBhAf;ThM#C zPC^6&q4C!`H~b-On8%L%-G!CZnz_i!eZIB3$xn8^`$6{$rFAO@oIZcOPfOS7Mg8%< zM6cESOE;BW?{_W!)6Dven{h8*C;d;~@6%WNWM*;SVz1wKD}7X4)V=0xx_EElLuqfJ z@2qcn|K~RP59}Q8bLQ>bl*#P$)3h$VB+-R_wbIX&XuadUE4?&B57?=-IqfdOK;1{a z-FF?vgGCEFzy83*Ynm5#ec1O~GJSIQgX{h*lP34jMIPnS#`NjPG>o@${nG5t$GyHj z((WC8aTlg@uYvD#SYDflKn&`q3LMK(=q)_X)wQ!Bfq|35(3?lm3gPE{x|W6uJ_sdY zi6#x7G%G$1k37%?;}0e-rGPFSXiGb22(XJ{0n2(e701BGanFqp=n8xi{}?gL@MuVQ zXu^WW22(sq0=4N`cBo-D^KBtCV+)Re?KP~5T5W&_P{y5g^sLwTO2^R=DI}7VJ2`uR zLQ#nSNw$bNo8hs;wrHx>>-l9 z$HXu+F91#sDs^IP8-d;7%<=IBt+40KYh56)v=X%Y+Xo)kFCX4};K%3v>+V-z`}l{g zjX2r$T4Wn}alzKcBRwt6)g{}nefiAo?`=7!e?iX~{R>)FZ@}hic@AAHe3Tkrg=w| zi^MVOigt?Lx^s`F%W^*quQIyPTf(*j74u5 zUq8~;`SK$-K4q@4;zSuO-Pi`%2H0CW^H}o_q4DyWL=iW01 z=o;T(&I9oo_&x3D+@xXD@-hC?b%NQ5^Ki;{YtQy~zfnDhs^48raXJ& z@5W$u%`pF+*>cTrRlI=@4pg7m+K%^|^Nr@cY(9fH+!EUG=^DD`iTF9^IP)r!+i_3J z!I-yv>p7L9Klp)M)(^XV2-fm(=Sb|Tt0Fr)b7wW0_0_};TD>}ar~2-@tM9G$#Kr5c zSGQJQd+jy0d0utZ>eU?Ui6^SNXJh|veG0p_+B?=?{7NU=80~vQn_q`0z~-niu!gop zlBE?KKK3v+Yq*K{7P!Hz58DWLnxPZvsRGYAQWwM`+X|$!u})(%Au+9MOzoL*8n(pX z;Fv)Ausw4AO75Jb1;qR{d7txr^lI!UKx>m8;`-1zvgTsU3h~BR7{2kIRugTELTp~f0tc#gnt*Y|>5wYzVp??EW4O$b8ZK;>aJfRY z1fIm!t6ekgO!~kNDSN=kb$T;=qnEN#ACL>%&R+abPo^&G_Z_dCbpLa z0d6iS2xE&6$kY7QC?TJ$r2RpxopBAYkDOw!87cz4({ONMpBPYVK3=b$f^Q#^n#vOr zE7AOXV}Q(7(;2T$&j(+zcz6N*F2F$|IFcBvs8N(GAWPy-!j8o&P`98w=}0@PTVoEX zickorq~<6xWeYt3pJfM*4eZD<$}$PRwv;4WKw-%wgG8O+-_{Ce7d3N^fv}-qeS%Jh z%XrxIBAKIf68VM@V-}9HSe7!u7D-e#!b}tq3Z1%Jtc%j1K{Ql`M)OGX?w?=hG#(MLmA>7}Zfx$5c!za&{(dEVRZ5b?yPkA~H9>!HCHTMCNIQx?spsC) zJP5V!h>y@Wfc0yEqvGCOq~b6gc&Sb(9tgb#TYYEsxi`}0i%dy**T8l;RV#RbX@E3t zt+a7)YZaVoKFm#zsCdzhM&z#7YLax?b%KhW0e@LwhQ_RSAL-jBdyDosspqrZ#aqj` ztzX*o&fpuQCSyl`zcGlZ#@&}&qjBvn6x3#EjYM#sKw2s|TvU6;uS9u$FE!2SBvoY+ zTbl_lOM!-6j+RnjAzPc|JnW&6r)u`t*`?Np zNGo&-dmgFF(5)9i$98Oh+H$D7RX%l=9h^R~McYd#a?zo#Z_T5!B^|nsOVh!oN?=yp zMn9uTo~Cf?8Mylz$FI9tV6kun6^?DBY#Ew*nI0rxfva&Dh-xvSPY+vT7#4Z+H>EAz z7~J%(@&5v?&)Tx)YUGL69J?B0If`APMyLJ=Vpk{loFT1x)WU{z5c7kgTX9~Nl%joc zpXis4JGBEkKIG6hz}6zyOdqrc#G^ODT&Q6@OVc#k5>;quY(`%_;|ped^`1R0Q|W1Z zufWPRR1&lhZ-=Hw!7EJ;>G3#}IK&cwz_`Dyvw9l$Mjl$;MMXgiUm2puJL&PoldbZ{ zm{pg)@|>Fo#_?$D_Ky;Md7np@AjjmN(_Pj`j(!oJ7`2L+Z@={+x;?Jhc1eSfd#GU{ ztkoK=sy88vbXjcxwefQS_jq8U^0DQhwSKG zA%&vLcIu(LHJGHXu`BH>6AuWly+qEqJ3iV)wr9hVcxS$&&9eOg&l+&7E45vE!1mUx zD`|bF=ccaKsS@q7JF{KwbdTMxXl*jveuucn8)y?2EfOwzS~u!WcmuHD@X~!3#wTGX zGlMWB=Bd{%$t#nVEjl{vl1fN4E!nF&({!2LAsnm2#peoWtQ#E}%ZBi^M#qJP&9QBb zFZ%&eSjQ(>L)zuzjtP3_ayMbyPGPBYLuOG^ljm%5yKL)<6}bm!-O|15n>wlR0M0gl z;a%@vT;E$0K9Zbpn=Yp!K8bkkmdbEbV#4Vv zyY3dpNo>RMM;zreJud#=PqIQF);WNqbe?zdy5u@2=x+O=Uw9cq-Pg~hkFQwbx#_Of zrr6}rGTooajb|S0TDS7ksdejjk~5?iyH2io zY18^fLmc8AS$rSpUx?m&zq3f(nyDOLCq~^-Qex?NWJ#D<7)29U4u@~zi6xr(7yJSjkJv9D_Y@$pU6R!kRR4=7|@|sk?Wf zWQJ%|DCEQ0JYcj4FpdIzW4N>=R}=^Gm)tuUBf0C)tfle7DIqh|-J3wYiF0BGpLwjl zaq}hDt|iejuVr3qtJhk6JzZ%iJrB?J(xca4YH@_@L_(3bMyVfyN7Ws@r*Mz6!Hc8>ca;P;LXw+Y{z%(e)1DT468W0 z|14CiL)p!n`OH^z?hEg&#%ABG-mQ-u;fRiVfHvR1c{BStc7$hBIu&1ik7ECuuVdbg z=5XzH*50q?cdVo9$ui!v9@1MLd#~Q|RNXZZokyIp5h4w9p0Q>-jPhh#qmemA{aJmC zEwW~NG=A73`OG8x>(dCMbG*|8b$W4)y^n2+61G2l=aK0lT||8pQ6J`-V2y^je?W$z z-rg9|Cg3f?%iNs-x&aR4>eHCDKVoo!Tz!~{bh=J38?pM+?N0Uo{!O*|x?|1@$MMC2 ztA<6(cAOK&`A7HJ>a$hLiZ?#-`+~Nfv-O;p=WktI?fI_gcVD}3>*|;1^Vd_uQ@}8w z_w3%?a}{j&qA}JoyaDfO&$j*D=WSQAd)(pn?MzwAt4FFYZoYqCAJYtxM(qD89X-mJ zp~s{X`VW}i5&DmJqxi>Te6Qem)||8%q~;7cmZ{{-MuN9%JbKZ`j7^cZZ){t{_}77< zQj$J4CR4V>=Mq~b+X$y16+$VrJ??=e1tX!2uLQxCSwBjfbQOfh5bn}pK3_?XWBNsU z6*oW}*gmK5bj*$^dNkBSn{k+xXh+1;g7V443P*Jvi7L(!z&1#R@LlT;v~5G0Bty-Z z#uYqm!V^CzH#UXU8L#xOJHMClJGLeJ4O$>9$v+9i34mgYN>0+znD z%nua30GSGu09Ctd>^XJNby4sgFg88nX5;u;SVHe%ON>^mec!OHX_gFZcE3YYQrwHP zHNoV7y{|;~-Wvqgd{H69ZO61kt5}LfQ8fYkmCd$7MELgPD?Ed0#lifRbZkE&#n8SU zj#-WOF58EeFaxpq|HgjU90N{=Up}PR)Z}WM7=qmr?^nM%H5L0F(h2T;9$L+x-2dvT zSOB4Y9BnQL=3>4jPZM4y##?_-SdccNmWCNo$81OQT0knZBH$naN9b&p#$wXe63=#V z|1Aq4fEZ*$NDH<^(k-_br&s!AD7de&5a3d(IG)J-gNY-gU_7 z=P8G7!AoBMjya@=<S`ir5C*61gzol3lT> z5$BB{+pt3j>iBsp1T{{j3FoR2r1PtPCXxjiS`x!FG*`S7utg%H1|Kt|uV57j^2TcC)3#-AH_;_dPK@m3Z7Tw z;7wy{kVUBzq)AefL@uzkH^Y?9swq~J?^n3$a$=ApJpTF7m(VvZbv@PS?O}lmzI3W? z&!VFF@TR1P^?%?VKXg54ZX__))j$APsi-*(`S>?(xKGnD40&mE-rFw(%Gl5ExUu-f=(Ni(Mj$2 z>Y3tGynMG3*xEQUObR6-OOfTYqfR>E(O9L2-2+vo0xL!|tx!T6o0>6lB+LP$rdQTX ziHL6?>PHf?lw}qtjlChefFje(LQ1BUD64D&2nxOlOx!nd=VX|w=a92wub>?Sxho&Z zTI%oC?m2t(I~W?Khnk%ZzAv9_XhB&PR#eyRz_%rqXEfSy%(;oagrX?Akza$vnG~di z+;K2Z=vVO^0NOo@GQ{xB0xC}6+@ka0FAJ;p(yQ+yne_NZ)9qZw7q}Tb1K$L*LMWnt zRj}C$RK!W}k`>820mlhgcf>RGvJDl3gQ;%~>aBy{6zZ-jqHK=mS`tRRzw?zY;#{;` z;C^!vJ~LpY8uT>kV(ldjU&gvoINDXHo97==pJn}$9X9Pi>yeh`XBQe%RLdiTy1`rN zTulSh(`1dH(+SUgE{kse9Pfeg`oSSe+==jl(@Ugz%qWA302KehqY7}wN^z^vFCP850!zv9sY;~3hM7TLU&(8^xhiElvbL3eNz z_Q2BUVC!XV=Y9Tjv?kT+K46tnsx0zj1F3s--cM>T-R_L8z~R|}fwC&4?r4|UL9$23 zh6eSTU8>}rr`X_vUy`w6H=qE3JdDBd%HS3I#+g=U^4yO)dLxw5|(g9dp8Df zuS1ODK9Y?GV(7x$io-UWG3nVwY362YO-+i75*cC zbjykx?8O(wS3KC%v<(Z?%*F1xH$Bz$i4~5!_~!R_rPn!5XR&W&Tlwz+f3m7;PvYt^O`cQ=agY-DI~pjeQv@}j66mQnmnA+^%qH} zHH{Tq-JOL-5tOJQDw<#h!&yYlFHpO9mlMBhh8pe@k%haws$MppdGWe8$r)ejo z8MJYacev8t3c_&BSwS0x+-uUnl1nI9kpXEI1EkKjHIMa*AnO-L4Z_&C#>RtVJnXxX zEZiA2;3FQ-3vGTU28D~u4W7P|=qt9R5YuF7LH#Gkt@r@+90(x2vs5fRvmt;BG2}W*I(zeRCu!* zXCE04_dMNtcVqv8;U!xe$Ah54yaVormSB85V84NvmzXnP?0@;?XP-4Z9Lgf(Sbh0v zL&oNDAic=McD!d=-Ehgl>h}KrU;i4^8`T!;*0`~(96Z=lSF%&}&T;P1$2mfD$>^GS zry0CA*&%V((42XM4baHXoIS)8%XUJ21D|;`eu-(ncFouW zxs!nx*#je6WkhrQ8QCa5W&$F9NP#{ZXDVxXn)vXCI+zX)u?R;oeoGw8#((X#m#fuA zt-F0#=mozQ{UJaf;D+H3UC?9Bz{1n_S#F}=31oe_SY zDeOn=XS*TH`6dmf^?tpd@zXf6Xy8coD8+{_fe{}6us`ynfM26;^urd)Fdx^;_^XEv z^PaA5SbLC7a3dN!X4@W#%rb1u04ZbZBjJe9rUMEoS*10U-M$Q)-eBZlHdo}DiKeGcvqX#6Uv^Hj8m;) zewf5fJ_-v~h;bE0*pR=ag9CQ~RU{uR{AO%5&zl;n425H9uxn@vq&tqBiJYAH(F}yUjvwAVyHi{Op~>& zG`U)6g84~VXeKeb6v2r1I{|46UQ4Ml7#|hk7Gw2Ou_VbcEP`OG<s)vjEui!>h) zi%Dc2TVqyW!oJh&)(N^_|AHXhUQ)4jY#-Uw{Fl2(4|pX9wa3-djG7x=O#j?W+j#Ha z8(PPt?^uN)*doShztDRrGpgl2Dl8^G7e#a! zpZwY;*~jJ@)j-WxegaSVrE1=ft)BSV&zVF|BeW{p5T~d)8yd7at zjEX*_06^z)yeAzhT3DtkqL}Xmc{E3H5z;NPZK(^oCt^6&QJk{y8#f;MfG;bX(L5BX z-jk3n#&AsWMgDPiUgPrg`#=nzS4^%d7PcVIIg#ZwOn zdTd;xdtzIE2?Y&}*hM3$8L;5fGt}vL+;QZ{WpOY(zHb8WT7O3~;+`#e430igo zGRZph*(|b}-1KKHBc%2<|!^qz6skk`*4sds0^~{w-4=)A657PI`@U6 z(Bt7v^uQkz{SPp{T(W3DZQ>XJB*~zRd%BKwZ!3yCh32}Jv|c+wU%n2*V>0FZ6ZpyH z3usjVNoO(4{s`lVSkT-!;^U{3Qnw94jp>BbfT4y|!fVCKgn!6avT3my$7>X8R9Qrg z#StpONCsNyKPUR`btvWX<$T5w20fy0V>tbD0okId$Swto*kAKHpW&TLbNv%lxi8OG(>VdwG7aV7J49afe>3g_Xh=2ePB`Tx)RL z#st#p4~&TnPR;t>cnSBPO1b+6#!C6#QClZE7MHJ-SonE)AND8@lTpVSuXVJe)hf3y z@35#>45U}sGP~AtY%AZL-6gb@Rn|Z%rN=yHw7t}wEr@|OD{H-fU|`g{I$xqet6k=0 ztGhNeHY!@jlx3F^o`YtkP@g#LCU`dGiVT5k{cS)a+`O1<<7`->sV$NG8>ib@geL7d zPhDH^CNiG4XXW61d(Tb(*&p^%Vg27Y@_|n^HScb7bKbVy7Cj?8&t2&_T@EcyPf%qd z>3wd5ob`z|Kes;FRQ&pqLT;t^h4N!L+iQ6A+D_lw^FG*A{wgOYHm;a>G)0*uOa81m zom}xZ@)MM3D10F8S1yk)DY~C{rr;-6oHeKm*Q)cIygiTQ9^W=G;;&g*rX>`w^q&2| z<4cw&;-B-KPY>Snscf#fuXXbTjf@oVkrZ#_;|2ew(TY8>Z7(I7@%|;CS+i>fqtJ6A zw-X&+_;j)Fr;}cea+wQo@T_~?Q*nPu@}~8fL^|<84rdTQwP<1w{VqR!QB%Q5HvMwZiYGJfqm{h7{)+X@8Rz}(r}W;okIF7u_sJlAapoDnFV(u_ z@YgnFHqBqsa>bSdIMeqHH}{91UisC`-a)4`m016-zD|G5$1~eHlYKb+nS*IpI9+|2 zANWIk{-!;y(<499url43TXON1%o;cCIuEW)BzyaE$!D4}i*pydJ9ABAxphwG#qKz6 zPXm4$dtMP=_k@MnOawFKx6$L?25MtbI2LL-i1AHf-NCU`Nn7JM%0MY-*?MUee@d^FH=w(Nk}mK zvSLmN=|Tz4OEOaUK{G?!yAYywDi~!YTHc`bWD4fl3G`|b%k%y?-KZ=Y^=bK6@{sF= zDteFxFRMW#_O*}bf=^=1YXcBRRr?PmkBCIFJIkR?Ju943kJjsS;7L;F37PSox zkkuhjAvj}cE88C->mKwCA9;zqgiDyh;UZ5~*0^;JLQrjQ3(goyPUe|CFmAgHgmkd! z!RJSrmRvIiq**A04qS;pjk+@;5RfdSFwK|+1?-a8DKJPOPUPvRymsgNzWPQw8QF=T(YEvKCqNcdr$nu>#zT2>(fuaj#oA1cK%Hn z{yiBSXY6Se^ND{)hRqvW^H&wAk@^5OqJ=C`y_MhZcXP*quDu(ei?1Ry_8sDp3 z*yo~a%af69Fv^2%gmvd5qqCAv&e{&qaq%8Er^!6Fdm5Vk%m+4U)!7`GXD*zHH2HB@ zWScaV!Fs+8s9HyO3$fZc#wT@6RAcwS!1h3FZ|8)1`(YF>5*&h-QFy(d!y|qq%XIXc zHTC`sH{N{skT#`Pq+u{P^R{bDB0>_3dxx&0%32Zahi{$n=}5NyO;t zCfMJ9@evdE!tLOP>1^-mzYs$(exaVfu*&BvA@*zh?sg5rk`QgZ5R5mr(gi)?JJ=Eb zWN>NX|8#EwQH9Ih4-6YZD)GyGl696d}eJ{Lpm?kn*4Ac zlH&<%c@SR23sRFtPT3^EuUE*BCw6ocgciVHHpT&FG|Z2fLj$bOc&3crhM;{oNCzsQ zSODY&F&x{$+CjfUufW5w57+n9bMXM$X$abeYlELx54T(LQrxsD@WlLSx-{5<`5qfIB z*xwHAS&$Q=>3!dBC$(P>wm(loA0?EW*G>Gmr(o%1(Cc0*S5286>Dn?DnAx8-wz(o=ejgzIN41*2-6dmi{ zWq7UcA#zob=>BEP(>p$hZBtfQ8#|G+(zK%h721cCTSh^CuHP4foTM$yYL}qW&j!}5 z!T>OFu9dd1kiE0fZ|Fey1N*KcmeXI@{tkqCX&es4a%N+wak>3-Db!8X3Cp zRnRwFHAZ622GL6)XL zz(}IcvXFBT1}B^twiI}^Z`g93RA7^wvgo!+oGL|Y%_J9th8R3udDLmAf%kW(H< zRgZN@@54gdFi(teQKTlPr9=}A&<#5rxdsM?3XDDpuQFzDVIQK^$sR0_%x$1LC)af7^8G! z8OF8B9`1_NFfAtS>!DTRD=LMzs>Lfsa$bc^Y??@pT9C*MXFa}P!oNwA)*r+GT>7Sp<9V6xy;H0#40nFa;cXsa%cZWO6Kn5J}%rNReS8{h*U?3};8An*@Y6gUYK12qB38pk%tr1KxoS7YA z!PN{%QnVx;2&QO_S$&ZNEt<;@BS!lQN%}PXwn?+m^oiem`?RD!c}&x$`+a}z?CdW7 zihuO8JLmV0&-r=Jec#VH2k#0R!edm_;HR3-!~HJ0t?Bct1ci=HHO>h1=wryd=tlPh z(4u|RVHpMuMvS;VQ%vX4?t70IVWUu>;{h{V!;IMMDQf;1(o6P5nhP#61`Zn`HwD~2 z5Sv5IrvFBVqaui2yn}FHLPVlVSW(ml^e8Oh=3<(pKf>$J2BaZ*@Pl;o|C$O-Kn^>@ zc2I9!drwv75l1Uc<&}hu))*Cj+EXJdmpn?+8>jM8dKl#<9RRbEx@ zN*W#7Otp8+ky=uvGouu_>q#ecmugq(LqeysNOo`6{=8eTL_#N=luo4ZG^r$|nXQ@$ zEmLU0R7qopu_jTyUgQpHD<^vetx2f^6it?^xdQLto_;u&&qca4B~s;7&Tx`4C&~aN zbE|Sr$|@yt+5Gxcl=6Gk9AOkX$cX4fq|~P7IBHdkkbVsTN5qKr>*_sgWYp7Y9RehU zDdH4H>eNH_$>JBn=CcRv9fx*UH$N9UJbfqG`_-XXOV_EHneeGueM7Od-TLXz#@&;( zgN8kHa})J-XN-Fb*TiO4Mc*un-+U^bp3`lG3)Su=GdE1_vTlCn*2f}6`H^eZeDPCj zZ#ebvm!{tfeDbMq`;qvUI`3IbPd*Zsr<_|dkFUAA?<9TNEfl67k2~Sur=4k`XPkJ< zDr6jsHjq{93uoN!p+1`aMWQDb)6B3fzEp51{!Bbvh||vMtq$Eh)O~Bg=|hKtV&iF4 z=%a^^4sGDR1*y*8RVCP!OzS%wr{GGGku_c2ba+8`!gUHAJ9awmhHiVQ6OKOHx_Fsg zxOr#y^ht-F>J}H>%>Fqdp0=icqczi=iM!6MTNih@GnR^l3op!yH#wmb(p|c@_Jx_~ z+o+rlw9#LPO}hPXm(%`xafeQAaIWt9y0u`2=$hHx9edytr6y^guwyf>>Fy3Wp-gx86X_Y5 z7Ro%aG-I1?JY=`JaSIZp-C-HCT3o)MoGge;;&j?~s}Kyv1`UiFP&JxSF~_%?y#B$e zO4@k2^a)mUq)wRm`CwEqW)-j}grQab=ry!*&2}S8<_#8trbsAU?yj8@WnI(Ac7@EW z!gHWo_XxZ#i9?8J7F|0dNkp|JGEWD|P3&H8YjcwkCSyRDwUEF#bxc}LwMct{FhiM) zFe;OhxNn?f9!w+6O&HfC@U;!%9u%97o}j=c_<@S}8lJ2pFzXscWE}>d*gWwE>v{Z4 z{4}O*UK%Ptgb)@CD3% z>6BT-&#>JC!5p5UL-ceE3|Ot^Q%YE&8W~SRXcMq5J-uO0lh%JEBCgRM4+%O_6>ck6 zuM(*GtoamY)rScj8h;?f89ngBszAz=i;1Eg%yN+G4Jd*{9wsA{2&_n24IATmROyY_n%HpT+^AkfL1WUu}2ZzQY{%|@oYUf1YQV-0*kPXg>VT2iV z!PZ8v!?UWvfhEyLc_jnFD?uSAVL;)aOA{EU1Kmk;Z%qg&Nz^Cu&9gh6x~j!b=P{gU zmi7cb9~RqaIOq(Z#G5!pq{Iw^CC=Z^MGCy}k1Zx6RCltkt?np$Kl?{aiETyQT!i#v7*=AlU^x zgVp-p(YlFme&J2o_1&aw=Ka`p+@tP3La)5?umAd!pN#y=$dAAK*L7U+yMH}`J*bVn z+poN`?DA!o|MstcvToz$yCz>Xvg=cmaj(oxBR^R;GQyZn9oK2#ClmEuYd5a@O=!bS z?Do<5%WP=igj25X39ob2;0|n#(YV~>4Z8Pa{l|D=?@+xbac_F(Uqc3xG~iU!xY)i zCxrLY=rX{w;XASJV~;Mv;McJGd%AgF_h^1S7>5l!k|Q?4`DWzTz$hDf1Do_Sc|VFb z9*D6=%wR=E8uhY;nC*fV&A)u|h~S@p&f{-Ka6D<9I_9q(;WJa`M=rbUjlhBh zljmMm|5^9YgN@gcy6QrwGBvUv6B7 z-{lSa_C?zlEnBpG-LCokT|m$qzrv}k^SApLW%=nV0F!m?f zG^)dh+0Ek_4nHl5zE1qnj@|GC=kU1in&0H`*!ZY_o}~Rve{Z$yx$fh<$69U`HzAyo zHDw^2lBD~_)8%C7AwM4d?ZpHElk^te=GzC(&z2njiRFF1+~uHuaGNLTe{me>y`%b? zQ5|f(f2w1Q?P3LKOz7<>o94)(CBa&>s#2N_C}Ul}V^q(NhO39S8u3Vt`q#tn77;(T zN&hpA_@cf4d%j-z%evn5+Nu<%YwwTn6NM_((fERGO!aW7-Cjm>ZH>l1H>sYU_4(6& zdTFgC0^{7uQGMU2zPqmT_rrIh650)qF(zg-sJKC8PQQFvPJEf@A6}e&Q(%e-Xzw4? z6p1e5nZxE0PioS`6rhqmtGy}bet?*j)3dX)DTo6a{hq_Zjt?1AIPobj;gy4|GXQz$ z2WPdIat`m}=Yj#loK2gjoIM}t$1T{9e4Ksl>A+3;EQzxLBm2ffFDGBbPV2yn2IT{E z{vjk+LN;d5=QnWnY`*y=U^s6$RubrA|L{MoKsw%@vzuR{*IpBJ{N5bDH14Z?0z40vFDr3??ghNJ{p6@k|gWvG@ccFP3=0uqr4 z_A)WVlwlIW5C`_K7ABtzYan5upaz$gM=)R$Q`7)ZRHVY8Wm&{Q1-s-9)SzO+06qOx*ygyKtq1PF$Ld60n6Qh^SXsk<=*2Ao-U@pEU+A?BsSC${!< zokbI$qlED~;DoCu&uFmkixi_fwB@_Scafe4xE9x^iL{W z)&>EF0$$q%L`NF}3nJJXXCxj@YCn3z*T2LnXO9$mccQ=fYau+?L{!3~)u%;1I>GNThvCLY@SA zO9Yz~2_wXDHbbW%iIwPWdJkJB38fTvb%xMk!4eZ{1ozr#bkGv&1Oo(2XI2`jny-HX zfL+lcl7+NcgQS-Z$KbM3qAvlN!P^l6=Kw%4*~AG@GrA_|vD9_=ZUSyK*H9WR z?2E$?*;|q;kw+4_%3fHDaCjHIG?FNH-3OiC8%8fs8H9cgZ8l&V3J<3 zY628Q@ih&!qe1cJj(CA14f$0U2Pq)l1@4xZjJWq;bnV87)^KjF;XN0#iO)OuM8BYB zpI??|EJR_C_Y25VdI;?IBlnL!fGzQK!J}grMd4>O-1g%w6zwrH#-p>DJ)Twk-ttnyR0+OEYw=RAaa)rDe^;zFY(RrfPnKv!ALhfk zuKgF-JrG*mW+P|)h10iz?Tp@y`q_hd2Dd@CuYh*T|8plP=%}v&<}f4`8VGWc+!RG_ zBN8;scf|x_WAcoa8GGpy7@I%0k>4BX5;9RTMY1P)c+GTL zjYA&OcrqA~oRdtYRMH&~T`SuYuBzz$c#!Wmai*hHYCEVA$B?;>f{YZTlo3Z$$xgKO z9-4b|)yW^k#?eAm<$GjjNhB5PX-4)}dj!Q3$&^e)Qi()`+9CN!W>S_*5c;8H!eCf|JMSnd=n_A! ztcI(GnH=tHdxd2$Az>XC*0COJ#9kHKiraCvS7g5$_r=Se)Qzv z^H;8pO><{mJ-x-Y=G=bG@h!on8!~41JZw?8rFgvzhK4=%Vo|ZKxfOx`i6moEG_5X0?TawL4;Q$JCS07czy~iBA@s z{k$sZ-oGAWaO%CQ!h9MCJ%=I9WBWZRjZQZ(1Jz__R5WujY=ygHANq{wyy0cab^l)9 z44KJpbw4DuJJb`hV=Zwz^P_JZ&e-Dk+}@bGp}EW6=6)&j(bs!y*)%x)6vgI}Ju?>5 zZS(9sws0VJ*uDOSPj~N#FOC1vM|M1GFTV0=Yss_IE^7_V*f$+hh}#)=+Kj`Q8@KFS zxOAx7{qycF%Z_ccoh$!$$0KgHYKgb~S^SZivFM}WX^Q|zwtZl0JY-Gj$V|85iwoV( zEjTGM6SdkqPVS2@e#F`k54#k$WCoWAk#$0v;ltR8{h)nnY1$n?J;bpw`;({|{Ew1^ z&co2euiZ6qG=BxU**h-(580LigQaG>XyA~ z2G3DOhcPc(7RSXg>Ez}i2OHvk)`O`l(5uZ1K6GK;$NXUBOgDd<+Mh02JgeG{k!hn` z2s~DjQ62(EbrRg=EQ#fl;H8Ug47A}Bl|MR=LY;W1{0>5?QCZ-Z`xSqCgQT2cRR)kN z7=z#??YFf)QHp4Z00mCpuO6bo6pVQORC`DfNh;Bd76t!oA%gldlxCsO5cNbHE)w=j zqhH?Gt12bD`4w!1y_W}ufUDM?PMPVuyPu<@=CgBk`bINnpctmW{%ae_2V8!(Ymn;OEWL;!PSBy4Nodie+Kx0Qi=hn+eN8__%co zo&$A4xVI2`P8q90jt}w`DeLySqb1><#=4dLK@L2v9u6usAvS(z{65H@mO`%O2oUTl zBEeS)$W5A#W%W#>GR_HRlK6i$hndqvA}ggFj>t_|caXv7U?VvX{P4Nxe$I|55doW{ z($E27F{PcF5|%7arz2_(KlNj2d?c2hz&DR^;YTh7Pd3tzGp;o3Z`H>`z|`IS=%ZI% zcG*=wj578Jxu~@Z7HFx4CkKHtHcwtbPmJ8OYlJkg2A_bfxFg@%-u$g^O>TW0@`Sr~ z{nvl3o%{x)7(ZUHfX}IG(B+YJ>(&Lfuf067D7YxNZ2q#za0x65Zk!DBd`K_y!jZoeRxoU*E--X-^={X1`1Lj=&oq8<$gjckEF^{*W;~AA1~= zDdeUb|M{5Ts0<>#{S3%=!XuyJ_zmo^foo1o^PS9$FE-qLo+ipej`Gt;v!QcgxeRq` z=%ZGw5FC%YeVux=I^N^&udeU0CQUf&vWPP-{U3OKD`5yqV1y|Ql!*klF^rMjFFgkm z^)YrP_TKaBn``mtNKEgqp|%e-Ik-@va2Mjro{`4M3C*!2v|5ZL4V$-n(=^W-TTiRBzY z3H0ZH_|=<&f;4sN{I%c34(wmOxxM+vko(;@WnEy|~h zPn0jg(a87Z*?FCjr>Fq@%nR zFat=M^c+9jx8FOlao_9wJ>99%ac%U{}8e#XZzG43+N z@{p$JG7TlusxEH{sk}MZn=I)z%9w^H&7+)_9^GZZ<}u=F#Cxwgxulq5(b%BVPy{`A zI<28s&SDt=O8F`)FLI9Hx)E;7<98Uo=f}$jzL((m?fs45MRq4k)O8Zdx6|m}?Ua%A z?OW)a&ku!LB*!!d8ho8j--qC~yzpb7oOjNj51uE&F@sFV#XB1yMc&J& z=f8yTfxuCZg&vcp2N_8MtmM5AIEQ!4{*MZr3mFKkz%S1+ef~KOs+YHJd?!_MWq>Sv zmeF8Ec=y@#PD3wvb5FnF7yTFDO8|oDS?j$MSM^y_(%n}Ogl>pXiSj{8=Bl^KiMHM1h z4oO(C!Bb`}O%jrm(gODoDd7a)mGlIk0?rM`GAjK0F>1L^Y}E(x>Ep38X8V^n5kR1# zu0U^kHE(D^(K(Wu^qr*d|F>=Q`+caIt0-JX^w60*Y0vjKylE6+#qunvVW^&ohmURo z+F_JPag{oy*cLR`m8i}t(*4S5SM#FM9>FXBAOC(jhal;*vY7cIP7IFr!5bu+aEFXB5rvI#A3f_i5W3OC$p2+Xmu zPHP&5QN7;OmpC@Rmc`B)y{$js2=Y4HD;;Pf*K6A≷k*=XNJ>ve$F75h*GpS`f|k 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 diff --git a/util/wan_aftup/A102dm_0040_V31.BIN b/util/wan_aftup/A102dm_0040_V31.BIN new file mode 100644 index 0000000000000000000000000000000000000000..fd9b527fe097a11ab10f556178d28e0739c9904f GIT binary patch literal 212392 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 S#tOSVLOk`!ls~%^um20#OG0S? literal 0 HcmV?d00001 diff --git a/util/wan_aftup/A102dm_0040_V33.BIN b/util/wan_aftup/A102dm_0040_V33.BIN deleted file mode 100644 index 33262f16f9444ca496518d291ba9b546655e12a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212392 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 diff --git a/util/wan_aftup/A104d_0100_V24.BIN b/util/wan_aftup/A104d_0100_V24.BIN new file mode 100644 index 0000000000000000000000000000000000000000..bb377a7155c023fc3cf1ce9b515175e7dffda707 GIT binary patch literal 402936 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�ea^hXoK(DU+dG)=bT>hwep#-e=(#%{r^dJw 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

    W#(9rJ7uI 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%0D=^%c*A@N5@UBF97DGU>!v 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 diff --git a/patches/kdrivers/wanec/.#wanec_cmd.c.1.49 b/patches/kdrivers/wanec/.#wanec_cmd.c.1.49 new file mode 100644 index 0000000..1edfe89 --- /dev/null +++ b/patches/kdrivers/wanec/.#wanec_cmd.c.1.49 @@ -0,0 +1,2176 @@ +/************************************************************* + * wanec_cmd.c WANPIPE Echo Canceller Layer (WANEC_LIP) + * + * + * + * =========================================================== + * + * May 10 2006 Alex Feldman Initial Version + * + * March 19, 2006 Alex Feldman Enable Sout Adaptive Noise + * Reduction for all channel by + * default. + */ + + +/*============================================================= + * Includes + */ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +#elif defined(__LINUX__) +# include +# include +# include +# include +#elif defined(__WINDOWS__) +# include +# include +# include +#endif + +int verbose; + +#include "oct6100_api.h" +#include "oct6100_version.h" + +#include "wanec_iface.h" +#include "wanec_tones.h" + +/*============================================================= + * Definitions + */ +#define WANEC_MAX_PORT_RANGE 32 +#define WANEC_MAX_BRI_PORT_RANGE 2 +#define WANEC_READ_LIMIT 0x10000 + +#define WANEC_MAX_CONFBRIDGE_DEF 32 +#define WANEC_MAC_PLAYOUT_BUFFERS 20 + +//FIXME: Take this out +#warning "WAN_MEDIA_BRI is localy defined to 0: do not commit" +#define WAN_MEDIA_BRI 0 +/*============================================================= + * Global Parameters + */ +UINT32 DetectedSoutToneNumbers[WAN_NUM_DTMF_TONES] = +{ + SOUT_DTMF_0, + SOUT_DTMF_1, + SOUT_DTMF_2, + SOUT_DTMF_3, + SOUT_DTMF_4, + SOUT_DTMF_5, + SOUT_DTMF_6, + SOUT_DTMF_7, + SOUT_DTMF_8, + SOUT_DTMF_9, + SOUT_DTMF_A, + SOUT_DTMF_B, + SOUT_DTMF_C, + SOUT_DTMF_D, + SOUT_DTMF_STAR, + SOUT_DTMF_POUND, +}; +UINT32 DetectedRoutToneNumbers[WAN_NUM_DTMF_TONES] = +{ + ROUT_DTMF_0, + ROUT_DTMF_1, + ROUT_DTMF_2, + ROUT_DTMF_3, + ROUT_DTMF_4, + ROUT_DTMF_5, + ROUT_DTMF_6, + ROUT_DTMF_7, + ROUT_DTMF_8, + ROUT_DTMF_9, + ROUT_DTMF_A, + ROUT_DTMF_B, + ROUT_DTMF_C, + ROUT_DTMF_D, + ROUT_DTMF_STAR, + ROUT_DTMF_POUND +}; + +/*============================================================= + * Function prototype +*/ + +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose); +int wanec_ChipOpen(wan_ec_dev_t*, int); +int wanec_ChipClose(wan_ec_dev_t*, int verbose); +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose); + +int wanec_ChannelOpen(wan_ec_dev_t*, int); +int wanec_ChannelClose(wan_ec_dev_t*, int); +int wanec_ChannelModify(wan_ec_dev_t*, INT, wanec_chan_modify_t*, int verbose); +int wanec_ChannelStats(wan_ec_dev_t*, INT channel, wanec_chan_stats_t *chan_stats, int reset); + +int wanec_ChannelMute(wan_ec_dev_t*, INT channel, unsigned char port_mask, int); +int wanec_ChannelUnMute(wan_ec_dev_t*, INT channel, unsigned char port_mask, int); + +int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char port, int verbose); +int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char port, int verbose); + +int wanec_DebugChannel(wan_ec_dev_t*, INT channel, int verbose); +int wanec_DebugGetData(wan_ec_dev_t*, wanec_chan_monitor_t *chan_monitor, int verbose); + +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose); +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose); +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); + +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); + +int wanec_EventTone(wan_ec_t *ec, int verbose); +int wanec_ISR(wan_ec_t *ec, int verbose); + +int wanec_fe2ec_channel(wan_ec_dev_t*, int); +static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl); +static int wanec_ec2fe_channel(wan_ec_t*, int, wan_ec_dev_t**); + +extern int wanec_ChipParam(wan_ec_t*,tPOCT6100_CHIP_OPEN, wan_custom_conf_t*, int); +extern int wanec_ChanParam(wan_ec_t*,tPOCT6100_CHANNEL_MODIFY, wan_custom_conf_t*, int); +extern int wanec_ChanParamList(wan_ec_t *ec); + +u32 wanec_req_write(void*, u32 write_addr, u16 write_data); +u32 wanec_req_write_smear(void*, u32 addr, u16 data, u32 len); +u32 wanec_req_write_burst(void*, u32 addr, u16 *data, u32 len); +u32 wanec_req_read(void*, u32 addr, u16 *data); +u32 wanec_req_read_burst(void*, u32 addr, u16 *data, u32 len); + +extern int wan_ec_write_internal_dword(wan_ec_dev_t *ec_dev, u32 addr1, u32 data); +extern int wan_ec_read_internal_dword(wan_ec_dev_t *ec_dev, u32 addr1, u32 *data); + +/*============================================================= + * Function definition +*/ +static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl) +{ + int channel = 0; + + for(channel = 0; channel < ec->max_channels; channel++){ + if (ec->pEchoChannelHndl[channel] == ChannelHndl){ + return channel; + } + } + return 0; +} +int wanec_fe2ec_channel(wan_ec_dev_t *ec_dev, int fe_channel) +{ + int ec_channel = 0; + + if (ec_dev->fe_media == WAN_MEDIA_BRI){ + if (ec_dev->fe_lineno >= 12){ + ec_channel = WANEC_MAX_PORT_RANGE; + } + ec_channel += (ec_dev->fe_lineno * WANEC_MAX_BRI_PORT_RANGE + (fe_channel-1)); + }else{ + /*ec_channel = ec_dev->fe_lineno * ec_dev->fe_max_channels + channel;*/ + ec_channel = ec_dev->fe_lineno * WANEC_MAX_PORT_RANGE + fe_channel; + } + return ec_channel; +} + +static int wanec_ec2fe_channel(wan_ec_t *ec, int ec_chan, wan_ec_dev_t **ec_dev) +{ + int fe_chan; + + *ec_dev = ec->pEcDevMap[ec_chan]; + if (*ec_dev == NULL) return 0; + + fe_chan = ec_chan % WANEC_MAX_PORT_RANGE; + if ((*ec_dev)->fe_media == WAN_MEDIA_BRI){ + fe_chan = fe_chan % WANEC_MAX_BRI_PORT_RANGE; + fe_chan++; + }else{ + if ((*ec_dev)->fe_media == WAN_MEDIA_T1 || + (*ec_dev)->fe_media == WAN_MEDIA_FXOFXS){ + fe_chan++; + } + } + return fe_chan; +} + + +/****************************************************************** +** +** +*******************************************************************/ +tOCT6100_CHIP_IMAGE_INFO f_ChipImageInfo; +#if 0 +tOCT6100_GET_HW_REVISION f_Revision; +#endif +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHIP_STATS f_ChipStats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + if (chip_stats){ + PRINT1(verbose, "%s: Reading chip statistics...\n", + ec->name); + } + Oct6100ChipGetStatsDef( &f_ChipStats ); + f_ChipStats.fResetChipStats = reset; + ulResult = Oct6100ChipGetStats( + ec->pChipInstance, + &f_ChipStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading chip statistics...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return -EINVAL; + } + if (chip_stats){ + memcpy( &chip_stats->f_ChipStats, + &f_ChipStats, + sizeof(tOCT6100_CHIP_STATS)); + } + + if (chip_stats){ + PRINT1(verbose, "%s: Reading chip image info...\n", + ec->name); + } + + Oct6100ChipGetImageInfoDef( &f_ChipImageInfo ); + ulResult = Oct6100ChipGetImageInfo( + ec->pChipInstance, + &f_ChipImageInfo); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading chip image info...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return -EINVAL; + } + if (chip_stats){ + if (chip_stats->f_ChipImageInfo){ + int err; + err = WAN_COPY_TO_USER( + &f_ChipImageInfo, + chip_stats->f_ChipImageInfo, + sizeof(tOCT6100_CHIP_IMAGE_INFO)); + if (err){ + DEBUG_EVENT( + "%s: Failed to copy chip image info to user space [%s:%d]!\n", + ec->name, __FUNCTION__,__LINE__); + return -EINVAL; + } + }else{ + PRINT1(verbose, + "%s: Echo Canceller image description:\n%s\n", + ec->name, f_ChipImageInfo.szVersionNumber); + PRINT1(verbose, + "%s: Echo Canceller image build ID\t\t\t%08X\n", + ec->name, f_ChipImageInfo.ulBuildId); + PRINT1(verbose, + "%s: Echo Canceller maximum number of channels\t%d\n", + ec->name, f_ChipImageInfo.ulMaxChannels); +#if 0 + PRINT1(verbose, + "%s: Echo Canceller maximum tail displacement\t\t%d\n", + ec->name, f_ChipImageInfo.ulMaxTailDisplacement); + PRINT1(verbose, + "%s: Echo Canceller per channel tail displacement\t%s\n", + ec->name, + (f_ChipImageInfo.fPerChannelTailDisplacement == TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller per channel tail length\t\t%s\n", + ec->name, + (f_ChipImageInfo.fPerChannelTailLength == TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller maximum tail length\t\t%d\n", + ec->name, f_ChipImageInfo.ulMaxTailLength); + PRINT1(verbose, + "%s: Echo Canceller buffer Playout support\t\t%s\n", + ec->name, + (f_ChipImageInfo.fBufferPlayout == TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller adaptive noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAdaptiveNoiseReduction==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller SOUT noise bleaching\t\t%s\n", + ec->name, + (f_ChipImageInfo.fSoutNoiseBleaching==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller ROUT noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fRoutNoiseReduction==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller ROUT noise reduction level\t\t%s\n", + ec->name, + (f_ChipImageInfo.fRoutNoiseReductionLevel==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller automatic level control\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAutoLevelControl==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller acoustic echo cancellation\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAcousticEcho==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller conferencing\t\t%s\n", + ec->name, + (f_ChipImageInfo.fConferencing==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller conferencing noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fConferencingNoiseReduction==TRUE)?"TRUE":"FALSE"); +#endif + } + } + if (f_ChipImageInfo.ulMaxChannels < (unsigned int)ec->max_channels){ + ec->max_channels = f_ChipImageInfo.ulMaxChannels-1; + } + +// DEBUG_EVENT(verbose, "%s: Reading hw revision...\n", +// ec->name); +#if 0 + DEBUG_EVENT(verbose, "%s: Reading hw revision...\n", + ec->name); + ec->f_Revision.ulUserChipId = 0; + ec->f_Revision.pProcessContext = &ec->f_Context; + ulResult = Oct6100GetHwRevision(&ec->f_Revision); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading hw revision...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return EINVAL; + } +#endif + return 0; +} + +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose) +{ + tOCT6100_GET_INSTANCE_SIZE InstanceSize; + wan_ec_t *ec; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(config->imageData == NULL); + ec = ec_dev->ec; + + ulResult = Oct6100ChipOpenDef( &ec->f_OpenChip ); + + /*==============================================================*/ + /* Configure clocks */ + + /* upclk oscillator is at 33.33 Mhz */ + ec->f_OpenChip.ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; + + /* mclk will be generated by internal PLL at 133 Mhz */ + ec->f_OpenChip.fEnableMemClkOut = TRUE; +#if 1 + ec->f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ; +#else + ec->f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_125_MHZ; /*125*/ +#endif + + /*==============================================================*/ + + /*==============================================================*/ + /* General parameters */ + + /* Chip ID.*/ + ec->f_OpenChip.ulUserChipId = ec->chip_no; + + /* Set the max number of accesses to 1024 to speed things up */ + ec->f_OpenChip.ulMaxRwAccesses = 1024; + + /* Set the maximums that the chip needs to support for this test */ + ec->f_OpenChip.ulMaxChannels = config->max_channels; + + ec->f_OpenChip.ulMaxBiDirChannels = 0; + ec->f_OpenChip.ulMaxConfBridges = 0; //WANEC_MAX_CONFBRIDGE_DEF; + ec->f_OpenChip.ulMaxPhasingTssts = 0; + ec->f_OpenChip.ulMaxTdmStreams = 32; + ec->f_OpenChip.ulMaxTsiCncts = 2; + + /*==============================================================*/ + + /*==============================================================*/ + /* External Memory Settings */ + + /* Use DDR memory.*/ +#if 1 + ec->f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_SDR; +#else + ec->f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_DDR; +#endif + + ec->f_OpenChip.ulNumMemoryChips = 2; + + /* + **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_8MB; + **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_16MB;*/ + ec->f_OpenChip.ulMemoryChipSize = config->memory_chip_size; + + ec->f_OpenChip.fEnableChannelRecording = TRUE; + +#if defined(ENABLE_ACOUSTICECHO) + ec->f_OpenChip.fEnableAcousticEcho = TRUE; +#endif + +#if defined(ENABLE_PRODBIST) + /* Enable production bist mode */ + ec->f_OpenChip.fEnableProductionBist = TRUE; + ec->f_OpenChip.ulNumProductionBistLoops = 0x1; +#endif + + ec->f_OpenChip.ulMaxPlayoutBuffers = WANEC_MAC_PLAYOUT_BUFFERS; + + ec->f_OpenChip.pbyImageFile = ec->pImageData; + ec->f_OpenChip.ulImageSize = ec->ImageSize; + + /* Assign board index (0). */ + ec->f_Context.ulBoardId = ec->chip_no; + + /* Handle to driver */ + ec->f_Context.ec_dev = ec_dev; + + /* Interface name to driver */ + strlcpy(ec->f_Context.devname, devname, WAN_DRVNAME_SZ); + + ulResult = Oct6100GetInstanceSize(&ec->f_OpenChip, &InstanceSize); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to get EC chip instance size (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* Allocate memory needed for API instance. */ + ec->pChipInstance = + (tPOCT6100_INSTANCE_API)wan_vmalloc(InstanceSize.ulApiInstanceSize); + if (ec->pChipInstance == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed to allocate memory for EC chip (%d bytes)!\n", + ec->name,InstanceSize.ulApiInstanceSize); + return -EINVAL; + } + + /* Open the OCT6100 on the evaluation board. */ + ec->f_OpenChip.pProcessContext = (PVOID)&ec->f_Context; + + /* parse advanced params (global custom configuration) */ + if (ec->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &ec->custom_conf, verbose); + } + /* parse advanced params (command line custom configuration) */ + if (config->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &config->custom_conf, verbose); + } + + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + ec->ulDebugDataMode = config->debug_data_mode; + return 0; +} + +int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + UINT32 ulResult, i = 0; + INT ec_chan = 0; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, + "%s: Opening Echo Canceller Chip ...\n", + ec->name); + if (ec->f_OpenChip.pbyImageFile == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid EC image pointer\n", + ec->name); + return -EINVAL; + } + ulResult = Oct6100ChipOpen( + ec->pChipInstance, /* API instance memory. */ + &ec->f_OpenChip ); /* Open chip structure. */ + if ( ulResult != cOCT6100_ERR_OK ){ + if (ec->imageLast == WANOPT_YES || + ulResult != cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS){ + DEBUG_EVENT( + "ERROR: %s: Failed to open Echo Canceller Chip (err=0x%X)\n", + ec->name, ulResult); + } + return -EINVAL; + } + + if (wanec_ChipStats(ec_dev, NULL, TRUE, verbose)){ + DEBUG_EVENT( + "ERROR: %s: Failed to read EC chip statistics!\n", + ec->name); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + + ec->pToneBufferIndexes = + wan_malloc(sizeof(UINT32) * ec->f_OpenChip.ulMaxPlayoutBuffers); + if (ec->pToneBufferIndexes == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for playout handles!\n", + ec->name); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + i = 0; + while(i < ec->f_OpenChip.ulMaxPlayoutBuffers){ + ec->pToneBufferIndexes[i++] = cOCT6100_INVALID_VALUE; + } + ec->pEchoChannelHndl = + wan_malloc(sizeof(UINT32) * ec->max_channels); + if (ec->pEchoChannelHndl == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for channel handle!\n", + ec->name); + wan_free(ec->pToneBufferIndexes); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + ec->pEcDevMap = wan_malloc(sizeof(wan_ec_dev_t*) * ec->max_channels); + if (ec->pEcDevMap == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for ec channel map!\n", + ec->name); + wan_free(ec->pToneBufferIndexes); + wan_free(ec->pEchoChannelHndl); + wanec_ChipClose(ec_dev, verbose); + return -EINVAL; + } + for(ec_chan = 0; ec_chan < ec->max_channels; ec_chan++){ + ec->pEchoChannelHndl[ec_chan] = cOCT6100_INVALID_HANDLE; + ec->pEcDevMap[ec_chan] = NULL; + } + return 0; +} + +int wanec_ChipClose(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHIP_CLOSE f_CloseChip; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Closing Echo Canceller Chip ...\n", + ec->name); + Oct6100ChipCloseDef( &f_CloseChip ); + ulResult = Oct6100ChipClose( + ec->pChipInstance, + &f_CloseChip ); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to close Echo Canceller chip (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + if (ec->pChipInstance){ + wan_vfree(ec->pChipInstance); + ec->pChipInstance = NULL; + } + if (ec->pToneBufferIndexes){ + wan_free(ec->pToneBufferIndexes); + ec->pToneBufferIndexes = NULL; + } + if (ec->pEchoChannelHndl){ + wan_free(ec->pEchoChannelHndl); + ec->pEchoChannelHndl = NULL; + } + if (ec->pEcDevMap){ + wan_free(ec->pEcDevMap); + ec->pEcDevMap = NULL; + } + return 0; +} + +int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, int verbose) +{ + tOCT6100_CHANNEL_OPEN EchoChannelOpen; + wan_ec_t *ec; + sdla_t *card; + UINT32 ulResult; + UINT32 stream = 0,timeslot=0; + INT channel, pcm_law_type; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(ec_dev->card == NULL); + ec = ec_dev->ec; + card = (sdla_t*)ec_dev->card; + + pcm_law_type = (WAN_FE_TDMV_LAW(&card->fe) == WAN_TDMV_MULAW) ? + cOCT6100_PCM_U_LAW : cOCT6100_PCM_A_LAW; + PRINT1(verbose, + "%s: Openning all Echo Canceller channels (%s)...\n", + ec->name, + (pcm_law_type == cOCT6100_PCM_U_LAW) ? + "MULAW":"ALAW"); + + for(channel = 0; channel < ec->max_channels; channel++){ + Oct6100ChannelOpenDef( &EchoChannelOpen ); + + /* Assign the handle memory.*/ + EchoChannelOpen.pulChannelHndl = &ec->pEchoChannelHndl[channel]; + + /* Make sure the channel does not perform echo cancellation */ +#if defined(WANEC_BYDEFAULT_NORMAL) + EchoChannelOpen.ulEchoOperationMode = + cOCT6100_ECHO_OP_MODE_NORMAL; +#else + EchoChannelOpen.ulEchoOperationMode = + cOCT6100_ECHO_OP_MODE_POWER_DOWN; +#endif + EchoChannelOpen.fEnableToneDisabler = TRUE; + + stream = (channel % 2 == 1) ? 4 : 0; + timeslot = channel / 2; + + /* Configure the TDM interface.*/ + EchoChannelOpen.TdmConfig.ulRinPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulRoutPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulSinPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulSoutPcmLaw = pcm_law_type; + + EchoChannelOpen.TdmConfig.ulRinStream = stream + 0; + EchoChannelOpen.TdmConfig.ulRinTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulRoutStream = stream + 1; + EchoChannelOpen.TdmConfig.ulRoutTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulSinStream = stream + 2; + EchoChannelOpen.TdmConfig.ulSinTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulSoutStream = stream + 3; + EchoChannelOpen.TdmConfig.ulSoutTimeslot = timeslot; + + /* Set the desired VQE features (TRUE/FALSE).*/ + EchoChannelOpen.VqeConfig.fEnableNlp = TRUE; + EchoChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + EchoChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; +#if defined(ENABLE_ACOUSTICECHO) + EchoChannelOpen.VqeConfig.fAcousticEcho = TRUE; +#endif + + EchoChannelOpen.VqeConfig.fSoutAdaptiveNoiseReduction = TRUE; + EchoChannelOpen.VqeConfig.ulComfortNoiseMode = + cOCT6100_COMFORT_NOISE_NORMAL; + /* cOCT6100_COMFORT_NOISE_NORMAL + ** cOCT6100_COMFORT_NOISE_EXTENDED, + ** cOCT6100_COMFORT_NOISE_OFF, + ** cOCT6100_COMFORT_NOISE_FAST_LATCH */ + + PRINT1(verbose, + "%s: Openning Echo Canceller channel %d (%s)...\n", + ec->name, + channel, + (pcm_law_type == cOCT6100_PCM_U_LAW) ? + "MULAW":"ALAW"); + /* Open the channel.*/ + ulResult = Oct6100ChannelOpen( ec->pChipInstance, + &EchoChannelOpen ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to open Echo Canceller channel %d (err=0x%X)!\n", + ec->name, + channel, + ulResult); + return ulResult; + } + } + + /* Init debug channel handle */ + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + + return 0; +} + +int wanec_ChannelClose(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_CLOSE EchoChannelClose; + UINT32 ulResult, channel; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Closing all Echo Canceller channels ...\n", + ec->name); + for(channel = 0; channel < (UINT32)ec->max_channels; channel++){ + Oct6100ChannelCloseDef( &EchoChannelClose ); + EchoChannelClose.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ChannelClose( ec->pChipInstance, + &EchoChannelClose ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to close Echo Canceller channel %d (err=0x%X)!\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + ec->pEchoChannelHndl[channel] = cOCT6100_INVALID_HANDLE; + } + return 0; +} + +int wanec_ChannelModify( wan_ec_dev_t *ec_dev, + INT channel, + wanec_chan_modify_t *chan_modify, + int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MODIFY EchoChannelModify; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + Oct6100ChannelModifyDef( &EchoChannelModify ); + + /* Assign the handle memory.*/ + EchoChannelModify.ulChannelHndl = ec->pEchoChannelHndl[channel]; + + /* parse advianced params */ + if (chan_modify->custom_conf.param_no){ + int err; + err = wanec_ChanParam(ec, &EchoChannelModify, &chan_modify->custom_conf, verbose); + if (err){ + DEBUG_EVENT( + "%s: WARNING: Unsupported parameter for channel %d!\n", + ec->name, channel); + return -EINVAL; + } + }else{ + + /* Echo Channel Operation Mode */ + EchoChannelModify.ulEchoOperationMode = chan_modify->opmode; + + if (chan_modify->mute != WANEC_IGNORE){ + EchoChannelModify.fVqeConfigModified = TRUE; + if (chan_modify->mute){ + EchoChannelModify.VqeConfig.fDtmfToneRemoval = TRUE; + }else{ + EchoChannelModify.VqeConfig.fDtmfToneRemoval = FALSE; + } + } + } + + /* Open the channel.*/ + ulResult = Oct6100ChannelModify( + ec->pChipInstance, + &EchoChannelModify ); + if (ulResult != cOCT6100_ERR_OK){ + PRINT1(verbose, + "%s: Failed to modify Channel config parameters for channel %d (err=0x%X)\n", + ec->name, + channel, + ulResult); + return EINVAL; + } + return 0; +} + +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ChannelMute(wan_ec_dev_t* ec_dev, INT channel, unsigned char port_mask, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MUTE f_ChannelMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, "%s: Muting channel %d on port %X...\n", + ec->name, channel, port_mask); + Oct6100ChannelMuteDef( &f_ChannelMute ); + f_ChannelMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + f_ChannelMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (port_mask & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (port_mask & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (port_mask & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (port_mask & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + ulResult = Oct6100ChannelMute( + ec->pChipInstance, + &f_ChannelMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute channel %d on port %X (%08X)!\n", + ec->name, channel, port_mask, ulResult); + return EINVAL; + } + return 0; +} +int wanec_ChannelUnMute(wan_ec_dev_t *ec_dev, INT channel, unsigned char port_mask, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_UNMUTE f_ChannelUnMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, "%s: Un-muting channel %d on port %X...\n", + ec->name, channel, port_mask); + Oct6100ChannelUnMuteDef( &f_ChannelUnMute ); + f_ChannelUnMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + f_ChannelUnMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (port_mask & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (port_mask & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (port_mask & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (port_mask & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + ulResult = Oct6100ChannelUnMute( + ec->pChipInstance, + &f_ChannelUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to un-mute channel %d on port %X (%08X)!\n", + ec->name, channel, port_mask, ulResult); + return EINVAL; + } + return 0; +} + +int wanec_ChannelStats(wan_ec_dev_t *ec_dev, INT channel, wanec_chan_stats_t *chan_stats, int reset) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_STATS f_ChannelStats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, "%s: Reading EC statistics for channel %d...\n", + ec->name, channel); + Oct6100ChannelGetStatsDef( &f_ChannelStats ); + f_ChannelStats.ulChannelHndl = ec->pEchoChannelHndl[channel]; + f_ChannelStats.fResetStats = reset; + ulResult = Oct6100ChannelGetStats( + ec->pChipInstance, + &f_ChannelStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to read EC stats for channel %d (%08X)!\n", + ec->name, channel, ulResult); + return EINVAL; + } + if (chan_stats){ + memcpy( &chan_stats->f_ChannelStats, + &f_ChannelStats, + sizeof(tOCT6100_CHANNEL_STATS)); + } + return 0; +} + +int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char type, int verbose) +{ + tOCT6100_TONE_DETECTION_ENABLE f_ToneDetectionEnable; + UINT32 ulResult; + int i; + + PRINT1(verbose, "%s: Enable tone detection on ec chan %d ...\n", + ec->name, + channel); + + if (type & WAN_EC_CHANNEL_PORT_ROUT){ + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); + f_ToneDetectionEnable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + f_ToneDetectionEnable.ulToneNumber = + DetectedRoutToneNumbers[i]; + ulResult = Oct6100ToneDetectionEnable ( + ec->pChipInstance, + &f_ToneDetectionEnable); + if ( ulResult == cOCT6100_ERR_OK ){ + continue; + }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ + PRINT1(verbose, + "%s: Tone detection is already enabled on channel %d for port ROUT!\n", + ec->name, channel); + continue; /* already activated */ + }else{ + DEBUG_EVENT( + "ERROR: %s: Failed to enable tone detection on ec chan %d!\n", + ec->name, channel); + DEBUG_EVENT( + "ERROR: %s: (err=0x%X,i=%d)!\n", + ec->name, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + if (type & WAN_EC_CHANNEL_PORT_SOUT){ + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); + f_ToneDetectionEnable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + f_ToneDetectionEnable.ulToneNumber = + DetectedSoutToneNumbers[i]; + ulResult = Oct6100ToneDetectionEnable ( + ec->pChipInstance, + &f_ToneDetectionEnable); + if ( ulResult == cOCT6100_ERR_OK ){ + continue; + }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ + PRINT1(verbose, + "%s: Tone detection is already enabled on channel %d for port SOUT!\n", + ec->name, channel); + continue; /* already activated */ + }else{ + DEBUG_EVENT( + "ERROR: %s: Failed to enable tone detection on channel %d!\n", + ec->name, channel); + DEBUG_EVENT( + "ERROR: %s: (err=0x%X,i=%d)!\n", + ec->name, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + + return 0; +} + +int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char type, int verbose) +{ + tOCT6100_TONE_DETECTION_DISABLE f_ToneDetectionDisable; + UINT32 ulResult; + INT i; + + PRINT1(verbose, "%s: Disable tone detection on channel %d ...\n", + ec->name, + channel); + if (type & WAN_EC_CHANNEL_PORT_ROUT){ + + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); + f_ToneDetectionDisable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + if (channel >= 0){ + f_ToneDetectionDisable.ulToneNumber = + DetectedRoutToneNumbers[i]; + }else{ + f_ToneDetectionDisable.fDisableAll = TRUE; + } + ulResult = Oct6100ToneDetectionDisable ( + ec->pChipInstance, + &f_ToneDetectionDisable); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, channel, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + if (type & WAN_EC_CHANNEL_PORT_SOUT){ + + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); + f_ToneDetectionDisable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + if (channel >= 0){ + f_ToneDetectionDisable.ulToneNumber = + DetectedSoutToneNumbers[i]; + }else{ + f_ToneDetectionDisable.fDisableAll = TRUE; + } + ulResult = Oct6100ToneDetectionDisable ( + ec->pChipInstance, + &f_ToneDetectionDisable); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, channel, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + return 0; +} + +//#if defined(WAN_DEBUG_HWEC) +#if 1 +static CHAR* wanec_ToneId2Str(UINT32 f_ulToneId) +{ + switch (f_ulToneId){ + /* DTMF Section */ + case ROUT_DTMF_0: return "ROUT_DTMF_0"; + case ROUT_DTMF_1: return "ROUT_DTMF_1"; + case ROUT_DTMF_2: return "ROUT_DTMF_2"; + case ROUT_DTMF_3: return "ROUT_DTMF_3"; + case ROUT_DTMF_4: return "ROUT_DTMF_4"; + case ROUT_DTMF_5: return "ROUT_DTMF_5"; + case ROUT_DTMF_6: return "ROUT_DTMF_6"; + case ROUT_DTMF_7: return "ROUT_DTMF_7"; + case ROUT_DTMF_8: return "ROUT_DTMF_8"; + case ROUT_DTMF_9: return "ROUT_DTMF_9"; + case ROUT_DTMF_A: return "ROUT_DTMF_A"; + case ROUT_DTMF_B: return "ROUT_DTMF_B"; + case ROUT_DTMF_C: return "ROUT_DTMF_C"; + case ROUT_DTMF_D: return "ROUT_DTMF_D"; + case ROUT_DTMF_STAR: return "ROUT_DTMF_STAR"; + case ROUT_DTMF_POUND: return "ROUT_DTMF_POUND"; + case SOUT_DTMF_0: return "SOUT_DTMF_0"; + case SOUT_DTMF_1: return "SOUT_DTMF_1"; + case SOUT_DTMF_2: return "SOUT_DTMF_2"; + case SOUT_DTMF_3: return "SOUT_DTMF_3"; + case SOUT_DTMF_4: return "SOUT_DTMF_4"; + case SOUT_DTMF_5: return "SOUT_DTMF_5"; + case SOUT_DTMF_6: return "SOUT_DTMF_6"; + case SOUT_DTMF_7: return "SOUT_DTMF_7"; + case SOUT_DTMF_8: return "SOUT_DTMF_8"; + case SOUT_DTMF_9: return "SOUT_DTMF_9"; + case SOUT_DTMF_A: return "SOUT_DTMF_A"; + case SOUT_DTMF_B: return "SOUT_DTMF_B"; + case SOUT_DTMF_C: return "SOUT_DTMF_C"; + case SOUT_DTMF_D: return "SOUT_DTMF_D"; + case SOUT_DTMF_STAR: return "SOUT_DTMF_STAR"; + case SOUT_DTMF_POUND: return "SOUT_DTMF_POUND"; + + /* System 5/6/7 Section */ + case SIN_SYSTEM5_2400: return "SIN_SYSTEM5_2400"; + case SIN_SYSTEM5_2600: return "SIN_SYSTEM5_2600"; + case SIN_SYSTEM5_2400_2600: return "SIN_SYSTEM5_2400_2600"; + case SIN_SYSTEM7_2000: return "SIN_SYSTEM7_2000"; + case SIN_SYSTEM7_1780: return "SIN_SYSTEM7_1780"; + + default: return "INVALID TONE ID!"; + } +} +#endif + +static unsigned char wanec_ConvertToneId(UINT32 f_ulToneId, unsigned char *ec_dtmf_port) +{ + switch (f_ulToneId){ + /* DTMF Section */ + case ROUT_DTMF_0: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '0'; + case ROUT_DTMF_1: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '1'; + case ROUT_DTMF_2: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '2'; + case ROUT_DTMF_3: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '3'; + case ROUT_DTMF_4: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '4'; + case ROUT_DTMF_5: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '5'; + case ROUT_DTMF_6: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '6'; + case ROUT_DTMF_7: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '7'; + case ROUT_DTMF_8: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '8'; + case ROUT_DTMF_9: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '9'; + case ROUT_DTMF_A: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'A'; + case ROUT_DTMF_B: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'B'; + case ROUT_DTMF_C: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'C'; + case ROUT_DTMF_D: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'D'; + case ROUT_DTMF_STAR: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '*'; + case ROUT_DTMF_POUND: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '#'; + case SOUT_DTMF_0: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '0'; + case SOUT_DTMF_1: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '1'; + case SOUT_DTMF_2: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '2'; + case SOUT_DTMF_3: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '3'; + case SOUT_DTMF_4: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '4'; + case SOUT_DTMF_5: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '5'; + case SOUT_DTMF_6: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '6'; + case SOUT_DTMF_7: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '7'; + case SOUT_DTMF_8: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '8'; + case SOUT_DTMF_9: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '9'; + case SOUT_DTMF_A: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'A'; + case SOUT_DTMF_B: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'B'; + case SOUT_DTMF_C: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'C'; + case SOUT_DTMF_D: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'D'; + case SOUT_DTMF_STAR: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '*'; + case SOUT_DTMF_POUND: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '#'; + } + return 0x00000000; +} + +#if 1 +//#if defined(WAN_DEBUG_HWEC) +static CHAR* wanec_ToneType2Str(UINT32 f_ulToneType) +{ + switch (f_ulToneType){ + case cOCT6100_TONE_PRESENT: return "cOCT6100_TONE_PRESENT"; + case cOCT6100_TONE_STOP: return "cOCT6100_TONE_STOP"; + default: return "INVALID TONE TYPE!"; + } +} +#endif +static unsigned char wanec_ConvertToneType(UINT32 f_ulToneType) +{ + switch (f_ulToneType){ + case cOCT6100_TONE_PRESENT: return WAN_EC_TONE_PRESENT; + case cOCT6100_TONE_STOP: return WAN_EC_TONE_STOP; + } + return 0x00; +} + + +/* +** wanec_EventTone() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ +int wanec_EventTone(wan_ec_t *ec, int verbose) +{ + tOCT6100_EVENT_GET_TONE f_GetToneEvent; + tOCT6100_TONE_EVENT ToneEvent[32]; + UINT32 ulResult; + wan_ec_dev_t *ec_dev; + sdla_t *card; + UINT32 i; + int ec_chan,fe_chan; + + PRINT1(verbose, "%s: Getting Tone events ...\n", + ec->name); + Oct6100EventGetToneDef( &f_GetToneEvent ); + f_GetToneEvent.fResetBufs = FALSE; + f_GetToneEvent.ulMaxToneEvent = 32; + f_GetToneEvent.pToneEvent = ToneEvent; + ulResult = Oct6100EventGetTone( + ec->pChipInstance, + &f_GetToneEvent); + if ( ulResult != cOCT6100_ERR_OK ){ + if ( ulResult != cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY ){ + PRINT1(verbose, "%s: There are not tone events!\n", + ec->name); + return 0; + } + DEBUG_EVENT( + "ERROR: %s: Failed to get tone events (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* No dtmf tone event returned */ + if (!f_GetToneEvent.ulNumValidToneEvent) return 0; + + for(i = 0; i < f_GetToneEvent.ulNumValidToneEvent; i++){ + ec_chan = wanec_hndl2ec_channel(ec, ToneEvent[i].ulChannelHndl); + ec_dev = ec->pEcDevMap[ec_chan]; + fe_chan = wanec_ec2fe_channel(ec, ec_chan, &ec_dev); + if (ec_dev == NULL || ec_dev->card == NULL){ + DEBUG_EVENT( + "%s: Internal Error: Failed to find fe channel (ec_chan=%d)\n", + ec->name, ec_chan); + continue; + } + + PRINT1(verbose, + "%s: Tone event %s %s on fe_chan=%d ec_chan=%d\n", + ec_dev->devname, + wanec_ToneId2Str(ToneEvent[i].ulToneDetected), + wanec_ToneType2Str(f_GetToneEvent.pToneEvent[i].ulEventType), + fe_chan, ec_chan); + + card = (sdla_t*)ec_dev->card; + if (card->wandev.event_callback.dtmf){ + wan_event_t event; + unsigned char dtmf_port = WAN_EC_CHANNEL_PORT_ROUT, dtmf_type; + + event.type = WAN_EVENT_EC_DTMF; + event.channel = fe_chan; + event.digit = wanec_ConvertToneId( + ToneEvent[i].ulToneDetected, + &dtmf_port); + dtmf_type = wanec_ConvertToneType(ToneEvent[i].ulEventType); + event.dtmf_type = dtmf_type; + event.dtmf_port = dtmf_port; + card->wandev.event_callback.dtmf(card, &event); + } + } + + /* Return 1 if more dtmf event are present, otherwise - 0 */ + return (f_GetToneEvent.fMoreEvents == TRUE) ? 1 : 0; +} + +/* +** wanec_ISR() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ +int wanec_ISR(wan_ec_t *ec, int verbose) +{ + UINT32 ulResult; + int ret = 0; + + WAN_ASSERT(ec == NULL); + + Oct6100InterruptServiceRoutineDef(&ec->f_InterruptFlag); + + ulResult = Oct6100InterruptServiceRoutine( + ec->pChipInstance, + &ec->f_InterruptFlag ); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to execute interrupt Service Routine (err=%08X)!\n", + ec->name, + ulResult); + return -EINVAL; + } + /* Critical errors */ + if (ec->f_InterruptFlag.fFatalGeneral == TRUE){ + DEBUG_EVENT( + "%s: An internal fatal chip error detected (0x%X)!\n", + ec->name, + ec->f_InterruptFlag.ulFatalGeneralFlags); + } + if (ec->f_InterruptFlag.fFatalReadTimeout == TRUE){ + DEBUG_EVENT( + "%s: A read to the external memory has failed!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorRefreshTooLate == TRUE){ + DEBUG_EVENT( + "%s: Error Refresh Too Late!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorPllJitter == TRUE){ + DEBUG_EVENT( + "%s: Error Pll Jitter\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100OutOfSync == TRUE){ + DEBUG_EVENT( + "%s: The H100 slave has lost its framing on the bus!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100ClkA == TRUE){ + DEBUG_EVENT( + "%s: The CT_C8_A clock behavior does not conform to the H.100 spec!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100FrameA == TRUE){ + DEBUG_EVENT( + "%s: The CT_FRAME_A clock behavior does not comform to the H.100 spec!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100ClkB == TRUE){ + DEBUG_EVENT( + "%s: The CT_C8_B clock is not running a 16.384 MHz!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorOverflowToneEvents == TRUE){ + DEBUG_EVENT( + "%s: Error: Tone Event buffer has overflowed\n", + ec->name); + } + if (ec->f_InterruptFlag.fToneEventsPending == TRUE){ + PRINT1(verbose, "%s: Tone Event pending....\n", + ec->name); + ret = wanec_EventTone(ec, verbose); + } + if (ec->f_InterruptFlag.fBufferPlayoutEventsPending == TRUE){ + PRINT1(verbose, + "%s: Buffer Playout Events Pending\n", + ec->name); + } + if (ec->f_InterruptFlag.fApiSynch == TRUE){ + PRINT1(verbose, + "%s: The chip interrupted the API for purpose of maintaining sync!\n", + ec->name); + } + return ret; +} + +int wanec_DebugChannel(wan_ec_dev_t *ec_dev, INT channel, int verbose) +{ + wan_ec_t *ec = NULL; + tOCT6100_DEBUG_SELECT_CHANNEL DebugSelectChannel; + wanec_chan_stats_t chan_stats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + /* Verify Echo Canceller Channel operation mode */ + ulResult = wanec_ChannelStats(ec_dev, channel, &chan_stats, 0); + if (chan_stats.f_ChannelStats.ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Channel %d operation mode (POWER DOWN)!\n", + ec_dev->name, channel); + return -EINVAL; + } + + if (ec_dev->ec->ulDebugChannelHndl != cOCT6100_INVALID_HANDLE){ + DEBUG_EVENT( + "ERROR: %s: Echo Canceller daemon can monitor only one ec channel (%d)!\n", + ec_dev->name, channel); + return -EINVAL; + } + Oct6100DebugSelectChannelDef( &DebugSelectChannel ); + + PRINT1(verbose, "%s: Select ec channel %d for monitoring...\n", + ec_dev->name, + channel); + /* Set selected debug channel */ + ec->DebugChannel = channel; + ec->ulDebugChannelHndl = ec->pEchoChannelHndl[channel]; + DebugSelectChannel.ulChannelHndl= ec->pEchoChannelHndl[channel]; + + /* Select Debug channel */ + ulResult = Oct6100DebugSelectChannel( + ec->pChipInstance, + &DebugSelectChannel ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to select debug ec channel %d for monitoring (err=0x%X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_DebugGetData(wan_ec_dev_t *ec_dev, wanec_chan_monitor_t *chan_monitor, int verbose) +{ + wan_ec_t *ec = NULL; + tOCT6100_DEBUG_GET_DATA fDebugGetData; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + if (ec->ulDebugChannelHndl == cOCT6100_INVALID_HANDLE){ + PRINT( +#if !defined(__WINDOWS__) + verbose, +#endif + "ERROR: %s: No Debug channel was selected!\n", + ec->name); + return -EINVAL; + } + + Oct6100DebugGetDataDef( &fDebugGetData ); + + PRINT1(verbose, + "%s: Retrieves debug data for ec channel %d...\n", + ec->name, + ec->DebugChannel); + + memset(&chan_monitor->data[0], 0, + sizeof(UINT8) * (MAX_MONITOR_DATA_LEN+1)); + /* Set selected debug channel */ + fDebugGetData.ulGetDataMode = ec->ulDebugDataMode; + fDebugGetData.ulMaxBytes = chan_monitor->max_len; + fDebugGetData.pbyData = &chan_monitor->data[0]; + + /* Select Debug channel */ + ulResult = Oct6100DebugGetData( + ec->pChipInstance, + &fDebugGetData ); + if (ulResult != cOCT6100_ERR_OK){ + PRINT( +#if !defined(__WINDOWS__) + verbose, +#endif + "ERROR: %s: Failed to get debug data for ec channel %d (err=0x%X)\n", + ec->name, + ec->DebugChannel, + ulResult); + return -EINVAL; + } + chan_monitor->data_len = fDebugGetData.ulValidNumBytes; + chan_monitor->remain_len = fDebugGetData.ulRemainingNumBytes; + chan_monitor->channel = ec->DebugChannel; + + if (fDebugGetData.ulRemainingNumBytes == 0){ + /* Last read */ + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + } + + return 0; +} + +static PUINT32 wanec_search_bufferindex(wan_ec_t *ec, UINT32 index) +{ + UINT32 i = 0; + + while(i < ec->f_OpenChip.ulMaxPlayoutBuffers){ + if (ec->pToneBufferIndexes[i] == index){ + return &ec->pToneBufferIndexes[i]; + } + i++; + } + return NULL; +} + +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose) +{ + wan_ec_t *ec; + tOCT6100_BUFFER_LOAD BufferLoad; + UINT32 size, ulResult; + PUINT8 pData = NULL; + int err; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Loading Tone buffer (%s) into OCT6100 Chip ...\n", + ec->name, tone_config->tone); + size = tone_config->size * sizeof(INT8); + pData = wan_vmalloc(size); + if (pData == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed to allocate memory for tone buffer!\n", + ec->name); + return -EINVAL; + } + err = WAN_COPY_FROM_USER(pData, tone_config->data, size); + if (err){ + DEBUG_EVENT( + "ERROR: %s: Failed to copy EC tone buffer from user space [%s:%d]!\n", + ec->name, + __FUNCTION__,__LINE__); + wan_vfree(pData); + return -EINVAL; + } + + Oct6100BufferPlayoutLoadDef( &BufferLoad ); + BufferLoad.pulBufferIndex = wanec_search_bufferindex(ec, cOCT6100_INVALID_VALUE); + /* FIXME: Can be alaw/mulaw */ + BufferLoad.ulBufferPcmLaw = + (ec_dev->fe_tdmv_law == WAN_TDMV_MULAW) ? + cOCT6100_PCM_U_LAW : + cOCT6100_PCM_A_LAW; + BufferLoad.pbyBufferPattern = pData; + BufferLoad.ulBufferSize = size; + ulResult = Oct6100BufferPlayoutLoad ( + ec->pChipInstance, + &BufferLoad); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult == cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN){ + goto buffer_load_done; + } + DEBUG_EVENT( + "%s: ERROR: Failed to load tone buffer into EC Chip (err=0x%X)\n", + ec->name, ulResult); + wan_vfree(pData); + return -EINVAL; + } +buffer_load_done: + wan_vfree(pData); + tone_config->buffer_index = *BufferLoad.pulBufferIndex; + PRINT1(verbose, + "%s: Current tone index is %d\n", + ec->name, tone_config->buffer_index); + return 0; +} + +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose) +{ + wan_ec_t *ec; + tOCT6100_BUFFER_UNLOAD BufferUnload; + PUINT32 pBufferIndex = NULL; + UINT32 index = 0, ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Unloading Tone buffer from EC chip ...\n", + ec->name); + +try_next_index: + Oct6100BufferPlayoutUnloadDef( &BufferUnload ); + if (tone_config->buffer_index != cOCT6100_INVALID_VALUE){ + pBufferIndex = wanec_search_bufferindex(ec, tone_config->buffer_index); + if (pBufferIndex == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid tone buffer index %X!\n", + ec->name, tone_config->buffer_index); + return EINVAL; + } + }else{ + if (index > ec->f_OpenChip.ulMaxPlayoutBuffers){ + goto buffer_unload_done; + } + if (ec->pToneBufferIndexes[index] == cOCT6100_INVALID_VALUE){ + index++; + goto try_next_index; + } + pBufferIndex = &ec->pToneBufferIndexes[index]; + } + + BufferUnload.ulBufferIndex = *pBufferIndex; + ulResult = Oct6100BufferPlayoutUnload ( + ec->pChipInstance, + &BufferUnload); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult == cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN){ + goto buffer_unload_done; + } + DEBUG_EVENT( + "ERROR: %s: Failed to unload tone buffer from EC Chip (err=0x%X)!\n", + ec->name, (unsigned int)ulResult); + return EINVAL; + } + *pBufferIndex = 0; + if (!tone_config->buffer_index){ + index++; + goto try_next_index; + } + +buffer_unload_done: + return 0; +} + +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_ADD BufferPlayoutAdd; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Add Tone buffer to ec channel %d...\n", + ec->name, channel); + if (playout->index == cOCT6100_INVALID_VALUE|| + wanec_search_bufferindex(ec, playout->index) == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid playout buffer index for ec channel %d!\n", + ec->name, channel); + return -EINVAL; + } + Oct6100BufferPlayoutAddDef( &BufferPlayoutAdd ); + BufferPlayoutAdd.fRepeat = playout->repeat; + BufferPlayoutAdd.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + BufferPlayoutAdd.ulMixingMode = cOCT6100_MIXING_MUTE; + BufferPlayoutAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutAdd.ulBufferIndex = playout->index; + BufferPlayoutAdd.ulDuration = (playout->duration) ? + playout->duration : 5000; + BufferPlayoutAdd.ulBufferLength = (playout->buffer_length) ? + playout->buffer_length : + cOCT6100_AUTO_SELECT; + ulResult = Oct6100BufferPlayoutAdd( + ec->pChipInstance, + &BufferPlayoutAdd); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to add playout buffer to ec channel %d (err=%08X)\n", + ec->name, channel, ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_START BufferPlayoutStart; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Active playout buffer on ec channel %d...\n", + ec->name, + channel); + Oct6100BufferPlayoutStartDef( &BufferPlayoutStart ); + BufferPlayoutStart.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutStart.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100BufferPlayoutStart( + ec->pChipInstance, + &BufferPlayoutStart); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to active playout buffer on ec channel %d (err=%08X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Deactive playout buffer on ec channel %d...\n", + ec->name, + channel); + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + BufferPlayoutStop.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100BufferPlayoutStop( + ec->pChipInstance, + &BufferPlayoutStop); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to deactive playout buffer on ec channel %d (err=%08X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + + +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_OPEN ConfBridgeOpen; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Opening Conference Bridge...\n", ec->name); + + if (ec->confbridges_no >= ec->f_OpenChip.ulMaxConfBridges){ + DEBUG_EVENT( + "ERROR: %s: Trying to open too many conference bridges (%d:%d)\n", + ec->name, + ec->confbridges_no, + ec->f_OpenChip.ulMaxConfBridges); + return -EINVAL; + } + + Oct6100ConfBridgeOpenDef( &ConfBridgeOpen ); + ConfBridgeOpen.pulConfBridgeHndl = &confbridge->ulHndl; + ConfBridgeOpen.fFlexibleConferencing = FALSE; + ulResult = Oct6100ConfBridgeOpen( + ec->pChipInstance, + &ConfBridgeOpen); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to open new conference bridge (err=%08X)\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Closing Conference Bridge...\n", ec->name); + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + ConfBridgeClose.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeClose( + ec->pChipInstance, + &ConfBridgeClose); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to close conference bridge (%X, err=%08X)\n", + ec->name, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanAdd(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_ADD ConfBridgeChanAdd; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Add channel %d to Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanAddDef( &ConfBridgeChanAdd ); + ConfBridgeChanAdd.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanAdd( + ec->pChipInstance, + &ConfBridgeChanAdd); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to add channel %d to conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanRemove(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE ConfBridgeChanRemove; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Remove channel %d from Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanRemoveDef( &ConfBridgeChanRemove ); + ConfBridgeChanRemove.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanRemove.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanRemove( + ec->pChipInstance, + &ConfBridgeChanRemove); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to remove channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_MUTE ConfBridgeChanMute; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Mute channel %d on a conference bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanMuteDef( &ConfBridgeChanMute ); + ConfBridgeChanMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanMute( + ec->pChipInstance, + &ConfBridgeChanMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute channel %d on a conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanUnMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_UNMUTE ConfBridgeChanUnMute; + UINT32 ulResult; + + PRINT1(verbose, + "%s: UnMute channel %d on a Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanUnMuteDef( &ConfBridgeChanUnMute ); + ConfBridgeChanUnMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanUnMute( + ec->pChipInstance, + &ConfBridgeChanUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to unmute channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeDominantSpeakerSet(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int enable, int verbose) +{ + tOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET ConfBridgeDominantSpeaker; + UINT32 ulResult; + + PRINT1(verbose, + "%s: %s Dominant speaker (channel %d) to a Conference Bridge %X...\n", + ec->name, + (enable) ? "Enable":"Disable", + channel, + confbridge->ulHndl); + + Oct6100ConfBridgeDominantSpeakerSetDef( &ConfBridgeDominantSpeaker ); + ConfBridgeDominantSpeaker.ulConfBridgeHndl = confbridge->ulHndl; + if (enable){ + ConfBridgeDominantSpeaker.ulChannelHndl = ec->pEchoChannelHndl[channel]; + }else{ + ConfBridgeDominantSpeaker.ulChannelHndl = cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL; + } + ulResult = Oct6100ConfBridgeDominantSpeakerSet( + ec->pChipInstance, + &ConfBridgeDominantSpeaker); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to %s dominant speaker to conference bridge (%X, err=%08X)\n", + ec->name, + (enable) ? "enable" : "disable", + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + + +int wanec_ConfBridgeMaskChange(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, UINT32 mask, int verbose) +{ + tOCT6100_CONF_BRIDGE_MASK_CHANGE ConfBridgeMaskChange; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Changing the listener (channel=%d) mask of bridge participant (%d)...\n", + ec->name, + channel, confbridge->ulHndl); + + Oct6100ConfBridgeMaskChangeDef( &ConfBridgeMaskChange ); + ConfBridgeMaskChange.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ConfBridgeMaskChange.ulNewListenerMask = mask; + ulResult = Oct6100ConfBridgeMaskChange( + ec->pChipInstance, + &ConfBridgeMaskChange); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to change the listener mask of bridge participant %d (err=%X)!\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeGetStats(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_STATS ConfBridgeStats; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Getting bridge statistics %X...\n", + ec->name, confbridge->ulHndl); + + Oct6100ConfBridgeGetStatsDef( &ConfBridgeStats ); + ConfBridgeStats.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeGetStats( + ec->pChipInstance, + &ConfBridgeStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to get conference bridge statistics (err=%X)!\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + +/*===========================================================================*\ + Oct6100Read +\*===========================================================================*/ + +static int +wan_ec_read(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data) +{ + u32 data; + wan_ec_read_internal_dword(ec_dev, read_addr, &data); + *read_data = (u16)(data & 0xFFFF); + return 0; +} + +/*===========================================================================*\ + Oct6100Write +\*===========================================================================*/ + +static int +wan_ec_write(wan_ec_dev_t *ec_dev, u32 write_addr, u32 write_data) +{ + return wan_ec_write_internal_dword(ec_dev, write_addr, write_data); +} + + +/*===========================================================================*\ + Oct6100WriteSequenceSub +\*===========================================================================*/ +static u32 +wan_ec_write_seq(wan_ec_dev_t *ec_dev, u32 write_addr, u16 write_data) +{ + u32 ulResult; + u32 ulData; + u16 usData; + u32 ulWordAddress; + u32 i; + + /* Create the word address from the provided byte address. */ + ulWordAddress = write_addr >> 1; + + /* 16-bit indirect access. */ + + /* First write to the address indirection registers. */ + ulData = ( ulWordAddress >> 19 ) & 0x1FFF; + ulResult = wan_ec_write( ec_dev, 0x8, ulData ); + if (ulResult) + return ulResult; + + ulData = ( ulWordAddress >> 3 ) & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0xA, ulData ); + if (ulResult) + return ulResult; + + /* Next, write data word to read/write data registers. */ + ulData = write_data & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0x4, ulData ); + if ( ulResult ) + return ulResult; + + + /* Write the parities and write enables, as well as last three bits + ** of wadd and request the write access. */ + ulData = ( ( 0x0 & 0x3 ) << 14 ) | ( ( 0x3 & 0x3 ) << 12 ) | ( ( ulWordAddress & 0x7 ) << 9 ) | 0x0100; + ulResult = wan_ec_write( ec_dev, 0x0, ulData ); + if ( ulResult ) + return ulResult; + + /* Keep polling register contol0 for the access_req bit to go low. */ + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) + { + ulResult = wan_ec_read( ec_dev, 0, &usData ); + if ( ulResult ) + return ulResult; + + if ( ( ( usData >> 8 ) & 0x1 ) == 0x0 ) + break; + } + + if ( i == WANEC_READ_LIMIT ){ + DEBUG_EVENT("%s: EC write command reached limit!\n", + ec_dev->name); + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; + } + return 0; +} + + +/*===========================================================================*\ + HandleReqWriteOct6100 +\*===========================================================================*/ +u32 wanec_req_write(void *arg, u32 write_addr, u16 write_data) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 ulResult; + + DEBUG_TEST("%s: EC WRITE API addr=%X data=%X\n", + ec_dev->ec->name, write_addr, write_data); + ulResult = wan_ec_write_seq(ec_dev, write_addr, write_data); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + write_addr, + write_data); + } + return ulResult; +} + + +/*===========================================================================*\ + HandleReqWriteSmearOct6100 +\*===========================================================================*/ +u32 wanec_req_write_smear(void *arg, u32 addr, u16 data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + + WAN_ASSERT(ec_dev == NULL); + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_write_seq(ec_dev, addr + (i*2), data); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + addr + (i*2), + data); + break; + } + } + return ulResult; +} + + +/*===========================================================================*\ + HandleReqWriteBurstOct6100 +\*===========================================================================*/ +u32 wanec_req_write_burst(void *arg, u32 addr, u16 *data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + + WAN_ASSERT(ec_dev == NULL); + + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_write_seq(ec_dev, addr + (i * 2), data[i]); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + addr + (i*2), + data[i]); + break; + } + } + return ulResult; +} + + +/*===========================================================================*\ + Oct6100ReadSequenceSub +\*===========================================================================*/ +static u32 +wan_ec_read_seq(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data, u32 read_len) +{ + u32 ulResult; + u32 ulData; + u32 ulWordAddress; + u32 ulReadBurstLength; + u16 usData; + u32 i; + + /* Create the word address from the provided byte address. */ + ulWordAddress = read_addr >> 1; + + /* Indirect accesses. */ + + /* First write to the address indirection registers. */ + ulData = ( ulWordAddress >> 19 ) & 0x1FFF; + ulResult = wan_ec_write( ec_dev, 0x8, ulData ); + if (ulResult) + return ulResult; + + ulData = ( ulWordAddress >> 3 ) & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0xA, ulData ); + if (ulResult) + return ulResult; + + /* Request access. */ + if ( read_len >= 128 ) + { + ulData = 0x100 | ( ( ulWordAddress & 0x7 ) << 9); + ulReadBurstLength = 0; + } + else + { + ulData = 0x100 | ( ( ulWordAddress & 0x7 ) << 9) | read_len; + ulReadBurstLength = read_len; + } + ulResult = wan_ec_write( ec_dev, 0x0, ulData ); + if (ulResult) + return ulResult; + + /* Keep polling register contol0 for the access_req bit to go low. */ + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) + { + ulResult = wan_ec_read( ec_dev, 0x0, &usData ); + if (ulResult) + return ulResult; + + if ( ( ( usData >> 8 ) & 0x1 ) == 0x0 ) + break; + } + if ( i == WANEC_READ_LIMIT ){ + DEBUG_EVENT("%s: EC read command reached limit!\n", + ec_dev->name); + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; + } + + if ( ( usData & 0xFF ) == 0x1 ) + { + i = 0; + } + + /* Retrieve read data. */ + ulResult = wan_ec_read( ec_dev, 0x4, &usData ); + if (ulResult) + return ulResult; + + if ( ( usData & 0xFF ) == 0x1 ) + { + i = 0; + } + + *read_data = usData; + return 0; +} + +u32 wanec_req_read(void *arg, u32 addr, u16 *data) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + DEBUG_TEST("%s: EC READ API addr=%X data=????\n", + ec_dev->ec->name, addr); + ulResult = wan_ec_read_seq( + ec_dev, + addr, + data, + 1); + if (ulResult){ + DEBUG_EVENT("%s: Failed to read data from addr %08X\n", + ec_dev->name, + addr); + if (ec_dev->ec){ + wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->ec->critical); + } + } + DEBUG_TEST("%s: EC READ API addr=%X data=%X\n", + ec_dev->ec->name, + addr, *data); + return ulResult; +} + +u32 wanec_req_read_burst(void *arg, u32 addr, u16 *data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + u16 read_data; + + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_read_seq(ec_dev, addr, &read_data, 1); + if (ulResult){ + DEBUG_EVENT("%s: Failed to read from addr %X\n", + ec_dev->name, + addr); + if (ec_dev->ec){ + wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->ec->critical); + } + break; + } + data[i] = (u16)read_data; + addr += 2; + } + return ulResult; +} diff --git a/patches/kdrivers/wanec/.#wanec_cmd.c.1.62 b/patches/kdrivers/wanec/.#wanec_cmd.c.1.62 new file mode 100644 index 0000000..16bccc2 --- /dev/null +++ b/patches/kdrivers/wanec/.#wanec_cmd.c.1.62 @@ -0,0 +1,2332 @@ +/************************************************************* + * wanec_cmd.c WANPIPE Echo Canceller Layer (WANEC_LIP) + * + * + * + * =========================================================== + * + * May 10 2006 Alex Feldman Initial Version + * + * March 19, 2006 Alex Feldman Enable Sout Adaptive Noise + * Reduction for all channel by + * default. + * + * January 9, 2008 David Rokhvarg + * Added support for Sangoma MS Windows Driver + * + */ + + +/*============================================================= + * Includes + */ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +#elif defined(__LINUX__) +# include +# include +# include +# include +#elif defined(__WINDOWS__) +# include +# include +# include +#endif + +int verbose; + +#include "oct6100_api.h" +#include "oct6100_version.h" + +#include "wanec_iface.h" +#include "wanec_tones.h" + +/*============================================================= + * Definitions + */ +#define WANEC_MAX_PORT_RANGE 32 +#define WANEC_MAX_BRI_PORT_RANGE 2 +#define WANEC_READ_LIMIT 0x10000 + +#define WANEC_MAX_CONFBRIDGE_DEF 32 +#define WANEC_MAC_PLAYOUT_BUFFERS 20 + +#define WANEC_MAX_TONEEVENTS 8 +#define WANEC_MAX_PLAYOUTEVENTS 8 + +/*============================================================= + * Global Parameters + */ +UINT32 DetectedSoutToneNumbers[WAN_NUM_DTMF_TONES] = +{ + SOUT_DTMF_0, + SOUT_DTMF_1, + SOUT_DTMF_2, + SOUT_DTMF_3, + SOUT_DTMF_4, + SOUT_DTMF_5, + SOUT_DTMF_6, + SOUT_DTMF_7, + SOUT_DTMF_8, + SOUT_DTMF_9, + SOUT_DTMF_A, + SOUT_DTMF_B, + SOUT_DTMF_C, + SOUT_DTMF_D, + SOUT_DTMF_STAR, + SOUT_DTMF_POUND, +}; +UINT32 DetectedRoutToneNumbers[WAN_NUM_DTMF_TONES] = +{ + ROUT_DTMF_0, + ROUT_DTMF_1, + ROUT_DTMF_2, + ROUT_DTMF_3, + ROUT_DTMF_4, + ROUT_DTMF_5, + ROUT_DTMF_6, + ROUT_DTMF_7, + ROUT_DTMF_8, + ROUT_DTMF_9, + ROUT_DTMF_A, + ROUT_DTMF_B, + ROUT_DTMF_C, + ROUT_DTMF_D, + ROUT_DTMF_STAR, + ROUT_DTMF_POUND +}; + +/*============================================================= + * Function prototype +*/ + +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose); +int wanec_ChipOpen(wan_ec_dev_t*, int); +int wanec_ChipClose(wan_ec_dev_t*, int verbose); +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose); + +int wanec_ChannelOpen(wan_ec_dev_t*, int); +int wanec_ChannelClose(wan_ec_dev_t*, int); +int wanec_ChannelModifyOpmode(wan_ec_dev_t*, INT, UINT32, int verbose); +int wanec_ChannelModifyCustom(wan_ec_dev_t*, INT, wanec_chan_custom_t*, int verbose); +int wanec_ChannelStats(wan_ec_dev_t*, INT channel, wanec_chan_stats_t *chan_stats, int reset); + +int wanec_ChannelMute(wan_ec_dev_t*, INT channel, wanec_chan_mute_t*, int); +int wanec_ChannelUnMute(wan_ec_dev_t*, INT channel, wanec_chan_mute_t*, int); + +int wanec_TonesEnable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t*, int verbose); +int wanec_TonesDisable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t*, int verbose); + +int wanec_DebugChannel(wan_ec_dev_t*, INT channel, int verbose); +int wanec_DebugGetData(wan_ec_dev_t*, wanec_chan_monitor_t *chan_monitor, int verbose); + +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose); +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose); +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); + +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); +int wanec_ConfBridgeChanAdd(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanRemove(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanUnMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeDominantSpeakerSet(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int enable, int verbose); +int wanec_ConfBridgeMaskChange(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, UINT32 mask, int verbose); +int wanec_ConfBridgeGetStats(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); + +int wanec_ToneEvent(wan_ec_t *ec, int verbose); +int wanec_PlayoutEvent(wan_ec_t *ec, int verbose); +int wanec_ISR(wan_ec_t *ec, int verbose); + +int wanec_fe2ec_channel(wan_ec_dev_t*, int); +static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl); +static int wanec_ec2fe_channel(wan_ec_t*, int, wan_ec_dev_t**); + +extern int wanec_ChipParam(wan_ec_t*,tPOCT6100_CHIP_OPEN, wan_custom_conf_t*, int); +extern int wanec_ChanParam(wan_ec_t*,tPOCT6100_CHANNEL_MODIFY, wan_custom_conf_t*, int); +extern int wanec_ChanParamList(wan_ec_t *ec); + +u32 wanec_req_write(void*, u32 write_addr, u16 write_data); +u32 wanec_req_write_smear(void*, u32 addr, u16 data, u32 len); +u32 wanec_req_write_burst(void*, u32 addr, u16 *data, u32 len); +u32 wanec_req_read(void*, u32 addr, u16 *data); +u32 wanec_req_read_burst(void*, u32 addr, u16 *data, u32 len); + +extern int wan_ec_write_internal_dword(wan_ec_dev_t *ec_dev, u32 addr1, u32 data); +extern int wan_ec_read_internal_dword(wan_ec_dev_t *ec_dev, u32 addr1, u32 *data); + +/*============================================================= + * Function definition +*/ +static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl) +{ + int channel = 0; + + for(channel = 0; channel < ec->max_channels; channel++){ + if (ec->pEchoChannelHndl[channel] == ChannelHndl){ + return channel; + } + } + return 0; +} +int wanec_fe2ec_channel(wan_ec_dev_t *ec_dev, int fe_channel) +{ + int ec_channel = 0; + + if (ec_dev->fe_media == WAN_MEDIA_BRI){ + if (ec_dev->fe_lineno >= 12){ + ec_channel = WANEC_MAX_PORT_RANGE; + } + ec_channel += (ec_dev->fe_lineno * WANEC_MAX_BRI_PORT_RANGE + (fe_channel-1)); + }else if (ec_dev->fe_media == WAN_MEDIA_T1 || ec_dev->fe_media == WAN_MEDIA_FXOFXS){ + ec_channel = ec_dev->fe_lineno * WANEC_MAX_PORT_RANGE + (fe_channel-1); + }else{ + /*ec_channel = ec_dev->fe_lineno * ec_dev->fe_max_chans + channel;*/ + ec_channel = ec_dev->fe_lineno * WANEC_MAX_PORT_RANGE + fe_channel; + } + return ec_channel; +} + +static int wanec_ec2fe_channel(wan_ec_t *ec, int ec_chan, wan_ec_dev_t **ec_dev) +{ + wan_ec_dev_t *ec_dev_tmp; + int fe_chan; + + ec_dev_tmp = ec->pEcDevMap[ec_chan]; + if (ec_dev_tmp == NULL) return 0; + + fe_chan = ec_chan % WANEC_MAX_PORT_RANGE; + if (ec_dev_tmp->fe_media == WAN_MEDIA_BRI){ + fe_chan = fe_chan % WANEC_MAX_BRI_PORT_RANGE; + fe_chan++; + }else{ + if (ec_dev_tmp->fe_media == WAN_MEDIA_T1 || + ec_dev_tmp->fe_media == WAN_MEDIA_FXOFXS){ + fe_chan++; + } + } + if (ec_dev && *ec_dev) *ec_dev = ec_dev_tmp; + return fe_chan; +} + + +/****************************************************************** +** +** +*******************************************************************/ +tOCT6100_CHIP_IMAGE_INFO f_ChipImageInfo; +#if 0 +tOCT6100_GET_HW_REVISION f_Revision; +#endif +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHIP_STATS f_ChipStats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + if (chip_stats){ + PRINT2(verbose, "%s: Reading chip statistics...\n", + ec->name); + } + Oct6100ChipGetStatsDef( &f_ChipStats ); + f_ChipStats.fResetChipStats = reset; + ulResult = Oct6100ChipGetStats( + ec->pChipInstance, + &f_ChipStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading chip statistics...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return -EINVAL; + } + if (chip_stats){ + memcpy( &chip_stats->f_ChipStats, + &f_ChipStats, + sizeof(tOCT6100_CHIP_STATS)); + } + + if (chip_stats){ + PRINT2(verbose, "%s: Reading chip image info...\n", + ec->name); + } + + Oct6100ChipGetImageInfoDef( &f_ChipImageInfo ); + ulResult = Oct6100ChipGetImageInfo( + ec->pChipInstance, + &f_ChipImageInfo); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading chip image info...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return -EINVAL; + } + if (chip_stats){ + if (chip_stats->f_ChipImageInfo){ + int err; + err = WAN_COPY_TO_USER( + &f_ChipImageInfo, + chip_stats->f_ChipImageInfo, + sizeof(tOCT6100_CHIP_IMAGE_INFO)); + if (err){ + DEBUG_EVENT( + "%s: Failed to copy chip image info to user space [%s:%d]!\n", + ec->name, __FUNCTION__,__LINE__); + return -EINVAL; + } + }else{ + PRINT2(verbose, + "%s: Echo Canceller image description:\n%s\n", + ec->name, f_ChipImageInfo.szVersionNumber); + PRINT2(verbose, + "%s: Echo Canceller image build ID\t\t\t%08X\n", + ec->name, f_ChipImageInfo.ulBuildId); + PRINT2(verbose, + "%s: Echo Canceller maximum number of channels\t%d\n", + ec->name, f_ChipImageInfo.ulMaxChannels); +#if 0 + PRINT2(verbose, + "%s: Echo Canceller maximum tail displacement\t\t%d\n", + ec->name, f_ChipImageInfo.ulMaxTailDisplacement); + PRINT2(verbose, + "%s: Echo Canceller per channel tail displacement\t%s\n", + ec->name, + (f_ChipImageInfo.fPerChannelTailDisplacement == TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller per channel tail length\t\t%s\n", + ec->name, + (f_ChipImageInfo.fPerChannelTailLength == TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller maximum tail length\t\t%d\n", + ec->name, f_ChipImageInfo.ulMaxTailLength); + PRINT2(verbose, + "%s: Echo Canceller buffer Playout support\t\t%s\n", + ec->name, + (f_ChipImageInfo.fBufferPlayout == TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller adaptive noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAdaptiveNoiseReduction==TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller SOUT noise bleaching\t\t%s\n", + ec->name, + (f_ChipImageInfo.fSoutNoiseBleaching==TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller ROUT noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fRoutNoiseReduction==TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller ROUT noise reduction level\t\t%s\n", + ec->name, + (f_ChipImageInfo.fRoutNoiseReductionLevel==TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller automatic level control\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAutoLevelControl==TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller acoustic echo cancellation\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAcousticEcho==TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller conferencing\t\t%s\n", + ec->name, + (f_ChipImageInfo.fConferencing==TRUE)?"TRUE":"FALSE"); + PRINT2(verbose, + "%s: Echo Canceller conferencing noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fConferencingNoiseReduction==TRUE)?"TRUE":"FALSE"); +#endif + } + } + if (f_ChipImageInfo.ulMaxChannels < (unsigned int)ec->max_channels){ + ec->max_channels = f_ChipImageInfo.ulMaxChannels-1; + } + +// DEBUG_EVENT(verbose, "%s: Reading hw revision...\n", +// ec->name); +#if 0 + DEBUG_EVENT(verbose, "%s: Reading hw revision...\n", + ec->name); + ec->f_Revision.ulUserChipId = 0; + ec->f_Revision.pProcessContext = &ec->f_Context; + ulResult = Oct6100GetHwRevision(&ec->f_Revision); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading hw revision...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return EINVAL; + } +#endif + return 0; +} + +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose) +{ + tOCT6100_GET_INSTANCE_SIZE InstanceSize; + wan_ec_t *ec; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(config->imageData == NULL); + ec = ec_dev->ec; + + ulResult = Oct6100ChipOpenDef( &ec->f_OpenChip ); + + /*==============================================================*/ + /* Configure clocks */ + + /* upclk oscillator is at 33.33 Mhz */ + ec->f_OpenChip.ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; + + /* mclk will be generated by internal PLL at 133 Mhz */ + ec->f_OpenChip.fEnableMemClkOut = TRUE; +#if 1 + ec->f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ; +#else + ec->f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_125_MHZ; /*125*/ +#endif + + /*==============================================================*/ + + /*==============================================================*/ + /* General parameters */ + + /* Chip ID.*/ + ec->f_OpenChip.ulUserChipId = ec->chip_no; + + /* Set the max number of accesses to 1024 to speed things up */ + ec->f_OpenChip.ulMaxRwAccesses = 1024; + + /* Set the maximums that the chip needs to support for this test */ + ec->f_OpenChip.ulMaxChannels = config->max_channels; + + ec->f_OpenChip.ulMaxBiDirChannels = 0; + ec->f_OpenChip.ulMaxConfBridges = 0; //WANEC_MAX_CONFBRIDGE_DEF; + ec->f_OpenChip.ulMaxPhasingTssts = 0; + ec->f_OpenChip.ulMaxTdmStreams = 32; + ec->f_OpenChip.ulMaxTsiCncts = 2; + + /*==============================================================*/ + + /*==============================================================*/ + /* External Memory Settings */ + + /* Use DDR memory.*/ +#if 1 + ec->f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_SDR; +#else + ec->f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_DDR; +#endif + /* + **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_8MB; + **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_16MB;*/ + ec->f_OpenChip.ulMemoryChipSize = config->memory_chip_size; + ec->f_OpenChip.ulNumMemoryChips = 2; + + ec->f_OpenChip.ulSoftBufferPlayoutEventsBufSize = 2048; + + ec->f_OpenChip.fEnableChannelRecording = TRUE; + +#if defined(ENABLE_ACOUSTICECHO) + ec->f_OpenChip.fEnableAcousticEcho = TRUE; +#endif + +#if defined(ENABLE_PRODBIST) + /* Enable production bist mode */ + ec->f_OpenChip.fEnableProductionBist = TRUE; + ec->f_OpenChip.ulNumProductionBistLoops = 0x1; +#endif + + ec->f_OpenChip.ulMaxPlayoutBuffers = WANEC_MAC_PLAYOUT_BUFFERS; + + ec->f_OpenChip.pbyImageFile = ec->pImageData; + ec->f_OpenChip.ulImageSize = ec->ImageSize; + + /* Assign board index (0). */ + ec->f_Context.ulBoardId = ec->chip_no; + + /* Handle to driver */ + ec->f_Context.ec_dev = ec_dev; + + /* Interface name to driver */ + strlcpy(ec->f_Context.devname, devname, WAN_DRVNAME_SZ); + + ulResult = Oct6100GetInstanceSize(&ec->f_OpenChip, &InstanceSize); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to get EC chip instance size (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* Allocate memory needed for API instance. */ + ec->pChipInstance = + (tPOCT6100_INSTANCE_API)wan_vmalloc(InstanceSize.ulApiInstanceSize); + if (ec->pChipInstance == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed to allocate memory for EC chip (%d bytes)!\n", + ec->name,InstanceSize.ulApiInstanceSize); + return -EINVAL; + } + + /* Open the OCT6100 on the evaluation board. */ + ec->f_OpenChip.pProcessContext = (PVOID)&ec->f_Context; + + /* parse advanced params (global custom configuration) */ + if (ec->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &ec->custom_conf, verbose); + } + /* parse advanced params (command line custom configuration) */ + if (config->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &config->custom_conf, verbose); + } + + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + ec->ulDebugDataMode = config->debug_data_mode; + return 0; +} + +int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + UINT32 ulResult, i = 0; + INT ec_chan = 0; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT2(verbose, + "%s: Opening Echo Canceller Chip ...\n", + ec->name); + if (ec->f_OpenChip.pbyImageFile == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid EC image pointer\n", + ec->name); + return -EINVAL; + } + ulResult = Oct6100ChipOpen( + ec->pChipInstance, /* API instance memory. */ + &ec->f_OpenChip ); /* Open chip structure. */ + if ( ulResult != cOCT6100_ERR_OK ){ + if (ec->imageLast == WANOPT_YES || + ulResult != cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS){ + DEBUG_EVENT( + "ERROR: %s: Failed to open Echo Canceller Chip (err=0x%X)\n", + ec->name, ulResult); + } + return -EINVAL; + } + + if (wanec_ChipStats(ec_dev, NULL, TRUE, verbose)){ + DEBUG_EVENT( + "ERROR: %s: Failed to read EC chip statistics!\n", + ec->name); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + + ec->pToneBufferIndexes = + wan_malloc(sizeof(UINT32) * ec->f_OpenChip.ulMaxPlayoutBuffers); + if (ec->pToneBufferIndexes == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for playout handles!\n", + ec->name); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + i = 0; + while(i < ec->f_OpenChip.ulMaxPlayoutBuffers){ + ec->pToneBufferIndexes[i++] = cOCT6100_INVALID_VALUE; + } + ec->pEchoChannelHndl = + wan_malloc(sizeof(UINT32) * ec->max_channels); + if (ec->pEchoChannelHndl == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for channel handle!\n", + ec->name); + wan_free(ec->pToneBufferIndexes); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } +#if !defined(__WINDOWS__) + ec->pEcDevMap = wan_malloc(sizeof(wan_ec_dev_t*) * ec->max_channels); +#endif + if (ec->pEcDevMap == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for ec channel map!\n", + ec->name); + wan_free(ec->pToneBufferIndexes); + wan_free(ec->pEchoChannelHndl); + wanec_ChipClose(ec_dev, verbose); + return -EINVAL; + } + for(ec_chan = 0; ec_chan < ec->max_channels; ec_chan++){ + ec->pEchoChannelHndl[ec_chan] = cOCT6100_INVALID_HANDLE; + ec->pEcDevMap[ec_chan] = NULL; + } + return 0; +} + +int wanec_ChipClose(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHIP_CLOSE f_CloseChip; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT2(verbose, + "%s: Closing Echo Canceller Chip ...\n", + ec->name); + Oct6100ChipCloseDef( &f_CloseChip ); + ulResult = Oct6100ChipClose( + ec->pChipInstance, + &f_CloseChip ); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to close Echo Canceller chip (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + if (ec->pChipInstance){ + wan_vfree(ec->pChipInstance); + ec->pChipInstance = NULL; + } + if (ec->pToneBufferIndexes){ + wan_free(ec->pToneBufferIndexes); + ec->pToneBufferIndexes = NULL; + } + if (ec->pEchoChannelHndl){ + wan_free(ec->pEchoChannelHndl); + ec->pEchoChannelHndl = NULL; + } +#if !defined(__WINDOWS__) + if (ec->pEcDevMap){ + wan_free(ec->pEcDevMap); + ec->pEcDevMap = NULL; + } +#endif + return 0; +} + +int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, int verbose) +{ + tOCT6100_CHANNEL_OPEN EchoChannelOpen; + wan_ec_t *ec; + sdla_t *card; + UINT32 ulResult; + UINT32 stream = 0,timeslot=0; + INT channel, pcm_law_type; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(ec_dev->card == NULL); + ec = ec_dev->ec; + card = (sdla_t*)ec_dev->card; + + pcm_law_type = (WAN_FE_TDMV_LAW(&card->fe) == WAN_TDMV_MULAW) ? + cOCT6100_PCM_U_LAW : cOCT6100_PCM_A_LAW; + PRINT2(verbose, + "%s: Openning all Echo Canceller channels (%s)...\n", + ec->name, + (pcm_law_type == cOCT6100_PCM_U_LAW) ? + "MULAW":"ALAW"); + + for(channel = 0; channel < ec->max_channels; channel++){ + Oct6100ChannelOpenDef( &EchoChannelOpen ); + + /* Assign the handle memory.*/ + EchoChannelOpen.pulChannelHndl = &ec->pEchoChannelHndl[channel]; + + /* Make sure the channel does not perform echo cancellation */ +#if defined(WANEC_BYDEFAULT_NORMAL) + EchoChannelOpen.ulEchoOperationMode = + cOCT6100_ECHO_OP_MODE_NORMAL; +#else + EchoChannelOpen.ulEchoOperationMode = + cOCT6100_ECHO_OP_MODE_POWER_DOWN; +#endif + EchoChannelOpen.fEnableToneDisabler = TRUE; + + stream = (channel % 2 == 1) ? 4 : 0; + timeslot = channel / 2; + + /* Configure the TDM interface.*/ + EchoChannelOpen.TdmConfig.ulRinPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulRoutPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulSinPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulSoutPcmLaw = pcm_law_type; + + EchoChannelOpen.TdmConfig.ulRinStream = stream + 0; + EchoChannelOpen.TdmConfig.ulRinTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulRoutStream = stream + 1; + EchoChannelOpen.TdmConfig.ulRoutTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulSinStream = stream + 2; + EchoChannelOpen.TdmConfig.ulSinTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulSoutStream = stream + 3; + EchoChannelOpen.TdmConfig.ulSoutTimeslot = timeslot; + + /* Set the desired VQE features (TRUE/FALSE).*/ + EchoChannelOpen.VqeConfig.fEnableNlp = TRUE; + EchoChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + EchoChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; +#if defined(ENABLE_ACOUSTICECHO) + EchoChannelOpen.VqeConfig.fAcousticEcho = TRUE; +#endif + + EchoChannelOpen.VqeConfig.fSoutAdaptiveNoiseReduction = TRUE; + EchoChannelOpen.VqeConfig.ulComfortNoiseMode = + cOCT6100_COMFORT_NOISE_NORMAL; + /* cOCT6100_COMFORT_NOISE_NORMAL + ** cOCT6100_COMFORT_NOISE_EXTENDED, + ** cOCT6100_COMFORT_NOISE_OFF, + ** cOCT6100_COMFORT_NOISE_FAST_LATCH */ + + PRINT2(verbose, + "%s: Openning Echo Canceller channel %d (%s)...\n", + ec->name, + channel, + (pcm_law_type == cOCT6100_PCM_U_LAW) ? + "MULAW":"ALAW"); + /* Open the channel.*/ + ulResult = Oct6100ChannelOpen( ec->pChipInstance, + &EchoChannelOpen ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to open Echo Canceller channel %d (err=0x%X)!\n", + ec->name, + channel, + ulResult); + return ulResult; + } + } + + /* Init debug channel handle */ + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + + return 0; +} + +int wanec_ChannelClose(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_CLOSE EchoChannelClose; + UINT32 ulResult, channel; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT2(verbose, + "%s: Closing all Echo Canceller channels ...\n", + ec->name); + for(channel = 0; channel < (UINT32)ec->max_channels; channel++){ + Oct6100ChannelCloseDef( &EchoChannelClose ); + EchoChannelClose.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ChannelClose( ec->pChipInstance, + &EchoChannelClose ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to close Echo Canceller channel %d (err=0x%X)!\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + ec->pEchoChannelHndl[channel] = cOCT6100_INVALID_HANDLE; + } + return 0; +} + +int wanec_ChannelModifyOpmode( wan_ec_dev_t *ec_dev, + INT channel, + UINT32 opmode, + int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MODIFY EchoChannelModify; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT2(verbose, "%s: Modifing EC Channel OPMODE to %d on ec_chan:%d...\n", + ec->name, opmode, channel); + + Oct6100ChannelModifyDef( &EchoChannelModify ); + /* Assign the handle memory.*/ + EchoChannelModify.ulChannelHndl = ec->pEchoChannelHndl[channel]; + + /* Echo Channel Operation Mode */ + EchoChannelModify.ulEchoOperationMode = opmode; + + /* Open the channel.*/ + ulResult = Oct6100ChannelModify( + ec->pChipInstance, + &EchoChannelModify ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "%s: Failed to modify EC Channel OPMOde for ec_chan:%d (err=0x%X)\n", + ec->name, channel, ulResult); + return EINVAL; + } + return 0; +} + +int wanec_ChannelModifyCustom( wan_ec_dev_t *ec_dev, + INT channel, + wanec_chan_custom_t *chan_custom, + int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MODIFY EchoChannelModify; + UINT32 ulResult; + int err; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(chan_custom == NULL); + WAN_ASSERT(chan_custom->custom_conf.param_no == 0); + ec = ec_dev->ec; + + PRINT2(verbose, "%s: Modifing EC Channel Config parameters for ec_chan:%d...\n", + ec->name, channel); + + Oct6100ChannelModifyDef( &EchoChannelModify ); + /* Assign the handle memory.*/ + EchoChannelModify.ulChannelHndl = ec->pEchoChannelHndl[channel]; + /* parse advianced params */ + err = wanec_ChanParam(ec, &EchoChannelModify, &chan_custom->custom_conf, verbose); + if (err){ + DEBUG_EVENT( + "%s: WARNING: Unsupported parameter for channel %d!\n", + ec->name, channel); + return -EINVAL; + } + + /* Open the channel.*/ + ulResult = Oct6100ChannelModify( + ec->pChipInstance, + &EchoChannelModify ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "%s: Failed to modify EC channel config parameters for ec_chan:%d (err=0x%X)\n", + ec->name, channel, ulResult); + return EINVAL; + } + return 0; +} + +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ChannelMute(wan_ec_dev_t* ec_dev, INT ec_chan, wanec_chan_mute_t *mute, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MUTE f_ChannelMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + Oct6100ChannelMuteDef( &f_ChannelMute ); + f_ChannelMute.ulChannelHndl = ec->pEchoChannelHndl[ec_chan]; + f_ChannelMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + PRINT2(verbose, "%s: Muting EC Channel %d on port:%X...\n", + ec->name, ec_chan, f_ChannelMute.ulPortMask); + ulResult = Oct6100ChannelMute( + ec->pChipInstance, + &f_ChannelMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute EC channel %d on port %X (%08X)!\n", + ec->name, ec_chan, f_ChannelMute.ulPortMask, ulResult); + return EINVAL; + } + return 0; +} +int wanec_ChannelUnMute(wan_ec_dev_t *ec_dev, INT ec_chan, wanec_chan_mute_t *mute, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_UNMUTE f_ChannelUnMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + Oct6100ChannelUnMuteDef( &f_ChannelUnMute ); + f_ChannelUnMute.ulChannelHndl = ec->pEchoChannelHndl[ec_chan]; + f_ChannelUnMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + PRINT2(verbose, "%s: Un-Muting EC channel %d on port:%X...\n", + ec->name, ec_chan, f_ChannelUnMute.ulPortMask); + ulResult = Oct6100ChannelUnMute( + ec->pChipInstance, + &f_ChannelUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to un-mute channel %d on port %X (%08X)!\n", + ec->name, ec_chan, f_ChannelUnMute.ulPortMask, ulResult); + return EINVAL; + } + return 0; +} + +int wanec_ChannelStats(wan_ec_dev_t *ec_dev, INT channel, wanec_chan_stats_t *chan_stats, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_STATS f_ChannelStats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT2(verbose, "%s: Reading EC statistics for channel %d...\n", + ec->name, channel); + Oct6100ChannelGetStatsDef( &f_ChannelStats ); + f_ChannelStats.ulChannelHndl = ec->pEchoChannelHndl[channel]; + f_ChannelStats.fResetStats = chan_stats->reset; + ulResult = Oct6100ChannelGetStats( + ec->pChipInstance, + &f_ChannelStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to read EC stats for channel %d (%08X)!\n", + ec->name, channel, ulResult); + return EINVAL; + } + if (chan_stats){ + memcpy( &chan_stats->f_ChannelStats, + &f_ChannelStats, + sizeof(tOCT6100_CHANNEL_STATS)); + } + return 0; +} + +int wanec_TonesEnable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t *dtmf, int verbose) +{ + tOCT6100_TONE_DETECTION_ENABLE f_ToneDetectionEnable; + UINT32 ulResult; + int i; + + PRINT2(verbose, "%s: Enable EC tone detection on chan %d port %X ...\n", + ec->name, + ec_chan, + (dtmf == NULL) ? WAN_EC_CHANNEL_PORT_SOUT|WAN_EC_CHANNEL_PORT_ROUT:dtmf->port_map); + + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_ROUT){ + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); + f_ToneDetectionEnable.ulChannelHndl = + ec->pEchoChannelHndl[ec_chan]; + f_ToneDetectionEnable.ulToneNumber = + DetectedRoutToneNumbers[i]; + ulResult = Oct6100ToneDetectionEnable ( + ec->pChipInstance, + &f_ToneDetectionEnable); + if ( ulResult == cOCT6100_ERR_OK ){ + continue; + }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ + PRINT2(verbose, + "%s: EC Tone detection is already enabled on channel %d for port ROUT!\n", + ec->name, ec_chan); + continue; /* already activated */ + }else{ + DEBUG_EVENT( + "ERROR: %s: Failed to enable EC tone detection on ec chan %d!\n", + ec->name, ec_chan); + DEBUG_EVENT( + "ERROR: %s: (err=0x%X,i=%d)!\n", + ec->name, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_SOUT){ + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); + f_ToneDetectionEnable.ulChannelHndl = + ec->pEchoChannelHndl[ec_chan]; + f_ToneDetectionEnable.ulToneNumber = + DetectedSoutToneNumbers[i]; + ulResult = Oct6100ToneDetectionEnable ( + ec->pChipInstance, + &f_ToneDetectionEnable); + if ( ulResult == cOCT6100_ERR_OK ){ + continue; + }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ + PRINT2(verbose, + "%s: EC Tone detection is already enabled on channel %d for port SOUT!\n", + ec->name, ec_chan); + continue; /* already activated */ + }else{ + DEBUG_EVENT( + "ERROR: %s: Failed to enable EC tone detection on channel %d!\n", + ec->name, ec_chan); + DEBUG_EVENT( + "ERROR: %s: (err=0x%X,i=%d)!\n", + ec->name, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + + return 0; +} + +int wanec_TonesDisable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t *dtmf, int verbose) +{ + tOCT6100_TONE_DETECTION_DISABLE f_ToneDetectionDisable; + UINT32 ulResult; + INT i; + + PRINT2(verbose, "%s: Disable EC tone detection on channel %d port %X...\n", + ec->name, + ec_chan, + (dtmf == NULL) ? WAN_EC_CHANNEL_PORT_SOUT|WAN_EC_CHANNEL_PORT_ROUT:dtmf->port_map); + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_ROUT){ + + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); + f_ToneDetectionDisable.ulChannelHndl = + ec->pEchoChannelHndl[ec_chan]; + if (ec_chan >= 0){ + f_ToneDetectionDisable.ulToneNumber = + DetectedRoutToneNumbers[i]; + }else{ + f_ToneDetectionDisable.fDisableAll = TRUE; + } + ulResult = Oct6100ToneDetectionDisable ( + ec->pChipInstance, + &f_ToneDetectionDisable); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult != cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable EC tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, ec_chan, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + } + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_SOUT){ + + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); + f_ToneDetectionDisable.ulChannelHndl = + ec->pEchoChannelHndl[ec_chan]; + if (ec_chan >= 0){ + f_ToneDetectionDisable.ulToneNumber = + DetectedSoutToneNumbers[i]; + }else{ + f_ToneDetectionDisable.fDisableAll = TRUE; + } + ulResult = Oct6100ToneDetectionDisable ( + ec->pChipInstance, + &f_ToneDetectionDisable); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult != cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable EC tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, ec_chan, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + } + return 0; +} + +//#if defined(WAN_DEBUG_HWEC) +#if 1 +static CHAR* wanec_ToneId2Str(UINT32 f_ulToneId) +{ + switch (f_ulToneId){ + /* DTMF Section */ + case ROUT_DTMF_0: return "ROUT_DTMF_0"; + case ROUT_DTMF_1: return "ROUT_DTMF_1"; + case ROUT_DTMF_2: return "ROUT_DTMF_2"; + case ROUT_DTMF_3: return "ROUT_DTMF_3"; + case ROUT_DTMF_4: return "ROUT_DTMF_4"; + case ROUT_DTMF_5: return "ROUT_DTMF_5"; + case ROUT_DTMF_6: return "ROUT_DTMF_6"; + case ROUT_DTMF_7: return "ROUT_DTMF_7"; + case ROUT_DTMF_8: return "ROUT_DTMF_8"; + case ROUT_DTMF_9: return "ROUT_DTMF_9"; + case ROUT_DTMF_A: return "ROUT_DTMF_A"; + case ROUT_DTMF_B: return "ROUT_DTMF_B"; + case ROUT_DTMF_C: return "ROUT_DTMF_C"; + case ROUT_DTMF_D: return "ROUT_DTMF_D"; + case ROUT_DTMF_STAR: return "ROUT_DTMF_STAR"; + case ROUT_DTMF_POUND: return "ROUT_DTMF_POUND"; + case SOUT_DTMF_0: return "SOUT_DTMF_0"; + case SOUT_DTMF_1: return "SOUT_DTMF_1"; + case SOUT_DTMF_2: return "SOUT_DTMF_2"; + case SOUT_DTMF_3: return "SOUT_DTMF_3"; + case SOUT_DTMF_4: return "SOUT_DTMF_4"; + case SOUT_DTMF_5: return "SOUT_DTMF_5"; + case SOUT_DTMF_6: return "SOUT_DTMF_6"; + case SOUT_DTMF_7: return "SOUT_DTMF_7"; + case SOUT_DTMF_8: return "SOUT_DTMF_8"; + case SOUT_DTMF_9: return "SOUT_DTMF_9"; + case SOUT_DTMF_A: return "SOUT_DTMF_A"; + case SOUT_DTMF_B: return "SOUT_DTMF_B"; + case SOUT_DTMF_C: return "SOUT_DTMF_C"; + case SOUT_DTMF_D: return "SOUT_DTMF_D"; + case SOUT_DTMF_STAR: return "SOUT_DTMF_STAR"; + case SOUT_DTMF_POUND: return "SOUT_DTMF_POUND"; + + /* System 5/6/7 Section */ + case SIN_SYSTEM5_2400: return "SIN_SYSTEM5_2400"; + case SIN_SYSTEM5_2600: return "SIN_SYSTEM5_2600"; + case SIN_SYSTEM5_2400_2600: return "SIN_SYSTEM5_2400_2600"; + case SIN_SYSTEM7_2000: return "SIN_SYSTEM7_2000"; + case SIN_SYSTEM7_1780: return "SIN_SYSTEM7_1780"; + + default: return "INVALID TONE ID!"; + } +} +#endif + +static unsigned char wanec_ConvertToneId(UINT32 f_ulToneId, unsigned char *ec_dtmf_port) +{ + switch (f_ulToneId){ + /* DTMF Section */ + case ROUT_DTMF_0: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '0'; + case ROUT_DTMF_1: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '1'; + case ROUT_DTMF_2: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '2'; + case ROUT_DTMF_3: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '3'; + case ROUT_DTMF_4: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '4'; + case ROUT_DTMF_5: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '5'; + case ROUT_DTMF_6: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '6'; + case ROUT_DTMF_7: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '7'; + case ROUT_DTMF_8: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '8'; + case ROUT_DTMF_9: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '9'; + case ROUT_DTMF_A: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'A'; + case ROUT_DTMF_B: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'B'; + case ROUT_DTMF_C: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'C'; + case ROUT_DTMF_D: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'D'; + case ROUT_DTMF_STAR: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '*'; + case ROUT_DTMF_POUND: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '#'; + case SOUT_DTMF_0: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '0'; + case SOUT_DTMF_1: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '1'; + case SOUT_DTMF_2: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '2'; + case SOUT_DTMF_3: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '3'; + case SOUT_DTMF_4: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '4'; + case SOUT_DTMF_5: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '5'; + case SOUT_DTMF_6: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '6'; + case SOUT_DTMF_7: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '7'; + case SOUT_DTMF_8: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '8'; + case SOUT_DTMF_9: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '9'; + case SOUT_DTMF_A: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'A'; + case SOUT_DTMF_B: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'B'; + case SOUT_DTMF_C: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'C'; + case SOUT_DTMF_D: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'D'; + case SOUT_DTMF_STAR: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '*'; + case SOUT_DTMF_POUND: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '#'; + } + return 0x00000000; +} + +#if 1 +//#if defined(WAN_DEBUG_HWEC) +static CHAR* wanec_ToneType2Str(UINT32 f_ulToneType) +{ + switch (f_ulToneType){ + case cOCT6100_TONE_PRESENT: return "cOCT6100_TONE_PRESENT"; + case cOCT6100_TONE_STOP: return "cOCT6100_TONE_STOP"; + default: return "INVALID TONE TYPE!"; + } +} +#endif +static unsigned char wanec_ConvertToneType(UINT32 f_ulToneType) +{ + switch (f_ulToneType){ + case cOCT6100_TONE_PRESENT: return WAN_EC_TONE_PRESENT; + case cOCT6100_TONE_STOP: return WAN_EC_TONE_STOP; + } + return 0x00; +} + +static CHAR* wanec_BufferPlayoutType2Str(UINT32 f_ulBufferPlayoutType) +{ + switch (f_ulBufferPlayoutType){ + case cOCT6100_BUFFER_PLAYOUT_EVENT_STOP: return "PLAYOUT_EVENT_STOP"; +#if 0 + case cOCT6100_BUFFER_PLAYOUT_EVENT_CALLER_ID_STOP: return "PLAYOUT_EVENT_CALLER_ID_STOP"; + case cOCT6100_BUFFER_PLAYOUT_EVENT_CALLER_ID_AS_STOP: return "PLAYOUT_EVENT_CALLER_ID_AS_STOP"; +#endif + default: return "INVALID BUFFER_PLAYOUT TYPE!"; + } +} + +/* +** wanec_ToneEvent() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ + +int wanec_ToneEvent(wan_ec_t *ec, int verbose) +{ + tOCT6100_EVENT_GET_TONE f_GetToneEvent; + tOCT6100_TONE_EVENT ToneEvent[32]; + UINT32 ulResult; + wan_ec_dev_t *ec_dev; + sdla_t *card; + UINT32 i; + int ec_chan,fe_chan; + + PRINT2(verbose, "%s: Getting Tone events ...\n", + ec->name); + Oct6100EventGetToneDef( &f_GetToneEvent ); + f_GetToneEvent.fResetBufs = FALSE; + f_GetToneEvent.ulMaxToneEvent = WANEC_MAX_TONEEVENTS; + f_GetToneEvent.pToneEvent = ToneEvent; + ulResult = Oct6100EventGetTone( + ec->pChipInstance, + &f_GetToneEvent); + if ( ulResult != cOCT6100_ERR_OK ){ + if ( ulResult != cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY ){ + PRINT2(verbose, "%s: There are not tone events!\n", + ec->name); + return 0; + } + DEBUG_EVENT( + "ERROR: %s: Failed to get tone events (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* No dtmf tone event returned */ + if (!f_GetToneEvent.ulNumValidToneEvent) return 0; + + for(i = 0; i < f_GetToneEvent.ulNumValidToneEvent; i++){ + ec_chan = wanec_hndl2ec_channel(ec, ToneEvent[i].ulChannelHndl); + ec_dev = ec->pEcDevMap[ec_chan]; + fe_chan = wanec_ec2fe_channel(ec, ec_chan, &ec_dev); + if (ec_dev == NULL || ec_dev->card == NULL){ + DEBUG_EVENT( + "%s: Internal Error: Failed to find fe channel (ec_chan=%d)\n", + ec->name, ec_chan); + continue; + } + + PRINT2(verbose, + "%s: Tone event %s %s on fe_chan=%d ec_chan=%d\n", + ec_dev->devname, + wanec_ToneId2Str(ToneEvent[i].ulToneDetected), + wanec_ToneType2Str(f_GetToneEvent.pToneEvent[i].ulEventType), + fe_chan, ec_chan); + + card = (sdla_t*)ec_dev->card; + if (card->wandev.event_callback.dtmf){ + wan_event_t event; + unsigned char dtmf_port = WAN_EC_CHANNEL_PORT_ROUT, dtmf_type; + + event.type = WAN_EVENT_EC_DTMF; + event.channel = fe_chan; + event.digit = wanec_ConvertToneId( + ToneEvent[i].ulToneDetected, + &dtmf_port); + dtmf_type = wanec_ConvertToneType(ToneEvent[i].ulEventType); + event.dtmf_type = dtmf_type; + event.dtmf_port = dtmf_port; + card->wandev.event_callback.dtmf(card, &event); + } + } + + /* Return 1 if more dtmf event are present, otherwise - 0 */ + return (f_GetToneEvent.fMoreEvents == TRUE) ? 1 : 0; +} + +/* +** wanec_PlayoutEvent() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ +int wanec_PlayoutEvent(wan_ec_t *ec, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_GET_EVENT f_BufferPlayoutGetEvent; + tOCT6100_BUFFER_PLAYOUT_EVENT PlayoutEvent[32]; + UINT32 ulResult; + wan_ec_dev_t *ec_dev; + UINT32 i; + int ec_chan,fe_chan; + + PRINT2(verbose, "%s: Getting EC Buffer Playout events ...\n", + ec->name); + Oct6100BufferPlayoutGetEventDef( &f_BufferPlayoutGetEvent ); + f_BufferPlayoutGetEvent.pBufferPlayoutEvent = PlayoutEvent; + f_BufferPlayoutGetEvent.ulMaxEvent = WANEC_MAX_PLAYOUTEVENTS; + f_BufferPlayoutGetEvent.fResetBufs = FALSE; + + ulResult = Oct6100BufferPlayoutGetEvent( + ec->pChipInstance, + &f_BufferPlayoutGetEvent); + if ( ulResult != cOCT6100_ERR_OK ){ + if ( ulResult != cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY ){ + PRINT2(verbose, "%s: There are not buffer playout events!\n", + ec->name); + return 0; + } + DEBUG_EVENT( + "ERROR: %s: Failed to get buffer playout events (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* No dtmf tone event returned */ + if (!f_BufferPlayoutGetEvent.ulNumValidEvent) return 0; + + for(i = 0; i < f_BufferPlayoutGetEvent.ulNumValidEvent; i++){ + ec_chan = wanec_hndl2ec_channel(ec, PlayoutEvent[i].ulChannelHndl); + ec_dev = ec->pEcDevMap[ec_chan]; + fe_chan = wanec_ec2fe_channel(ec, ec_chan, &ec_dev); + if (ec_dev == NULL || ec_dev->card == NULL){ + DEBUG_EVENT( + "%s: Internal Error: Failed to find fe channel (ec_chan=%d)\n", + ec->name, ec_chan); + continue; + } + + PRINT2(verbose, + "%s: EC Buffer Playout event id %d %s on fe_chan=%d ec_chan=%d port=%s\n", + ec_dev->devname, + PlayoutEvent[i].ulUserEventId, + wanec_BufferPlayoutType2Str(PlayoutEvent[i].ulEventType), + fe_chan, ec_chan, + (PlayoutEvent[i].ulChannelPort==cOCT6100_CHANNEL_PORT_ROUT) ? "ROUT" : "SOUT"); +#if 0 + card = (sdla_t*)ec_dev->card; + if (card->wandev.event_callback.playout){ + } +#endif + } + + /* Return 1 if more playout event are present, otherwise - 0 */ + return (f_BufferPlayoutGetEvent.fMoreEvents == TRUE) ? 1 : 0; +} + +/* +** wanec_ISR() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ +int wanec_ISR(wan_ec_t *ec, int verbose) +{ + UINT32 ulResult; + int ret = 0; + + WAN_ASSERT(ec == NULL); + + PRINT2(verbose, "%s: Executing EC interrupt routine ...\n", + ec->name); + Oct6100InterruptServiceRoutineDef(&ec->f_InterruptFlag); + + ulResult = Oct6100InterruptServiceRoutine( + ec->pChipInstance, + &ec->f_InterruptFlag ); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to execute interrupt Service Routine (err=%08X)!\n", + ec->name, + ulResult); + return -EINVAL; + } + /* Critical errors */ + if (ec->f_InterruptFlag.fFatalGeneral == TRUE){ + DEBUG_EVENT( + "%s: An internal fatal chip error detected (0x%X)!\n", + ec->name, + ec->f_InterruptFlag.ulFatalGeneralFlags); + } + if (ec->f_InterruptFlag.fFatalReadTimeout == TRUE){ + DEBUG_EVENT( + "%s: A read to the external memory has failed!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorRefreshTooLate == TRUE){ + DEBUG_EVENT( + "%s: Error Refresh Too Late!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorPllJitter == TRUE){ + DEBUG_EVENT( + "%s: Error Pll Jitter\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100OutOfSync == TRUE){ + DEBUG_EVENT( + "%s: The H100 slave has lost its framing on the bus!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100ClkA == TRUE){ + DEBUG_EVENT( + "%s: The CT_C8_A clock behavior does not conform to the H.100 spec!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100FrameA == TRUE){ + DEBUG_EVENT( + "%s: The CT_FRAME_A clock behavior does not comform to the H.100 spec!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100ClkB == TRUE){ + DEBUG_EVENT( + "%s: The CT_C8_B clock is not running a 16.384 MHz!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorOverflowToneEvents == TRUE){ + DEBUG_EVENT( + "%s: Error: Tone Event buffer has overflowed\n", + ec->name); + } + if (ec->f_InterruptFlag.fToneEventsPending == TRUE){ + PRINT2(verbose, "%s: Tone Event pending....\n", + ec->name); + ret = wanec_ToneEvent(ec, ec->tone_verbose); + } + if (ec->f_InterruptFlag.fBufferPlayoutEventsPending == TRUE){ + PRINT2(verbose, + "%s: Buffer Playout Events Pending\n", + ec->name); + ret = wanec_PlayoutEvent(ec, ec->playout_verbose); + } + if (ec->f_InterruptFlag.fApiSynch == TRUE){ + PRINT2(verbose, + "%s: The chip interrupted the API for purpose of maintaining sync!\n", + ec->name); + } + return ret; +} + +int wanec_DebugChannel(wan_ec_dev_t *ec_dev, INT channel, int verbose) +{ + wan_ec_t *ec = NULL; + tOCT6100_DEBUG_SELECT_CHANNEL DebugSelectChannel; + wanec_chan_stats_t chan_stats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + /* Verify Echo Canceller Channel operation mode */ + memset(&chan_stats, 0, sizeof(wanec_chan_stats_t)); + ulResult = wanec_ChannelStats(ec_dev, channel, &chan_stats, 0); + if (chan_stats.f_ChannelStats.ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Channel %d operation mode (POWER DOWN)!\n", + ec_dev->name, channel); + return -EINVAL; + } + + if (ec_dev->ec->ulDebugChannelHndl != cOCT6100_INVALID_HANDLE){ + DEBUG_EVENT( + "ERROR: %s: Echo Canceller daemon can monitor only one ec channel (%d)!\n", + ec_dev->name, channel); + return -EINVAL; + } + Oct6100DebugSelectChannelDef( &DebugSelectChannel ); + + PRINT2(verbose, "%s: Select ec channel %d for monitoring...\n", + ec_dev->name, + channel); + /* Set selected debug channel */ + ec->DebugChannel = channel; + ec->ulDebugChannelHndl = ec->pEchoChannelHndl[channel]; + DebugSelectChannel.ulChannelHndl= ec->pEchoChannelHndl[channel]; + + /* Select Debug channel */ + ulResult = Oct6100DebugSelectChannel( + ec->pChipInstance, + &DebugSelectChannel ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to select debug ec channel %d for monitoring (err=0x%X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_DebugGetData(wan_ec_dev_t *ec_dev, wanec_chan_monitor_t *chan_monitor, int verbose) +{ + wan_ec_t *ec = NULL; + tOCT6100_DEBUG_GET_DATA fDebugGetData; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + if (ec->ulDebugChannelHndl == cOCT6100_INVALID_HANDLE){ + DEBUG_EVENT( + "ERROR: %s: No Debug channel was selected!\n", + ec->name); + return -EINVAL; + } + + Oct6100DebugGetDataDef( &fDebugGetData ); + + PRINT2(verbose, + "%s: Retrieves debug data for ec channel %d...\n", + ec->name, + ec->DebugChannel); + + memset(&chan_monitor->data[0], 0, + sizeof(UINT8) * (MAX_MONITOR_DATA_LEN+1)); + /* Set selected debug channel */ + fDebugGetData.ulGetDataMode = ec->ulDebugDataMode; + fDebugGetData.ulMaxBytes = chan_monitor->max_len; + fDebugGetData.pbyData = &chan_monitor->data[0]; + + /* Select Debug channel */ + ulResult = Oct6100DebugGetData( + ec->pChipInstance, + &fDebugGetData ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to get debug data for ec channel %d (err=0x%X)\n", + ec->name, + ec->DebugChannel, + ulResult); + return -EINVAL; + } + chan_monitor->data_len = fDebugGetData.ulValidNumBytes; + chan_monitor->remain_len= fDebugGetData.ulRemainingNumBytes; + //chan_monitor->fe_chan = ec->DebugChannel; + chan_monitor->fe_chan = wanec_ec2fe_channel(ec, ec->DebugChannel, NULL); + + if (fDebugGetData.ulRemainingNumBytes == 0){ + /* Last read */ + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + } + + return 0; +} + +static PUINT32 wanec_search_bufferindex(wan_ec_t *ec, UINT32 index) +{ + UINT32 i = 0; + + while(i < ec->f_OpenChip.ulMaxPlayoutBuffers){ + if (ec->pToneBufferIndexes[i] == index){ + return &ec->pToneBufferIndexes[i]; + } + i++; + } + return NULL; +} + +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose) +{ + wan_ec_t *ec; + tOCT6100_BUFFER_LOAD BufferLoad; + UINT32 size, ulResult, pcmlaw = WAN_EC_PCM_U_LAW; + PUINT8 pData = NULL; + int err; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + pcmlaw = (buffer_config->pcmlaw) ? buffer_config->pcmlaw : WAN_EC_PCM_U_LAW; + PRINT2(verbose, + "%s: Loading Tone buffer (%s) law=%s into Echo Canceller Chip ...\n", + ec->name, + buffer_config->buffer, + WAN_EC_DECODE_PCM_LAW(pcmlaw)); + size = buffer_config->size * sizeof(INT8); + pData = wan_vmalloc(size); + if (pData == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed to allocate memory for buffer!\n", + ec->name); + return -EINVAL; + } + err = WAN_COPY_FROM_USER(pData, buffer_config->data, size); + if (err){ + DEBUG_EVENT( + "ERROR: %s: Failed to copy EC buffer from user space [%s:%d]!\n", + ec->name, + __FUNCTION__,__LINE__); + wan_vfree(pData); + return -EINVAL; + } + + Oct6100BufferPlayoutLoadDef( &BufferLoad ); + BufferLoad.pulBufferIndex = wanec_search_bufferindex(ec, cOCT6100_INVALID_VALUE); + /* FIXME: Can be alaw/mulaw */ + BufferLoad.ulBufferPcmLaw = (pcmlaw == WAN_EC_PCM_U_LAW) ? + cOCT6100_PCM_U_LAW : cOCT6100_PCM_A_LAW; + BufferLoad.pbyBufferPattern = pData; + BufferLoad.ulBufferSize = size; + ulResult = Oct6100BufferPlayoutLoad ( + ec->pChipInstance, + &BufferLoad); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult == cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN){ + goto buffer_load_done; + } + DEBUG_EVENT( + "%s: ERROR: Failed to load buffer into EC Chip (err=0x%X)\n", + ec->name, ulResult); + wan_vfree(pData); + return -EINVAL; + } +buffer_load_done: + wan_vfree(pData); + buffer_config->buffer_index = *BufferLoad.pulBufferIndex; + PRINT2(verbose, + "%s: Current buffer index is %d\n", + ec->name, buffer_config->buffer_index); + return 0; +} + +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose) +{ + wan_ec_t *ec; + tOCT6100_BUFFER_UNLOAD BufferUnload; + PUINT32 pBufferIndex = NULL; + UINT32 index = 0, ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT2(verbose, + "%s: Unloading buffer from EC chip ...\n", + ec->name); + +try_next_index: + Oct6100BufferPlayoutUnloadDef( &BufferUnload ); + if (buffer_config->buffer_index != cOCT6100_INVALID_VALUE){ + pBufferIndex = wanec_search_bufferindex(ec, buffer_config->buffer_index); + if (pBufferIndex == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid buffer index %X!\n", + ec->name, buffer_config->buffer_index); + return EINVAL; + } + }else{ + if (index > ec->f_OpenChip.ulMaxPlayoutBuffers){ + goto buffer_unload_done; + } + if (ec->pToneBufferIndexes[index] == cOCT6100_INVALID_VALUE){ + index++; + goto try_next_index; + } + pBufferIndex = &ec->pToneBufferIndexes[index]; + } + + BufferUnload.ulBufferIndex = *pBufferIndex; + ulResult = Oct6100BufferPlayoutUnload ( + ec->pChipInstance, + &BufferUnload); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult == cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN){ + goto buffer_unload_done; + } + DEBUG_EVENT( + "ERROR: %s: Failed to unload buffer from EC Chip (err=0x%X)!\n", + ec->name, (unsigned int)ulResult); + return EINVAL; + } + *pBufferIndex = 0; + if (!buffer_config->buffer_index){ + index++; + goto try_next_index; + } + +buffer_unload_done: + return 0; +} + +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_ADD BufferPlayoutAdd; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Add Tone buffer to ec channel %d port %s duration %d:%d...\n", + ec->name, + channel, + WAN_EC_DECODE_CHANNEL_PORT(playout->port), + playout->duration, + playout->repeat_cnt); + if (playout->index == cOCT6100_INVALID_VALUE|| + wanec_search_bufferindex(ec, playout->index) == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid playout buffer index for ec channel %d!\n", + ec->name, channel); + return -EINVAL; + } + Oct6100BufferPlayoutAddDef( &BufferPlayoutAdd ); + if (playout->repeat_cnt == 1){ + BufferPlayoutAdd.fRepeat = FALSE; + }else{ + BufferPlayoutAdd.fRepeat = TRUE; + } + BufferPlayoutAdd.ulPlayoutPort = + (playout->port == WAN_EC_CHANNEL_PORT_ROUT) ? + cOCT6100_CHANNEL_PORT_ROUT : + cOCT6100_CHANNEL_PORT_SOUT; + BufferPlayoutAdd.ulMixingMode = cOCT6100_MIXING_MUTE; + BufferPlayoutAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutAdd.ulBufferIndex = playout->index; + BufferPlayoutAdd.fRepeat = (playout->repeat_cnt) ? TRUE : FALSE; + BufferPlayoutAdd.ulRepeatCount = playout->repeat_cnt; + BufferPlayoutAdd.ulDuration = (playout->duration) ? + playout->duration : 5000; + BufferPlayoutAdd.ulBufferLength = (playout->buffer_length) ? + playout->buffer_length : + cOCT6100_AUTO_SELECT; + ulResult = Oct6100BufferPlayoutAdd( + ec->pChipInstance, + &BufferPlayoutAdd); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to add playout buffer to ec channel %d (err=%08X)\n", + ec->name, channel, ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_START BufferPlayoutStart; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Active playout buffer on ec channel %d port %s ...\n", + ec->name, + channel, + WAN_EC_DECODE_CHANNEL_PORT(playout->port)); + Oct6100BufferPlayoutStartDef( &BufferPlayoutStart ); + BufferPlayoutStart.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutStart.ulPlayoutPort = + (playout->port == WAN_EC_CHANNEL_PORT_ROUT) ? + cOCT6100_CHANNEL_PORT_ROUT : + cOCT6100_CHANNEL_PORT_SOUT; + BufferPlayoutStart.fNotifyOnPlayoutStop = playout->notifyonstop; + BufferPlayoutStart.ulUserEventId = playout->user_event_id; + ulResult = Oct6100BufferPlayoutStart( + ec->pChipInstance, + &BufferPlayoutStart); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to active playout buffer on ec channel %d (err=%08X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Deactive playout buffer on ec channel %d port %s...\n", + ec->name, + channel, + WAN_EC_DECODE_CHANNEL_PORT(playout->port)); + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + BufferPlayoutStop.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutStop.ulPlayoutPort = + (playout->port == WAN_EC_CHANNEL_PORT_ROUT) ? + cOCT6100_CHANNEL_PORT_ROUT : + cOCT6100_CHANNEL_PORT_SOUT; + ulResult = Oct6100BufferPlayoutStop( + ec->pChipInstance, + &BufferPlayoutStop); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult != cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED){ + DEBUG_EVENT( + "ERROR: %s: Failed to deactive playout buffer on ec channel %d (err=%08X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + } + return 0; +} + + +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_OPEN ConfBridgeOpen; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Opening Conference Bridge...\n", ec->name); + + if ((unsigned int)ec->confbridges_no >= ec->f_OpenChip.ulMaxConfBridges){ + DEBUG_EVENT( + "ERROR: %s: Trying to open too many conference bridges (%d:%d)\n", + ec->name, + ec->confbridges_no, + ec->f_OpenChip.ulMaxConfBridges); + return -EINVAL; + } + + Oct6100ConfBridgeOpenDef( &ConfBridgeOpen ); + ConfBridgeOpen.pulConfBridgeHndl = &confbridge->ulHndl; + ConfBridgeOpen.fFlexibleConferencing = FALSE; + ulResult = Oct6100ConfBridgeOpen( + ec->pChipInstance, + &ConfBridgeOpen); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to open new conference bridge (err=%08X)\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Closing Conference Bridge...\n", ec->name); + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + ConfBridgeClose.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeClose( + ec->pChipInstance, + &ConfBridgeClose); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to close conference bridge (%X, err=%08X)\n", + ec->name, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanAdd(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_ADD ConfBridgeChanAdd; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Add channel %d to Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanAddDef( &ConfBridgeChanAdd ); + ConfBridgeChanAdd.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanAdd( + ec->pChipInstance, + &ConfBridgeChanAdd); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to add channel %d to conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanRemove(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE ConfBridgeChanRemove; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Remove channel %d from Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanRemoveDef( &ConfBridgeChanRemove ); + ConfBridgeChanRemove.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanRemove.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanRemove( + ec->pChipInstance, + &ConfBridgeChanRemove); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to remove channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_MUTE ConfBridgeChanMute; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Mute channel %d on a conference bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanMuteDef( &ConfBridgeChanMute ); + ConfBridgeChanMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanMute( + ec->pChipInstance, + &ConfBridgeChanMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute channel %d on a conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanUnMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_UNMUTE ConfBridgeChanUnMute; + UINT32 ulResult; + + PRINT2(verbose, + "%s: UnMute channel %d on a Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanUnMuteDef( &ConfBridgeChanUnMute ); + ConfBridgeChanUnMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanUnMute( + ec->pChipInstance, + &ConfBridgeChanUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to unmute channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeDominantSpeakerSet(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int enable, int verbose) +{ + tOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET ConfBridgeDominantSpeaker; + UINT32 ulResult; + + PRINT2(verbose, + "%s: %s Dominant speaker (channel %d) to a Conference Bridge %X...\n", + ec->name, + (enable) ? "Enable":"Disable", + channel, + confbridge->ulHndl); + + Oct6100ConfBridgeDominantSpeakerSetDef( &ConfBridgeDominantSpeaker ); + ConfBridgeDominantSpeaker.ulConfBridgeHndl = confbridge->ulHndl; + if (enable){ + ConfBridgeDominantSpeaker.ulChannelHndl = ec->pEchoChannelHndl[channel]; + }else{ + ConfBridgeDominantSpeaker.ulChannelHndl = cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL; + } + ulResult = Oct6100ConfBridgeDominantSpeakerSet( + ec->pChipInstance, + &ConfBridgeDominantSpeaker); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to %s dominant speaker to conference bridge (%X, err=%08X)\n", + ec->name, + (enable) ? "enable" : "disable", + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + + +int wanec_ConfBridgeMaskChange(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, UINT32 mask, int verbose) +{ + tOCT6100_CONF_BRIDGE_MASK_CHANGE ConfBridgeMaskChange; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Changing the listener (channel=%d) mask of bridge participant (%d)...\n", + ec->name, + channel, confbridge->ulHndl); + + Oct6100ConfBridgeMaskChangeDef( &ConfBridgeMaskChange ); + ConfBridgeMaskChange.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ConfBridgeMaskChange.ulNewListenerMask = mask; + ulResult = Oct6100ConfBridgeMaskChange( + ec->pChipInstance, + &ConfBridgeMaskChange); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to change the listener mask of bridge participant %d (err=%X)!\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeGetStats(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_STATS ConfBridgeStats; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Getting bridge statistics %X...\n", + ec->name, confbridge->ulHndl); + + Oct6100ConfBridgeGetStatsDef( &ConfBridgeStats ); + ConfBridgeStats.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeGetStats( + ec->pChipInstance, + &ConfBridgeStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to get conference bridge statistics (err=%X)!\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + +/*===========================================================================*\ + Oct6100Read +\*===========================================================================*/ + +static int +wan_ec_read(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data) +{ + u32 data; + wan_ec_read_internal_dword(ec_dev, read_addr, &data); + *read_data = (u16)(data & 0xFFFF); + return 0; +} + +/*===========================================================================*\ + Oct6100Write +\*===========================================================================*/ + +static int +wan_ec_write(wan_ec_dev_t *ec_dev, u32 write_addr, u32 write_data) +{ + return wan_ec_write_internal_dword(ec_dev, write_addr, write_data); +} + + +/*===========================================================================*\ + Oct6100WriteSequenceSub +\*===========================================================================*/ +static u32 +wan_ec_write_seq(wan_ec_dev_t *ec_dev, u32 write_addr, u16 write_data) +{ + u32 ulResult; + u32 ulData; + u16 usData; + u32 ulWordAddress; + u32 i; + + /* Create the word address from the provided byte address. */ + ulWordAddress = write_addr >> 1; + + /* 16-bit indirect access. */ + + /* First write to the address indirection registers. */ + ulData = ( ulWordAddress >> 19 ) & 0x1FFF; + ulResult = wan_ec_write( ec_dev, 0x8, ulData ); + if (ulResult) + return ulResult; + + ulData = ( ulWordAddress >> 3 ) & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0xA, ulData ); + if (ulResult) + return ulResult; + + /* Next, write data word to read/write data registers. */ + ulData = write_data & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0x4, ulData ); + if ( ulResult ) + return ulResult; + + + /* Write the parities and write enables, as well as last three bits + ** of wadd and request the write access. */ + ulData = ( ( 0x0 & 0x3 ) << 14 ) | ( ( 0x3 & 0x3 ) << 12 ) | ( ( ulWordAddress & 0x7 ) << 9 ) | 0x0100; + ulResult = wan_ec_write( ec_dev, 0x0, ulData ); + if ( ulResult ) + return ulResult; + + /* Keep polling register contol0 for the access_req bit to go low. */ + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) + { + ulResult = wan_ec_read( ec_dev, 0, &usData ); + if ( ulResult ) + return ulResult; + + if ( ( ( usData >> 8 ) & 0x1 ) == 0x0 ) + break; + } + + if ( i == WANEC_READ_LIMIT ){ + DEBUG_EVENT("%s: EC write command reached limit!\n", + ec_dev->name); + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; + } + return 0; +} + + +/*===========================================================================*\ + HandleReqWriteOct6100 +\*===========================================================================*/ +u32 wanec_req_write(void *arg, u32 write_addr, u16 write_data) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 ulResult; + + DEBUG_TEST("%s: EC WRITE API addr=%X data=%X\n", + ec_dev->ec->name, write_addr, write_data); + ulResult = wan_ec_write_seq(ec_dev, write_addr, write_data); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + write_addr, + write_data); + } + return ulResult; +} + + +/*===========================================================================*\ + HandleReqWriteSmearOct6100 +\*===========================================================================*/ +u32 wanec_req_write_smear(void *arg, u32 addr, u16 data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + + WAN_ASSERT(ec_dev == NULL); + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_write_seq(ec_dev, addr + (i*2), data); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + addr + (i*2), + data); + break; + } + } + return ulResult; +} + + +/*===========================================================================*\ + HandleReqWriteBurstOct6100 +\*===========================================================================*/ +u32 wanec_req_write_burst(void *arg, u32 addr, u16 *data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + + WAN_ASSERT(ec_dev == NULL); + + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_write_seq(ec_dev, addr + (i * 2), data[i]); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + addr + (i*2), + data[i]); + break; + } + } + return ulResult; +} + + +/*===========================================================================*\ + Oct6100ReadSequenceSub +\*===========================================================================*/ +static u32 +wan_ec_read_seq(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data, u32 read_len) +{ + u32 ulResult; + u32 ulData; + u32 ulWordAddress; + u32 ulReadBurstLength; + u16 usData; + u32 i; + + /* Create the word address from the provided byte address. */ + ulWordAddress = read_addr >> 1; + + /* Indirect accesses. */ + + /* First write to the address indirection registers. */ + ulData = ( ulWordAddress >> 19 ) & 0x1FFF; + ulResult = wan_ec_write( ec_dev, 0x8, ulData ); + if (ulResult) + return ulResult; + + ulData = ( ulWordAddress >> 3 ) & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0xA, ulData ); + if (ulResult) + return ulResult; + + /* Request access. */ + if ( read_len >= 128 ) + { + ulData = 0x100 | ( ( ulWordAddress & 0x7 ) << 9); + ulReadBurstLength = 0; + } + else + { + ulData = 0x100 | ( ( ulWordAddress & 0x7 ) << 9) | read_len; + ulReadBurstLength = read_len; + } + ulResult = wan_ec_write( ec_dev, 0x0, ulData ); + if (ulResult) + return ulResult; + + /* Keep polling register contol0 for the access_req bit to go low. */ + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) + { + ulResult = wan_ec_read( ec_dev, 0x0, &usData ); + if (ulResult) + return ulResult; + + if ( ( ( usData >> 8 ) & 0x1 ) == 0x0 ) + break; + } + if ( i == WANEC_READ_LIMIT ){ + DEBUG_EVENT("%s: EC read command reached limit!\n", + ec_dev->name); + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; + } + + if ( ( usData & 0xFF ) == 0x1 ) + { + i = 0; + } + + /* Retrieve read data. */ + ulResult = wan_ec_read( ec_dev, 0x4, &usData ); + if (ulResult) + return ulResult; + + if ( ( usData & 0xFF ) == 0x1 ) + { + i = 0; + } + + *read_data = usData; + return 0; +} + +u32 wanec_req_read(void *arg, u32 addr, u16 *data) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + DEBUG_TEST("%s: EC READ API addr=%X data=????\n", + ec_dev->ec->name, addr); + ulResult = wan_ec_read_seq( + ec_dev, + addr, + data, + 1); + if (ulResult){ + DEBUG_EVENT("%s: Failed to read data from addr %08X\n", + ec_dev->name, + addr); + if (ec_dev->ec){ + wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->ec->critical); + } + } + DEBUG_TEST("%s: EC READ API addr=%X data=%X\n", + ec_dev->ec->name, + addr, *data); + return ulResult; +} + +u32 wanec_req_read_burst(void *arg, u32 addr, u16 *data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + u16 read_data; + + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_read_seq(ec_dev, addr, &read_data, 1); + if (ulResult){ + DEBUG_EVENT("%s: Failed to read from addr %X\n", + ec_dev->name, + addr); + if (ec_dev->ec){ + wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->ec->critical); + } + break; + } + data[i] = (u16)read_data; + addr += 2; + } + return ulResult; +} diff --git a/patches/kdrivers/wanec/.tmp_versions/wanec.mod b/patches/kdrivers/wanec/.tmp_versions/wanec.mod index 4f82a26..a828d7c 100644 --- a/patches/kdrivers/wanec/.tmp_versions/wanec.mod +++ b/patches/kdrivers/wanec/.tmp_versions/wanec.mod @@ -1,2 +1,2 @@ -/root/3.2/wanpipe/patches/kdrivers/wanec/wanec.ko -/root/3.2/wanpipe/patches/kdrivers/wanec/wanec_iface.o /root/3.2/wanpipe/patches/kdrivers/wanec/wanec_cmd.o /root/3.2/wanpipe/patches/kdrivers/wanec/wanec_utils.o /root/3.2/wanpipe/patches/kdrivers/wanec/wanec_dev.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/apilib/bt/octapi_bt0.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/apilib/largmath/octapi_largmath.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/apilib/llman/octapi_llman.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_events.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o /root/3.2/wanpipe/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_user.o +/root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/wanec.ko +/root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/wanec_iface.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/wanec_cmd.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/wanec_utils.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/wanec_dev.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/apilib/bt/octapi_bt0.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/apilib/largmath/octapi_largmath.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/apilib/llman/octapi_llman.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_apimi/oct6100_mask_interrupts.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_events.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o /root/development/3.3/wanpipe-3.3.2/patches/kdrivers/wanec/oct6100_api/octdeviceapi/oct6100api/oct6100_api/oct6100_user.o diff --git a/patches/kdrivers/wanec/Makefile.Windows b/patches/kdrivers/wanec/Makefile.Windows new file mode 100755 index 0000000..b6c73b5 --- /dev/null +++ b/patches/kdrivers/wanec/Makefile.Windows @@ -0,0 +1,9 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def + + diff --git a/patches/kdrivers/wanec/Makefile6.FreeBSD b/patches/kdrivers/wanec/Makefile6.FreeBSD index 0a489a5..ec053a0 100755 --- a/patches/kdrivers/wanec/Makefile6.FreeBSD +++ b/patches/kdrivers/wanec/Makefile6.FreeBSD @@ -27,7 +27,7 @@ DESTDIR = / KMODDIR = /boot/modules MODULE_DEPEND = wanrouter SRCS = wanec_iface.c wanec_cmd.c wanec_utils.c octapi_bt0.c octapi_largmath.c octapi_llman.c oct6100_mask_interrupts.c oct6100_adpcm_chan.c oct6100_channel.c oct6100_chip_open.c oct6100_chip_stats.c oct6100_conf_bridge.c oct6100_debug.c oct6100_events.c oct6100_interrupts.c oct6100_memory.c oct6100_miscellaneous.c oct6100_mixer.c oct6100_phasing_tsst.c oct6100_playout_buf.c oct6100_remote_debug.c oct6100_tlv.c oct6100_tone_detection.c oct6100_tsi_cnct.c oct6100_tsst.c oct6100_user.c -CFLAGS += -Wunused -I/sys -I/usr/include/wanpipe -Ioct6100_api/include -Ioct6100_api/include/apilib -Ioct6100_api/apilib/bt -Ioct6100_api/apilib/llman -Ioct6100_api/apilib/largmath -Ioct6100_api/include/octrpc -Ioct6100_api/include/oct6100api -Ioct6100_api/octdeviceapi/oct6100api -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_FR -DCONFIG_PRODUCT_WANPIPE_CHDLC -DCONFIG_PRODUCT_WANPIPE_PPP -DCONFIG_PRODUCT_WANPIPE_ADSL -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_A200 -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DCONFIG_PRODUCT_WANPIPE_MLINK_PPP -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE ${WAN_GLB_CFLAGS} +CFLAGS += -Wunused -I/sys -I/wanpipe/code/include -I/common/include -Ioct6100_api/include -Ioct6100_api/include/apilib -Ioct6100_api/apilib/bt -Ioct6100_api/apilib/llman -Ioct6100_api/apilib/largmath -Ioct6100_api/include/octrpc -Ioct6100_api/include/oct6100api -Ioct6100_api/octdeviceapi/oct6100api -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_FR -DCONFIG_PRODUCT_WANPIPE_CHDLC -DCONFIG_PRODUCT_WANPIPE_PPP -DCONFIG_PRODUCT_WANPIPE_ADSL -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_RM -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -DCONFIG_PRODUCT_WANPIPE_MLINK_PPP -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -DCONFIG_WANPIPE_HWEC ${WAN_GLB_CFLAGS} hdr_install: \cp -f wanec_iface.h /usr/include/wanpipe diff --git a/patches/kdrivers/wanec/oct6100_api.PR48/apilib/bt/octapi_bt0_private.h b/patches/kdrivers/wanec/oct6100_api.PR48/apilib/bt/octapi_bt0_private.h index b0c501a..0d24ba0 100644 --- a/patches/kdrivers/wanec/oct6100_api.PR48/apilib/bt/octapi_bt0_private.h +++ b/patches/kdrivers/wanec/oct6100_api.PR48/apilib/bt/octapi_bt0_private.h @@ -87,7 +87,9 @@ void OctApiBt0UpdateLinkDepth( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link ); void OctApiBt0Rebalance( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); void OctApiBt0ExternalHeavy( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * root_link ); UINT32 OctApiBt0RemoveNode2( OCTAPI_BT0 * bb, OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link ); +UINT32 OctApiBt0RemoveNode3(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link, UINT32 * lkey, OCTAPI_BT0_LINK * link_to_removed_node, UINT32 state, OCTAPI_BT0_LINK * volatile_grandparent_link, UINT32 *p_prev_node_number ); +UINT32 OctApiBt0QueryNode2(OCTAPI_BT0 * bb,OCTAPI_BT0_LINK * link,UINT32 * lkey,UINT32 * node_number); #endif /*__OCTAPI_BT0_PRIVATE_H__*/ diff --git a/patches/kdrivers/wanec/oct6100_api.PR48/include/apilib/octapi_llman.h b/patches/kdrivers/wanec/oct6100_api.PR48/include/apilib/octapi_llman.h index d1a29fe..d2d30bf 100644 --- a/patches/kdrivers/wanec/oct6100_api.PR48/include/apilib/octapi_llman.h +++ b/patches/kdrivers/wanec/oct6100_api.PR48/include/apilib/octapi_llman.h @@ -134,6 +134,7 @@ UINT32 OctApiLlm2ListLength( PVOID l, UINT32 list_handle, PUINT32 number_of_item UINT32 OctApiLlm2ListInsertItem(void * l, UINT32 list_handle, UINT32 item_key, void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt ); UINT32 OctApiLlm2ListRemoveItem(void * l, UINT32 list_handle, UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt ); UINT32 OctApiLlm2ListItemData( PVOID l, UINT32 list_handle, UINT32 item_key, PVOID* item_data_pnt, PUINT32 item_number ); +UINT32 OctApiLlm2ListDelete(void * l,UINT32 list_handle); #ifdef __cplusplus } diff --git a/patches/kdrivers/wanec/oct6100_api.PR48/include/oct6100api/oct6100_apiud.h b/patches/kdrivers/wanec/oct6100_api.PR48/include/oct6100api/oct6100_apiud.h index e44811d..51ffb68 100644 --- a/patches/kdrivers/wanec/oct6100_api.PR48/include/oct6100api/oct6100_apiud.h +++ b/patches/kdrivers/wanec/oct6100_api.PR48/include/oct6100api/oct6100_apiud.h @@ -128,8 +128,12 @@ $Octasic_Revision: 16 $ /***************************** TYPES ***************************************/ -/*Change this type if your platform uses 64bits semaphores/locks */ -typedef UINT32 tOCT6100_USER_SERIAL_OBJECT; +/*Change this type if your platform uses 64bits semaphores/locks */ +/* Dec 14 2007 ALEX +** The type is changed to PVOID in order to support 64-bit platform. The +** value is allocated in CreateObject function and freed in DestroyObject. +******************************************************************************/ +typedef PVOID tOCT6100_USER_SERIAL_OBJECT; /* UINT32 */ typedef struct _OCT6100_GET_TIME_ { diff --git a/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c b/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c index dd272d6..ed7d79b 100644 --- a/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c +++ b/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_api/oct6100_user.c @@ -23,7 +23,6 @@ $Octasic_Revision: 25 $ /***************************** INCLUDE FILES *******************************/ - /* System specific includes */ #if defined(WAN_EC_USER) # include @@ -73,13 +72,10 @@ $Octasic_Revision: 25 $ # include # include # endif - -#include "oct6100api/oct6100_apiud.h" -#include "oct6100api/oct6100_errors.h" - -#include "oct6100api/oct6100_api.h" -#include "oct6100_version.h" - +# include "oct6100api/oct6100_apiud.h" +# include "oct6100api/oct6100_errors.h" +# include "oct6100api/oct6100_api.h" +# include "oct6100_version.h" # include "wanec_iface.h" #endif @@ -116,11 +112,11 @@ UINT32 Oct6100UserGetTime( #if !defined(__WINDOWS__) /* Retrieve clock tick */ -#if defined(WAN_KERNEL) +# if defined(WAN_KERNEL) wan_getcurrenttime( &TimeVal.tv_sec, &TimeVal.tv_usec ); -#else +# else gettimeofday( &TimeVal, NULL ); -#endif +# endif /* ulClockTicks = ( TimeVal.tv_sec * 1000000 ) + ( TimeVal.tv_usec ); */ /* Create a value im ms (as clock does) */ ulClockTicks = ( TimeVal.tv_sec * 1000 ) + ( TimeVal.tv_usec /1000 ); @@ -211,6 +207,9 @@ union semun { }; #endif +#if defined(WAN_KERNEL) + +#else typedef struct _SEM_FILE_INF_ { UINT32 ulMainProcessId; @@ -224,6 +223,7 @@ typedef struct _SEM_INF_ CHAR szFileName[PATH_MAX]; } tSEM_INF, *tPSEM_INF; +#endif /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ @@ -392,6 +392,25 @@ UINT32 Oct6100UserCreateSerializeObject( return ulRc; #else + wan_spinlock_t *pLockInf; + tPOCTPCIDRV_USER_PROCESS_CONTEXT pContext; + + pContext = (tPOCTPCIDRV_USER_PROCESS_CONTEXT)f_pCreate->pProcessContext; + + if ( ( f_pCreate == NULL ) || ( f_pCreate->pszSerialObjName == NULL ) ) + return cOCT6100_CREATE_SERIAL_FAILED_0; + + /* Alloc a sem inf structure */ + pLockInf = (wan_spinlock_t*)wan_malloc( sizeof(wan_spinlock_t) ); + + /* Check if malloc failed!!! */ + if ( pLockInf == NULL ) + return cOCT6100_CREATE_SERIAL_FAILED_0; /* No memory. */ + + wan_spin_lock_init(pLockInf, "wan_ecapi_lock"); + /* Keep pointer to semaphore information. */ + f_pCreate->ulSerialObjHndl = (PVOID)pLockInf; + return cOCT6100_ERR_OK; #endif } @@ -485,6 +504,18 @@ UINT32 Oct6100UserDestroySerializeObject( return ulRc; #else + wan_spinlock_t *pLockInf; + + if ( ( f_pDestroy == NULL ) || ( f_pDestroy->ulSerialObjHndl == 0x0 ) ) + return cOCT6100_DESTROY_SERIAL_FAILED_0; + + pLockInf = (wan_spinlock_t*)(f_pDestroy->ulSerialObjHndl); + + if (wan_spin_is_locked(pLockInf)){ + return cOCT6100_DESTROY_SERIAL_FAILED_0; + } + + wan_free( pLockInf ); return cOCT6100_ERR_OK; #endif } @@ -575,8 +606,24 @@ UINT32 Oct6100UserSeizeSerializeObject( } return( ulRc ); #else - return cOCT6100_ERR_OK; + wan_spinlock_t *pLockInf; + if( f_pSeize == NULL ) + return cOCT6100_SEIZE_SERIAL_FAILED_0; + + if ( f_pSeize->ulSerialObjHndl == 0 ) + return cOCT6100_SEIZE_SERIAL_FAILED_0; + + pLockInf = (wan_spinlock_t*)f_pSeize->ulSerialObjHndl; + + /* Check mutex handle */ + if ( pLockInf ){ + if (wan_spin_trylock(pLockInf)){ + return cOCT6100_ERR_OK; + } + return cOCT6100_SEIZE_SERIAL_FAILED_1; + } + return cOCT6100_ERR_OK; #endif } @@ -629,7 +676,21 @@ UINT32 Oct6100UserReleaseSerializeObject( return( ulRc ); #else + wan_spinlock_t *pLockInf; + if( f_pRelease == NULL ) + return cOCT6100_RELEASE_SERIAL_FAILED_0; + + if ( f_pRelease->ulSerialObjHndl == 0 ) + return cOCT6100_RELEASE_SERIAL_FAILED_0; + + pLockInf = (wan_spinlock_t*)f_pRelease->ulSerialObjHndl; + + /* Check mutex handle */ + if ( pLockInf ){ + wan_spin_unlock(pLockInf); + return cOCT6100_ERR_OK; + } return cOCT6100_ERR_OK; #endif diff --git a/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_channel_priv.h b/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_channel_priv.h index 496b3b8..bf2667e 100644 --- a/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_channel_priv.h +++ b/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapi/oct6100api/oct6100_channel_priv.h @@ -526,4 +526,13 @@ INT32 Oct6100ApiOctFloatToDbEnergyHalf( UINT16 Oct6100ApiDbAmpHalfToOctFloat( IN INT32 x ); +UINT32 Oct6100ApiReserveBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + OUT PUINT16 f_pusBiDirChanIndex ); + +UINT32 Oct6100ApiReleaseBiDirChanEntry( + IN tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulBiDirChanIndex ); + + #endif /* __OCT6100_CHANNEL_PRIV_H__ */ diff --git a/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapiw/oct6100_apiw_linux/oct6100api.mak b/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapiw/oct6100_apiw_linux/oct6100api.mak index 427c129..a70429e 100755 --- a/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapiw/oct6100_apiw_linux/oct6100api.mak +++ b/patches/kdrivers/wanec/oct6100_api.PR48/octdeviceapiw/oct6100_apiw_linux/oct6100api.mak @@ -1,6 +1,6 @@ #============================================================================= # -# File: oct6100api.mak ($Revision: 1.1 $) +# File: oct6100api.mak ($Revision: 1.2 $) # # Description: Makefile for building the OCT6100 API library. # @@ -47,7 +47,7 @@ INC = -I../../include \ -I../../include/oct6100api \ -I../../include/apilib \ -I../../octdeviceapi/oct6100api \ - -I/usr/include/ -I../../../ + -I/usr/include/wanpipe -I../../../ CCFLAGS = -m32 -DDEVICE_IOCTL -DWAN_EC_USER -D__LINUX__ -L/usr/local/lib \ -fPIC -ansi -Wall -Wpointer-arith -Winline -fno-builtin \ diff --git a/patches/kdrivers/wanec/sources b/patches/kdrivers/wanec/sources index 7abc756..063dd8e 100755 --- a/patches/kdrivers/wanec/sources +++ b/patches/kdrivers/wanec/sources @@ -9,22 +9,19 @@ MSC_WARNING_LEVEL=-W3 -WX #make sure no optimization done, even in "Free" build: MSC_OPTIMIZATION=/Odi -C_DEFINES=$(C_DEFINES) -D__WINDOWS__ -D__KERNEL__ -DBUSENUM_DRV -C_DEFINES=$(C_DEFINES) -DSANG_DBG +C_DEFINES=$(C_DEFINES) -D__WINDOWS__ -D__KERNEL__ -DVIRTUAL_IF_DRV -#build can not expand Env Vars names longer than 8 chars, so use -#absolute paths INCLUDES=$(DDK_INC_PATH);\ -D:\cvshome\development\wanpipe_windows\include\pnp;\ -D:\cvshome\development\wanpipe_windows\include\api;\ -D:\cvshome\development\wanpipe_windows\include\octasic\include;\ -D:\cvshome\development\wanpipe_windows\include\octasic\include\oct6100api;\ -D:\cvshome\development\wanpipe_windows\include\octasic\octdeviceapi\oct6100api;\ -D:\cvshome\development\wanpipe_windows\include\octasic\apilib\llman;\ -D:\cvshome\development\wanpipe_windows\include\octasic\include\apilib;\ -D:\cvshome\development\wanpipe_windows\include\octasic\include\octrpc;\ -D:\cvshome\development\wanpipe_windows\include\octasic\apilib\bt;\ -D:\cvshome\development\wanpipe_windows\include\debug +d:\development\wanpipe_windows\include;\ +d:\development\wanpipe_common\include;\ +d:\development\wanpipe_common\wanec;\ +d:\development\wanpipe_common\wanec\oct6100_api.PR43\include;\ +d:\development\wanpipe_common\wanec\oct6100_api.PR43\include\oct6100api;\ +d:\development\wanpipe_common\wanec\oct6100_api.PR43\octdeviceapi\oct6100api;\ +d:\development\wanpipe_common\wanec\oct6100_api.PR43\apilib\llman;\ +d:\development\wanpipe_common\wanec\oct6100_api.PR43\include\apilib;\ +d:\development\wanpipe_common\wanec\oct6100_api.PR43\include\octrpc;\ +d:\development\wanpipe_common\wanec\oct6100_api.PR43\apilib\bt SOURCES= wanec_iface.c \ wanec_cmd.c \ diff --git a/patches/kdrivers/wanec/wanec b/patches/kdrivers/wanec/wanec new file mode 120000 index 0000000..6919cf0 --- /dev/null +++ b/patches/kdrivers/wanec/wanec @@ -0,0 +1 @@ +../../wanpipe_common/wanec \ No newline at end of file diff --git a/patches/kdrivers/wanec/wanec.mod.c b/patches/kdrivers/wanec/wanec.mod.c index f73e369..27490c5 100644 --- a/patches/kdrivers/wanec/wanec.mod.c +++ b/patches/kdrivers/wanec/wanec.mod.c @@ -18,6 +18,7 @@ __attribute_used__ __attribute__((section("__versions"))) = { { 0x89e24b9c, "struct_module" }, { 0x12da5bb2, "__kmalloc" }, + { 0x7e3f931f, "_spin_trylock" }, { 0xec7bc0d, "__mod_timer" }, { 0xd6ee688f, "vmalloc" }, { 0x4827a016, "del_timer" }, @@ -25,6 +26,7 @@ __attribute__((section("__versions"))) = { { 0xb5513e49, "class_device_create" }, { 0xab978df6, "malloc_sizes" }, { 0x1bcd461f, "_spin_lock" }, + { 0x4e830a3e, "strnicmp" }, { 0xeae3dfd6, "__const_udelay" }, { 0x2fd1d81c, "vfree" }, { 0x1d26aa98, "sprintf" }, @@ -51,4 +53,4 @@ __attribute__((section(".modinfo"))) = "depends="; -MODULE_INFO(srcversion, "4B81F8CBCF0FE7DE2D1F612"); +MODULE_INFO(srcversion, "A6BF1CF61774AE275ECC9A5"); diff --git a/patches/kdrivers/wanec/wanec_cmd.c b/patches/kdrivers/wanec/wanec_cmd.c index 7341fbc..b2832e6 100644 --- a/patches/kdrivers/wanec/wanec_cmd.c +++ b/patches/kdrivers/wanec/wanec_cmd.c @@ -10,6 +10,10 @@ * March 19, 2006 Alex Feldman Enable Sout Adaptive Noise * Reduction for all channel by * default. + * + * January 9, 2008 David Rokhvarg + * Added support for Sangoma MS Windows Driver + * */ @@ -43,8 +47,15 @@ int verbose; /*============================================================= * Definitions */ -#define MAX_EC_PORT_RANGE 32 -#define WAN_OCT6100_READ_LIMIT 0x10000 +#define WANEC_MAX_PORT_RANGE 32 +#define WANEC_MAX_BRI_PORT_RANGE 2 +#define WANEC_READ_LIMIT 0x10000 + +#define WANEC_MAX_CONFBRIDGE_DEF 32 +#define WANEC_MAC_PLAYOUT_BUFFERS 20 + +#define WANEC_MAX_TONEEVENTS 8 +#define WANEC_MAX_PLAYOUTEVENTS 8 /*============================================================= * Global Parameters @@ -92,41 +103,52 @@ UINT32 DetectedRoutToneNumbers[WAN_NUM_DTMF_TONES] = * Function prototype */ -int wanec_ChipOpenPrep(wan_ec_dev_t*, wan_ec_api_t*); +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose); int wanec_ChipOpen(wan_ec_dev_t*, int); -int wanec_ChipOpen_OLD(wan_ec_dev_t*, wan_ec_api_t*); int wanec_ChipClose(wan_ec_dev_t*, int verbose); -int wanec_ChipStats(wan_ec_dev_t*, wan_ec_api_t*, int reset); +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose); -int wanec_ChannelOpen(wan_ec_dev_t*, wan_ec_api_t*); -int wanec_ChannelClose(wan_ec_dev_t*, wan_ec_api_t*, int); -int wanec_ChannelModify(wan_ec_dev_t*, INT, UINT32, wan_ec_api_t*, int verbose); -int wanec_ChannelStats(wan_ec_dev_t*, INT channel, wan_ec_api_t*, int); +int wanec_ChannelOpen(wan_ec_dev_t*, int); +int wanec_ChannelClose(wan_ec_dev_t*, int); +int wanec_ChannelModifyOpmode(wan_ec_dev_t*, INT, UINT32, int verbose); +int wanec_ChannelModifyCustom(wan_ec_dev_t*, INT, wanec_chan_custom_t*, int verbose); +int wanec_ChannelStats(wan_ec_dev_t*, INT channel, wanec_chan_stats_t *chan_stats, int reset); -int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char port, int verbose); -int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char port, int verbose); +int wanec_ChannelMute(wan_ec_dev_t*, INT channel, wanec_chan_mute_t*, int); +int wanec_ChannelUnMute(wan_ec_dev_t*, INT channel, wanec_chan_mute_t*, int); -int wanec_DebugChannel(wan_ec_t *ec, INT channel, int verbose); -int wanec_DebugGetData(wan_ec_t *ec, wan_ec_api_t *ec_api); +int wanec_TonesEnable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t*, int verbose); +int wanec_TonesDisable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t*, int verbose); -int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api); -int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api); -int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api); +int wanec_DebugChannel(wan_ec_dev_t*, INT channel, int verbose); +int wanec_DebugGetData(wan_ec_dev_t*, wanec_chan_monitor_t *chan_monitor, int verbose); -int wanec_ConfBridgeOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -int wanec_ConfBridgeClose(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose); +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose); +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); -int wanec_EventTone(wan_ec_t *ec, int verbose); +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); +int wanec_ConfBridgeChanAdd(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanRemove(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanUnMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeDominantSpeakerSet(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int enable, int verbose); +int wanec_ConfBridgeMaskChange(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, UINT32 mask, int verbose); +int wanec_ConfBridgeGetStats(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); + +int wanec_ToneEvent(wan_ec_t *ec, int verbose); +int wanec_PlayoutEvent(wan_ec_t *ec, int verbose); int wanec_ISR(wan_ec_t *ec, int verbose); int wanec_fe2ec_channel(wan_ec_dev_t*, int); static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl); static int wanec_ec2fe_channel(wan_ec_t*, int, wan_ec_dev_t**); -extern int wanec_ChipParam(wan_ec_t*,tPOCT6100_CHIP_OPEN, wan_ec_api_t*); -extern int wanec_ChanParam(wan_ec_t*,tPOCT6100_CHANNEL_MODIFY, wan_ec_api_t*); +extern int wanec_ChipParam(wan_ec_t*,tPOCT6100_CHIP_OPEN, wan_custom_conf_t*, int); +extern int wanec_ChanParam(wan_ec_t*,tPOCT6100_CHANNEL_MODIFY, wan_custom_conf_t*, int); extern int wanec_ChanParamList(wan_ec_t *ec); u32 wanec_req_write(void*, u32 write_addr, u16 write_data); @@ -154,23 +176,41 @@ static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl) } int wanec_fe2ec_channel(wan_ec_dev_t *ec_dev, int fe_channel) { - /*ec_channel = ec_dev->fe_lineno * ec_dev->fe_max_channels + channel;*/ - return ec_dev->fe_lineno * MAX_EC_PORT_RANGE + fe_channel; + int ec_channel = 0; + + if (ec_dev->fe_media == WAN_MEDIA_BRI){ + if (ec_dev->fe_lineno >= 12){ + ec_channel = WANEC_MAX_PORT_RANGE; + } + ec_channel += (ec_dev->fe_lineno * WANEC_MAX_BRI_PORT_RANGE + (fe_channel-1)); + }else if (ec_dev->fe_media == WAN_MEDIA_T1 || ec_dev->fe_media == WAN_MEDIA_FXOFXS){ + ec_channel = ec_dev->fe_lineno * WANEC_MAX_PORT_RANGE + (fe_channel-1); + }else{ + /*ec_channel = ec_dev->fe_lineno * ec_dev->fe_max_chans + channel;*/ + ec_channel = ec_dev->fe_lineno * WANEC_MAX_PORT_RANGE + fe_channel; + } + return ec_channel; } static int wanec_ec2fe_channel(wan_ec_t *ec, int ec_chan, wan_ec_dev_t **ec_dev) { - int fe_chan; + wan_ec_dev_t *ec_dev_tmp; + int fe_chan; - *ec_dev = ec->pEcDevMap[ec_chan]; - if (*ec_dev == NULL) return 0; + ec_dev_tmp = ec->pEcDevMap[ec_chan]; + if (ec_dev_tmp == NULL) return 0; - fe_chan = ec_chan % MAX_EC_PORT_RANGE; - - if ((*ec_dev)->fe_media == WAN_MEDIA_T1 || - (*ec_dev)->fe_media == WAN_MEDIA_FXOFXS){ - fe_chan++; + fe_chan = ec_chan % WANEC_MAX_PORT_RANGE; + if (ec_dev_tmp->fe_media == WAN_MEDIA_BRI){ + fe_chan = fe_chan % WANEC_MAX_BRI_PORT_RANGE; + fe_chan++; + }else{ + if (ec_dev_tmp->fe_media == WAN_MEDIA_T1 || + ec_dev_tmp->fe_media == WAN_MEDIA_FXOFXS){ + fe_chan++; + } } + if (ec_dev && *ec_dev) *ec_dev = ec_dev_tmp; return fe_chan; } @@ -183,7 +223,7 @@ tOCT6100_CHIP_IMAGE_INFO f_ChipImageInfo; #if 0 tOCT6100_GET_HW_REVISION f_Revision; #endif -int wanec_ChipStats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int reset) +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose) { wan_ec_t *ec; tOCT6100_CHIP_STATS f_ChipStats; @@ -193,9 +233,8 @@ int wanec_ChipStats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int reset) WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - if (ec_api){ - PRINT1(ec_api->verbose, - "%s: Reading chip statistics...\n", + if (chip_stats){ + PRINT2(verbose, "%s: Reading chip statistics...\n", ec->name); } Oct6100ChipGetStatsDef( &f_ChipStats ); @@ -209,18 +248,17 @@ int wanec_ChipStats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int reset) ec->name, ulResult); return -EINVAL; } - if (ec_api){ - memcpy( &ec_api->u_chip_stats.f_ChipStats, + if (chip_stats){ + memcpy( &chip_stats->f_ChipStats, &f_ChipStats, sizeof(tOCT6100_CHIP_STATS)); } - if (ec_api){ - PRINT1(ec_api->verbose, - "%s: Reading chip image info...\n", + if (chip_stats){ + PRINT2(verbose, "%s: Reading chip image info...\n", ec->name); } - + Oct6100ChipGetImageInfoDef( &f_ChipImageInfo ); ulResult = Oct6100ChipGetImageInfo( ec->pChipInstance, @@ -231,78 +269,77 @@ int wanec_ChipStats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int reset) ec->name, ulResult); return -EINVAL; } - if (ec_api){ - if (ec_api->u_chip_stats.f_ChipImageInfo){ + if (chip_stats){ + if (chip_stats->f_ChipImageInfo){ int err; err = WAN_COPY_TO_USER( &f_ChipImageInfo, - ec_api->u_chip_stats.f_ChipImageInfo, + chip_stats->f_ChipImageInfo, sizeof(tOCT6100_CHIP_IMAGE_INFO)); if (err){ DEBUG_EVENT( "%s: Failed to copy chip image info to user space [%s:%d]!\n", - ec_api->devname, - __FUNCTION__,__LINE__); + ec->name, __FUNCTION__,__LINE__); return -EINVAL; } }else{ - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller image description:\n%s\n", ec->name, f_ChipImageInfo.szVersionNumber); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller image build ID\t\t\t%08X\n", ec->name, f_ChipImageInfo.ulBuildId); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller maximum number of channels\t%d\n", ec->name, f_ChipImageInfo.ulMaxChannels); #if 0 - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller maximum tail displacement\t\t%d\n", ec->name, f_ChipImageInfo.ulMaxTailDisplacement); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller per channel tail displacement\t%s\n", ec->name, (f_ChipImageInfo.fPerChannelTailDisplacement == TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller per channel tail length\t\t%s\n", ec->name, (f_ChipImageInfo.fPerChannelTailLength == TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller maximum tail length\t\t%d\n", ec->name, f_ChipImageInfo.ulMaxTailLength); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller buffer Playout support\t\t%s\n", ec->name, (f_ChipImageInfo.fBufferPlayout == TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller adaptive noise reduction\t\t%s\n", ec->name, (f_ChipImageInfo.fAdaptiveNoiseReduction==TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller SOUT noise bleaching\t\t%s\n", ec->name, (f_ChipImageInfo.fSoutNoiseBleaching==TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller ROUT noise reduction\t\t%s\n", ec->name, (f_ChipImageInfo.fRoutNoiseReduction==TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller ROUT noise reduction level\t\t%s\n", ec->name, (f_ChipImageInfo.fRoutNoiseReductionLevel==TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller automatic level control\t\t%s\n", ec->name, (f_ChipImageInfo.fAutoLevelControl==TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller acoustic echo cancellation\t\t%s\n", ec->name, (f_ChipImageInfo.fAcousticEcho==TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller conferencing\t\t%s\n", ec->name, (f_ChipImageInfo.fConferencing==TRUE)?"TRUE":"FALSE"); - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Echo Canceller conferencing noise reduction\t\t%s\n", ec->name, (f_ChipImageInfo.fConferencingNoiseReduction==TRUE)?"TRUE":"FALSE"); @@ -331,38 +368,17 @@ int wanec_ChipStats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int reset) return 0; } -int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose) { tOCT6100_GET_INSTANCE_SIZE InstanceSize; wan_ec_t *ec; UINT32 ulResult; - INT err; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); - WAN_ASSERT(ec_api->u_config.imageData == NULL); + WAN_ASSERT(config->imageData == NULL); ec = ec_dev->ec; - ec->pImageData = wan_vmalloc(ec_api->u_config.imageSize * sizeof(UINT8)); - if (ec->pImageData == NULL){ - DEBUG_EVENT( - "ERROR: Failed to allocate memory for EC image %ld bytes [%s:%d]!\n", - (unsigned long)ec_api->u_config.imageSize*sizeof(UINT8), - __FUNCTION__,__LINE__); - return -EINVAL; - } - err = WAN_COPY_FROM_USER( - ec->pImageData, - ec_api->u_config.imageData, - ec_api->u_config.imageSize * sizeof(UINT8)); - if (err){ - DEBUG_EVENT( - "ERROR: Failed to copy EC image from user space [%s:%d]!\n", - __FUNCTION__,__LINE__); - wan_vfree(ec->pImageData); - return -EINVAL; - } - ulResult = Oct6100ChipOpenDef( &ec->f_OpenChip ); /*==============================================================*/ @@ -385,19 +401,19 @@ int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) /* General parameters */ /* Chip ID.*/ - ec->f_OpenChip.ulUserChipId = 1; + ec->f_OpenChip.ulUserChipId = ec->chip_no; /* Set the max number of accesses to 1024 to speed things up */ - ec->f_OpenChip.ulMaxRwAccesses = 1024; + ec->f_OpenChip.ulMaxRwAccesses = 1024; /* Set the maximums that the chip needs to support for this test */ - ec->f_OpenChip.ulMaxChannels = ec_api->u_config.max_channels; + ec->f_OpenChip.ulMaxChannels = config->max_channels; ec->f_OpenChip.ulMaxBiDirChannels = 0; - ec->f_OpenChip.ulMaxConfBridges = 0; + ec->f_OpenChip.ulMaxConfBridges = 0; //WANEC_MAX_CONFBRIDGE_DEF; ec->f_OpenChip.ulMaxPhasingTssts = 0; - ec->f_OpenChip.ulMaxTdmStreams = 32; - ec->f_OpenChip.ulMaxTsiCncts = 2; + ec->f_OpenChip.ulMaxTdmStreams = 32; + ec->f_OpenChip.ulMaxTsiCncts = 2; /*==============================================================*/ @@ -410,18 +426,18 @@ int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) #else ec->f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_DDR; #endif - - ec->f_OpenChip.ulNumMemoryChips = 2; - /* **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_8MB; **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_16MB;*/ - ec->f_OpenChip.ulMemoryChipSize = ec_api->u_config.memory_chip_size; + ec->f_OpenChip.ulMemoryChipSize = config->memory_chip_size; + ec->f_OpenChip.ulNumMemoryChips = 2; + ec->f_OpenChip.ulSoftBufferPlayoutEventsBufSize = 2048; + ec->f_OpenChip.fEnableChannelRecording = TRUE; #if defined(ENABLE_ACOUSTICECHO) - ec->f_OpenChip.fEnableAcousticEcho = TRUE; + ec->f_OpenChip.fEnableAcousticEcho = TRUE; #endif #if defined(ENABLE_PRODBIST) @@ -430,10 +446,10 @@ int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) ec->f_OpenChip.ulNumProductionBistLoops = 0x1; #endif - ec->f_OpenChip.pbyImageFile = ec->pImageData; - ec->f_OpenChip.ulImageSize = ec_api->u_config.imageSize; + ec->f_OpenChip.ulMaxPlayoutBuffers = WANEC_MAC_PLAYOUT_BUFFERS; - ec->f_OpenChip.ulMaxPlayoutBuffers = cOCT6100_MAX_PLAYOUT_BUFFERS; + ec->f_OpenChip.pbyImageFile = ec->pImageData; + ec->f_OpenChip.ulImageSize = ec->ImageSize; /* Assign board index (0). */ ec->f_Context.ulBoardId = ec->chip_no; @@ -442,14 +458,13 @@ int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) ec->f_Context.ec_dev = ec_dev; /* Interface name to driver */ - strlcpy(ec->f_Context.devname, ec_api->devname, WAN_DRVNAME_SZ); + strlcpy(ec->f_Context.devname, devname, WAN_DRVNAME_SZ); ulResult = Oct6100GetInstanceSize(&ec->f_OpenChip, &InstanceSize); if ( ulResult != cOCT6100_ERR_OK ){ DEBUG_EVENT( "ERROR: %s: Failed to get EC chip instance size (err=0x%X)!\n", ec->name, ulResult); - wan_vfree(ec->pImageData); return -EINVAL; } @@ -460,22 +475,23 @@ int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) DEBUG_EVENT( "ERROR: %s: Failed to allocate memory for EC chip (%d bytes)!\n", ec->name,InstanceSize.ulApiInstanceSize); - wan_vfree(ec->pImageData); return -EINVAL; } /* Open the OCT6100 on the evaluation board. */ - ec->f_OpenChip.pProcessContext = (PVOID)&ec->f_Context; + ec->f_OpenChip.pProcessContext = (PVOID)&ec->f_Context; - /* parse advianced params */ - if (ec_api->param_no){ - wanec_ChipParam(ec, &ec->f_OpenChip, ec_api); + /* parse advanced params (global custom configuration) */ + if (ec->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &ec->custom_conf, verbose); + } + /* parse advanced params (command line custom configuration) */ + if (config->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &config->custom_conf, verbose); } - /* Chip Open parameter verification */ - ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; - ec->ulDebugDataMode = ec_api->u_config.debug_data_mode; + ec->ulDebugDataMode = config->debug_data_mode; return 0; } @@ -489,9 +505,15 @@ int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - PRINT1(verbose, + PRINT2(verbose, "%s: Opening Echo Canceller Chip ...\n", ec->name); + if (ec->f_OpenChip.pbyImageFile == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid EC image pointer\n", + ec->name); + return -EINVAL; + } ulResult = Oct6100ChipOpen( ec->pChipInstance, /* API instance memory. */ &ec->f_OpenChip ); /* Open chip structure. */ @@ -502,12 +524,13 @@ int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) "ERROR: %s: Failed to open Echo Canceller Chip (err=0x%X)\n", ec->name, ulResult); } - wan_vfree(ec->pImageData); return -EINVAL; } - wan_vfree(ec->pImageData); - if (wanec_ChipStats(ec_dev, NULL, TRUE)){ + if (wanec_ChipStats(ec_dev, NULL, TRUE, verbose)){ + DEBUG_EVENT( + "ERROR: %s: Failed to read EC chip statistics!\n", + ec->name); wanec_ChipClose(ec_dev, verbose); return EINVAL; } @@ -535,7 +558,9 @@ int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) wanec_ChipClose(ec_dev, verbose); return EINVAL; } +#if !defined(__WINDOWS__) ec->pEcDevMap = wan_malloc(sizeof(wan_ec_dev_t*) * ec->max_channels); +#endif if (ec->pEcDevMap == NULL){ DEBUG_EVENT( "ERROR: %s: Failed allocate memory for ec channel map!\n", @@ -549,219 +574,6 @@ int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) ec->pEchoChannelHndl[ec_chan] = cOCT6100_INVALID_HANDLE; ec->pEcDevMap[ec_chan] = NULL; } - - return 0; -} - -int wanec_ChipOpen_OLD(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) -{ - tOCT6100_CHIP_OPEN f_OpenChip; - tOCT6100_GET_INSTANCE_SIZE InstanceSize; - wan_ec_t *ec; - /*PUINT8 pImageData = NULL;*/ - UINT32 ulResult, i = 0; - INT ec_chan = 0, err; - - WAN_ASSERT(ec_dev == NULL); - WAN_ASSERT(ec_dev->ec == NULL); - WAN_ASSERT(ec_api->u_config.imageData == NULL); - ec = ec_dev->ec; - - ec->pImageData = wan_vmalloc(ec_api->u_config.imageSize * sizeof(UINT8)); - if (ec->pImageData == NULL){ - DEBUG_EVENT( - "ERROR: Failed to allocate memory for EC image %ld bytes [%s:%d]!\n", - (unsigned long)ec_api->u_config.imageSize*sizeof(UINT8), - __FUNCTION__,__LINE__); - return -EINVAL; - } - err = WAN_COPY_FROM_USER( - ec->pImageData, - ec_api->u_config.imageData, - ec_api->u_config.imageSize * sizeof(UINT8)); - if (err){ - DEBUG_EVENT( - "ERROR: Failed to copy EC image from user space [%s:%d]!\n", - __FUNCTION__,__LINE__); - wan_vfree(ec->pImageData); - return -EINVAL; - } - - ulResult = Oct6100ChipOpenDef( &f_OpenChip ); - - /*==============================================================*/ - /* Configure clocks */ - - /* upclk oscillator is at 33.33 Mhz */ - f_OpenChip.ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; - - /* mclk will be generated by internal PLL at 133 Mhz */ - f_OpenChip.fEnableMemClkOut = TRUE; -#if 1 - f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ; -#else - f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_125_MHZ; /*125*/ -#endif - - /*==============================================================*/ - - /*==============================================================*/ - /* General parameters */ - - /* Chip ID.*/ - f_OpenChip.ulUserChipId = 1; - - /* Set the max number of accesses to 1024 to speed things up */ - f_OpenChip.ulMaxRwAccesses = 1024; - - /* Set the maximums that the chip needs to support for this test */ - f_OpenChip.ulMaxChannels = ec_api->u_config.max_channels; - -#if 1 - f_OpenChip.ulMaxPlayoutBuffers = WAN_NUM_PLAYOUT_TONES; -#else - f_OpenChip.ulMaxPlayoutBuffers = 2; -#endif - - f_OpenChip.ulMaxBiDirChannels = 0; - f_OpenChip.ulMaxConfBridges = 0; - f_OpenChip.ulMaxPhasingTssts = 0; - f_OpenChip.ulMaxTdmStreams = 32; - f_OpenChip.ulMaxTsiCncts = 2; - - /*==============================================================*/ - - /*==============================================================*/ - /* External Memory Settings */ - - /* Use DDR memory.*/ -#if 1 - f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_SDR; -#else - f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_DDR; -#endif - - f_OpenChip.ulNumMemoryChips = 2; - - /* - **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_8MB; - **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_16MB;*/ - f_OpenChip.ulMemoryChipSize = ec_api->u_config.memory_chip_size; - - f_OpenChip.fEnableChannelRecording = TRUE; - -#if defined(ENABLE_ACOUSTICECHO) - f_OpenChip.fEnableAcousticEcho = TRUE; -#endif - -#if defined(ENABLE_PRODBIST) - /* Enable production bist mode */ - f_OpenChip.fEnableProductionBist = TRUE; - f_OpenChip.ulNumProductionBistLoops = 0x1; -#endif - - f_OpenChip.pbyImageFile = ec->pImageData; - f_OpenChip.ulImageSize = ec_api->u_config.imageSize; - - /* Assign board index (0). */ - ec->f_Context.ulBoardId = ec->chip_no; - - /* Handle to driver */ - ec->f_Context.ec_dev = ec_dev; - - /* Interface name to driver */ - strlcpy(ec->f_Context.devname, ec_api->devname, WAN_DRVNAME_SZ); - - ulResult = Oct6100GetInstanceSize(&f_OpenChip, &InstanceSize); - if ( ulResult != cOCT6100_ERR_OK ){ - DEBUG_EVENT( - "ERROR: %s: Failed to get EC chip instance size (err=0x%X)!\n", - ec->name, ulResult); - wan_vfree(ec->pImageData); - return -EINVAL; - } - - /* Allocate memory needed for API instance. */ - ec->pChipInstance = - (tPOCT6100_INSTANCE_API)wan_vmalloc(InstanceSize.ulApiInstanceSize); - if (ec->pChipInstance == NULL){ - DEBUG_EVENT( - "ERROR: %s: Failed to allocate memory for EC chip (%d bytes)!\n", - ec->name,InstanceSize.ulApiInstanceSize); - wan_vfree(ec->pImageData); - return -EINVAL; - } - - /* Open the OCT6100 on the evaluation board. */ - f_OpenChip.pProcessContext = (PVOID)&ec->f_Context; - - /* parse advianced params */ - if (ec_api->param_no){ - wanec_ChipParam(ec, &f_OpenChip, ec_api); - } - - PRINT1(ec_api->verbose, - "%s: Opening Echo Canceller Chip ...\n", - ec->name); - ulResult = Oct6100ChipOpen( - ec->pChipInstance, /* API instance memory. */ - &f_OpenChip ); /* Open chip structure. */ - if ( ulResult != cOCT6100_ERR_OK ){ - DEBUG_EVENT( - "ERROR: %s: Failed to open Echo Canceller Chip (err=0x%X)\n", - ec->name, ulResult); - wan_vfree(ec->pImageData); - return -EINVAL; - } - wan_vfree(ec->pImageData); - - if (wanec_ChipStats(ec_dev, NULL, TRUE)){ - wanec_ChipClose(ec_dev, ec_api->verbose); - return EINVAL; - } - - ec->pToneBufferIndexes = - wan_malloc(sizeof(UINT32) * ec->f_OpenChip.ulMaxPlayoutBuffers); - if (ec->pToneBufferIndexes == NULL){ - DEBUG_EVENT( - "ERROR: %s: Failed allocate memory for playout handles!\n", - ec->name); - wanec_ChipClose(ec_dev, ec_api->verbose); - return EINVAL; - } - i = 0; - while(i < ec->f_OpenChip.ulMaxPlayoutBuffers){ - ec->pToneBufferIndexes[i++] = cOCT6100_INVALID_VALUE; - } - - ec->pEchoChannelHndl = - wan_malloc(sizeof(UINT32) * ec->max_channels); - if (ec->pEchoChannelHndl == NULL){ - DEBUG_EVENT( - "ERROR: %s: Failed allocate memory for channel handle!\n", - ec->name); - wan_free(ec->pToneBufferIndexes); - wanec_ChipClose(ec_dev, ec_api->verbose); - return EINVAL; - } - ec->pEcDevMap = wan_malloc(sizeof(wan_ec_dev_t*) * ec->max_channels); - if (ec->pEcDevMap == NULL){ - DEBUG_EVENT( - "ERROR: %s: Failed allocate memory for ec channel map!\n", - ec->name); - wan_free(ec->pToneBufferIndexes); - wan_free(ec->pEchoChannelHndl); - wanec_ChipClose(ec_dev, ec_api->verbose); - return -EINVAL; - } - for(ec_chan = 0; ec_chan < ec->max_channels; ec_chan++){ - ec->pEchoChannelHndl[ec_chan] = cOCT6100_INVALID_HANDLE; - ec->pEcDevMap[ec_chan] = NULL; - } - - ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; - ec->ulDebugDataMode = ec_api->u_config.debug_data_mode; - return 0; } @@ -774,7 +586,7 @@ int wanec_ChipClose(wan_ec_dev_t *ec_dev, int verbose) WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - PRINT1(verbose, + PRINT2(verbose, "%s: Closing Echo Canceller Chip ...\n", ec->name); Oct6100ChipCloseDef( &f_CloseChip ); @@ -799,14 +611,16 @@ int wanec_ChipClose(wan_ec_dev_t *ec_dev, int verbose) wan_free(ec->pEchoChannelHndl); ec->pEchoChannelHndl = NULL; } +#if !defined(__WINDOWS__) if (ec->pEcDevMap){ wan_free(ec->pEcDevMap); ec->pEcDevMap = NULL; } +#endif return 0; } -int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, int verbose) { tOCT6100_CHANNEL_OPEN EchoChannelOpen; wan_ec_t *ec; @@ -823,7 +637,7 @@ int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) pcm_law_type = (WAN_FE_TDMV_LAW(&card->fe) == WAN_TDMV_MULAW) ? cOCT6100_PCM_U_LAW : cOCT6100_PCM_A_LAW; - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Openning all Echo Canceller channels (%s)...\n", ec->name, (pcm_law_type == cOCT6100_PCM_U_LAW) ? @@ -831,7 +645,8 @@ int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) DEBUG_EVENT("%s: Opening HW Echo Canceller (NoiseRed=%s)\n", ec->name,card->hwec_conf.noise_reduction?"On":"Off"); - + + for(channel = 0; channel < ec->max_channels; channel++){ Oct6100ChannelOpenDef( &EchoChannelOpen ); @@ -887,7 +702,7 @@ int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) ** cOCT6100_COMFORT_NOISE_OFF, ** cOCT6100_COMFORT_NOISE_FAST_LATCH */ - PRINT1(ec_api->verbose, + PRINT2(verbose, "%s: Openning Echo Canceller channel %d (%s)...\n", ec->name, channel, @@ -912,7 +727,7 @@ int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) return 0; } -int wanec_ChannelClose(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) +int wanec_ChannelClose(wan_ec_dev_t *ec_dev, int verbose) { wan_ec_t *ec; tOCT6100_CHANNEL_CLOSE EchoChannelClose; @@ -921,7 +736,7 @@ int wanec_ChannelClose(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - PRINT1(verbose, + PRINT2(verbose, "%s: Closing all Echo Canceller channels ...\n", ec->name); for(channel = 0; channel < (UINT32)ec->max_channels; channel++){ @@ -943,11 +758,10 @@ int wanec_ChannelClose(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) return 0; } -int wanec_ChannelModify( wan_ec_dev_t *ec_dev, - INT channel, - UINT32 mode, - wan_ec_api_t *ec_api, - int verbose) +int wanec_ChannelModifyOpmode( wan_ec_dev_t *ec_dev, + INT channel, + UINT32 opmode, + int verbose) { wan_ec_t *ec; tOCT6100_CHANNEL_MODIFY EchoChannelModify; @@ -957,44 +771,58 @@ int wanec_ChannelModify( wan_ec_dev_t *ec_dev, WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - Oct6100ChannelModifyDef( &EchoChannelModify ); + PRINT2(verbose, "%s: Modifing EC Channel OPMODE to %d on ec_chan:%d...\n", + ec->name, opmode, channel); + Oct6100ChannelModifyDef( &EchoChannelModify ); /* Assign the handle memory.*/ EchoChannelModify.ulChannelHndl = ec->pEchoChannelHndl[channel]; - /* Enable echo cancellation */ - EchoChannelModify.ulEchoOperationMode = mode; - - /* parse advianced params */ - if (ec_api && ec_api->param_no){ - int err; - err = wanec_ChanParam(ec, &EchoChannelModify, ec_api); - if (err){ - DEBUG_EVENT( - "%s: WARNING: Unsupported parameter for channel %d!\n", - ec->name, - channel); - return -EINVAL; - } - }else if (mode == cOCT6100_KEEP_PREVIOUS_SETTING){ - wanec_ChanParamList(ec); - return 0; + /* Echo Channel Operation Mode */ + EchoChannelModify.ulEchoOperationMode = opmode; + + /* Open the channel.*/ + ulResult = Oct6100ChannelModify( + ec->pChipInstance, + &EchoChannelModify ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "%s: Failed to modify EC Channel OPMOde for ec_chan:%d (err=0x%X)\n", + ec->name, channel, ulResult); + return EINVAL; } + return 0; +} - if (mode == cOCT6100_KEEP_PREVIOUS_SETTING){ - PRINT1(verbose, - "%s: Modify Channel configuration for channel %d...\n", - ec->name, - channel); - }else{ - PRINT1(verbose, - "%s: Modify EC mode for channel %d to %s ...\n", - ec->name, - channel, - (mode == cOCT6100_ECHO_OP_MODE_POWER_DOWN) ? - "POWER_DOWN" : - (mode == cOCT6100_ECHO_OP_MODE_NORMAL) ? - "NORMAL" : "UNKNOWN"); +int wanec_ChannelModifyCustom( wan_ec_dev_t *ec_dev, + INT channel, + wanec_chan_custom_t *chan_custom, + int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MODIFY EchoChannelModify; + UINT32 ulResult; + int err; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(chan_custom == NULL); + WAN_ASSERT(chan_custom->custom_conf.param_no == 0); + ec = ec_dev->ec; + + PRINT2(verbose, "%s: Modifing EC Channel Config parameters for ec_chan:%d...\n", + ec->name, channel); + + Oct6100ChannelModifyDef( &EchoChannelModify ); + /* Assign the handle memory.*/ + EchoChannelModify.ulChannelHndl = ec->pEchoChannelHndl[channel]; + /* parse advianced params */ + err = wanec_ChanParam(ec, &EchoChannelModify, &chan_custom->custom_conf, verbose); + if (err){ + DEBUG_EVENT( + "%s: WARNING: Unsupported parameter for channel %d!\n", + ec->name, channel); + return -EINVAL; } /* Open the channel.*/ @@ -1002,29 +830,87 @@ int wanec_ChannelModify( wan_ec_dev_t *ec_dev, ec->pChipInstance, &EchoChannelModify ); if (ulResult != cOCT6100_ERR_OK){ - if (mode == cOCT6100_KEEP_PREVIOUS_SETTING){ - PRINT1(verbose, - "%s: Failed to modify Channel config parameters for channel %d (err=0x%X)\n", - ec->name, - channel, - ulResult); - }else{ - DEBUG_EVENT( - "ERROR: %s: Failed to modify EC mode %s for channel %d (err=0x%X)\n", - ec->name, - (mode == cOCT6100_ECHO_OP_MODE_POWER_DOWN) ? - "POWER_DOWN" : - (mode == cOCT6100_ECHO_OP_MODE_NORMAL) ? - "NORMAL" : "UNKNOWN", - channel, - ulResult); - } + DEBUG_EVENT( + "%s: Failed to modify EC channel config parameters for ec_chan:%d (err=0x%X)\n", + ec->name, channel, ulResult); return EINVAL; } return 0; } -int wanec_ChannelStats(wan_ec_dev_t *ec_dev, INT channel, wan_ec_api_t *ec_api, int reset) +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ChannelMute(wan_ec_dev_t* ec_dev, INT ec_chan, wanec_chan_mute_t *mute, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MUTE f_ChannelMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + Oct6100ChannelMuteDef( &f_ChannelMute ); + f_ChannelMute.ulChannelHndl = ec->pEchoChannelHndl[ec_chan]; + f_ChannelMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + PRINT2(verbose, "%s: Muting EC Channel %d on port:%X...\n", + ec->name, ec_chan, f_ChannelMute.ulPortMask); + ulResult = Oct6100ChannelMute( + ec->pChipInstance, + &f_ChannelMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute EC channel %d on port %X (%08X)!\n", + ec->name, ec_chan, f_ChannelMute.ulPortMask, ulResult); + return EINVAL; + } + return 0; +} +int wanec_ChannelUnMute(wan_ec_dev_t *ec_dev, INT ec_chan, wanec_chan_mute_t *mute, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_UNMUTE f_ChannelUnMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + Oct6100ChannelUnMuteDef( &f_ChannelUnMute ); + f_ChannelUnMute.ulChannelHndl = ec->pEchoChannelHndl[ec_chan]; + f_ChannelUnMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (mute == NULL || mute->port_map & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + PRINT2(verbose, "%s: Un-Muting EC channel %d on port:%X...\n", + ec->name, ec_chan, f_ChannelUnMute.ulPortMask); + ulResult = Oct6100ChannelUnMute( + ec->pChipInstance, + &f_ChannelUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to un-mute channel %d on port %X (%08X)!\n", + ec->name, ec_chan, f_ChannelUnMute.ulPortMask, ulResult); + return EINVAL; + } + return 0; +} + +int wanec_ChannelStats(wan_ec_dev_t *ec_dev, INT channel, wanec_chan_stats_t *chan_stats, int verbose) { wan_ec_t *ec; tOCT6100_CHANNEL_STATS f_ChannelStats; @@ -1034,11 +920,11 @@ int wanec_ChannelStats(wan_ec_dev_t *ec_dev, INT channel, wan_ec_api_t *ec_api, WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - PRINT1(ec_api->verbose, "%s: Reading EC statistics for channel %d...\n", + PRINT2(verbose, "%s: Reading EC statistics for channel %d...\n", ec->name, channel); Oct6100ChannelGetStatsDef( &f_ChannelStats ); f_ChannelStats.ulChannelHndl = ec->pEchoChannelHndl[channel]; - f_ChannelStats.fResetStats = reset; + f_ChannelStats.fResetStats = chan_stats->reset; ulResult = Oct6100ChannelGetStats( ec->pChipInstance, &f_ChannelStats); @@ -1048,30 +934,31 @@ int wanec_ChannelStats(wan_ec_dev_t *ec_dev, INT channel, wan_ec_api_t *ec_api, ec->name, channel, ulResult); return EINVAL; } - if (ec_api){ - memcpy( &ec_api->u_chan_stats.f_ChannelStats, + if (chan_stats){ + memcpy( &chan_stats->f_ChannelStats, &f_ChannelStats, sizeof(tOCT6100_CHANNEL_STATS)); } return 0; } -int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char type, int verbose) +int wanec_TonesEnable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t *dtmf, int verbose) { tOCT6100_TONE_DETECTION_ENABLE f_ToneDetectionEnable; UINT32 ulResult; int i; - PRINT1(verbose, "%s: Enable tone detection on channel %d ...\n", + PRINT2(verbose, "%s: Enable EC tone detection on chan %d port %X ...\n", ec->name, - channel); + ec_chan, + (dtmf == NULL) ? WAN_EC_CHANNEL_PORT_SOUT|WAN_EC_CHANNEL_PORT_ROUT:dtmf->port_map); - if (type & WAN_EC_CHANNEL_PORT_ROUT){ + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_ROUT){ for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); f_ToneDetectionEnable.ulChannelHndl = - ec->pEchoChannelHndl[channel]; + ec->pEchoChannelHndl[ec_chan]; f_ToneDetectionEnable.ulToneNumber = DetectedRoutToneNumbers[i]; ulResult = Oct6100ToneDetectionEnable ( @@ -1080,14 +967,14 @@ int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char type, int verbose if ( ulResult == cOCT6100_ERR_OK ){ continue; }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ - PRINT1(verbose, - "%s: Tone detection is already enabled on channel %d for port ROUT!\n", - ec->name, channel); + PRINT2(verbose, + "%s: EC Tone detection is already enabled on channel %d for port ROUT!\n", + ec->name, ec_chan); continue; /* already activated */ }else{ DEBUG_EVENT( - "ERROR: %s: Failed to enable tone detection on channel %d!\n", - ec->name, channel); + "ERROR: %s: Failed to enable EC tone detection on ec chan %d!\n", + ec->name, ec_chan); DEBUG_EVENT( "ERROR: %s: (err=0x%X,i=%d)!\n", ec->name, @@ -1096,12 +983,12 @@ int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char type, int verbose } } } - if (type & WAN_EC_CHANNEL_PORT_SOUT){ + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_SOUT){ for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); f_ToneDetectionEnable.ulChannelHndl = - ec->pEchoChannelHndl[channel]; + ec->pEchoChannelHndl[ec_chan]; f_ToneDetectionEnable.ulToneNumber = DetectedSoutToneNumbers[i]; ulResult = Oct6100ToneDetectionEnable ( @@ -1110,14 +997,14 @@ int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char type, int verbose if ( ulResult == cOCT6100_ERR_OK ){ continue; }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ - PRINT1(verbose, - "%s: Tone detection is already enabled on channel %d for port SOUT!\n", - ec->name, channel); + PRINT2(verbose, + "%s: EC Tone detection is already enabled on channel %d for port SOUT!\n", + ec->name, ec_chan); continue; /* already activated */ }else{ DEBUG_EVENT( - "ERROR: %s: Failed to enable tone detection on channel %d!\n", - ec->name, channel); + "ERROR: %s: Failed to enable EC tone detection on channel %d!\n", + ec->name, ec_chan); DEBUG_EVENT( "ERROR: %s: (err=0x%X,i=%d)!\n", ec->name, @@ -1130,23 +1017,24 @@ int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char type, int verbose return 0; } -int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char type, int verbose) +int wanec_TonesDisable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t *dtmf, int verbose) { tOCT6100_TONE_DETECTION_DISABLE f_ToneDetectionDisable; UINT32 ulResult; INT i; - PRINT1(verbose, "%s: Disable tone detection on channel %d ...\n", + PRINT2(verbose, "%s: Disable EC tone detection on channel %d port %X...\n", ec->name, - channel); - if (type & WAN_EC_CHANNEL_PORT_ROUT){ + ec_chan, + (dtmf == NULL) ? WAN_EC_CHANNEL_PORT_SOUT|WAN_EC_CHANNEL_PORT_ROUT:dtmf->port_map); + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_ROUT){ for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); f_ToneDetectionDisable.ulChannelHndl = - ec->pEchoChannelHndl[channel]; - if (channel >= 0){ + ec->pEchoChannelHndl[ec_chan]; + if (ec_chan >= 0){ f_ToneDetectionDisable.ulToneNumber = DetectedRoutToneNumbers[i]; }else{ @@ -1156,22 +1044,24 @@ int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char type, int verbos ec->pChipInstance, &f_ToneDetectionDisable); if ( ulResult != cOCT6100_ERR_OK ){ - DEBUG_EVENT( - "ERROR: %s: Failed to disable tone detection for channel %d (err=0x%X,i=%d)!\n", - ec->name, channel, - (unsigned int)ulResult, i); - return -EINVAL; + if (ulResult != cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable EC tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, ec_chan, + (unsigned int)ulResult, i); + return -EINVAL; + } } } } - if (type & WAN_EC_CHANNEL_PORT_SOUT){ + if (dtmf == NULL || dtmf->port_map & WAN_EC_CHANNEL_PORT_SOUT){ for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); f_ToneDetectionDisable.ulChannelHndl = - ec->pEchoChannelHndl[channel]; - if (channel >= 0){ + ec->pEchoChannelHndl[ec_chan]; + if (ec_chan >= 0){ f_ToneDetectionDisable.ulToneNumber = DetectedSoutToneNumbers[i]; }else{ @@ -1181,11 +1071,13 @@ int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char type, int verbos ec->pChipInstance, &f_ToneDetectionDisable); if ( ulResult != cOCT6100_ERR_OK ){ - DEBUG_EVENT( - "ERROR: %s: Failed to disable tone detection for channel %d (err=0x%X,i=%d)!\n", - ec->name, channel, - (unsigned int)ulResult, i); - return -EINVAL; + if (ulResult != cOCT6100_ERR_TONE_DETECTION_TONE_NOT_ACTIVATED){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable EC tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, ec_chan, + (unsigned int)ulResult, i); + return -EINVAL; + } } } } @@ -1303,8 +1195,27 @@ static unsigned char wanec_ConvertToneType(UINT32 f_ulToneType) return 0x00; } +static CHAR* wanec_BufferPlayoutType2Str(UINT32 f_ulBufferPlayoutType) +{ + switch (f_ulBufferPlayoutType){ + case cOCT6100_BUFFER_PLAYOUT_EVENT_STOP: return "PLAYOUT_EVENT_STOP"; +#if 0 + case cOCT6100_BUFFER_PLAYOUT_EVENT_CALLER_ID_STOP: return "PLAYOUT_EVENT_CALLER_ID_STOP"; + case cOCT6100_BUFFER_PLAYOUT_EVENT_CALLER_ID_AS_STOP: return "PLAYOUT_EVENT_CALLER_ID_AS_STOP"; +#endif + default: return "INVALID BUFFER_PLAYOUT TYPE!"; + } +} -int wanec_EventTone(wan_ec_t *ec, int verbose) +/* +** wanec_ToneEvent() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ + +int wanec_ToneEvent(wan_ec_t *ec, int verbose) { tOCT6100_EVENT_GET_TONE f_GetToneEvent; tOCT6100_TONE_EVENT ToneEvent[32]; @@ -1314,27 +1225,30 @@ int wanec_EventTone(wan_ec_t *ec, int verbose) UINT32 i; int ec_chan,fe_chan; - PRINT1(verbose, "%s: Getting Tone events ...\n", + PRINT2(verbose, "%s: Getting Tone events ...\n", ec->name); Oct6100EventGetToneDef( &f_GetToneEvent ); f_GetToneEvent.fResetBufs = FALSE; - f_GetToneEvent.ulMaxToneEvent = 32; + f_GetToneEvent.ulMaxToneEvent = WANEC_MAX_TONEEVENTS; f_GetToneEvent.pToneEvent = ToneEvent; ulResult = Oct6100EventGetTone( ec->pChipInstance, &f_GetToneEvent); if ( ulResult != cOCT6100_ERR_OK ){ if ( ulResult != cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY ){ - PRINT1(verbose, "%s: There are not tone events!\n", + PRINT2(verbose, "%s: There are not tone events!\n", ec->name); return 0; } DEBUG_EVENT( "ERROR: %s: Failed to get tone events (err=0x%X)!\n", ec->name, ulResult); - return EINVAL; + return -EINVAL; } + /* No dtmf tone event returned */ + if (!f_GetToneEvent.ulNumValidToneEvent) return 0; + for(i = 0; i < f_GetToneEvent.ulNumValidToneEvent; i++){ ec_chan = wanec_hndl2ec_channel(ec, ToneEvent[i].ulChannelHndl); ec_dev = ec->pEcDevMap[ec_chan]; @@ -1346,7 +1260,7 @@ int wanec_EventTone(wan_ec_t *ec, int verbose) continue; } - PRINT1(verbose, + PRINT2(verbose, "%s: Tone event %s %s on fe_chan=%d ec_chan=%d\n", ec_dev->devname, wanec_ToneId2Str(ToneEvent[i].ulToneDetected), @@ -1356,7 +1270,7 @@ int wanec_EventTone(wan_ec_t *ec, int verbose) card = (sdla_t*)ec_dev->card; if (card->wandev.event_callback.dtmf){ wan_event_t event; - unsigned char dtmf_port=0, dtmf_type=0; + unsigned char dtmf_port = WAN_EC_CHANNEL_PORT_ROUT, dtmf_type; event.type = WAN_EVENT_EC_DTMF; event.channel = fe_chan; @@ -1370,15 +1284,96 @@ int wanec_EventTone(wan_ec_t *ec, int verbose) } } - return 0; + /* Return 1 if more dtmf event are present, otherwise - 0 */ + return (f_GetToneEvent.fMoreEvents == TRUE) ? 1 : 0; } +/* +** wanec_PlayoutEvent() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ +int wanec_PlayoutEvent(wan_ec_t *ec, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_GET_EVENT f_BufferPlayoutGetEvent; + tOCT6100_BUFFER_PLAYOUT_EVENT PlayoutEvent[32]; + UINT32 ulResult; + wan_ec_dev_t *ec_dev; + UINT32 i; + int ec_chan,fe_chan; + + PRINT2(verbose, "%s: Getting EC Buffer Playout events ...\n", + ec->name); + Oct6100BufferPlayoutGetEventDef( &f_BufferPlayoutGetEvent ); + f_BufferPlayoutGetEvent.pBufferPlayoutEvent = PlayoutEvent; + f_BufferPlayoutGetEvent.ulMaxEvent = WANEC_MAX_PLAYOUTEVENTS; + f_BufferPlayoutGetEvent.fResetBufs = FALSE; + + ulResult = Oct6100BufferPlayoutGetEvent( + ec->pChipInstance, + &f_BufferPlayoutGetEvent); + if ( ulResult != cOCT6100_ERR_OK ){ + if ( ulResult != cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY ){ + PRINT2(verbose, "%s: There are not buffer playout events!\n", + ec->name); + return 0; + } + DEBUG_EVENT( + "ERROR: %s: Failed to get buffer playout events (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* No dtmf tone event returned */ + if (!f_BufferPlayoutGetEvent.ulNumValidEvent) return 0; + + for(i = 0; i < f_BufferPlayoutGetEvent.ulNumValidEvent; i++){ + ec_chan = wanec_hndl2ec_channel(ec, PlayoutEvent[i].ulChannelHndl); + ec_dev = ec->pEcDevMap[ec_chan]; + fe_chan = wanec_ec2fe_channel(ec, ec_chan, &ec_dev); + if (ec_dev == NULL || ec_dev->card == NULL){ + DEBUG_EVENT( + "%s: Internal Error: Failed to find fe channel (ec_chan=%d)\n", + ec->name, ec_chan); + continue; + } + + PRINT2(verbose, + "%s: EC Buffer Playout event id %d %s on fe_chan=%d ec_chan=%d port=%s\n", + ec_dev->devname, + PlayoutEvent[i].ulUserEventId, + wanec_BufferPlayoutType2Str(PlayoutEvent[i].ulEventType), + fe_chan, ec_chan, + (PlayoutEvent[i].ulChannelPort==cOCT6100_CHANNEL_PORT_ROUT) ? "ROUT" : "SOUT"); +#if 0 + card = (sdla_t*)ec_dev->card; + if (card->wandev.event_callback.playout){ + } +#endif + } + + /* Return 1 if more playout event are present, otherwise - 0 */ + return (f_BufferPlayoutGetEvent.fMoreEvents == TRUE) ? 1 : 0; +} + +/* +** wanec_ISR() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ int wanec_ISR(wan_ec_t *ec, int verbose) { UINT32 ulResult; + int ret = 0; WAN_ASSERT(ec == NULL); + PRINT2(verbose, "%s: Executing EC interrupt routine ...\n", + ec->name); Oct6100InterruptServiceRoutineDef(&ec->f_InterruptFlag); ulResult = Oct6100InterruptServiceRoutine( @@ -1413,7 +1408,7 @@ int wanec_ISR(wan_ec_t *ec, int verbose) "%s: Error Pll Jitter\n", ec->name); } - if (ec->f_InterruptFlag.fErrorH100OutOfSync == TRUE){ + if (ec->f_InterruptFlag.fErrorH100OutOfSync == TRUE && !ec->ignore_H100){ DEBUG_EVENT( "%s: The H100 slave has lost its framing on the bus!\n", ec->name); @@ -1434,44 +1429,59 @@ int wanec_ISR(wan_ec_t *ec, int verbose) ec->name); } if (ec->f_InterruptFlag.fErrorOverflowToneEvents == TRUE){ - PRINT1(verbose, - "%s: Error Overflow Tone Events\n", + DEBUG_EVENT( + "%s: Error: Tone Event buffer has overflowed\n", ec->name); } if (ec->f_InterruptFlag.fToneEventsPending == TRUE){ - PRINT1(verbose, "%s: Tone Event pending....\n", + PRINT2(verbose, "%s: Tone Event pending....\n", ec->name); - wanec_EventTone(ec, verbose); + ret = wanec_ToneEvent(ec, ec->tone_verbose); } if (ec->f_InterruptFlag.fBufferPlayoutEventsPending == TRUE){ - PRINT1(verbose, + PRINT2(verbose, "%s: Buffer Playout Events Pending\n", ec->name); + ret = wanec_PlayoutEvent(ec, ec->playout_verbose); } if (ec->f_InterruptFlag.fApiSynch == TRUE){ - PRINT1(verbose, + PRINT2(verbose, "%s: The chip interrupted the API for purpose of maintaining sync!\n", ec->name); } - return 0; + return ret; } -int wanec_DebugChannel(wan_ec_t *ec, INT channel, int verbose) +int wanec_DebugChannel(wan_ec_dev_t *ec_dev, INT channel, int verbose) { + wan_ec_t *ec = NULL; tOCT6100_DEBUG_SELECT_CHANNEL DebugSelectChannel; + wanec_chan_stats_t chan_stats; UINT32 ulResult; - if (ec->ulDebugChannelHndl != cOCT6100_INVALID_HANDLE){ + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + /* Verify Echo Canceller Channel operation mode */ + memset(&chan_stats, 0, sizeof(wanec_chan_stats_t)); + ulResult = wanec_ChannelStats(ec_dev, channel, &chan_stats, 0); + if (chan_stats.f_ChannelStats.ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN){ DEBUG_EVENT( - "ERROR: %s: Echo Canceller daemon can monitor only one channel (%d)!\n", - ec->name, - ec->DebugChannel); + "ERROR: %s: Invalid Echo Channel %d operation mode (POWER DOWN)!\n", + ec_dev->name, channel); + return -EINVAL; + } + + if (ec_dev->ec->ulDebugChannelHndl != cOCT6100_INVALID_HANDLE){ + DEBUG_EVENT( + "ERROR: %s: Echo Canceller daemon can monitor only one ec channel (%d)!\n", + ec_dev->name, channel); return -EINVAL; } Oct6100DebugSelectChannelDef( &DebugSelectChannel ); - PRINT1(verbose, "%s: Select channel %d for monitoring...\n", - ec->name, + PRINT2(verbose, "%s: Select ec channel %d for monitoring...\n", + ec_dev->name, channel); /* Set selected debug channel */ ec->DebugChannel = channel; @@ -1484,7 +1494,7 @@ int wanec_DebugChannel(wan_ec_t *ec, INT channel, int verbose) &DebugSelectChannel ); if (ulResult != cOCT6100_ERR_OK){ DEBUG_EVENT( - "ERROR: %s: Failed to select debug channel %d for monitoring (err=0x%X)\n", + "ERROR: %s: Failed to select debug ec channel %d for monitoring (err=0x%X)\n", ec->name, channel, ulResult); @@ -1493,16 +1503,17 @@ int wanec_DebugChannel(wan_ec_t *ec, INT channel, int verbose) return 0; } -int wanec_DebugGetData(wan_ec_t *ec, wan_ec_api_t *ec_api) +int wanec_DebugGetData(wan_ec_dev_t *ec_dev, wanec_chan_monitor_t *chan_monitor, int verbose) { + wan_ec_t *ec = NULL; tOCT6100_DEBUG_GET_DATA fDebugGetData; UINT32 ulResult; + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; if (ec->ulDebugChannelHndl == cOCT6100_INVALID_HANDLE){ - PRINT( -#if !defined(__WINDOWS__) - verbose, -#endif + DEBUG_EVENT( "ERROR: %s: No Debug channel was selected!\n", ec->name); return -EINVAL; @@ -1510,36 +1521,34 @@ int wanec_DebugGetData(wan_ec_t *ec, wan_ec_api_t *ec_api) Oct6100DebugGetDataDef( &fDebugGetData ); - PRINT1(ec_api->verbose, - "%s: Retrieves debug data for channel %d...\n", + PRINT2(verbose, + "%s: Retrieves debug data for ec channel %d...\n", ec->name, ec->DebugChannel); - memset(&ec_api->u_chan_monitor.data[0], 0, + memset(&chan_monitor->data[0], 0, sizeof(UINT8) * (MAX_MONITOR_DATA_LEN+1)); /* Set selected debug channel */ fDebugGetData.ulGetDataMode = ec->ulDebugDataMode; - fDebugGetData.ulMaxBytes = ec_api->u_chan_monitor.max_len; - fDebugGetData.pbyData = &ec_api->u_chan_monitor.data[0]; + fDebugGetData.ulMaxBytes = chan_monitor->max_len; + fDebugGetData.pbyData = &chan_monitor->data[0]; /* Select Debug channel */ ulResult = Oct6100DebugGetData( ec->pChipInstance, &fDebugGetData ); if (ulResult != cOCT6100_ERR_OK){ - PRINT( -#if !defined(__WINDOWS__) - verbose, -#endif - "ERROR: %s: Failed to get debug data for channel %d (err=0x%X)\n", + DEBUG_EVENT( + "ERROR: %s: Failed to get debug data for ec channel %d (err=0x%X)\n", ec->name, ec->DebugChannel, ulResult); return -EINVAL; } - ec_api->u_chan_monitor.data_len = fDebugGetData.ulValidNumBytes; - ec_api->u_chan_monitor.remain_len = fDebugGetData.ulRemainingNumBytes; - ec_api->channel = ec->DebugChannel; + chan_monitor->data_len = fDebugGetData.ulValidNumBytes; + chan_monitor->remain_len= fDebugGetData.ulRemainingNumBytes; + //chan_monitor->fe_chan = ec->DebugChannel; + chan_monitor->fe_chan = wanec_ec2fe_channel(ec, ec->DebugChannel, NULL); if (fDebugGetData.ulRemainingNumBytes == 0){ /* Last read */ @@ -1562,35 +1571,35 @@ static PUINT32 wanec_search_bufferindex(wan_ec_t *ec, UINT32 index) return NULL; } -int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose) { wan_ec_t *ec; tOCT6100_BUFFER_LOAD BufferLoad; - UINT32 size, ulResult; + UINT32 size, ulResult, pcmlaw = WAN_EC_PCM_U_LAW; PUINT8 pData = NULL; int err; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - PRINT1(ec_api->verbose, - "%s: Loading Tone buffer (%s) into OCT6100 Chip ...\n", - ec->name, ec_api->u_tone_config.tone); - size = ec_api->u_tone_config.size * sizeof(INT8); + pcmlaw = (buffer_config->pcmlaw) ? buffer_config->pcmlaw : WAN_EC_PCM_U_LAW; + PRINT2(verbose, + "%s: Loading Tone buffer (%s) law=%s into Echo Canceller Chip ...\n", + ec->name, + buffer_config->buffer, + WAN_EC_DECODE_PCM_LAW(pcmlaw)); + size = buffer_config->size * sizeof(INT8); pData = wan_vmalloc(size); if (pData == NULL){ DEBUG_EVENT( - "ERROR: %s: Failed to allocate memory for tone buffer!\n", + "ERROR: %s: Failed to allocate memory for buffer!\n", ec->name); return -EINVAL; } - err = WAN_COPY_FROM_USER( - pData, - ec_api->u_tone_config.data, - size); + err = WAN_COPY_FROM_USER(pData, buffer_config->data, size); if (err){ DEBUG_EVENT( - "ERROR: %s: Failed to copy EC tone buffer from user space [%s:%d]!\n", + "ERROR: %s: Failed to copy EC buffer from user space [%s:%d]!\n", ec->name, __FUNCTION__,__LINE__); wan_vfree(pData); @@ -1600,10 +1609,8 @@ int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) Oct6100BufferPlayoutLoadDef( &BufferLoad ); BufferLoad.pulBufferIndex = wanec_search_bufferindex(ec, cOCT6100_INVALID_VALUE); /* FIXME: Can be alaw/mulaw */ - BufferLoad.ulBufferPcmLaw = - (ec_dev->fe_tdmv_law == WAN_TDMV_MULAW) ? - cOCT6100_PCM_U_LAW : - cOCT6100_PCM_A_LAW; + BufferLoad.ulBufferPcmLaw = (pcmlaw == WAN_EC_PCM_U_LAW) ? + cOCT6100_PCM_U_LAW : cOCT6100_PCM_A_LAW; BufferLoad.pbyBufferPattern = pData; BufferLoad.ulBufferSize = size; ulResult = Oct6100BufferPlayoutLoad ( @@ -1614,21 +1621,21 @@ int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) goto buffer_load_done; } DEBUG_EVENT( - "%s: ERROR: Failed to load tone buffer into EC Chip (err=0x%X)\n", + "%s: ERROR: Failed to load buffer into EC Chip (err=0x%X)\n", ec->name, ulResult); wan_vfree(pData); return -EINVAL; } buffer_load_done: wan_vfree(pData); - ec_api->u_tone_config.buffer_index = *BufferLoad.pulBufferIndex; - PRINT1(ec_api->verbose, - "%s: Current tone index is %d\n", - ec->name, ec_api->u_tone_config.buffer_index); + buffer_config->buffer_index = *BufferLoad.pulBufferIndex; + PRINT2(verbose, + "%s: Current buffer index is %d\n", + ec->name, buffer_config->buffer_index); return 0; } -int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose) { wan_ec_t *ec; tOCT6100_BUFFER_UNLOAD BufferUnload; @@ -1638,18 +1645,18 @@ int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - PRINT1(ec_api->verbose, - "%s: Unloading Tone buffer from EC chip ...\n", + PRINT2(verbose, + "%s: Unloading buffer from EC chip ...\n", ec->name); try_next_index: Oct6100BufferPlayoutUnloadDef( &BufferUnload ); - if (ec_api->u_tone_config.buffer_index != cOCT6100_INVALID_VALUE){ - pBufferIndex = wanec_search_bufferindex(ec, ec_api->u_tone_config.buffer_index); + if (buffer_config->buffer_index != cOCT6100_INVALID_VALUE){ + pBufferIndex = wanec_search_bufferindex(ec, buffer_config->buffer_index); if (pBufferIndex == NULL){ DEBUG_EVENT( - "ERROR: %s: Invalid tone buffer index %X!\n", - ec->name, ec_api->u_tone_config.buffer_index); + "ERROR: %s: Invalid buffer index %X!\n", + ec->name, buffer_config->buffer_index); return EINVAL; } }else{ @@ -1672,12 +1679,12 @@ try_next_index: goto buffer_unload_done; } DEBUG_EVENT( - "ERROR: %s: Failed to unload tone buffer from EC Chip (err=0x%X)!\n", + "ERROR: %s: Failed to unload buffer from EC Chip (err=0x%X)!\n", ec->name, (unsigned int)ulResult); return EINVAL; } *pBufferIndex = 0; - if (!ec_api->u_tone_config.buffer_index){ + if (!buffer_config->buffer_index){ index++; goto try_next_index; } @@ -1686,62 +1693,81 @@ buffer_unload_done: return 0; } -int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api) +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) { tOCT6100_BUFFER_PLAYOUT_ADD BufferPlayoutAdd; UINT32 ulResult; - PRINT1(ec_api->verbose, - "%s: Add Tone buffer to channel %d...\n", - ec->name, channel); - if (ec_api->u_playout.index == cOCT6100_INVALID_VALUE|| - wanec_search_bufferindex(ec, ec_api->u_playout.index) == NULL){ + PRINT2(verbose, + "%s: Add Tone buffer to ec channel %d port %s duration %d:%d...\n", + ec->name, + channel, + WAN_EC_DECODE_CHANNEL_PORT(playout->port), + playout->duration, + playout->repeat_cnt); + if (playout->index == cOCT6100_INVALID_VALUE|| + wanec_search_bufferindex(ec, playout->index) == NULL){ DEBUG_EVENT( - "ERROR: %s: Invalid playout buffer index for channel %d!\n", + "ERROR: %s: Invalid playout buffer index for ec channel %d!\n", ec->name, channel); return -EINVAL; } Oct6100BufferPlayoutAddDef( &BufferPlayoutAdd ); - BufferPlayoutAdd.fRepeat = ec_api->u_playout.repeat; - BufferPlayoutAdd.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + if (playout->repeat_cnt == 1){ + BufferPlayoutAdd.fRepeat = FALSE; + }else{ + BufferPlayoutAdd.fRepeat = TRUE; + } + BufferPlayoutAdd.ulPlayoutPort = + (playout->port == WAN_EC_CHANNEL_PORT_ROUT) ? + cOCT6100_CHANNEL_PORT_ROUT : + cOCT6100_CHANNEL_PORT_SOUT; BufferPlayoutAdd.ulMixingMode = cOCT6100_MIXING_MUTE; BufferPlayoutAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; - BufferPlayoutAdd.ulBufferIndex = ec_api->u_playout.index; - BufferPlayoutAdd.ulDuration = (ec_api->u_playout.duration) ? - ec_api->u_playout.duration : 5000; - BufferPlayoutAdd.ulBufferLength = (ec_api->u_playout.buffer_length) ? - ec_api->u_playout.buffer_length : + BufferPlayoutAdd.ulBufferIndex = playout->index; + BufferPlayoutAdd.fRepeat = (playout->repeat_cnt) ? TRUE : FALSE; + BufferPlayoutAdd.ulRepeatCount = playout->repeat_cnt; + BufferPlayoutAdd.ulDuration = (playout->duration) ? + playout->duration : 5000; + BufferPlayoutAdd.ulBufferLength = (playout->buffer_length) ? + playout->buffer_length : cOCT6100_AUTO_SELECT; ulResult = Oct6100BufferPlayoutAdd( ec->pChipInstance, &BufferPlayoutAdd); if ( ulResult != cOCT6100_ERR_OK ){ DEBUG_EVENT( - "ERROR: %s: Failed to add playout buffer to channel %d (err=%08X)\n", + "ERROR: %s: Failed to add playout buffer to ec channel %d (err=%08X)\n", ec->name, channel, ulResult); return -EINVAL; } return 0; } -int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api) +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) { tOCT6100_BUFFER_PLAYOUT_START BufferPlayoutStart; UINT32 ulResult; - PRINT1(ec_api->verbose, - "%s: Active playout buffer on channel %d...\n", + PRINT2(verbose, + "%s: Active playout buffer on ec channel %d port %s ...\n", ec->name, - channel); + channel, + WAN_EC_DECODE_CHANNEL_PORT(playout->port)); Oct6100BufferPlayoutStartDef( &BufferPlayoutStart ); BufferPlayoutStart.ulChannelHndl = ec->pEchoChannelHndl[channel]; - BufferPlayoutStart.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + BufferPlayoutStart.ulPlayoutPort = + (playout->port == WAN_EC_CHANNEL_PORT_ROUT) ? + cOCT6100_CHANNEL_PORT_ROUT : + cOCT6100_CHANNEL_PORT_SOUT; + BufferPlayoutStart.fNotifyOnPlayoutStop = playout->notifyonstop; + BufferPlayoutStart.ulUserEventId = playout->user_event_id; ulResult = Oct6100BufferPlayoutStart( ec->pChipInstance, &BufferPlayoutStart); if ( ulResult != cOCT6100_ERR_OK ){ DEBUG_EVENT( - "ERROR: %s: Failed to active playout buffer on channel %d (err=%08X)\n", + "ERROR: %s: Failed to active playout buffer on ec channel %d (err=%08X)\n", ec->name, channel, ulResult); @@ -1750,25 +1776,256 @@ int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api) return 0; } -int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api) +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) { tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; UINT32 ulResult; - PRINT1(ec_api->verbose, - "%s: Deactive playout buffer on channel %d...\n", + PRINT2(verbose, + "%s: Deactive playout buffer on ec channel %d port %s...\n", ec->name, - channel); + channel, + WAN_EC_DECODE_CHANNEL_PORT(playout->port)); Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); BufferPlayoutStop.ulChannelHndl = ec->pEchoChannelHndl[channel]; - BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + BufferPlayoutStop.ulPlayoutPort = + (playout->port == WAN_EC_CHANNEL_PORT_ROUT) ? + cOCT6100_CHANNEL_PORT_ROUT : + cOCT6100_CHANNEL_PORT_SOUT; ulResult = Oct6100BufferPlayoutStop( ec->pChipInstance, &BufferPlayoutStop); if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult != cOCT6100_ERR_BUFFER_PLAYOUT_NOT_STARTED){ + DEBUG_EVENT( + "ERROR: %s: Failed to deactive playout buffer on ec channel %d (err=%08X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + } + return 0; +} + + +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_OPEN ConfBridgeOpen; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Opening Conference Bridge...\n", ec->name); + + if ((unsigned int)ec->confbridges_no >= ec->f_OpenChip.ulMaxConfBridges){ DEBUG_EVENT( - "ERROR: %s: Failed to deactive playout buffer on channel %d (err=%08X)\n", + "ERROR: %s: Trying to open too many conference bridges (%d:%d)\n", ec->name, + ec->confbridges_no, + ec->f_OpenChip.ulMaxConfBridges); + return -EINVAL; + } + + Oct6100ConfBridgeOpenDef( &ConfBridgeOpen ); + ConfBridgeOpen.pulConfBridgeHndl = &confbridge->ulHndl; + ConfBridgeOpen.fFlexibleConferencing = FALSE; + ulResult = Oct6100ConfBridgeOpen( + ec->pChipInstance, + &ConfBridgeOpen); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to open new conference bridge (err=%08X)\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Closing Conference Bridge...\n", ec->name); + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + ConfBridgeClose.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeClose( + ec->pChipInstance, + &ConfBridgeClose); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to close conference bridge (%X, err=%08X)\n", + ec->name, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanAdd(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_ADD ConfBridgeChanAdd; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Add channel %d to Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanAddDef( &ConfBridgeChanAdd ); + ConfBridgeChanAdd.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanAdd( + ec->pChipInstance, + &ConfBridgeChanAdd); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to add channel %d to conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanRemove(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE ConfBridgeChanRemove; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Remove channel %d from Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanRemoveDef( &ConfBridgeChanRemove ); + ConfBridgeChanRemove.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanRemove.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanRemove( + ec->pChipInstance, + &ConfBridgeChanRemove); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to remove channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_MUTE ConfBridgeChanMute; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Mute channel %d on a conference bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanMuteDef( &ConfBridgeChanMute ); + ConfBridgeChanMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanMute( + ec->pChipInstance, + &ConfBridgeChanMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute channel %d on a conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanUnMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_UNMUTE ConfBridgeChanUnMute; + UINT32 ulResult; + + PRINT2(verbose, + "%s: UnMute channel %d on a Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanUnMuteDef( &ConfBridgeChanUnMute ); + ConfBridgeChanUnMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanUnMute( + ec->pChipInstance, + &ConfBridgeChanUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to unmute channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeDominantSpeakerSet(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int enable, int verbose) +{ + tOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET ConfBridgeDominantSpeaker; + UINT32 ulResult; + + PRINT2(verbose, + "%s: %s Dominant speaker (channel %d) to a Conference Bridge %X...\n", + ec->name, + (enable) ? "Enable":"Disable", + channel, + confbridge->ulHndl); + + Oct6100ConfBridgeDominantSpeakerSetDef( &ConfBridgeDominantSpeaker ); + ConfBridgeDominantSpeaker.ulConfBridgeHndl = confbridge->ulHndl; + if (enable){ + ConfBridgeDominantSpeaker.ulChannelHndl = ec->pEchoChannelHndl[channel]; + }else{ + ConfBridgeDominantSpeaker.ulChannelHndl = cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL; + } + ulResult = Oct6100ConfBridgeDominantSpeakerSet( + ec->pChipInstance, + &ConfBridgeDominantSpeaker); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to %s dominant speaker to conference bridge (%X, err=%08X)\n", + ec->name, + (enable) ? "enable" : "disable", + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + + +int wanec_ConfBridgeMaskChange(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, UINT32 mask, int verbose) +{ + tOCT6100_CONF_BRIDGE_MASK_CHANGE ConfBridgeMaskChange; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Changing the listener (channel=%d) mask of bridge participant (%d)...\n", + ec->name, + channel, confbridge->ulHndl); + + Oct6100ConfBridgeMaskChangeDef( &ConfBridgeMaskChange ); + ConfBridgeMaskChange.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ConfBridgeMaskChange.ulNewListenerMask = mask; + ulResult = Oct6100ConfBridgeMaskChange( + ec->pChipInstance, + &ConfBridgeMaskChange); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to change the listener mask of bridge participant %d (err=%X)!\n", + ec->name, channel, ulResult); return -EINVAL; @@ -1776,6 +2033,30 @@ int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api) return 0; } +int wanec_ConfBridgeGetStats(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_STATS ConfBridgeStats; + UINT32 ulResult; + + PRINT2(verbose, + "%s: Getting bridge statistics %X...\n", + ec->name, confbridge->ulHndl); + + Oct6100ConfBridgeGetStatsDef( &ConfBridgeStats ); + ConfBridgeStats.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeGetStats( + ec->pChipInstance, + &ConfBridgeStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to get conference bridge statistics (err=%X)!\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + /*===========================================================================*\ Oct6100Read \*===========================================================================*/ @@ -1843,7 +2124,7 @@ wan_ec_write_seq(wan_ec_dev_t *ec_dev, u32 write_addr, u16 write_data) return ulResult; /* Keep polling register contol0 for the access_req bit to go low. */ - for ( i = 0; i < WAN_OCT6100_READ_LIMIT; i++ ) + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) { ulResult = wan_ec_read( ec_dev, 0, &usData ); if ( ulResult ) @@ -1853,10 +2134,10 @@ wan_ec_write_seq(wan_ec_dev_t *ec_dev, u32 write_addr, u16 write_data) break; } - if ( i == WAN_OCT6100_READ_LIMIT ){ + if ( i == WANEC_READ_LIMIT ){ DEBUG_EVENT("%s: EC write command reached limit!\n", ec_dev->name); - return WAN_OCT6100_RC_CPU_INTERFACE_NO_RESPONSE; + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; } return 0; } @@ -1889,7 +2170,7 @@ u32 wanec_req_write(void *arg, u32 write_addr, u16 write_data) u32 wanec_req_write_smear(void *arg, u32 addr, u16 data, u32 len) { wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; - u32 i, ulResult = WAN_OCT6100_RC_OK; + u32 i, ulResult = WAN_EC_RC_OK; WAN_ASSERT(ec_dev == NULL); for ( i = 0; i < len; i++ ){ @@ -1912,7 +2193,7 @@ u32 wanec_req_write_smear(void *arg, u32 addr, u16 data, u32 len) u32 wanec_req_write_burst(void *arg, u32 addr, u16 *data, u32 len) { wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; - u32 i, ulResult = WAN_OCT6100_RC_OK; + u32 i, ulResult = WAN_EC_RC_OK; WAN_ASSERT(ec_dev == NULL); @@ -1975,7 +2256,7 @@ wan_ec_read_seq(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data, u32 read_le return ulResult; /* Keep polling register contol0 for the access_req bit to go low. */ - for ( i = 0; i < WAN_OCT6100_READ_LIMIT; i++ ) + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) { ulResult = wan_ec_read( ec_dev, 0x0, &usData ); if (ulResult) @@ -1984,10 +2265,10 @@ wan_ec_read_seq(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data, u32 read_le if ( ( ( usData >> 8 ) & 0x1 ) == 0x0 ) break; } - if ( i == WAN_OCT6100_READ_LIMIT ){ + if ( i == WANEC_READ_LIMIT ){ DEBUG_EVENT("%s: EC read command reached limit!\n", ec_dev->name); - return WAN_OCT6100_RC_CPU_INTERFACE_NO_RESPONSE; + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; } if ( ( usData & 0xFF ) == 0x1 ) @@ -2039,7 +2320,7 @@ u32 wanec_req_read(void *arg, u32 addr, u16 *data) u32 wanec_req_read_burst(void *arg, u32 addr, u16 *data, u32 len) { wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; - u32 i, ulResult = WAN_OCT6100_RC_OK; + u32 i, ulResult = WAN_EC_RC_OK; u16 read_data; for ( i = 0; i < len; i++ ){ diff --git a/patches/kdrivers/wanec/wanec_cmd.nc.c b/patches/kdrivers/wanec/wanec_cmd.nc.c new file mode 100644 index 0000000..1d57c5f --- /dev/null +++ b/patches/kdrivers/wanec/wanec_cmd.nc.c @@ -0,0 +1,2189 @@ +/************************************************************* + * wanec_cmd.c WANPIPE Echo Canceller Layer (WANEC_LIP) + * + * + * + * =========================================================== + * + * May 10 2006 Alex Feldman Initial Version + * + * March 19, 2006 Alex Feldman Enable Sout Adaptive Noise + * Reduction for all channel by + * default. + */ + + +/*============================================================= + * Includes + */ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +#elif defined(__LINUX__) +# include +# include +# include +# include +#elif defined(__WINDOWS__) +# include +# include +# include +#endif + +int verbose; + +#include "oct6100_api.h" +#include "oct6100_version.h" + +#include "wanec_iface.h" +#include "wanec_tones.h" + +/*============================================================= + * Definitions + */ +#define WANEC_MAX_PORT_RANGE 32 +#define WANEC_MAX_BRI_PORT_RANGE 2 +#define WANEC_READ_LIMIT 0x10000 + +#define WANEC_MAX_CONFBRIDGE_DEF 32 +#define WANEC_MAC_PLAYOUT_BUFFERS 20 +<<<<<<< wanec_cmd.c + +//FIXME: Take this out +#warning "WAN_MEDIA_BRI is localy defined to 0: do not commit" +#define WAN_MEDIA_BRI 0 +======= + +>>>>>>> 1.52 +/*============================================================= + * Global Parameters + */ +UINT32 DetectedSoutToneNumbers[WAN_NUM_DTMF_TONES] = +{ + SOUT_DTMF_0, + SOUT_DTMF_1, + SOUT_DTMF_2, + SOUT_DTMF_3, + SOUT_DTMF_4, + SOUT_DTMF_5, + SOUT_DTMF_6, + SOUT_DTMF_7, + SOUT_DTMF_8, + SOUT_DTMF_9, + SOUT_DTMF_A, + SOUT_DTMF_B, + SOUT_DTMF_C, + SOUT_DTMF_D, + SOUT_DTMF_STAR, + SOUT_DTMF_POUND, +}; +UINT32 DetectedRoutToneNumbers[WAN_NUM_DTMF_TONES] = +{ + ROUT_DTMF_0, + ROUT_DTMF_1, + ROUT_DTMF_2, + ROUT_DTMF_3, + ROUT_DTMF_4, + ROUT_DTMF_5, + ROUT_DTMF_6, + ROUT_DTMF_7, + ROUT_DTMF_8, + ROUT_DTMF_9, + ROUT_DTMF_A, + ROUT_DTMF_B, + ROUT_DTMF_C, + ROUT_DTMF_D, + ROUT_DTMF_STAR, + ROUT_DTMF_POUND +}; + +/*============================================================= + * Function prototype +*/ + +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose); +int wanec_ChipOpen(wan_ec_dev_t*, int); +int wanec_ChipClose(wan_ec_dev_t*, int verbose); +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose); + +int wanec_ChannelOpen(wan_ec_dev_t*, int); +int wanec_ChannelClose(wan_ec_dev_t*, int); +int wanec_ChannelModify(wan_ec_dev_t*, INT, wanec_chan_modify_t*, int verbose); +int wanec_ChannelStats(wan_ec_dev_t*, INT channel, wanec_chan_stats_t *chan_stats, int reset); + +int wanec_ChannelMute(wan_ec_dev_t*, INT channel, unsigned char port_mask, int); +int wanec_ChannelUnMute(wan_ec_dev_t*, INT channel, unsigned char port_mask, int); + +int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char port, int verbose); +int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char port, int verbose); + +int wanec_DebugChannel(wan_ec_dev_t*, INT channel, int verbose); +int wanec_DebugGetData(wan_ec_dev_t*, wanec_chan_monitor_t *chan_monitor, int verbose); + +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose); +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose); +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose); + +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); +int wanec_ConfBridgeChanAdd(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanRemove(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeChanUnMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose); +int wanec_ConfBridgeDominantSpeakerSet(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int enable, int verbose); +int wanec_ConfBridgeMaskChange(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, UINT32 mask, int verbose); +int wanec_ConfBridgeGetStats(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose); + +int wanec_EventTone(wan_ec_t *ec, int verbose); +int wanec_ISR(wan_ec_t *ec, int verbose); + +int wanec_fe2ec_channel(wan_ec_dev_t*, int); +static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl); +static int wanec_ec2fe_channel(wan_ec_t*, int, wan_ec_dev_t**); + +extern int wanec_ChipParam(wan_ec_t*,tPOCT6100_CHIP_OPEN, wan_custom_conf_t*, int); +extern int wanec_ChanParam(wan_ec_t*,tPOCT6100_CHANNEL_MODIFY, wan_custom_conf_t*, int); +extern int wanec_ChanParamList(wan_ec_t *ec); + +u32 wanec_req_write(void*, u32 write_addr, u16 write_data); +u32 wanec_req_write_smear(void*, u32 addr, u16 data, u32 len); +u32 wanec_req_write_burst(void*, u32 addr, u16 *data, u32 len); +u32 wanec_req_read(void*, u32 addr, u16 *data); +u32 wanec_req_read_burst(void*, u32 addr, u16 *data, u32 len); + +extern int wan_ec_write_internal_dword(wan_ec_dev_t *ec_dev, u32 addr1, u32 data); +extern int wan_ec_read_internal_dword(wan_ec_dev_t *ec_dev, u32 addr1, u32 *data); + +/*============================================================= + * Function definition +*/ +static int wanec_hndl2ec_channel(wan_ec_t *ec, UINT32 ChannelHndl) +{ + int channel = 0; + + for(channel = 0; channel < ec->max_channels; channel++){ + if (ec->pEchoChannelHndl[channel] == ChannelHndl){ + return channel; + } + } + return 0; +} +int wanec_fe2ec_channel(wan_ec_dev_t *ec_dev, int fe_channel) +{ + int ec_channel = 0; + + if (ec_dev->fe_media == WAN_MEDIA_BRI){ + if (ec_dev->fe_lineno >= 12){ + ec_channel = WANEC_MAX_PORT_RANGE; + } + ec_channel += (ec_dev->fe_lineno * WANEC_MAX_BRI_PORT_RANGE + (fe_channel-1)); + }else if (ec_dev->fe_media == WAN_MEDIA_T1 || ec_dev->fe_media == WAN_MEDIA_FXOFXS){ + ec_channel = ec_dev->fe_lineno * WANEC_MAX_PORT_RANGE + (fe_channel-1); + }else{ + /*ec_channel = ec_dev->fe_lineno * ec_dev->fe_max_channels + channel;*/ + ec_channel = ec_dev->fe_lineno * WANEC_MAX_PORT_RANGE + fe_channel; + } + return ec_channel; +} + +static int wanec_ec2fe_channel(wan_ec_t *ec, int ec_chan, wan_ec_dev_t **ec_dev) +{ + int fe_chan; + + *ec_dev = ec->pEcDevMap[ec_chan]; + if (*ec_dev == NULL) return 0; + + fe_chan = ec_chan % WANEC_MAX_PORT_RANGE; + if ((*ec_dev)->fe_media == WAN_MEDIA_BRI){ + fe_chan = fe_chan % WANEC_MAX_BRI_PORT_RANGE; + fe_chan++; + }else{ + if ((*ec_dev)->fe_media == WAN_MEDIA_T1 || + (*ec_dev)->fe_media == WAN_MEDIA_FXOFXS){ + fe_chan++; + } + } + return fe_chan; +} + + +/****************************************************************** +** +** +*******************************************************************/ +tOCT6100_CHIP_IMAGE_INFO f_ChipImageInfo; +#if 0 +tOCT6100_GET_HW_REVISION f_Revision; +#endif +int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHIP_STATS f_ChipStats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + if (chip_stats){ + PRINT1(verbose, "%s: Reading chip statistics...\n", + ec->name); + } + Oct6100ChipGetStatsDef( &f_ChipStats ); + f_ChipStats.fResetChipStats = reset; + ulResult = Oct6100ChipGetStats( + ec->pChipInstance, + &f_ChipStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading chip statistics...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return -EINVAL; + } + if (chip_stats){ + memcpy( &chip_stats->f_ChipStats, + &f_ChipStats, + sizeof(tOCT6100_CHIP_STATS)); + } + + if (chip_stats){ + PRINT1(verbose, "%s: Reading chip image info...\n", + ec->name); + } + + Oct6100ChipGetImageInfoDef( &f_ChipImageInfo ); + ulResult = Oct6100ChipGetImageInfo( + ec->pChipInstance, + &f_ChipImageInfo); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading chip image info...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return -EINVAL; + } + if (chip_stats){ + if (chip_stats->f_ChipImageInfo){ + int err; + err = WAN_COPY_TO_USER( + &f_ChipImageInfo, + chip_stats->f_ChipImageInfo, + sizeof(tOCT6100_CHIP_IMAGE_INFO)); + if (err){ + DEBUG_EVENT( + "%s: Failed to copy chip image info to user space [%s:%d]!\n", + ec->name, __FUNCTION__,__LINE__); + return -EINVAL; + } + }else{ + PRINT1(verbose, + "%s: Echo Canceller image description:\n%s\n", + ec->name, f_ChipImageInfo.szVersionNumber); + PRINT1(verbose, + "%s: Echo Canceller image build ID\t\t\t%08X\n", + ec->name, f_ChipImageInfo.ulBuildId); + PRINT1(verbose, + "%s: Echo Canceller maximum number of channels\t%d\n", + ec->name, f_ChipImageInfo.ulMaxChannels); +#if 0 + PRINT1(verbose, + "%s: Echo Canceller maximum tail displacement\t\t%d\n", + ec->name, f_ChipImageInfo.ulMaxTailDisplacement); + PRINT1(verbose, + "%s: Echo Canceller per channel tail displacement\t%s\n", + ec->name, + (f_ChipImageInfo.fPerChannelTailDisplacement == TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller per channel tail length\t\t%s\n", + ec->name, + (f_ChipImageInfo.fPerChannelTailLength == TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller maximum tail length\t\t%d\n", + ec->name, f_ChipImageInfo.ulMaxTailLength); + PRINT1(verbose, + "%s: Echo Canceller buffer Playout support\t\t%s\n", + ec->name, + (f_ChipImageInfo.fBufferPlayout == TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller adaptive noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAdaptiveNoiseReduction==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller SOUT noise bleaching\t\t%s\n", + ec->name, + (f_ChipImageInfo.fSoutNoiseBleaching==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller ROUT noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fRoutNoiseReduction==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller ROUT noise reduction level\t\t%s\n", + ec->name, + (f_ChipImageInfo.fRoutNoiseReductionLevel==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller automatic level control\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAutoLevelControl==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller acoustic echo cancellation\t\t%s\n", + ec->name, + (f_ChipImageInfo.fAcousticEcho==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller conferencing\t\t%s\n", + ec->name, + (f_ChipImageInfo.fConferencing==TRUE)?"TRUE":"FALSE"); + PRINT1(verbose, + "%s: Echo Canceller conferencing noise reduction\t\t%s\n", + ec->name, + (f_ChipImageInfo.fConferencingNoiseReduction==TRUE)?"TRUE":"FALSE"); +#endif + } + } + if (f_ChipImageInfo.ulMaxChannels < (unsigned int)ec->max_channels){ + ec->max_channels = f_ChipImageInfo.ulMaxChannels-1; + } + +// DEBUG_EVENT(verbose, "%s: Reading hw revision...\n", +// ec->name); +#if 0 + DEBUG_EVENT(verbose, "%s: Reading hw revision...\n", + ec->name); + ec->f_Revision.ulUserChipId = 0; + ec->f_Revision.pProcessContext = &ec->f_Context; + ulResult = Oct6100GetHwRevision(&ec->f_Revision); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "%s: Reading hw revision...\tFailed (err=0x%X)\n", + ec->name, ulResult); + return EINVAL; + } +#endif + return 0; +} + +int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int verbose) +{ + tOCT6100_GET_INSTANCE_SIZE InstanceSize; + wan_ec_t *ec; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(config->imageData == NULL); + ec = ec_dev->ec; + + ulResult = Oct6100ChipOpenDef( &ec->f_OpenChip ); + + /*==============================================================*/ + /* Configure clocks */ + + /* upclk oscillator is at 33.33 Mhz */ + ec->f_OpenChip.ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; + + /* mclk will be generated by internal PLL at 133 Mhz */ + ec->f_OpenChip.fEnableMemClkOut = TRUE; +#if 1 + ec->f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ; +#else + ec->f_OpenChip.ulMemClkFreq = cOCT6100_MCLK_FREQ_125_MHZ; /*125*/ +#endif + + /*==============================================================*/ + + /*==============================================================*/ + /* General parameters */ + + /* Chip ID.*/ + ec->f_OpenChip.ulUserChipId = ec->chip_no; + + /* Set the max number of accesses to 1024 to speed things up */ + ec->f_OpenChip.ulMaxRwAccesses = 1024; + + /* Set the maximums that the chip needs to support for this test */ + ec->f_OpenChip.ulMaxChannels = config->max_channels; + + ec->f_OpenChip.ulMaxBiDirChannels = 0; + ec->f_OpenChip.ulMaxConfBridges = 0; //WANEC_MAX_CONFBRIDGE_DEF; + ec->f_OpenChip.ulMaxPhasingTssts = 0; + ec->f_OpenChip.ulMaxTdmStreams = 32; + ec->f_OpenChip.ulMaxTsiCncts = 2; + + /*==============================================================*/ + + /*==============================================================*/ + /* External Memory Settings */ + + /* Use DDR memory.*/ +#if 1 + ec->f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_SDR; +#else + ec->f_OpenChip.ulMemoryType = cOCT6100_MEM_TYPE_DDR; +#endif + + ec->f_OpenChip.ulNumMemoryChips = 2; + + /* + **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_8MB; + **f_OpenChip.ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_16MB;*/ + ec->f_OpenChip.ulMemoryChipSize = config->memory_chip_size; + + ec->f_OpenChip.fEnableChannelRecording = TRUE; + +#if defined(ENABLE_ACOUSTICECHO) + ec->f_OpenChip.fEnableAcousticEcho = TRUE; +#endif + +#if defined(ENABLE_PRODBIST) + /* Enable production bist mode */ + ec->f_OpenChip.fEnableProductionBist = TRUE; + ec->f_OpenChip.ulNumProductionBistLoops = 0x1; +#endif + + ec->f_OpenChip.ulMaxPlayoutBuffers = WANEC_MAC_PLAYOUT_BUFFERS; + + ec->f_OpenChip.pbyImageFile = ec->pImageData; + ec->f_OpenChip.ulImageSize = ec->ImageSize; + + /* Assign board index (0). */ + ec->f_Context.ulBoardId = ec->chip_no; + + /* Handle to driver */ + ec->f_Context.ec_dev = ec_dev; + + /* Interface name to driver */ + strlcpy(ec->f_Context.devname, devname, WAN_DRVNAME_SZ); + + ulResult = Oct6100GetInstanceSize(&ec->f_OpenChip, &InstanceSize); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to get EC chip instance size (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* Allocate memory needed for API instance. */ + ec->pChipInstance = + (tPOCT6100_INSTANCE_API)wan_vmalloc(InstanceSize.ulApiInstanceSize); + if (ec->pChipInstance == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed to allocate memory for EC chip (%d bytes)!\n", + ec->name,InstanceSize.ulApiInstanceSize); + return -EINVAL; + } + + /* Open the OCT6100 on the evaluation board. */ + ec->f_OpenChip.pProcessContext = (PVOID)&ec->f_Context; + + /* parse advanced params (global custom configuration) */ + if (ec->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &ec->custom_conf, verbose); + } + /* parse advanced params (command line custom configuration) */ + if (config->custom_conf.param_no){ + wanec_ChipParam(ec, &ec->f_OpenChip, &config->custom_conf, verbose); + } + + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + ec->ulDebugDataMode = config->debug_data_mode; + return 0; +} + +int wanec_ChipOpen(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + UINT32 ulResult, i = 0; + INT ec_chan = 0; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, + "%s: Opening Echo Canceller Chip ...\n", + ec->name); + if (ec->f_OpenChip.pbyImageFile == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid EC image pointer\n", + ec->name); + return -EINVAL; + } + ulResult = Oct6100ChipOpen( + ec->pChipInstance, /* API instance memory. */ + &ec->f_OpenChip ); /* Open chip structure. */ + if ( ulResult != cOCT6100_ERR_OK ){ + if (ec->imageLast == WANOPT_YES || + ulResult != cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS){ + DEBUG_EVENT( + "ERROR: %s: Failed to open Echo Canceller Chip (err=0x%X)\n", + ec->name, ulResult); + } + return -EINVAL; + } + + if (wanec_ChipStats(ec_dev, NULL, TRUE, verbose)){ + DEBUG_EVENT( + "ERROR: %s: Failed to read EC chip statistics!\n", + ec->name); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + + ec->pToneBufferIndexes = + wan_malloc(sizeof(UINT32) * ec->f_OpenChip.ulMaxPlayoutBuffers); + if (ec->pToneBufferIndexes == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for playout handles!\n", + ec->name); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + i = 0; + while(i < ec->f_OpenChip.ulMaxPlayoutBuffers){ + ec->pToneBufferIndexes[i++] = cOCT6100_INVALID_VALUE; + } + ec->pEchoChannelHndl = + wan_malloc(sizeof(UINT32) * ec->max_channels); + if (ec->pEchoChannelHndl == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for channel handle!\n", + ec->name); + wan_free(ec->pToneBufferIndexes); + wanec_ChipClose(ec_dev, verbose); + return EINVAL; + } + ec->pEcDevMap = wan_malloc(sizeof(wan_ec_dev_t*) * ec->max_channels); + if (ec->pEcDevMap == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed allocate memory for ec channel map!\n", + ec->name); + wan_free(ec->pToneBufferIndexes); + wan_free(ec->pEchoChannelHndl); + wanec_ChipClose(ec_dev, verbose); + return -EINVAL; + } + for(ec_chan = 0; ec_chan < ec->max_channels; ec_chan++){ + ec->pEchoChannelHndl[ec_chan] = cOCT6100_INVALID_HANDLE; + ec->pEcDevMap[ec_chan] = NULL; + } + return 0; +} + +int wanec_ChipClose(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHIP_CLOSE f_CloseChip; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Closing Echo Canceller Chip ...\n", + ec->name); + Oct6100ChipCloseDef( &f_CloseChip ); + ulResult = Oct6100ChipClose( + ec->pChipInstance, + &f_CloseChip ); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to close Echo Canceller chip (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + if (ec->pChipInstance){ + wan_vfree(ec->pChipInstance); + ec->pChipInstance = NULL; + } + if (ec->pToneBufferIndexes){ + wan_free(ec->pToneBufferIndexes); + ec->pToneBufferIndexes = NULL; + } + if (ec->pEchoChannelHndl){ + wan_free(ec->pEchoChannelHndl); + ec->pEchoChannelHndl = NULL; + } + if (ec->pEcDevMap){ + wan_free(ec->pEcDevMap); + ec->pEcDevMap = NULL; + } + return 0; +} + +int wanec_ChannelOpen(wan_ec_dev_t *ec_dev, int verbose) +{ + tOCT6100_CHANNEL_OPEN EchoChannelOpen; + wan_ec_t *ec; + sdla_t *card; + UINT32 ulResult; + UINT32 stream = 0,timeslot=0; + INT channel, pcm_law_type; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(ec_dev->card == NULL); + ec = ec_dev->ec; + card = (sdla_t*)ec_dev->card; + + pcm_law_type = (WAN_FE_TDMV_LAW(&card->fe) == WAN_TDMV_MULAW) ? + cOCT6100_PCM_U_LAW : cOCT6100_PCM_A_LAW; + PRINT1(verbose, + "%s: Openning all Echo Canceller channels (%s)...\n", + ec->name, + (pcm_law_type == cOCT6100_PCM_U_LAW) ? + "MULAW":"ALAW"); + + for(channel = 0; channel < ec->max_channels; channel++){ + Oct6100ChannelOpenDef( &EchoChannelOpen ); + + /* Assign the handle memory.*/ + EchoChannelOpen.pulChannelHndl = &ec->pEchoChannelHndl[channel]; + + /* Make sure the channel does not perform echo cancellation */ +#if defined(WANEC_BYDEFAULT_NORMAL) + EchoChannelOpen.ulEchoOperationMode = + cOCT6100_ECHO_OP_MODE_NORMAL; +#else + EchoChannelOpen.ulEchoOperationMode = + cOCT6100_ECHO_OP_MODE_POWER_DOWN; +#endif + EchoChannelOpen.fEnableToneDisabler = TRUE; + + stream = (channel % 2 == 1) ? 4 : 0; + timeslot = channel / 2; + + /* Configure the TDM interface.*/ + EchoChannelOpen.TdmConfig.ulRinPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulRoutPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulSinPcmLaw = pcm_law_type; + EchoChannelOpen.TdmConfig.ulSoutPcmLaw = pcm_law_type; + + EchoChannelOpen.TdmConfig.ulRinStream = stream + 0; + EchoChannelOpen.TdmConfig.ulRinTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulRoutStream = stream + 1; + EchoChannelOpen.TdmConfig.ulRoutTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulSinStream = stream + 2; + EchoChannelOpen.TdmConfig.ulSinTimeslot = timeslot; + EchoChannelOpen.TdmConfig.ulSoutStream = stream + 3; + EchoChannelOpen.TdmConfig.ulSoutTimeslot = timeslot; + + /* Set the desired VQE features (TRUE/FALSE).*/ + EchoChannelOpen.VqeConfig.fEnableNlp = TRUE; + EchoChannelOpen.VqeConfig.fRinDcOffsetRemoval = TRUE; + EchoChannelOpen.VqeConfig.fSinDcOffsetRemoval = TRUE; +#if defined(ENABLE_ACOUSTICECHO) + EchoChannelOpen.VqeConfig.fAcousticEcho = TRUE; +#endif + + EchoChannelOpen.VqeConfig.fSoutAdaptiveNoiseReduction = TRUE; + EchoChannelOpen.VqeConfig.ulComfortNoiseMode = + cOCT6100_COMFORT_NOISE_NORMAL; + /* cOCT6100_COMFORT_NOISE_NORMAL + ** cOCT6100_COMFORT_NOISE_EXTENDED, + ** cOCT6100_COMFORT_NOISE_OFF, + ** cOCT6100_COMFORT_NOISE_FAST_LATCH */ + + PRINT1(verbose, + "%s: Openning Echo Canceller channel %d (%s)...\n", + ec->name, + channel, + (pcm_law_type == cOCT6100_PCM_U_LAW) ? + "MULAW":"ALAW"); + /* Open the channel.*/ + ulResult = Oct6100ChannelOpen( ec->pChipInstance, + &EchoChannelOpen ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to open Echo Canceller channel %d (err=0x%X)!\n", + ec->name, + channel, + ulResult); + return ulResult; + } + } + + /* Init debug channel handle */ + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + + return 0; +} + +int wanec_ChannelClose(wan_ec_dev_t *ec_dev, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_CLOSE EchoChannelClose; + UINT32 ulResult, channel; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Closing all Echo Canceller channels ...\n", + ec->name); + for(channel = 0; channel < (UINT32)ec->max_channels; channel++){ + Oct6100ChannelCloseDef( &EchoChannelClose ); + EchoChannelClose.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ChannelClose( ec->pChipInstance, + &EchoChannelClose ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to close Echo Canceller channel %d (err=0x%X)!\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + ec->pEchoChannelHndl[channel] = cOCT6100_INVALID_HANDLE; + } + return 0; +} + +int wanec_ChannelModify( wan_ec_dev_t *ec_dev, + INT channel, + wanec_chan_modify_t *chan_modify, + int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MODIFY EchoChannelModify; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + Oct6100ChannelModifyDef( &EchoChannelModify ); + + /* Assign the handle memory.*/ + EchoChannelModify.ulChannelHndl = ec->pEchoChannelHndl[channel]; + + /* parse advianced params */ + if (chan_modify->custom_conf.param_no){ + int err; + err = wanec_ChanParam(ec, &EchoChannelModify, &chan_modify->custom_conf, verbose); + if (err){ + DEBUG_EVENT( + "%s: WARNING: Unsupported parameter for channel %d!\n", + ec->name, channel); + return -EINVAL; + } + }else{ + + /* Echo Channel Operation Mode */ + EchoChannelModify.ulEchoOperationMode = chan_modify->opmode; + + if (chan_modify->mute != WANEC_IGNORE){ + EchoChannelModify.fVqeConfigModified = TRUE; + if (chan_modify->mute){ + EchoChannelModify.VqeConfig.fDtmfToneRemoval = TRUE; + }else{ + EchoChannelModify.VqeConfig.fDtmfToneRemoval = FALSE; + } + } + } + + /* Open the channel.*/ + ulResult = Oct6100ChannelModify( + ec->pChipInstance, + &EchoChannelModify ); + if (ulResult != cOCT6100_ERR_OK){ + PRINT1(verbose, + "%s: Failed to modify Channel config parameters for channel %d (err=0x%X)\n", + ec->name, + channel, + ulResult); + return EINVAL; + } + return 0; +} + +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ChannelMute(wan_ec_dev_t* ec_dev, INT channel, unsigned char port_mask, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_MUTE f_ChannelMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, "%s: Muting channel %d on port %X...\n", + ec->name, channel, port_mask); + Oct6100ChannelMuteDef( &f_ChannelMute ); + f_ChannelMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + f_ChannelMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (port_mask & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (port_mask & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (port_mask & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (port_mask & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + ulResult = Oct6100ChannelMute( + ec->pChipInstance, + &f_ChannelMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute channel %d on port %X (%08X)!\n", + ec->name, channel, port_mask, ulResult); + return EINVAL; + } + return 0; +} +int wanec_ChannelUnMute(wan_ec_dev_t *ec_dev, INT channel, unsigned char port_mask, int verbose) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_UNMUTE f_ChannelUnMute; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, "%s: Un-muting channel %d on port %X...\n", + ec->name, channel, port_mask); + Oct6100ChannelUnMuteDef( &f_ChannelUnMute ); + f_ChannelUnMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + f_ChannelUnMute.ulPortMask = cOCT6100_CHANNEL_MUTE_PORT_NONE; + if (port_mask & WAN_EC_CHANNEL_PORT_SOUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SOUT; + if (port_mask & WAN_EC_CHANNEL_PORT_SIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_SIN; + if (port_mask & WAN_EC_CHANNEL_PORT_ROUT) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_ROUT; + if (port_mask & WAN_EC_CHANNEL_PORT_RIN) + f_ChannelUnMute.ulPortMask |= cOCT6100_CHANNEL_MUTE_PORT_RIN; + ulResult = Oct6100ChannelUnMute( + ec->pChipInstance, + &f_ChannelUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to un-mute channel %d on port %X (%08X)!\n", + ec->name, channel, port_mask, ulResult); + return EINVAL; + } + return 0; +} + +int wanec_ChannelStats(wan_ec_dev_t *ec_dev, INT channel, wanec_chan_stats_t *chan_stats, int reset) +{ + wan_ec_t *ec; + tOCT6100_CHANNEL_STATS f_ChannelStats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + PRINT1(verbose, "%s: Reading EC statistics for channel %d...\n", + ec->name, channel); + Oct6100ChannelGetStatsDef( &f_ChannelStats ); + f_ChannelStats.ulChannelHndl = ec->pEchoChannelHndl[channel]; + f_ChannelStats.fResetStats = reset; + ulResult = Oct6100ChannelGetStats( + ec->pChipInstance, + &f_ChannelStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to read EC stats for channel %d (%08X)!\n", + ec->name, channel, ulResult); + return EINVAL; + } + if (chan_stats){ + memcpy( &chan_stats->f_ChannelStats, + &f_ChannelStats, + sizeof(tOCT6100_CHANNEL_STATS)); + } + return 0; +} + +int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char type, int verbose) +{ + tOCT6100_TONE_DETECTION_ENABLE f_ToneDetectionEnable; + UINT32 ulResult; + int i; + + PRINT1(verbose, "%s: Enable tone detection on ec chan %d ...\n", + ec->name, + channel); + + if (type & WAN_EC_CHANNEL_PORT_ROUT){ + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); + f_ToneDetectionEnable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + f_ToneDetectionEnable.ulToneNumber = + DetectedRoutToneNumbers[i]; + ulResult = Oct6100ToneDetectionEnable ( + ec->pChipInstance, + &f_ToneDetectionEnable); + if ( ulResult == cOCT6100_ERR_OK ){ + continue; + }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ + PRINT1(verbose, + "%s: Tone detection is already enabled on channel %d for port ROUT!\n", + ec->name, channel); + continue; /* already activated */ + }else{ + DEBUG_EVENT( + "ERROR: %s: Failed to enable tone detection on ec chan %d!\n", + ec->name, channel); + DEBUG_EVENT( + "ERROR: %s: (err=0x%X,i=%d)!\n", + ec->name, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + if (type & WAN_EC_CHANNEL_PORT_SOUT){ + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionEnableDef( &f_ToneDetectionEnable ); + f_ToneDetectionEnable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + f_ToneDetectionEnable.ulToneNumber = + DetectedSoutToneNumbers[i]; + ulResult = Oct6100ToneDetectionEnable ( + ec->pChipInstance, + &f_ToneDetectionEnable); + if ( ulResult == cOCT6100_ERR_OK ){ + continue; + }else if (ulResult == cOCT6100_ERR_TONE_DETECTION_TONE_ACTIVATED){ + PRINT1(verbose, + "%s: Tone detection is already enabled on channel %d for port SOUT!\n", + ec->name, channel); + continue; /* already activated */ + }else{ + DEBUG_EVENT( + "ERROR: %s: Failed to enable tone detection on channel %d!\n", + ec->name, channel); + DEBUG_EVENT( + "ERROR: %s: (err=0x%X,i=%d)!\n", + ec->name, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + + return 0; +} + +int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char type, int verbose) +{ + tOCT6100_TONE_DETECTION_DISABLE f_ToneDetectionDisable; + UINT32 ulResult; + INT i; + + PRINT1(verbose, "%s: Disable tone detection on channel %d ...\n", + ec->name, + channel); + if (type & WAN_EC_CHANNEL_PORT_ROUT){ + + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); + f_ToneDetectionDisable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + if (channel >= 0){ + f_ToneDetectionDisable.ulToneNumber = + DetectedRoutToneNumbers[i]; + }else{ + f_ToneDetectionDisable.fDisableAll = TRUE; + } + ulResult = Oct6100ToneDetectionDisable ( + ec->pChipInstance, + &f_ToneDetectionDisable); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, channel, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + if (type & WAN_EC_CHANNEL_PORT_SOUT){ + + for(i = 0; i < WAN_NUM_DTMF_TONES; i++){ + + Oct6100ToneDetectionDisableDef( &f_ToneDetectionDisable ); + f_ToneDetectionDisable.ulChannelHndl = + ec->pEchoChannelHndl[channel]; + if (channel >= 0){ + f_ToneDetectionDisable.ulToneNumber = + DetectedSoutToneNumbers[i]; + }else{ + f_ToneDetectionDisable.fDisableAll = TRUE; + } + ulResult = Oct6100ToneDetectionDisable ( + ec->pChipInstance, + &f_ToneDetectionDisable); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to disable tone detection for channel %d (err=0x%X,i=%d)!\n", + ec->name, channel, + (unsigned int)ulResult, i); + return -EINVAL; + } + } + } + return 0; +} + +//#if defined(WAN_DEBUG_HWEC) +#if 1 +static CHAR* wanec_ToneId2Str(UINT32 f_ulToneId) +{ + switch (f_ulToneId){ + /* DTMF Section */ + case ROUT_DTMF_0: return "ROUT_DTMF_0"; + case ROUT_DTMF_1: return "ROUT_DTMF_1"; + case ROUT_DTMF_2: return "ROUT_DTMF_2"; + case ROUT_DTMF_3: return "ROUT_DTMF_3"; + case ROUT_DTMF_4: return "ROUT_DTMF_4"; + case ROUT_DTMF_5: return "ROUT_DTMF_5"; + case ROUT_DTMF_6: return "ROUT_DTMF_6"; + case ROUT_DTMF_7: return "ROUT_DTMF_7"; + case ROUT_DTMF_8: return "ROUT_DTMF_8"; + case ROUT_DTMF_9: return "ROUT_DTMF_9"; + case ROUT_DTMF_A: return "ROUT_DTMF_A"; + case ROUT_DTMF_B: return "ROUT_DTMF_B"; + case ROUT_DTMF_C: return "ROUT_DTMF_C"; + case ROUT_DTMF_D: return "ROUT_DTMF_D"; + case ROUT_DTMF_STAR: return "ROUT_DTMF_STAR"; + case ROUT_DTMF_POUND: return "ROUT_DTMF_POUND"; + case SOUT_DTMF_0: return "SOUT_DTMF_0"; + case SOUT_DTMF_1: return "SOUT_DTMF_1"; + case SOUT_DTMF_2: return "SOUT_DTMF_2"; + case SOUT_DTMF_3: return "SOUT_DTMF_3"; + case SOUT_DTMF_4: return "SOUT_DTMF_4"; + case SOUT_DTMF_5: return "SOUT_DTMF_5"; + case SOUT_DTMF_6: return "SOUT_DTMF_6"; + case SOUT_DTMF_7: return "SOUT_DTMF_7"; + case SOUT_DTMF_8: return "SOUT_DTMF_8"; + case SOUT_DTMF_9: return "SOUT_DTMF_9"; + case SOUT_DTMF_A: return "SOUT_DTMF_A"; + case SOUT_DTMF_B: return "SOUT_DTMF_B"; + case SOUT_DTMF_C: return "SOUT_DTMF_C"; + case SOUT_DTMF_D: return "SOUT_DTMF_D"; + case SOUT_DTMF_STAR: return "SOUT_DTMF_STAR"; + case SOUT_DTMF_POUND: return "SOUT_DTMF_POUND"; + + /* System 5/6/7 Section */ + case SIN_SYSTEM5_2400: return "SIN_SYSTEM5_2400"; + case SIN_SYSTEM5_2600: return "SIN_SYSTEM5_2600"; + case SIN_SYSTEM5_2400_2600: return "SIN_SYSTEM5_2400_2600"; + case SIN_SYSTEM7_2000: return "SIN_SYSTEM7_2000"; + case SIN_SYSTEM7_1780: return "SIN_SYSTEM7_1780"; + + default: return "INVALID TONE ID!"; + } +} +#endif + +static unsigned char wanec_ConvertToneId(UINT32 f_ulToneId, unsigned char *ec_dtmf_port) +{ + switch (f_ulToneId){ + /* DTMF Section */ + case ROUT_DTMF_0: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '0'; + case ROUT_DTMF_1: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '1'; + case ROUT_DTMF_2: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '2'; + case ROUT_DTMF_3: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '3'; + case ROUT_DTMF_4: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '4'; + case ROUT_DTMF_5: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '5'; + case ROUT_DTMF_6: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '6'; + case ROUT_DTMF_7: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '7'; + case ROUT_DTMF_8: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '8'; + case ROUT_DTMF_9: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '9'; + case ROUT_DTMF_A: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'A'; + case ROUT_DTMF_B: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'B'; + case ROUT_DTMF_C: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'C'; + case ROUT_DTMF_D: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return 'D'; + case ROUT_DTMF_STAR: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '*'; + case ROUT_DTMF_POUND: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_ROUT; return '#'; + case SOUT_DTMF_0: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '0'; + case SOUT_DTMF_1: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '1'; + case SOUT_DTMF_2: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '2'; + case SOUT_DTMF_3: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '3'; + case SOUT_DTMF_4: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '4'; + case SOUT_DTMF_5: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '5'; + case SOUT_DTMF_6: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '6'; + case SOUT_DTMF_7: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '7'; + case SOUT_DTMF_8: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '8'; + case SOUT_DTMF_9: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '9'; + case SOUT_DTMF_A: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'A'; + case SOUT_DTMF_B: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'B'; + case SOUT_DTMF_C: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'C'; + case SOUT_DTMF_D: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return 'D'; + case SOUT_DTMF_STAR: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '*'; + case SOUT_DTMF_POUND: *ec_dtmf_port = WAN_EC_CHANNEL_PORT_SOUT; return '#'; + } + return 0x00000000; +} + +#if 1 +//#if defined(WAN_DEBUG_HWEC) +static CHAR* wanec_ToneType2Str(UINT32 f_ulToneType) +{ + switch (f_ulToneType){ + case cOCT6100_TONE_PRESENT: return "cOCT6100_TONE_PRESENT"; + case cOCT6100_TONE_STOP: return "cOCT6100_TONE_STOP"; + default: return "INVALID TONE TYPE!"; + } +} +#endif +static unsigned char wanec_ConvertToneType(UINT32 f_ulToneType) +{ + switch (f_ulToneType){ + case cOCT6100_TONE_PRESENT: return WAN_EC_TONE_PRESENT; + case cOCT6100_TONE_STOP: return WAN_EC_TONE_STOP; + } + return 0x00; +} + + +/* +** wanec_EventTone() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ +int wanec_EventTone(wan_ec_t *ec, int verbose) +{ + tOCT6100_EVENT_GET_TONE f_GetToneEvent; + tOCT6100_TONE_EVENT ToneEvent[32]; + UINT32 ulResult; + wan_ec_dev_t *ec_dev; + sdla_t *card; + UINT32 i; + int ec_chan,fe_chan; + + PRINT1(verbose, "%s: Getting Tone events ...\n", + ec->name); + Oct6100EventGetToneDef( &f_GetToneEvent ); + f_GetToneEvent.fResetBufs = FALSE; + f_GetToneEvent.ulMaxToneEvent = 32; + f_GetToneEvent.pToneEvent = ToneEvent; + ulResult = Oct6100EventGetTone( + ec->pChipInstance, + &f_GetToneEvent); + if ( ulResult != cOCT6100_ERR_OK ){ + if ( ulResult != cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY ){ + PRINT1(verbose, "%s: There are not tone events!\n", + ec->name); + return 0; + } + DEBUG_EVENT( + "ERROR: %s: Failed to get tone events (err=0x%X)!\n", + ec->name, ulResult); + return -EINVAL; + } + + /* No dtmf tone event returned */ + if (!f_GetToneEvent.ulNumValidToneEvent) return 0; + + for(i = 0; i < f_GetToneEvent.ulNumValidToneEvent; i++){ + ec_chan = wanec_hndl2ec_channel(ec, ToneEvent[i].ulChannelHndl); + ec_dev = ec->pEcDevMap[ec_chan]; + fe_chan = wanec_ec2fe_channel(ec, ec_chan, &ec_dev); + if (ec_dev == NULL || ec_dev->card == NULL){ + DEBUG_EVENT( + "%s: Internal Error: Failed to find fe channel (ec_chan=%d)\n", + ec->name, ec_chan); + continue; + } + + PRINT1(verbose, + "%s: Tone event %s %s on fe_chan=%d ec_chan=%d\n", + ec_dev->devname, + wanec_ToneId2Str(ToneEvent[i].ulToneDetected), + wanec_ToneType2Str(f_GetToneEvent.pToneEvent[i].ulEventType), + fe_chan, ec_chan); + + card = (sdla_t*)ec_dev->card; + if (card->wandev.event_callback.dtmf){ + wan_event_t event; + unsigned char dtmf_port = WAN_EC_CHANNEL_PORT_ROUT, dtmf_type; + + event.type = WAN_EVENT_EC_DTMF; + event.channel = fe_chan; + event.digit = wanec_ConvertToneId( + ToneEvent[i].ulToneDetected, + &dtmf_port); + dtmf_type = wanec_ConvertToneType(ToneEvent[i].ulEventType); + event.dtmf_type = dtmf_type; + event.dtmf_port = dtmf_port; + card->wandev.event_callback.dtmf(card, &event); + } + } + + /* Return 1 if more dtmf event are present, otherwise - 0 */ + return (f_GetToneEvent.fMoreEvents == TRUE) ? 1 : 0; +} + +/* +** wanec_ISR() +** +** Return: 0 - on success +** <0 - on error +** 1 - pending dtmf events +**/ +int wanec_ISR(wan_ec_t *ec, int verbose) +{ + UINT32 ulResult; + int ret = 0; + + WAN_ASSERT(ec == NULL); + + Oct6100InterruptServiceRoutineDef(&ec->f_InterruptFlag); + + ulResult = Oct6100InterruptServiceRoutine( + ec->pChipInstance, + &ec->f_InterruptFlag ); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to execute interrupt Service Routine (err=%08X)!\n", + ec->name, + ulResult); + return -EINVAL; + } + /* Critical errors */ + if (ec->f_InterruptFlag.fFatalGeneral == TRUE){ + DEBUG_EVENT( + "%s: An internal fatal chip error detected (0x%X)!\n", + ec->name, + ec->f_InterruptFlag.ulFatalGeneralFlags); + } + if (ec->f_InterruptFlag.fFatalReadTimeout == TRUE){ + DEBUG_EVENT( + "%s: A read to the external memory has failed!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorRefreshTooLate == TRUE){ + DEBUG_EVENT( + "%s: Error Refresh Too Late!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorPllJitter == TRUE){ + DEBUG_EVENT( + "%s: Error Pll Jitter\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100OutOfSync == TRUE){ + DEBUG_EVENT( + "%s: The H100 slave has lost its framing on the bus!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100ClkA == TRUE){ + DEBUG_EVENT( + "%s: The CT_C8_A clock behavior does not conform to the H.100 spec!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100FrameA == TRUE){ + DEBUG_EVENT( + "%s: The CT_FRAME_A clock behavior does not comform to the H.100 spec!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorH100ClkB == TRUE){ + DEBUG_EVENT( + "%s: The CT_C8_B clock is not running a 16.384 MHz!\n", + ec->name); + } + if (ec->f_InterruptFlag.fErrorOverflowToneEvents == TRUE){ + DEBUG_EVENT( + "%s: Error: Tone Event buffer has overflowed\n", + ec->name); + } + if (ec->f_InterruptFlag.fToneEventsPending == TRUE){ + PRINT1(verbose, "%s: Tone Event pending....\n", + ec->name); + ret = wanec_EventTone(ec, verbose); + } + if (ec->f_InterruptFlag.fBufferPlayoutEventsPending == TRUE){ + PRINT1(verbose, + "%s: Buffer Playout Events Pending\n", + ec->name); + } + if (ec->f_InterruptFlag.fApiSynch == TRUE){ + PRINT1(verbose, + "%s: The chip interrupted the API for purpose of maintaining sync!\n", + ec->name); + } + return ret; +} + +int wanec_DebugChannel(wan_ec_dev_t *ec_dev, INT channel, int verbose) +{ + wan_ec_t *ec = NULL; + tOCT6100_DEBUG_SELECT_CHANNEL DebugSelectChannel; + wanec_chan_stats_t chan_stats; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + /* Verify Echo Canceller Channel operation mode */ + ulResult = wanec_ChannelStats(ec_dev, channel, &chan_stats, 0); + if (chan_stats.f_ChannelStats.ulEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Channel %d operation mode (POWER DOWN)!\n", + ec_dev->name, channel); + return -EINVAL; + } + + if (ec_dev->ec->ulDebugChannelHndl != cOCT6100_INVALID_HANDLE){ + DEBUG_EVENT( + "ERROR: %s: Echo Canceller daemon can monitor only one ec channel (%d)!\n", + ec_dev->name, channel); + return -EINVAL; + } + Oct6100DebugSelectChannelDef( &DebugSelectChannel ); + + PRINT1(verbose, "%s: Select ec channel %d for monitoring...\n", + ec_dev->name, + channel); + /* Set selected debug channel */ + ec->DebugChannel = channel; + ec->ulDebugChannelHndl = ec->pEchoChannelHndl[channel]; + DebugSelectChannel.ulChannelHndl= ec->pEchoChannelHndl[channel]; + + /* Select Debug channel */ + ulResult = Oct6100DebugSelectChannel( + ec->pChipInstance, + &DebugSelectChannel ); + if (ulResult != cOCT6100_ERR_OK){ + DEBUG_EVENT( + "ERROR: %s: Failed to select debug ec channel %d for monitoring (err=0x%X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_DebugGetData(wan_ec_dev_t *ec_dev, wanec_chan_monitor_t *chan_monitor, int verbose) +{ + wan_ec_t *ec = NULL; + tOCT6100_DEBUG_GET_DATA fDebugGetData; + UINT32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + if (ec->ulDebugChannelHndl == cOCT6100_INVALID_HANDLE){ + PRINT( +#if !defined(__WINDOWS__) + verbose, +#endif + "ERROR: %s: No Debug channel was selected!\n", + ec->name); + return -EINVAL; + } + + Oct6100DebugGetDataDef( &fDebugGetData ); + + PRINT1(verbose, + "%s: Retrieves debug data for ec channel %d...\n", + ec->name, + ec->DebugChannel); + + memset(&chan_monitor->data[0], 0, + sizeof(UINT8) * (MAX_MONITOR_DATA_LEN+1)); + /* Set selected debug channel */ + fDebugGetData.ulGetDataMode = ec->ulDebugDataMode; + fDebugGetData.ulMaxBytes = chan_monitor->max_len; + fDebugGetData.pbyData = &chan_monitor->data[0]; + + /* Select Debug channel */ + ulResult = Oct6100DebugGetData( + ec->pChipInstance, + &fDebugGetData ); + if (ulResult != cOCT6100_ERR_OK){ + PRINT( +#if !defined(__WINDOWS__) + verbose, +#endif + "ERROR: %s: Failed to get debug data for ec channel %d (err=0x%X)\n", + ec->name, + ec->DebugChannel, + ulResult); + return -EINVAL; + } + chan_monitor->data_len = fDebugGetData.ulValidNumBytes; + chan_monitor->remain_len = fDebugGetData.ulRemainingNumBytes; + chan_monitor->channel = ec->DebugChannel; + + if (fDebugGetData.ulRemainingNumBytes == 0){ + /* Last read */ + ec->ulDebugChannelHndl = cOCT6100_INVALID_HANDLE; + } + + return 0; +} + +static PUINT32 wanec_search_bufferindex(wan_ec_t *ec, UINT32 index) +{ + UINT32 i = 0; + + while(i < ec->f_OpenChip.ulMaxPlayoutBuffers){ + if (ec->pToneBufferIndexes[i] == index){ + return &ec->pToneBufferIndexes[i]; + } + i++; + } + return NULL; +} + +int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose) +{ + wan_ec_t *ec; + tOCT6100_BUFFER_LOAD BufferLoad; + UINT32 size, ulResult; + PUINT8 pData = NULL; + int err; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Loading Tone buffer (%s) into OCT6100 Chip ...\n", + ec->name, tone_config->tone); + size = tone_config->size * sizeof(INT8); + pData = wan_vmalloc(size); + if (pData == NULL){ + DEBUG_EVENT( + "ERROR: %s: Failed to allocate memory for tone buffer!\n", + ec->name); + return -EINVAL; + } + err = WAN_COPY_FROM_USER(pData, tone_config->data, size); + if (err){ + DEBUG_EVENT( + "ERROR: %s: Failed to copy EC tone buffer from user space [%s:%d]!\n", + ec->name, + __FUNCTION__,__LINE__); + wan_vfree(pData); + return -EINVAL; + } + + Oct6100BufferPlayoutLoadDef( &BufferLoad ); + BufferLoad.pulBufferIndex = wanec_search_bufferindex(ec, cOCT6100_INVALID_VALUE); + /* FIXME: Can be alaw/mulaw */ + BufferLoad.ulBufferPcmLaw = + (ec_dev->fe_tdmv_law == WAN_TDMV_MULAW) ? + cOCT6100_PCM_U_LAW : + cOCT6100_PCM_A_LAW; + BufferLoad.pbyBufferPattern = pData; + BufferLoad.ulBufferSize = size; + ulResult = Oct6100BufferPlayoutLoad ( + ec->pChipInstance, + &BufferLoad); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult == cOCT6100_ERR_BUFFER_PLAYOUT_ALL_BUFFERS_OPEN){ + goto buffer_load_done; + } + DEBUG_EVENT( + "%s: ERROR: Failed to load tone buffer into EC Chip (err=0x%X)\n", + ec->name, ulResult); + wan_vfree(pData); + return -EINVAL; + } +buffer_load_done: + wan_vfree(pData); + tone_config->buffer_index = *BufferLoad.pulBufferIndex; + PRINT1(verbose, + "%s: Current tone index is %d\n", + ec->name, tone_config->buffer_index); + return 0; +} + +int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_tone_config_t *tone_config, int verbose) +{ + wan_ec_t *ec; + tOCT6100_BUFFER_UNLOAD BufferUnload; + PUINT32 pBufferIndex = NULL; + UINT32 index = 0, ulResult; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + PRINT1(verbose, + "%s: Unloading Tone buffer from EC chip ...\n", + ec->name); + +try_next_index: + Oct6100BufferPlayoutUnloadDef( &BufferUnload ); + if (tone_config->buffer_index != cOCT6100_INVALID_VALUE){ + pBufferIndex = wanec_search_bufferindex(ec, tone_config->buffer_index); + if (pBufferIndex == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid tone buffer index %X!\n", + ec->name, tone_config->buffer_index); + return EINVAL; + } + }else{ + if (index > ec->f_OpenChip.ulMaxPlayoutBuffers){ + goto buffer_unload_done; + } + if (ec->pToneBufferIndexes[index] == cOCT6100_INVALID_VALUE){ + index++; + goto try_next_index; + } + pBufferIndex = &ec->pToneBufferIndexes[index]; + } + + BufferUnload.ulBufferIndex = *pBufferIndex; + ulResult = Oct6100BufferPlayoutUnload ( + ec->pChipInstance, + &BufferUnload); + if ( ulResult != cOCT6100_ERR_OK ){ + if (ulResult == cOCT6100_ERR_BUFFER_PLAYOUT_NOT_OPEN){ + goto buffer_unload_done; + } + DEBUG_EVENT( + "ERROR: %s: Failed to unload tone buffer from EC Chip (err=0x%X)!\n", + ec->name, (unsigned int)ulResult); + return EINVAL; + } + *pBufferIndex = 0; + if (!tone_config->buffer_index){ + index++; + goto try_next_index; + } + +buffer_unload_done: + return 0; +} + +int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_ADD BufferPlayoutAdd; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Add Tone buffer to ec channel %d...\n", + ec->name, channel); + if (playout->index == cOCT6100_INVALID_VALUE|| + wanec_search_bufferindex(ec, playout->index) == NULL){ + DEBUG_EVENT( + "ERROR: %s: Invalid playout buffer index for ec channel %d!\n", + ec->name, channel); + return -EINVAL; + } + Oct6100BufferPlayoutAddDef( &BufferPlayoutAdd ); + BufferPlayoutAdd.fRepeat = playout->repeat; + BufferPlayoutAdd.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + BufferPlayoutAdd.ulMixingMode = cOCT6100_MIXING_MUTE; + BufferPlayoutAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutAdd.ulBufferIndex = playout->index; + BufferPlayoutAdd.ulDuration = (playout->duration) ? + playout->duration : 5000; + BufferPlayoutAdd.ulBufferLength = (playout->buffer_length) ? + playout->buffer_length : + cOCT6100_AUTO_SELECT; + ulResult = Oct6100BufferPlayoutAdd( + ec->pChipInstance, + &BufferPlayoutAdd); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to add playout buffer to ec channel %d (err=%08X)\n", + ec->name, channel, ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_START BufferPlayoutStart; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Active playout buffer on ec channel %d...\n", + ec->name, + channel); + Oct6100BufferPlayoutStartDef( &BufferPlayoutStart ); + BufferPlayoutStart.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutStart.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100BufferPlayoutStart( + ec->pChipInstance, + &BufferPlayoutStart); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to active playout buffer on ec channel %d (err=%08X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wanec_playout_t *playout, int verbose) +{ + tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Deactive playout buffer on ec channel %d...\n", + ec->name, + channel); + Oct6100BufferPlayoutStopDef( &BufferPlayoutStop ); + BufferPlayoutStop.ulChannelHndl = ec->pEchoChannelHndl[channel]; + BufferPlayoutStop.ulPlayoutPort = cOCT6100_CHANNEL_PORT_ROUT; + ulResult = Oct6100BufferPlayoutStop( + ec->pChipInstance, + &BufferPlayoutStop); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to deactive playout buffer on ec channel %d (err=%08X)\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + + +/****************************************************************************** +** CONFERENCE BRIDGE FUNCTIONS +******************************************************************************/ +int wanec_ConfBridgeOpen(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_OPEN ConfBridgeOpen; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Opening Conference Bridge...\n", ec->name); + + if (ec->confbridges_no >= ec->f_OpenChip.ulMaxConfBridges){ + DEBUG_EVENT( + "ERROR: %s: Trying to open too many conference bridges (%d:%d)\n", + ec->name, + ec->confbridges_no, + ec->f_OpenChip.ulMaxConfBridges); + return -EINVAL; + } + + Oct6100ConfBridgeOpenDef( &ConfBridgeOpen ); + ConfBridgeOpen.pulConfBridgeHndl = &confbridge->ulHndl; + ConfBridgeOpen.fFlexibleConferencing = FALSE; + ulResult = Oct6100ConfBridgeOpen( + ec->pChipInstance, + &ConfBridgeOpen); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to open new conference bridge (err=%08X)\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeClose(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Closing Conference Bridge...\n", ec->name); + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + ConfBridgeClose.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeClose( + ec->pChipInstance, + &ConfBridgeClose); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to close conference bridge (%X, err=%08X)\n", + ec->name, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanAdd(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_ADD ConfBridgeChanAdd; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Add channel %d to Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanAddDef( &ConfBridgeChanAdd ); + ConfBridgeChanAdd.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanAdd.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanAdd( + ec->pChipInstance, + &ConfBridgeChanAdd); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to add channel %d to conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanRemove(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE ConfBridgeChanRemove; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Remove channel %d from Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanRemoveDef( &ConfBridgeChanRemove ); + ConfBridgeChanRemove.ulConfBridgeHndl = confbridge->ulHndl; + ConfBridgeChanRemove.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanRemove( + ec->pChipInstance, + &ConfBridgeChanRemove); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to remove channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_MUTE ConfBridgeChanMute; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Mute channel %d on a conference bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanMuteDef( &ConfBridgeChanMute ); + ConfBridgeChanMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanMute( + ec->pChipInstance, + &ConfBridgeChanMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to mute channel %d on a conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeChanUnMute(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int verbose) +{ + tOCT6100_CONF_BRIDGE_CHAN_UNMUTE ConfBridgeChanUnMute; + UINT32 ulResult; + + PRINT1(verbose, + "%s: UnMute channel %d on a Conference Bridge %X...\n", + ec->name, channel, confbridge->ulHndl); + + Oct6100ConfBridgeChanUnMuteDef( &ConfBridgeChanUnMute ); + ConfBridgeChanUnMute.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ulResult = Oct6100ConfBridgeChanUnMute( + ec->pChipInstance, + &ConfBridgeChanUnMute); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to unmute channel %d from conference bridge (%X, err=%08X)\n", + ec->name, channel, + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeDominantSpeakerSet(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, int enable, int verbose) +{ + tOCT6100_CONF_BRIDGE_DOMINANT_SPEAKER_SET ConfBridgeDominantSpeaker; + UINT32 ulResult; + + PRINT1(verbose, + "%s: %s Dominant speaker (channel %d) to a Conference Bridge %X...\n", + ec->name, + (enable) ? "Enable":"Disable", + channel, + confbridge->ulHndl); + + Oct6100ConfBridgeDominantSpeakerSetDef( &ConfBridgeDominantSpeaker ); + ConfBridgeDominantSpeaker.ulConfBridgeHndl = confbridge->ulHndl; + if (enable){ + ConfBridgeDominantSpeaker.ulChannelHndl = ec->pEchoChannelHndl[channel]; + }else{ + ConfBridgeDominantSpeaker.ulChannelHndl = cOCT6100_CONF_NO_DOMINANT_SPEAKER_HNDL; + } + ulResult = Oct6100ConfBridgeDominantSpeakerSet( + ec->pChipInstance, + &ConfBridgeDominantSpeaker); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to %s dominant speaker to conference bridge (%X, err=%08X)\n", + ec->name, + (enable) ? "enable" : "disable", + confbridge->ulHndl, + ulResult); + return -EINVAL; + } + return 0; +} + + +int wanec_ConfBridgeMaskChange(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int channel, UINT32 mask, int verbose) +{ + tOCT6100_CONF_BRIDGE_MASK_CHANGE ConfBridgeMaskChange; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Changing the listener (channel=%d) mask of bridge participant (%d)...\n", + ec->name, + channel, confbridge->ulHndl); + + Oct6100ConfBridgeMaskChangeDef( &ConfBridgeMaskChange ); + ConfBridgeMaskChange.ulChannelHndl = ec->pEchoChannelHndl[channel]; + ConfBridgeMaskChange.ulNewListenerMask = mask; + ulResult = Oct6100ConfBridgeMaskChange( + ec->pChipInstance, + &ConfBridgeMaskChange); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to change the listener mask of bridge participant %d (err=%X)!\n", + ec->name, + channel, + ulResult); + return -EINVAL; + } + return 0; +} + +int wanec_ConfBridgeGetStats(wan_ec_t *ec, wan_ec_confbridge_t *confbridge, int verbose) +{ + tOCT6100_CONF_BRIDGE_STATS ConfBridgeStats; + UINT32 ulResult; + + PRINT1(verbose, + "%s: Getting bridge statistics %X...\n", + ec->name, confbridge->ulHndl); + + Oct6100ConfBridgeGetStatsDef( &ConfBridgeStats ); + ConfBridgeStats.ulConfBridgeHndl = confbridge->ulHndl; + ulResult = Oct6100ConfBridgeGetStats( + ec->pChipInstance, + &ConfBridgeStats); + if ( ulResult != cOCT6100_ERR_OK ){ + DEBUG_EVENT( + "ERROR: %s: Failed to get conference bridge statistics (err=%X)!\n", + ec->name, + ulResult); + return -EINVAL; + } + return 0; +} + +/*===========================================================================*\ + Oct6100Read +\*===========================================================================*/ + +static int +wan_ec_read(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data) +{ + u32 data; + wan_ec_read_internal_dword(ec_dev, read_addr, &data); + *read_data = (u16)(data & 0xFFFF); + return 0; +} + +/*===========================================================================*\ + Oct6100Write +\*===========================================================================*/ + +static int +wan_ec_write(wan_ec_dev_t *ec_dev, u32 write_addr, u32 write_data) +{ + return wan_ec_write_internal_dword(ec_dev, write_addr, write_data); +} + + +/*===========================================================================*\ + Oct6100WriteSequenceSub +\*===========================================================================*/ +static u32 +wan_ec_write_seq(wan_ec_dev_t *ec_dev, u32 write_addr, u16 write_data) +{ + u32 ulResult; + u32 ulData; + u16 usData; + u32 ulWordAddress; + u32 i; + + /* Create the word address from the provided byte address. */ + ulWordAddress = write_addr >> 1; + + /* 16-bit indirect access. */ + + /* First write to the address indirection registers. */ + ulData = ( ulWordAddress >> 19 ) & 0x1FFF; + ulResult = wan_ec_write( ec_dev, 0x8, ulData ); + if (ulResult) + return ulResult; + + ulData = ( ulWordAddress >> 3 ) & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0xA, ulData ); + if (ulResult) + return ulResult; + + /* Next, write data word to read/write data registers. */ + ulData = write_data & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0x4, ulData ); + if ( ulResult ) + return ulResult; + + + /* Write the parities and write enables, as well as last three bits + ** of wadd and request the write access. */ + ulData = ( ( 0x0 & 0x3 ) << 14 ) | ( ( 0x3 & 0x3 ) << 12 ) | ( ( ulWordAddress & 0x7 ) << 9 ) | 0x0100; + ulResult = wan_ec_write( ec_dev, 0x0, ulData ); + if ( ulResult ) + return ulResult; + + /* Keep polling register contol0 for the access_req bit to go low. */ + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) + { + ulResult = wan_ec_read( ec_dev, 0, &usData ); + if ( ulResult ) + return ulResult; + + if ( ( ( usData >> 8 ) & 0x1 ) == 0x0 ) + break; + } + + if ( i == WANEC_READ_LIMIT ){ + DEBUG_EVENT("%s: EC write command reached limit!\n", + ec_dev->name); + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; + } + return 0; +} + + +/*===========================================================================*\ + HandleReqWriteOct6100 +\*===========================================================================*/ +u32 wanec_req_write(void *arg, u32 write_addr, u16 write_data) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 ulResult; + + DEBUG_TEST("%s: EC WRITE API addr=%X data=%X\n", + ec_dev->ec->name, write_addr, write_data); + ulResult = wan_ec_write_seq(ec_dev, write_addr, write_data); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + write_addr, + write_data); + } + return ulResult; +} + + +/*===========================================================================*\ + HandleReqWriteSmearOct6100 +\*===========================================================================*/ +u32 wanec_req_write_smear(void *arg, u32 addr, u16 data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + + WAN_ASSERT(ec_dev == NULL); + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_write_seq(ec_dev, addr + (i*2), data); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + addr + (i*2), + data); + break; + } + } + return ulResult; +} + + +/*===========================================================================*\ + HandleReqWriteBurstOct6100 +\*===========================================================================*/ +u32 wanec_req_write_burst(void *arg, u32 addr, u16 *data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + + WAN_ASSERT(ec_dev == NULL); + + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_write_seq(ec_dev, addr + (i * 2), data[i]); + if (ulResult){ + DEBUG_EVENT("%s: Failed to write %04X to addr %08X\n", + ec_dev->name, + addr + (i*2), + data[i]); + break; + } + } + return ulResult; +} + + +/*===========================================================================*\ + Oct6100ReadSequenceSub +\*===========================================================================*/ +static u32 +wan_ec_read_seq(wan_ec_dev_t *ec_dev, u32 read_addr, u16 *read_data, u32 read_len) +{ + u32 ulResult; + u32 ulData; + u32 ulWordAddress; + u32 ulReadBurstLength; + u16 usData; + u32 i; + + /* Create the word address from the provided byte address. */ + ulWordAddress = read_addr >> 1; + + /* Indirect accesses. */ + + /* First write to the address indirection registers. */ + ulData = ( ulWordAddress >> 19 ) & 0x1FFF; + ulResult = wan_ec_write( ec_dev, 0x8, ulData ); + if (ulResult) + return ulResult; + + ulData = ( ulWordAddress >> 3 ) & 0xFFFF; + ulResult = wan_ec_write( ec_dev, 0xA, ulData ); + if (ulResult) + return ulResult; + + /* Request access. */ + if ( read_len >= 128 ) + { + ulData = 0x100 | ( ( ulWordAddress & 0x7 ) << 9); + ulReadBurstLength = 0; + } + else + { + ulData = 0x100 | ( ( ulWordAddress & 0x7 ) << 9) | read_len; + ulReadBurstLength = read_len; + } + ulResult = wan_ec_write( ec_dev, 0x0, ulData ); + if (ulResult) + return ulResult; + + /* Keep polling register contol0 for the access_req bit to go low. */ + for ( i = 0; i < WANEC_READ_LIMIT; i++ ) + { + ulResult = wan_ec_read( ec_dev, 0x0, &usData ); + if (ulResult) + return ulResult; + + if ( ( ( usData >> 8 ) & 0x1 ) == 0x0 ) + break; + } + if ( i == WANEC_READ_LIMIT ){ + DEBUG_EVENT("%s: EC read command reached limit!\n", + ec_dev->name); + return WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE; + } + + if ( ( usData & 0xFF ) == 0x1 ) + { + i = 0; + } + + /* Retrieve read data. */ + ulResult = wan_ec_read( ec_dev, 0x4, &usData ); + if (ulResult) + return ulResult; + + if ( ( usData & 0xFF ) == 0x1 ) + { + i = 0; + } + + *read_data = usData; + return 0; +} + +u32 wanec_req_read(void *arg, u32 addr, u16 *data) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 ulResult; + + WAN_ASSERT(ec_dev == NULL); + DEBUG_TEST("%s: EC READ API addr=%X data=????\n", + ec_dev->ec->name, addr); + ulResult = wan_ec_read_seq( + ec_dev, + addr, + data, + 1); + if (ulResult){ + DEBUG_EVENT("%s: Failed to read data from addr %08X\n", + ec_dev->name, + addr); + if (ec_dev->ec){ + wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->ec->critical); + } + } + DEBUG_TEST("%s: EC READ API addr=%X data=%X\n", + ec_dev->ec->name, + addr, *data); + return ulResult; +} + +u32 wanec_req_read_burst(void *arg, u32 addr, u16 *data, u32 len) +{ + wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; + u32 i, ulResult = WAN_EC_RC_OK; + u16 read_data; + + for ( i = 0; i < len; i++ ){ + ulResult = wan_ec_read_seq(ec_dev, addr, &read_data, 1); + if (ulResult){ + DEBUG_EVENT("%s: Failed to read from addr %X\n", + ec_dev->name, + addr); + if (ec_dev->ec){ + wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->ec->critical); + } + break; + } + data[i] = (u16)read_data; + addr += 2; + } + return ulResult; +} diff --git a/patches/kdrivers/wanec/wanec_dev.c b/patches/kdrivers/wanec/wanec_dev.c index a6e5216..41fde57 100644 --- a/patches/kdrivers/wanec/wanec_dev.c +++ b/patches/kdrivers/wanec/wanec_dev.c @@ -35,6 +35,7 @@ #include "oct6100_version.h" #include "wanec_iface.h" +#include "wanec_iface_api.h" #if !defined(__WINDOWS__) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) diff --git a/patches/kdrivers/wanec/wanec_iface.c b/patches/kdrivers/wanec/wanec_iface.c index 00c0830..f27695f 100644 --- a/patches/kdrivers/wanec/wanec_iface.c +++ b/patches/kdrivers/wanec/wanec_iface.c @@ -1,12 +1,17 @@ -/************************************************************* +/******************************************************************** * wanec_iface.c WANPIPE Echo Canceller Layer (WANEC) * * * - * =========================================================== + * ================================================================== * - * May 10 2006 Alex Feldman Initial Versionr - */ + * May 10 2006 Alex Feldman + * Initial Version + * + * January 9 2008 David Rokhvarg + * Added support for Sangoma MS Windows Driver + * + ********************************************************************/ /*============================================================= * Includes @@ -33,12 +38,10 @@ # include # include # include - -# define DEBUG_HWEC_V1 DbgPrint -//#define DEBUG_HWEC_V1 +/*# define DEBUG*/ #endif -#include "wanec_iface.h" +#include "wanec_iface_api.h" /*============================================================= * Definitions @@ -48,16 +51,16 @@ #define WAN_OCT6100_READ_LIMIT 0x10000 #if 0 -# define DEBUG +# define WANEC_DEBUG #endif /*============================================================= * Global Parameters */ -#if defined(DEBUG) -static int global_verbose = WAN_EC_VERBOSE_EXTRA1; +#if defined(WANEC_DEBUG) +static int wanec_verbose = WAN_EC_VERBOSE_EXTRA2; #else -static int global_verbose = WAN_EC_VERBOSE_NONE; +static int wanec_verbose = WAN_EC_VERBOSE_NONE; #endif WAN_LIST_HEAD(wan_ec_head_, wan_ec_) wan_ec_head = @@ -68,15 +71,12 @@ wanec_iface_t wanec_iface = 0, NULL, NULL, - NULL, NULL, NULL, NULL }; -static int wan_ec_no = 0; - static unsigned char wpec_fullname[]="WANPIPE(tm) WANEC Layer"; static unsigned char wpec_copyright[]="(c) 1995-2006 Sangoma Technologies Inc."; /*============================================================= @@ -98,44 +98,56 @@ void unregister_wanec_iface (void); extern int wanec_fe2ec_channel(wan_ec_dev_t*, int); -extern int wanec_ChipOpenPrep(wan_ec_dev_t*, wan_ec_api_t*); +extern int wanec_ChipOpenPrep(wan_ec_dev_t *ec_dev, char *devname, wanec_config_t *config, int); extern int wanec_ChipOpen(wan_ec_dev_t*, int verbose); -extern int wanec_ChipOpen_OLD(wan_ec_dev_t*, wan_ec_api_t*); extern int wanec_ChipClose(wan_ec_dev_t*, int verbose); -extern int wanec_ChipStats(wan_ec_dev_t*, wan_ec_api_t*, int); +extern int wanec_ChipStats(wan_ec_dev_t *ec_dev, wanec_chip_stats_t *chip_stats, int reset, int verbose); -extern int wanec_ChannelOpen(wan_ec_dev_t*, wan_ec_api_t *ec_api); -extern int wanec_ChannelClose(wan_ec_dev_t*, wan_ec_api_t *ec_api, int); -extern int wanec_ChannelModify(wan_ec_dev_t*, INT, UINT32, wan_ec_api_t*, int verbose); -extern int wanec_ChannelStats(wan_ec_dev_t*, INT channel, wan_ec_api_t *ec_api, int reset); +extern int wanec_ChannelOpen(wan_ec_dev_t*, int); +extern int wanec_ChannelClose(wan_ec_dev_t*, int); +extern int wanec_ChannelModifyOpmode(wan_ec_dev_t*, INT, UINT32, int verbose); +extern int wanec_ChannelModifyCustom(wan_ec_dev_t*, INT, wanec_chan_custom_t*, int verbose); +extern int wanec_ChannelStats(wan_ec_dev_t*, INT ec_chan, wanec_chan_stats_t *chan_stats, int reset); -extern int wanec_TonesEnable(wan_ec_t *ec, int channel, unsigned char, int verbose); -extern int wanec_TonesDisable(wan_ec_t *ec, int channel, unsigned char, int verbose); +extern int wanec_ChannelMute(wan_ec_dev_t*, INT ec_chan, wanec_chan_mute_t*, int); +extern int wanec_ChannelUnMute(wan_ec_dev_t*, INT ec_chan, wanec_chan_mute_t*, int); -extern int wanec_DebugChannel(wan_ec_t *ec, INT channel, int verbose); -extern int wanec_DebugGetData(wan_ec_t *ec, wan_ec_api_t *ec_api); +extern int wanec_TonesEnable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t*, int verbose); +extern int wanec_TonesDisable(wan_ec_t *ec, int ec_chan, wanec_dtmf_config_t*, int verbose); -extern int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -extern int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -extern int wanec_BufferPlayoutAdd(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api); -extern int wanec_BufferPlayoutStart(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api); -extern int wanec_BufferPlayoutStop(wan_ec_t *ec, int channel, wan_ec_api_t *ec_api); +extern int wanec_DebugChannel(wan_ec_dev_t*, INT, int); +extern int wanec_DebugGetData(wan_ec_dev_t*, wanec_chan_monitor_t*, int); + +extern int wanec_BufferLoad(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose); +extern int wanec_BufferUnload(wan_ec_dev_t *ec_dev, wanec_buffer_config_t *buffer_config, int verbose); +extern int wanec_BufferPlayoutAdd(wan_ec_t *ec, int ec_chan, wanec_playout_t *playout, int verbose); +extern int wanec_BufferPlayoutStart(wan_ec_t *ec, int ec_chan, wanec_playout_t *playout, int verbose); +extern int wanec_BufferPlayoutStop(wan_ec_t *ec, int ec_chan, wanec_playout_t *playout, int verbose); extern int wanec_EventTone(wan_ec_t *ec, int verbose); extern int wanec_ISR(wan_ec_t *ec, int verbose); -static int wanec_config(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -static int wanec_release(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose); -static int wanec_channel_open(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -static int wanec_modify_channel(wan_ec_dev_t *ec_dev, int fe_chan, u32 cmd, int verbose); -static int wanec_modify(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -static int wanec_modify_mode(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -static int wanec_modify_bypass(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); -static int wanec_bypass(wan_ec_dev_t *ec_dev, int fe_channel, int enable, int verbose); +static int wanec_channel_opmode_modify(wan_ec_dev_t *ec_dev, int fe_chan, UINT32 opmode, int verbose); +static int wanec_channel_dtmf(wan_ec_dev_t*, int, int, wanec_dtmf_config_t*, int); + +static int wanec_bypass(wan_ec_dev_t *ec_dev, int fe_chan, int enable, int verbose); + +static int wanec_api_config(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_release(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose); +static int wanec_api_channel_open(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_modify(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_chan_opmode(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_chan_custom(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_modify_bypass(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_dtmf(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_stats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_buffer(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_playout(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); +static int wanec_api_monitor(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api); static wan_ec_dev_t *wanec_search(char *devname); -static int wanec_enable(void *pcard, int enable, int channel); +static int wanec_enable(void *pcard, int enable, int fe_chan); static int wanec_poll(void *arg, void *pcard); #if defined(__FreeBSD__) || defined(__OpenBSD__) @@ -149,7 +161,10 @@ int wan_ec_read_internal_dword(wan_ec_dev_t *ec_dev, u32 addr1, u32 *data); int wanec_init(void*); int wanec_exit(void*); - +#if defined(__FreeBSD__) +int wanec_shutdown(void*); +int wanec_ready_unload(void*); +#endif /*****************************************************************************/ @@ -245,16 +260,16 @@ static int wanec_reset(wan_ec_dev_t *ec_dev, int reset) err = card->wandev.hwec_reset(card, reset); if (!err){ if (reset){ - ec->state = WAN_OCT6100_STATE_RESET; + ec->state = WAN_EC_STATE_RESET; }else{ - ec->state = WAN_OCT6100_STATE_READY; + ec->state = WAN_EC_STATE_READY; } } } return err; } -static int wanec_enable(void *pcard, int enable, int fe_channel) +static int wanec_enable(void *pcard, int enable, int fe_chan) { sdla_t *card = (sdla_t*)pcard; wan_ec_dev_t *ec_dev = NULL; @@ -271,24 +286,25 @@ static int wanec_enable(void *pcard, int enable, int fe_channel) #if defined(WANEC_BYDEFAULT_NORMAL) WAN_ASSERT(ec_dev->ec == NULL); wan_spin_lock(&ec_dev->ec->lock); - err=wanec_bypass(ec_dev, fe_channel, enable, 0); + err = wanec_bypass(ec_dev, fe_chan, enable, 0); wan_spin_unlock(&ec_dev->ec->lock); return err; #else - return wanec_modify_channel( + return wanec_channel_opmode_modify( ec_dev, - fe_channel, - (enable) ? WAN_EC_CMD_ENABLE : WAN_EC_CMD_DISABLE, + fe_chan, + (enable) ? cOCT6100_ECHO_OP_MODE_NORMAL : cOCT6100_ECHO_OP_MODE_POWER_DOWN, 0); #endif } -static int wanec_bypass(wan_ec_dev_t *ec_dev, int fe_channel, int enable, int verbose) +static int +wanec_bypass(wan_ec_dev_t *ec_dev, int fe_chan, int enable, int verbose) { wan_ec_t *ec = NULL; sdla_t *card = NULL; - int err = -ENODEV; + int ec_chan = 0, err = -ENODEV; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); @@ -297,52 +313,56 @@ static int wanec_bypass(wan_ec_dev_t *ec_dev, int fe_channel, int enable, int ve card = ec_dev->card; PRINT1(verbose, - "%s: %s bypass mode for channel %d (%lX)!\n", + "%s: %s bypass mode for fe_chan:%d (ec map:%lX, fe map:%X)!\n", card->devname, (enable) ? "Enable" : "Disable", - fe_channel, - card->wandev.ec_map); + fe_chan, + card->wandev.fe_ec_map, ec_dev->fe_channel_map); if (card->wandev.hwec_enable == NULL){ - DEBUG_EVENT("%s: Undefined HW EC callback function!\n", + DEBUG_EVENT( "%s: Undefined HW EC Bypass callback function!\n", ec->name); return -ENODEV; } + if (!wan_test_bit(fe_chan, &ec_dev->fe_channel_map)){ + PRINT1(verbose, "%s: FE channel %d is not available (fe_chan_map=%X)!\n", + ec->name, fe_chan, ec_dev->fe_channel_map); + return 0; + } + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); if (enable){ - if (!wan_test_bit(fe_channel, &card->wandev.ec_map)){ - if (ec->ec_active >= ec->max_channels){ - DEBUG_EVENT( - "%s: Exceeded maximum number of Echo Canceller channels (max=%d)!\n", - ec->name, - ec->max_channels); - return -ENODEV; - } - }else{ + if (wan_test_bit(fe_chan, &card->wandev.fe_ec_map)){ /* Already enabled */ + PRINT2(verbose, + "%s: Enable bypass mode overrun detected for ec_chan %d!\n", + card->devname, ec_chan); return 0; } }else{ - if (!wan_test_bit(fe_channel, &card->wandev.ec_map)){ + if (!wan_test_bit(fe_chan, &card->wandev.fe_ec_map)){ /* Already disabled */ + PRINT2(verbose, + "%s: Disble bypass mode overrun detected for ec_channel %d!\n", + card->devname, ec_chan); return 0; } - } - err = card->wandev.hwec_enable(card, enable, fe_channel); + err = card->wandev.hwec_enable(card, enable, fe_chan); if (!err){ if (enable){ - ec->ec_active++; + wan_set_bit(fe_chan, &card->wandev.fe_ec_map); }else{ - if (ec->ec_active) ec->ec_active--; + wan_clear_bit(fe_chan, &card->wandev.fe_ec_map); } + }else if (err < 0){ + DEBUG_EVENT("ERROR: %s: Failed to %s Bypass mode on fe_chan:%d!\n", + ec->name, + (enable) ? "Enable" : "Disable", + fe_chan); + return err; }else{ - if (err < 0){ - PRINT1(verbose, - "%s: HWEC option is not enable for the channel %d (%lX)!\n", - ec->name, fe_channel, card->wandev.ec_enable_map); - return err; - } - return 0; + /* no action made */ + err = 0; } return err; } @@ -394,27 +414,6 @@ static void wanec_enable_timer(wan_ec_dev_t* ec_dev, u_int8_t cmd, u_int32_t del WAN_ASSERT1(ec_dev->card == NULL); card = (sdla_t*)ec_dev->card; -#if defined (__WINDOWS__) - if(KeGetCurrentIrql() > DISPATCH_LEVEL){ - /* May get here on AFT card because front end interrupt - is handled inside ISR not in DPC as on S514. - The KeSetTimer() function is illegal inside ISR, - so queue 'front_end_dpc_obj' DPC and this routine - will be called again from xilinx_front_end_dpc(). - */ - card->xilinx_fe_dpc.te_timer_delay = delay; - ec_dev->poll_cmd = (u_int8_t)cmd; - - if(KeInsertQueueDpc(&card->front_end_dpc_obj, NULL, - (PVOID)ENABLE_HWEC_TIMER) == FALSE){ - - DEBUG_HWEC("Failed to queue 'front_end_dpc_obj'!\n"); - }else{ - DEBUG_HWEC("Successfully queued 'front_end_dpc_obj'.\n"); - } - return; - }/* if() */ -#endif if (wan_test_bit(WAN_EC_BIT_TIMER_KILL,(void*)&ec_dev->critical)){ wan_clear_bit(WAN_EC_BIT_TIMER_RUNNING, (void*)&ec_dev->critical); return; @@ -453,7 +452,157 @@ wan_ec_dev_t *wanec_search(char *devname) return NULL; } -static int wanec_config(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) + +static int wanec_channel_opmode_modify(wan_ec_dev_t *ec_dev, int fe_chan, UINT32 opmode, int verbose) +{ + wan_ec_t *ec = NULL; + u_int32_t ec_chan = 0; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + WAN_ASSERT(ec_dev->card == NULL); + ec = ec_dev->ec; + + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", + ec_dev->devname, + ec->name, + WAN_EC_STATE_DECODE(ec->state)); + return -EINVAL; + } + + switch(opmode){ + case cOCT6100_ECHO_OP_MODE_NORMAL: + case cOCT6100_ECHO_OP_MODE_HT_FREEZE: + case cOCT6100_ECHO_OP_MODE_HT_RESET: + case cOCT6100_ECHO_OP_MODE_NO_ECHO: + case cOCT6100_ECHO_OP_MODE_POWER_DOWN: + case cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION: + break; + default: + DEBUG_EVENT( + "%s: Invalid Echo Channel Operation Mode (opmode=%X)\n", + ec_dev->devname, opmode); + return -EINVAL; + } + + /* Enable Echo cancelation on Oct6100 */ + PRINT1(verbose, + "%s: Modify Echo Channel OpMode %s on fe_chan:%d ...\n", + ec_dev->devname, + (opmode == cOCT6100_ECHO_OP_MODE_NORMAL) ? "Normal" : + (opmode == cOCT6100_ECHO_OP_MODE_POWER_DOWN) ? "Power Down" : + (opmode == cOCT6100_ECHO_OP_MODE_HT_FREEZE) ? "HT Freeze" : + (opmode == cOCT6100_ECHO_OP_MODE_HT_RESET) ? "HT Reset" : + (opmode == cOCT6100_ECHO_OP_MODE_NO_ECHO) ? "NO Echo" : + (opmode == cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION) ? "Speech Recognition" : "Unknown", + fe_chan); + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); + return wanec_ChannelModifyOpmode(ec_dev, ec_chan, opmode, verbose); +} + +static int wanec_channel_dtmf( wan_ec_dev_t *ec_dev, + int fe_chan, + int cmd, + wanec_dtmf_config_t *dtmf, + int verbose) +{ + wan_ec_t *ec = NULL; + int ec_chan, err; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + ec_dev->devname, + ec->name, + WAN_EC_STATE_DECODE(ec->state)); + return -EINVAL; + } + + if (dtmf){ + if ((dtmf->port_map & (WAN_EC_CHANNEL_PORT_SOUT|WAN_EC_CHANNEL_PORT_ROUT)) != dtmf->port_map){ + + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller port value (%X)!\n", + ec_dev->devname, + dtmf->port_map); + return -EINVAL; + } + } + /* Enable/Disable Normal mode on Oct6100 */ + PRINT1(verbose, "%s: %s EC DTMF detection on fe_chan:%d ...\n", + ec_dev->devname, (cmd==WAN_TRUE) ? "Enable" : "Disable", + fe_chan); + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); + if (cmd == WAN_TRUE){ + err = wanec_TonesEnable(ec, ec_chan, dtmf, verbose); + }else{ + err = wanec_TonesDisable(ec, ec_chan, dtmf, verbose); + } + if (err == WAN_EC_API_RC_OK){ + if (cmd == WAN_TRUE){ + wan_set_bit(WAN_EC_BIT_EVENT_DTMF, &ec_dev->events); + ec->tone_verbose = verbose; + }else{ + /* FIXME: Once the DTMF event was enabled, do not + ** disable it otherwise dtmf events for other + ** channels will be delayed + ** wan_clear_bit(WAN_EC_BIT_EVENT_DTMF, &ec_dev->events); + ** ec->tone_verbose = 0; */ + } + } + return err; +} + + +static int wanec_channel_mute( wan_ec_dev_t *ec_dev, + int fe_chan, + int cmd, + wanec_chan_mute_t *mute, + int verbose) +{ + wan_ec_t *ec = NULL; + int ec_chan, err; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", + ec_dev->devname, + ec->name, + WAN_EC_STATE_DECODE(ec->state)); + return -EINVAL; + } + + /* Enable/Disable Normal mode on Oct6100 */ + PRINT1(verbose, + "%s: %s EC channel on fe_chan:%d ...\n", + ec_dev->devname, + (cmd == WAN_TRUE) ? "Mute" : "Un-mute", + fe_chan); + + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); + if (cmd == WAN_TRUE){ + err = wanec_ChannelMute(ec_dev, ec_chan, mute, verbose); + }else{ + err = wanec_ChannelUnMute(ec_dev, ec_chan, mute, verbose); + } + return err; +} + + +/****************************************************************************** +** WANPIPE EC API INTERFACE FUNCTION +******************************************************************************/ + +static int wanec_api_config(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; int err; @@ -462,126 +611,170 @@ static int wanec_config(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; switch(ec->state){ - case WAN_OCT6100_STATE_RESET: - case WAN_OCT6100_STATE_READY: + case WAN_EC_STATE_RESET: + case WAN_EC_STATE_READY: break; - case WAN_OCT6100_STATE_CHIP_OPEN: - case WAN_OCT6100_STATE_CHIP_OPEN_PENDING: - case WAN_OCT6100_STATE_CHIP_READY: + case WAN_EC_STATE_CHIP_OPEN: + case WAN_EC_STATE_CHIP_OPEN_PENDING: + case WAN_EC_STATE_CHIP_READY: DEBUG_HWEC( "%s: Echo Canceller %s chip is %s!\n", ec_api->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); break; default: DEBUG_EVENT( "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_api->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); ec_api->err = WAN_EC_API_RC_INVALID_STATE; return 0; } - if (ec->state == WAN_OCT6100_STATE_RESET){ + if (ec->state == WAN_EC_STATE_RESET){ err = wanec_reset(ec_dev, 0); if (err) return err; } - if (ec->state == WAN_OCT6100_STATE_READY){ + if (ec->state == WAN_EC_STATE_READY){ - if (wanec_ChipOpenPrep(ec_dev, ec_api)){ + ec->pImageData = wan_vmalloc(ec_api->u_config.imageSize * sizeof(UINT8)); + if (ec->pImageData == NULL){ + DEBUG_EVENT( + "ERROR: Failed to allocate memory for EC image %ld bytes [%s:%d]!\n", + (unsigned long)ec_api->u_config.imageSize*sizeof(UINT8), + __FUNCTION__,__LINE__); + err = wanec_reset(ec_dev, 0); + return -EINVAL; + } + err = WAN_COPY_FROM_USER( + ec->pImageData, + ec_api->u_config.imageData, + ec_api->u_config.imageSize * sizeof(UINT8)); + if (err){ + DEBUG_EVENT( + "ERROR: Failed to copy EC image from user space [%s:%d]!\n", + __FUNCTION__,__LINE__); + wan_vfree(ec->pImageData); + err = wanec_reset(ec_dev, 0); + return -EINVAL; + } + ec->ImageSize = ec_api->u_config.imageSize; + + /* Copyin custom configuration (if exists) */ + if (ec_api->custom_conf.param_no){ + ec_api->u_config.custom_conf.params = + wan_malloc(ec_api->custom_conf.param_no * sizeof(wan_custom_param_t)); + if (ec_api->u_config.custom_conf.params){ + int err = 0; + err = WAN_COPY_FROM_USER( + ec_api->u_config.custom_conf.params, + ec_api->custom_conf.params, + ec_api->custom_conf.param_no * sizeof(wan_custom_param_t)); + ec_api->u_config.custom_conf.param_no = ec_api->custom_conf.param_no; + } + } + + if (wanec_ChipOpenPrep(ec_dev, ec_api->devname, &ec_api->u_config, ec_api->verbose)){ + wan_vfree(ec->pImageData); + if (ec_api->u_config.custom_conf.params){ + wan_free(ec_api->u_config.custom_conf.params); + } wanec_reset(ec_dev, 1); return -EINVAL; } + if (ec_api->u_config.custom_conf.params){ + wan_free(ec_api->u_config.custom_conf.params); + } ec->imageLast = ec_api->u_config.imageLast; - ec->state = WAN_OCT6100_STATE_CHIP_OPEN_PENDING; + ec->state = WAN_EC_STATE_CHIP_OPEN_PENDING; wanec_enable_timer(ec_dev, WAN_EC_POLL_CHIPOPENPENDING, 10); } ec_dev->state = ec->state; return 0; } -static int wanec_channel_open(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_channel_open(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { - wan_ec_t *ec = NULL; - unsigned int ec_chan, fe_chan; + wan_ec_t *ec = NULL; + int ec_chan, fe_chan; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; switch(ec->state){ - case WAN_OCT6100_STATE_CHIP_OPEN: + case WAN_EC_STATE_CHIP_OPEN: break; - case WAN_OCT6100_STATE_CHIP_READY: - DEBUG_HWEC( + case WAN_EC_STATE_CHIP_READY: + PRINT1(ec_api->verbose, "%s: Echo Canceller %s chip is %s!\n", ec_api->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); break; default: - PRINT1(ec_api->verbose, + DEBUG_EVENT( "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_api->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); ec_api->err = WAN_EC_API_RC_INVALID_STATE; return 0; } - if (ec->state == WAN_OCT6100_STATE_CHIP_OPEN){ + if (ec->state == WAN_EC_STATE_CHIP_OPEN){ /* Open all channels */ - if (wanec_ChannelOpen(ec_dev, ec_api)){ + if (wanec_ChannelOpen(ec_dev, ec_api->verbose)){ wanec_ChipClose(ec_dev, ec_api->verbose); wanec_reset(ec_dev, 1); return -EINVAL; } - ec->state = WAN_OCT6100_STATE_CHIP_READY; + ec->state = WAN_EC_STATE_CHIP_READY; } ec_dev->state = ec->state; /* EC_DEV_MAP */ - for(fe_chan=0; fe_chan < ec_dev->fe_max_channels; fe_chan++){ + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); ec->pEcDevMap[ec_chan] = ec_dev; } return 0; } -int wanec_release(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) +int wanec_api_release(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) { wan_ec_t *ec = NULL; wan_ec_dev_t *ec_dev_tmp = NULL; - unsigned int fe_chan, ec_chan, err = 0; + int fe_chan, ec_chan, err = 0; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; switch(ec->state){ - case WAN_OCT6100_STATE_READY: - case WAN_OCT6100_STATE_CHIP_OPEN: - case WAN_OCT6100_STATE_CHIP_OPEN_PENDING: - case WAN_OCT6100_STATE_CHIP_READY: + case WAN_EC_STATE_READY: + case WAN_EC_STATE_CHIP_OPEN: + case WAN_EC_STATE_CHIP_OPEN_PENDING: + case WAN_EC_STATE_CHIP_READY: break; - case WAN_OCT6100_STATE_RESET: + case WAN_EC_STATE_RESET: return 0; default: PRINT1(verbose, "%s: WARNING: Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return 0; } #if defined(__WINDOWS__) //for TDMV API there is only only one device created. //So 'release' request should simply go ahead. - FUNC_DEBUG(); + EC_FUNC_DEBUG(); #else WAN_LIST_FOREACH(ec_dev_tmp, &ec->ec_dev_head, next){ if (ec_dev_tmp != ec_dev){ - if (ec_dev_tmp->state == WAN_OCT6100_STATE_CHIP_READY){ + if (ec_dev_tmp->state == WAN_EC_STATE_CHIP_READY){ /* This EC device is still connected */ ec->f_Context.ec_dev = ec_dev_tmp; strlcpy(ec->f_Context.devname, ec_dev_tmp->devname, WAN_DRVNAME_SZ); @@ -592,13 +785,13 @@ int wanec_release(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) #endif - for(fe_chan = 0; fe_chan < ec_dev->fe_max_channels; fe_chan++){ + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); if (ec->pEcDevMap){ ec->pEcDevMap[ec_chan] = NULL; } } - ec_dev->state = WAN_OCT6100_STATE_RESET; + ec_dev->state = WAN_EC_STATE_RESET; if (ec_dev_tmp){ /* EC device is still in used */ return 0; @@ -606,23 +799,23 @@ int wanec_release(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) /* EC device is not in used anymore. ** Close all channels and chip */ - if (ec->state == WAN_OCT6100_STATE_CHIP_READY){ - if (wanec_ChannelClose(ec_dev, ec_api, verbose)){ + if (ec->state == WAN_EC_STATE_CHIP_READY){ + if (wanec_ChannelClose(ec_dev, verbose)){ return EINVAL; } - ec->state = WAN_OCT6100_STATE_CHIP_OPEN; + ec->state = WAN_EC_STATE_CHIP_OPEN; } - if (ec->state == WAN_OCT6100_STATE_CHIP_OPEN){ + if (ec->state == WAN_EC_STATE_CHIP_OPEN){ if (wanec_ChipClose(ec_dev, verbose)){ return EINVAL; } - ec->state = WAN_OCT6100_STATE_READY; + ec->state = WAN_EC_STATE_READY; } - if (ec->state == WAN_OCT6100_STATE_CHIP_OPEN_PENDING){ - ec->state = WAN_OCT6100_STATE_READY; + if (ec->state == WAN_EC_STATE_CHIP_OPEN_PENDING){ + ec->state = WAN_EC_STATE_READY; } - if (ec->state == WAN_OCT6100_STATE_READY){ + if (ec->state == WAN_EC_STATE_READY){ err = wanec_reset(ec_dev, 1); if (err){ return EINVAL; @@ -631,77 +824,12 @@ int wanec_release(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api, int verbose) return 0; } -static int wanec_modify_channel(wan_ec_dev_t *ec_dev, int fe_chan, u32 cmd, int verbose) + +static int wanec_api_modify(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; - sdla_t *card = NULL; - u_int32_t ec_chan = 0; - int err; - - WAN_ASSERT(ec_dev == NULL); - WAN_ASSERT(ec_dev->ec == NULL); - WAN_ASSERT(ec_dev->card == NULL); - ec = ec_dev->ec; - card = ec_dev->card; - - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", - ec_dev->devname, - ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); - return WAN_EC_API_RC_INVALID_STATE; - } - - /* Enable Echo cancelation on Oct6100 */ - PRINT1(verbose, - "%s: %s Echo Canceller on channel %d ...\n", - ec_dev->devname, - (cmd == WAN_EC_CMD_ENABLE) ? "Enable" : "Disable", - fe_chan); - ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); - if (cmd == WAN_EC_CMD_ENABLE){ - err = wanec_ChannelModify( - ec_dev, - ec_chan, - cOCT6100_ECHO_OP_MODE_NORMAL, - NULL, - verbose); - if (err){ - return WAN_EC_API_RC_FAILED; - } - - /* Change rx/tx traffic through Oct6100 */ - if (wanec_bypass(ec_dev, fe_chan, 1, verbose)){ - return WAN_EC_API_RC_FAILED; - } - }else{ - /* Change rx/tx traffic through Oct6100 */ - if (wanec_bypass(ec_dev, fe_chan, 0, verbose)){ - return WAN_EC_API_RC_FAILED; - } - - err = wanec_ChannelModify( - ec_dev, - ec_chan, - cOCT6100_ECHO_OP_MODE_POWER_DOWN, - NULL, - verbose); - if (err){ - return WAN_EC_API_RC_FAILED; - } - } - - return 0; -} - - -static int wanec_modify(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) -{ - wan_ec_t *ec = NULL; - sdla_t *card = NULL; u_int32_t cmd = ec_api->cmd; - u_int32_t fe_chan = 0; + int fe_chan = 0; #if 0 u_int32_t ec_chan = 0; #endif @@ -709,153 +837,88 @@ static int wanec_modify(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); - WAN_ASSERT(ec_dev->card == NULL); ec = ec_dev->ec; - card = ec_dev->card; - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api->verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } - if (ec_api->channel_map == 0xFFFFFFFF){ + if (ec_api->fe_chan_map == 0xFFFFFFFF){ /* All channels selected */ - ec_api->channel_map = 0l; - for (fe_chan = 0; fe_chan < ec_dev->fe_max_channels; fe_chan++){ - ec_api->channel_map |= (1 << fe_chan); - } - }else{ - if (ec_dev->fe_media == WAN_MEDIA_T1 || - ec_dev->fe_media == WAN_MEDIA_FXOFXS){ - ec_api->channel_map = ec_api->channel_map >> 1; - } + ec_api->fe_chan_map = ec_dev->fe_channel_map; } /* Enable Echo cancelation on Oct6100 */ PRINT1(ec_api->verbose, - "%s: %s Echo Canceller on channel(s) map=0x%08lX ...\n", + "%s: %s Echo Canceller on channel(s) chan_map=0x%08lX ...\n", ec_dev->devname, - (cmd == WAN_EC_CMD_ENABLE) ? "Enable" : "Disable", - ec_api->channel_map); + (cmd == WAN_EC_API_CMD_ENABLE) ? "Enable" : "Disable", + ec_api->fe_chan_map); /*for(chan = fe_first; chan <= fe_last; chan++){*/ - for(fe_chan=0; fe_chan < ec_dev->fe_max_channels; fe_chan++){ - if (!(ec_api->channel_map & (1 << fe_chan))){ + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ + if (!(ec_api->fe_chan_map & (1 << fe_chan))){ continue; } if (ec_dev->fe_media == WAN_MEDIA_E1 && fe_chan == 0) continue; -#if 1 - err = wanec_modify_channel(ec_dev, fe_chan, cmd, ec_api->verbose); -#else - ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); - if (cmd == WAN_EC_CMD_ENABLE){ - err = wanec_ChannelModify( - ec_dev, - ec_chan, - cOCT6100_ECHO_OP_MODE_NORMAL, - ec_api); - if (err){ - return WAN_EC_API_RC_FAILED; - } - - /* Change rx/tx traffic through Oct6100 */ - if (wanec_bypass(ec_dev, fe_chan, 1, ec_api->verbose)){ - return WAN_EC_API_RC_FAILED; - } + if (cmd == WAN_EC_API_CMD_ENABLE){ + err = wanec_channel_opmode_modify( + ec_dev, fe_chan, + cOCT6100_ECHO_OP_MODE_NORMAL, + ec_api->verbose); + if (err) return WAN_EC_API_RC_FAILED; + err = wanec_bypass(ec_dev, fe_chan, 1, ec_api->verbose); }else{ - /* Change rx/tx traffic through Oct6100 */ - if (wanec_bypass(ec_dev, fe_chan, 0, ec_api->verbose)){ - return WAN_EC_API_RC_FAILED; - } - - err = wanec_ChannelModify( - ec_dev, - ec_chan, - cOCT6100_ECHO_OP_MODE_POWER_DOWN, - ec_api); - if (err){ - return WAN_EC_API_RC_FAILED; - } + wanec_bypass(ec_dev, fe_chan, 0, ec_api->verbose); + err = wanec_channel_opmode_modify( + ec_dev, fe_chan, + cOCT6100_ECHO_OP_MODE_POWER_DOWN, + ec_api->verbose); + } + if (err){ + return WAN_EC_API_RC_FAILED; } -#endif } return 0; } -static int wanec_modify_mode(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_chan_opmode(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; - u_int32_t cmd = ec_api->cmd; - u_int32_t chan, ec_channel; - int err; + int fe_chan, err; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api->verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } - if (ec_api->channel_map == 0xFFFFFFFF){ + if (ec_api->fe_chan_map == 0xFFFFFFFF){ /* All channels selected */ - ec_api->channel_map = 0l; - for (chan = 0; chan < ec_dev->fe_max_channels; chan++){ - ec_api->channel_map |= (1 << chan); - } - }else{ - if (ec_dev->fe_media == WAN_MEDIA_T1 || - ec_dev->fe_media == WAN_MEDIA_FXOFXS){ - ec_api->channel_map = ec_api->channel_map >> 1; - } + ec_api->fe_chan_map = ec_dev->fe_channel_map; } /* Enable/Disable Normal mode on Oct6100 */ PRINT1(ec_api->verbose, - "%s: %s Echo Canceller mode on channel(s) map=0x%08lX ...\n", - ec_dev->devname, - (cmd == WAN_EC_CMD_MODE_NORMAL) ? "Enable" : - (cmd == WAN_EC_CMD_MODE_POWERDOWN) ? "Disable" : "Modify", - ec_api->channel_map); - for(chan=0; chan < ec_dev->fe_max_channels; chan++){ - if (!(ec_api->channel_map & (1 << chan))){ + "%s: Modify Echo Canceller opmode on channel(s) chan_map=0x%08lX ...\n", + ec_dev->devname, ec_api->fe_chan_map); + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ + if (!(ec_api->fe_chan_map & (1 << fe_chan))){ continue; } - if (ec_dev->fe_media == WAN_MEDIA_E1 && chan == 0) continue; - ec_channel = wanec_fe2ec_channel(ec_dev, chan); - switch(cmd){ - case WAN_EC_CMD_MODE_NORMAL: - err = wanec_ChannelModify( - ec_dev, - ec_channel, - cOCT6100_ECHO_OP_MODE_NORMAL, - ec_api, - ec_api->verbose); - break; - case WAN_EC_CMD_MODE_POWERDOWN: - err = wanec_ChannelModify( - ec_dev, - ec_channel, - cOCT6100_ECHO_OP_MODE_POWER_DOWN, - ec_api, - ec_api->verbose); - break; - default: - err = wanec_ChannelModify( - ec_dev, - ec_channel, - cOCT6100_KEEP_PREVIOUS_SETTING, - ec_api, - ec_api->verbose); - break; - } + if (ec_dev->fe_media == WAN_MEDIA_E1 && fe_chan == 0) continue; + err = wanec_channel_opmode_modify( + ec_dev, fe_chan, ec_api->u_chan_opmode.opmode, ec_api->verbose); if (err){ return WAN_EC_API_RC_FAILED; } @@ -863,50 +926,104 @@ static int wanec_modify_mode(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) return 0; } -static int wanec_modify_bypass(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_chan_custom(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { - wan_ec_t *ec = NULL; - sdla_t *card = NULL; - unsigned int chan, fe_chan = 0; + wan_ec_t *ec = NULL; + wanec_chan_custom_t *chan_custom; + int fe_chan, ec_chan, err; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); - WAN_ASSERT(ec_dev->card == NULL); ec = ec_dev->ec; - card = ec_dev->card; - - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api->verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } - if (ec_api->channel_map == 0xFFFFFFFF){ + + if (ec_api->fe_chan_map == 0xFFFFFFFF){ /* All channels selected */ - ec_api->channel_map = 0l; - for (chan = 0; chan < ec_dev->fe_max_channels; chan++){ - ec_api->channel_map |= (1 << chan); - } + ec_api->fe_chan_map = ec_dev->fe_channel_map; + } + /* Enable/Disable Normal mode on Oct6100 */ + PRINT1(ec_api->verbose, + "%s: Modify EC Channel config (parms:%d) on channel(s) chan_map=0x%08lX ...\n", + ec_dev->devname, ec_api->custom_conf.param_no, + ec_api->fe_chan_map); + if (ec_api->custom_conf.param_no == 0){ + /* nothing to do */ + return 0; + } + chan_custom = &ec_api->u_chan_custom; + chan_custom->custom_conf.params = + wan_malloc(ec_api->custom_conf.param_no * sizeof(wan_custom_param_t)); + if (chan_custom->custom_conf.params){ + int err = 0; + err = WAN_COPY_FROM_USER( + chan_custom->custom_conf.params, + ec_api->custom_conf.params, + ec_api->custom_conf.param_no * sizeof(wan_custom_param_t)); + chan_custom->custom_conf.param_no = ec_api->custom_conf.param_no; }else{ - if (ec_dev->fe_media == WAN_MEDIA_T1 || - ec_dev->fe_media == WAN_MEDIA_FXOFXS){ - ec_api->channel_map = ec_api->channel_map >> 1; + DEBUG_EVENT( + "%s: WARNING: Skipping custom OCT6100 configuration (allocation failed)!\n", + ec_dev->devname); + return WAN_EC_API_RC_FAILED; + } + + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ + if (!(ec_api->fe_chan_map & (1 << fe_chan))){ + continue; } + if (ec_dev->fe_media == WAN_MEDIA_E1 && fe_chan == 0) continue; + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); + err = wanec_ChannelModifyCustom(ec_dev, ec_chan, chan_custom, ec_api->verbose); + if (err){ + wan_free(chan_custom->custom_conf.params); + chan_custom->custom_conf.params = NULL; + return WAN_EC_API_RC_FAILED; + } + } + wan_free(chan_custom->custom_conf.params); + chan_custom->custom_conf.params = NULL; + return 0; +} + +static int wanec_api_modify_bypass(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +{ + wan_ec_t *ec = NULL; + unsigned int fe_chan = 0; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", + ec_dev->devname, + ec->name, + WAN_EC_STATE_DECODE(ec->state)); + return WAN_EC_API_RC_INVALID_STATE; + } + if (ec_api->fe_chan_map == 0xFFFFFFFF){ + /* All channels selected */ + ec_api->fe_chan_map = ec_dev->fe_channel_map; } /* Enable/Disable bypass mode on Oct6100 */ PRINT1(ec_api->verbose, - "%s: %s Bypass mode on channel(s) map=0x%08lX ...\n", + "%s: %s Bypass mode on channel(s) chan_map=0x%08lX ...\n", ec_dev->devname, - (ec_api->cmd == WAN_EC_CMD_BYPASS_ENABLE) ? "Enable" : "Disable", - ec_api->channel_map); - for(chan = 0; chan < ec_dev->fe_max_channels; chan++){ - if (!(ec_api->channel_map & (1 << chan))){ + (ec_api->cmd == WAN_EC_API_CMD_BYPASS_ENABLE) ? "Enable" : "Disable", + ec_api->fe_chan_map); + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= (unsigned int)ec_dev->fe_stop_chan; fe_chan++){ + if (!(ec_api->fe_chan_map & (1 << fe_chan))){ continue; } - fe_chan = chan; - if (ec_api->cmd == WAN_EC_CMD_BYPASS_ENABLE){ + if (ec_api->cmd == WAN_EC_API_CMD_BYPASS_ENABLE){ /* Change rx/tx traffic through Oct6100 */ if (wanec_bypass(ec_dev, fe_chan, 1, ec_api->verbose)){ return WAN_EC_API_RC_FAILED; @@ -922,82 +1039,42 @@ static int wanec_modify_bypass(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) } -static int wanec_modify_dtmf(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_channel_mute(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; - sdla_t *card = NULL; - unsigned int fe_chan, ec_channel; + int fe_chan; int err = WAN_EC_API_RC_OK; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); - WAN_ASSERT(ec_dev->card == NULL); ec = ec_dev->ec; - card = ec_dev->card; - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api->verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } - - if (ec_api->channel_map == 0xFFFFFFFF){ + if (ec_api->fe_chan_map == 0xFFFFFFFF){ /* All channels selected */ - ec_api->channel_map = 0l; - for (fe_chan = 0; fe_chan < ec_dev->fe_max_channels; fe_chan++){ - ec_api->channel_map |= (1 << fe_chan); - } - }else{ - if (ec_dev->fe_media == WAN_MEDIA_T1 || - ec_dev->fe_media == WAN_MEDIA_FXOFXS){ - ec_api->channel_map = ec_api->channel_map >> 1; - } + ec_api->fe_chan_map = ec_dev->fe_channel_map; } - if (!ec_api->channel_map){ + if (!ec_api->fe_chan_map){ return WAN_EC_API_RC_NOACTION; } - /* Enable/Disable Normal mode on Oct6100 */ - PRINT1(ec_api->verbose, - "%s: %s Echo Canceller DTMF on channel(s) map=0x%08lX ...\n", - ec_dev->devname, - (ec_api->cmd == WAN_EC_CMD_DTMF_ENABLE) ? "Enable" : - (ec_api->cmd == WAN_EC_CMD_DTMF_DISABLE) ? "Disable" : - "Unknown", - ec_api->channel_map); - for(fe_chan=0; fe_chan < ec_dev->fe_max_channels; fe_chan++){ - if (!(ec_api->channel_map & (1 << fe_chan))){ + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ + if (!(ec_api->fe_chan_map & (1 << fe_chan))){ continue; } if (ec_dev->fe_media == WAN_MEDIA_E1 && fe_chan == 0) continue; - ec_channel = wanec_fe2ec_channel(ec_dev, fe_chan); - switch(ec_api->cmd){ - case WAN_EC_CMD_DTMF_ENABLE: - if (wanec_bypass(ec_dev, fe_chan, 1, ec_api->verbose)){ - return WAN_EC_API_RC_FAILED; - } - err = wanec_TonesEnable( - ec, - ec_channel, - ec_api->u_dtmf_config.port, + err = wanec_channel_mute( + ec_dev, + fe_chan, + (ec_api->cmd == WAN_EC_API_CMD_CHANNEL_MUTE) ? WAN_TRUE: WAN_FALSE, + &ec_api->u_chan_mute, ec_api->verbose); - break; - case WAN_EC_CMD_DTMF_DISABLE: - err = wanec_TonesDisable( - ec, - ec_channel, - ec_api->u_dtmf_config.port, - ec_api->verbose); - if (wanec_bypass(ec_dev, fe_chan, 0, ec_api->verbose)){ - return WAN_EC_API_RC_FAILED; - } - break; - default: - err = WAN_EC_API_RC_INVALID_CMD; - break; - } if (err){ return WAN_EC_API_RC_FAILED; } @@ -1005,101 +1082,161 @@ static int wanec_modify_dtmf(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) return err; } -static int wanec_stats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_dtmf(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; - unsigned int fe_chan, ec_channel, err = 0; + int fe_chan, err = WAN_EC_API_RC_OK; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api->verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } - if (ec_dev->fe_media == WAN_MEDIA_T1 || ec_dev->fe_media == WAN_MEDIA_FXOFXS){ - ec_api->channel_map = ec_api->channel_map >> 1; + if (ec_api->fe_chan_map == 0xFFFFFFFF){ + /* All channels selected */ + ec_api->fe_chan_map = ec_dev->fe_channel_map; } + + if (!ec_api->fe_chan_map){ + return WAN_EC_API_RC_NOACTION; + } + /* Enable/Disable Normal mode on Oct6100 */ PRINT1(ec_api->verbose, - "%s: Read Echo Canceller stats on channel(s) map=0x%08lX reset %d...\n", + "%s: %s Echo Canceller DTMF on channel(s) chan_map=0x%08lX ...\n", ec_dev->devname, - ec_api->channel_map, - (ec_api->channel_map) ? + (ec_api->cmd == WAN_EC_API_CMD_DTMF_ENABLE) ? "Enable" : + (ec_api->cmd == WAN_EC_API_CMD_DTMF_DISABLE) ? "Disable" : + "Unknown", + ec_api->fe_chan_map); + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ + if (!(ec_api->fe_chan_map & (1 << fe_chan))){ + continue; + } + if (ec_dev->fe_media == WAN_MEDIA_E1 && fe_chan == 0) continue; + err = wanec_channel_dtmf( + ec_dev, + fe_chan, + (ec_api->cmd == WAN_EC_API_CMD_DTMF_ENABLE) ? WAN_TRUE : WAN_FALSE, + &ec_api->u_dtmf_config, + ec_api->verbose); + if (err){ + return WAN_EC_API_RC_FAILED; + } + } + return err; +} + +static int wanec_api_stats(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +{ + wan_ec_t *ec = NULL; + int fe_chan, ec_chan, err = 0; + + WAN_ASSERT(ec_dev == NULL); + WAN_ASSERT(ec_dev->ec == NULL); + ec = ec_dev->ec; + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", + ec_dev->devname, + ec->name, + WAN_EC_STATE_DECODE(ec->state)); + return WAN_EC_API_RC_INVALID_STATE; + } + + PRINT1(ec_api->verbose, + "%s: Read EC stats on channel(s) chan_map=0x%08lX reset:%d...\n", + ec_dev->devname, + ec_api->fe_chan_map, + (ec_api->fe_chan_map) ? ec_api->u_chan_stats.reset:ec_api->u_chip_stats.reset); if (wanec_ISR(ec, ec_api->verbose)){ return WAN_EC_API_RC_FAILED; } - if (ec_api->channel_map){ - for(fe_chan=0; fe_chan < ec_dev->fe_max_channels; fe_chan++){ - if (!(ec_api->channel_map & (1 << fe_chan))){ + if (ec_api->fe_chan_map){ + int ready = 0; + for(fe_chan = ec_dev->fe_start_chan; fe_chan <= ec_dev->fe_stop_chan; fe_chan++){ + if (!(ec_api->fe_chan_map & (1 << fe_chan))){ + continue; + } + if (!wan_test_bit(fe_chan, &ec_dev->fe_channel_map)){ continue; } if (ec_dev->fe_media == WAN_MEDIA_E1 && fe_chan == 0){ continue; } - ec_channel = wanec_fe2ec_channel(ec_dev, fe_chan); + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); err = wanec_ChannelStats( ec_dev, - ec_channel, - ec_api, - ec_api->u_chan_stats.reset); + ec_chan, + &ec_api->u_chan_stats, + ec_api->verbose); if (err){ return WAN_EC_API_RC_FAILED; } + ready = 1; + break; + } + if (!ready){ + return WAN_EC_API_RC_INVALID_CHANNELS; } }else{ - wanec_ChipStats(ec_dev, ec_api, ec_api->u_chip_stats.reset); + wanec_ChipStats(ec_dev, &ec_api->u_chip_stats, ec_api->u_chip_stats.reset, ec_api->verbose); } return 0; } -static int wanec_monitor(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_monitor(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; - unsigned int channel = ec_api->channel, - ec_channel; + int fe_chan = ec_api->fe_chan, + ec_chan = 0; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api-> verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } /* Sanity check from channel selection */ - if (((ec_dev->fe_media == WAN_MEDIA_T1) && (channel > ec_dev->fe_max_channels)) || - ((ec_dev->fe_media == WAN_MEDIA_E1) && (channel >= ec_dev->fe_max_channels))){ + if (fe_chan > ec_dev->fe_stop_chan){ DEBUG_EVENT( - "ERROR: %s: Channel number %d out of range!\n", - ec_dev->devname, - channel); + "ERROR: %s: Front-End channel number %d is out of range!\n", + ec_dev->devname, fe_chan); return WAN_EC_API_RC_INVALID_CHANNELS; } - if (channel){ - if (ec_dev->fe_media == WAN_MEDIA_T1 || ec_dev->fe_media == WAN_MEDIA_FXOFXS) channel--; - ec_channel = wanec_fe2ec_channel(ec_dev, channel); - if (wanec_DebugChannel(ec, ec_channel, ec_api->verbose)){ + if (fe_chan){ + if (!(ec_dev->fe_channel_map & (1 << fe_chan))){ + return WAN_EC_API_RC_INVALID_CHANNELS; + } + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); + if (wanec_DebugChannel(ec_dev, ec_chan, ec_api->verbose)){ return WAN_EC_API_RC_FAILED; } }else{ - wanec_DebugGetData(ec, ec_api); + if (wanec_DebugGetData(ec_dev, &ec_api->u_chan_monitor, ec_api->verbose)){ + return WAN_EC_API_RC_FAILED; + } + ec_api->fe_chan = ec_api->u_chan_monitor.fe_chan; } return 0; } -static int wanec_tone(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_buffer(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; int err; @@ -1107,18 +1244,18 @@ static int wanec_tone(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api->verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } - if (ec_api->cmd == WAN_EC_CMD_TONE_LOAD){ - err = wanec_BufferLoad(ec_dev, ec_api); + if (ec_api->cmd == WAN_EC_API_CMD_BUFFER_LOAD){ + err = wanec_BufferLoad(ec_dev, &ec_api->u_buffer_config, ec_api->verbose); }else{ - err = wanec_BufferUnload(ec_dev, ec_api); + err = wanec_BufferUnload(ec_dev, &ec_api->u_buffer_config, ec_api->verbose); } if (err){ return WAN_EC_API_RC_FAILED; @@ -1126,51 +1263,70 @@ static int wanec_tone(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) return 0; } -static int wanec_playout(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) +static int wanec_api_playout(wan_ec_dev_t *ec_dev, wan_ec_api_t *ec_api) { wan_ec_t *ec = NULL; - int ec_channel; + int fe_chan = ec_api->fe_chan, + ec_chan = 0; WAN_ASSERT(ec_dev == NULL); WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - PRINT1(ec_api->verbose, - "WARNING: %s: Invalid Echo Canceller %s API state (%s)\n", + if (ec->state != WAN_EC_STATE_CHIP_READY){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller %s API state (%s)\n", ec_dev->devname, ec->name, - WAN_OCT6100_STATE_DECODE(ec->state)); + WAN_EC_STATE_DECODE(ec->state)); return WAN_EC_API_RC_INVALID_STATE; } - if (ec_dev->fe_media == WAN_MEDIA_E1 && ec_api->channel == 0){ + if (ec_dev->fe_media == WAN_MEDIA_E1 && ec_api->fe_chan == 0){ return WAN_EC_API_RC_NOACTION; } - if (((ec_dev->fe_media == WAN_MEDIA_T1) && ((unsigned int)ec_api->channel > ec_dev->fe_max_channels)) || - ((ec_dev->fe_media == WAN_MEDIA_E1) && ((unsigned int)ec_api->channel >= ec_dev->fe_max_channels))){ + if (fe_chan > ec_dev->fe_stop_chan){ DEBUG_EVENT( - "ERROR: %s: Channel number %d out of range!\n", - ec_dev->devname, - ec_api->channel); + "ERROR: %s: Front-End channel number %d is out of range!\n", + ec_dev->devname, fe_chan); return WAN_EC_API_RC_INVALID_CHANNELS; } + if (ec_api->u_playout.port != WAN_EC_CHANNEL_PORT_SOUT && + ec_api->u_playout.port != WAN_EC_CHANNEL_PORT_ROUT){ + DEBUG_EVENT( + "ERROR: %s: Invalid Echo Canceller port value (%s)!\n", + ec_dev->devname, + WAN_EC_DECODE_CHANNEL_PORT(ec_api->u_playout.port)); + return WAN_EC_API_RC_INVALID_PORT; + } + ec_chan = wanec_fe2ec_channel(ec_dev, fe_chan); - if (ec_dev->fe_media == WAN_MEDIA_T1 || ec_dev->fe_media == WAN_MEDIA_FXOFXS) - ec_api->channel--; - ec_channel = wanec_fe2ec_channel(ec_dev, ec_api->channel); - + PRINT1(ec_api->verbose, + "%s: Buffer Playout %s on fe_chan:%d ...\n", + ec_dev->devname, + (ec_api->cmd == WAN_EC_API_CMD_PLAYOUT_START) ? + "Start" : "Stop", + fe_chan); switch(ec_api->cmd){ - case WAN_EC_CMD_PLAYOUT_START: - if (wanec_BufferPlayoutAdd(ec, ec_channel, ec_api)){ + case WAN_EC_API_CMD_PLAYOUT_START: + if (wanec_BufferPlayoutAdd(ec, ec_chan, &ec_api->u_playout, ec_api->verbose)){ return WAN_EC_API_RC_FAILED; } - if (wanec_BufferPlayoutStart(ec, ec_channel, ec_api)){ - wanec_BufferPlayoutStop(ec, ec_channel, ec_api); + if (wanec_BufferPlayoutStart(ec, ec_chan, &ec_api->u_playout, ec_api->verbose)){ + wanec_BufferPlayoutStop(ec, ec_chan, &ec_api->u_playout, ec_api->verbose); return WAN_EC_API_RC_FAILED; } + ec->playout_verbose = ec_api->verbose; + if (ec_api->u_playout.notifyonstop){ + wan_set_bit(WAN_EC_BIT_EVENT_PLAYOUT, &ec_dev->events); + } break; - case WAN_EC_CMD_PLAYOUT_STOP: - wanec_BufferPlayoutStop(ec, ec_channel, ec_api); + case WAN_EC_API_CMD_PLAYOUT_STOP: + wanec_BufferPlayoutStop(ec, ec_chan, &ec_api->u_playout, ec_api->verbose); + /* FIXME: Once the Playout event was enabled, do not + ** disable it otherwise playout events for other + ** channels will be delayed + **ec->playout_verbose = 0; + **wan_clear_bit(WAN_EC_BIT_EVENT_PLAYOUT, &ec_dev->events);*/ break; } @@ -1230,7 +1386,7 @@ int wanec_ioctl(void *data, void *pcard) wanec_search(ec_api->devname); #endif if (ec_dev == NULL){ - PRINT1(ec_api->verbose, + DEBUG_EVENT( "%s: Failed to find device [%s:%d]!\n", ec_api->devname, __FUNCTION__,__LINE__); ec_api->err = WAN_EC_API_RC_INVALID_DEV; @@ -1238,17 +1394,19 @@ int wanec_ioctl(void *data, void *pcard) } WAN_ASSERT(ec_dev->ec == NULL); ec = ec_dev->ec; +#if !defined(__WINDOWS__) + /* Windows: can not copy to/from user when locked */ wan_spin_lock(&ec->lock); - +#endif if (wan_test_bit(WAN_EC_BIT_CRIT_DOWN, &ec_dev->critical)){ - PRINT1(ec_api->verbose, + DEBUG_EVENT( "%s: Echo Canceller device is down!\n", ec_api->devname); ec_api->err = WAN_EC_API_RC_INVALID_DEV; goto wanec_ioctl_done; } if (wan_test_and_set_bit(WAN_EC_BIT_CRIT_CMD, &ec->critical)){ - PRINT1(ec_api->verbose, + DEBUG_EVENT( "%s: Echo Canceller is busy!\n", ec_api->devname); ec_api->err = WAN_EC_API_RC_BUSY; @@ -1256,61 +1414,83 @@ int wanec_ioctl(void *data, void *pcard) } PRINT2(ec_api->verbose, "%s: WPEC_LIP IOCTL: %s\n", - ec_api->devname, WAN_EC_CMD_DECODE(ec_api->cmd)); + ec_api->devname, WAN_EC_API_CMD_DECODE(ec_api->cmd)); ec_api->err = WAN_EC_API_RC_OK; +/* + { + int i; + u8 *t = (u8*)ec_api; + for(i = 0; i < sizeof(wan_ec_api_t); i++){ + DEBUG_HWEC("[%i]=%02X\n", i, t[i]); + if(i > 1000){ + DEBUG_HWEC("...\n"); + break; + } + } + + } +*/ switch(ec_api->cmd){ - case WAN_EC_CMD_GETINFO: + case WAN_EC_API_CMD_GETINFO: ec_api->u_info.max_channels = ec->max_channels; ec_api->state = ec->state; break; - case WAN_EC_CMD_CONFIG: - err = wanec_config(ec_dev, ec_api); + case WAN_EC_API_CMD_CONFIG: + err = wanec_api_config(ec_dev, ec_api); break; - case WAN_EC_CMD_RELEASE: - err = wanec_release(ec_dev, ec_api, ec_api->verbose); + case WAN_EC_API_CMD_CONFIG_POLL: + ec_api->state = ec->state; break; - case WAN_EC_CMD_CHANNEL_OPEN: - err = wanec_channel_open(ec_dev, ec_api); + case WAN_EC_API_CMD_RELEASE: + err = wanec_api_release(ec_dev, ec_api, ec_api->verbose); break; - case WAN_EC_CMD_ENABLE: - case WAN_EC_CMD_DISABLE: - err = wanec_modify(ec_dev, ec_api); + case WAN_EC_API_CMD_CHANNEL_OPEN: + err = wanec_api_channel_open(ec_dev, ec_api); break; - case WAN_EC_CMD_BYPASS_ENABLE: - case WAN_EC_CMD_BYPASS_DISABLE: - err = wanec_modify_bypass(ec_dev, ec_api); + case WAN_EC_API_CMD_ENABLE: + case WAN_EC_API_CMD_DISABLE: + err = wanec_api_modify(ec_dev, ec_api); break; - case WAN_EC_CMD_MODE_NORMAL: - case WAN_EC_CMD_MODE_POWERDOWN: - case WAN_EC_CMD_MODIFY_CHANNEL: - err = wanec_modify_mode(ec_dev, ec_api); + case WAN_EC_API_CMD_BYPASS_ENABLE: + case WAN_EC_API_CMD_BYPASS_DISABLE: + err = wanec_api_modify_bypass(ec_dev, ec_api); break; - case WAN_EC_CMD_DTMF_ENABLE: - case WAN_EC_CMD_DTMF_DISABLE: - ec_api->err = wanec_modify_dtmf(ec_dev, ec_api); + case WAN_EC_API_CMD_OPMODE: + err = wanec_api_chan_opmode(ec_dev, ec_api); break; - case WAN_EC_CMD_STATS: - case WAN_EC_CMD_STATS_FULL: - err = wanec_stats(ec_dev, ec_api); + case WAN_EC_API_CMD_CHANNEL_MUTE: + case WAN_EC_API_CMD_CHANNEL_UNMUTE: + err = wanec_api_channel_mute(ec_dev, ec_api); break; - case WAN_EC_CMD_TONE_LOAD: - case WAN_EC_CMD_TONE_UNLOAD: - err = wanec_tone(ec_dev, ec_api); + case WAN_EC_API_CMD_MODIFY_CHANNEL: + err = wanec_api_chan_custom(ec_dev, ec_api); break; - case WAN_EC_CMD_PLAYOUT_START: - case WAN_EC_CMD_PLAYOUT_STOP: - err = wanec_playout(ec_dev, ec_api); + case WAN_EC_API_CMD_DTMF_ENABLE: + case WAN_EC_API_CMD_DTMF_DISABLE: + ec_api->err = wanec_api_dtmf(ec_dev, ec_api); break; - case WAN_EC_CMD_MONITOR: - err = wanec_monitor(ec_dev, ec_api); + case WAN_EC_API_CMD_STATS: + case WAN_EC_API_CMD_STATS_FULL: + err = wanec_api_stats(ec_dev, ec_api); break; - case WAN_EC_CMD_RELEASE_ALL: + case WAN_EC_API_CMD_BUFFER_LOAD: + case WAN_EC_API_CMD_BUFFER_UNLOAD: + err = wanec_api_buffer(ec_dev, ec_api); + break; + case WAN_EC_API_CMD_PLAYOUT_START: + case WAN_EC_API_CMD_PLAYOUT_STOP: + err = wanec_api_playout(ec_dev, ec_api); + break; + case WAN_EC_API_CMD_MONITOR: + err = wanec_api_monitor(ec_dev, ec_api); + break; + case WAN_EC_API_CMD_RELEASE_ALL: break; } if (err){ PRINT2(ec_api->verbose, "%s: %s return error (Command: %s)\n", - ec_api->devname, __FUNCTION__, WAN_EC_CMD_DECODE(ec_api->cmd)); + ec_api->devname, __FUNCTION__, WAN_EC_API_CMD_DECODE(ec_api->cmd)); ec_api->err = err; } if (ec_api->err == WAN_EC_API_RC_INVALID_STATE){ @@ -1319,7 +1499,11 @@ int wanec_ioctl(void *data, void *pcard) wan_clear_bit(WAN_EC_BIT_CRIT_CMD, &ec->critical); wanec_ioctl_done: +#if !defined(__WINDOWS__) + /* Windows: can not copy to/from user when locked */ wan_spin_unlock(&ec->lock); +#endif + wanec_ioctl_exit: #if defined(__LINUX__) err = WAN_COPY_TO_USER( @@ -1338,7 +1522,7 @@ wanec_ioctl_exit: PRINT2(ec_api->verbose, "%s: WPEC_LIP IOCTL: %s returns %d\n", ec_api->devname, - WAN_EC_CMD_DECODE(ec_api->cmd), + WAN_EC_API_CMD_DECODE(ec_api->cmd), ec_api->err); #if defined(__LINUX__) @@ -1372,15 +1556,15 @@ static int wan_ec_devnum(char *ptr) return num; } -static void* wanec_register(void *pcard, int max_channels) +static void* +wanec_register(void *pcard, u_int32_t fe_port_mask, int max_line_no, int max_channels, void *pconf) { - sdla_t *card = (sdla_t*)pcard; - wan_ec_t *ec = NULL; - wan_ec_dev_t *ec_dev = NULL, *ec_dev_new = NULL; + sdla_t *card = (sdla_t*)pcard; + wan_custom_conf_t *conf = (wan_custom_conf_t*)pconf; + wan_ec_t *ec = NULL; + wan_ec_dev_t *ec_dev = NULL, *ec_dev_new = NULL; WAN_DEBUG_FUNC_START; - - #if defined(__WINDOWS__) ec = get_wan_ec_ptr(card); #else @@ -1388,14 +1572,9 @@ static void* wanec_register(void *pcard, int max_channels) WAN_LIST_FOREACH(ec_dev, &ec->ec_dev_head, next){ if (ec_dev->card == NULL || ec_dev->card == card){ DEBUG_EVENT("%s: Internal Error (%s:%d)\n", - card->devname, - __FUNCTION__,__LINE__); + card->devname, __FUNCTION__,__LINE__); return NULL; } - } - } - WAN_LIST_FOREACH(ec, &wan_ec_head, next){ - WAN_LIST_FOREACH(ec_dev, &ec->ec_dev_head, next){ if (card->hw_iface.hw_same(ec_dev->card->hw, card->hw)){ /* Current OCT6100 chip is already in use */ break; @@ -1429,6 +1608,7 @@ static void* wanec_register(void *pcard, int max_channels) #else if (ec_dev == NULL){ #endif + /* First device for current Oct6100 chip */ ec = wan_malloc(sizeof(wan_ec_t)); if (ec == NULL){ @@ -1437,20 +1617,45 @@ static void* wanec_register(void *pcard, int max_channels) __FUNCTION__,__LINE__); return NULL; } - memset(ec, 0, sizeof(wan_ec_t)); - ec->chip_no = ++wan_ec_no; - ec->state = WAN_OCT6100_STATE_RESET; - ec->ec_active = 0; - ec->max_channels = max_channels; - wan_spin_lock_init(&ec->lock); + + ec->chip_no = card->hw_iface.get_hwec_index(card->hw); + if (ec->chip_no < 0){ + DEBUG_EVENT("%s: ERROR: Failed to get EC chip number!\n", + card->devname); + wan_free(ec); + return NULL; + } + ec->state = WAN_EC_STATE_RESET; + ec->max_channels = (u_int16_t)max_channels; + wan_spin_lock_init(&ec->lock, "wan_ec_lock"); sprintf(ec->name, "%s%d", WANEC_DEV_NAME, ec->chip_no); + + /* Copy EC chip custom configuration */ + if (conf->param_no){ + /* Copy custom oct parameter from user space */ + ec->custom_conf.params = wan_malloc(conf->param_no * sizeof(wan_custom_param_t)); + if (ec->custom_conf.params){ + int err = 0; + err = WAN_COPY_FROM_USER( + ec->custom_conf.params, + conf->params, + conf->param_no * sizeof(wan_custom_param_t)); + ec->custom_conf.param_no = conf->param_no; + }else{ + DEBUG_EVENT( + "%s: WARNING: Skipping custom OCT6100 configuration (allocation failed)!\n", + card->devname); + } + } + Oct6100InterruptServiceRoutineDef(&ec->f_InterruptFlag); #if defined(__WINDOWS__) set_wan_ec_ptr(card, ec); #else WAN_LIST_INIT(&ec->ec_dev_head); + WAN_LIST_INIT(&ec->ec_confbridge_head); WAN_LIST_INSERT_HEAD(&wan_ec_head, ec, next); #endif }else{ @@ -1459,14 +1664,28 @@ static void* wanec_register(void *pcard, int max_channels) #endif } ec->usage++; - ec_dev_new->ecdev_no = wan_ec_devnum(card->devname); + ec_dev_new->ecdev_no = wan_ec_devnum(card->devname); ec_dev_new->ec = ec; ec_dev_new->name = ec->name; ec_dev_new->card = card; ec_dev_new->fe_media = WAN_FE_MEDIA(&card->fe); ec_dev_new->fe_lineno = WAN_FE_LINENO(&card->fe); - ec_dev_new->fe_max_channels = WAN_FE_MAX_CHANNELS(&card->fe); + ec_dev_new->fe_start_chan = WAN_FE_START_CHANNEL(&card->fe); + ec_dev_new->fe_max_chans = WAN_FE_MAX_CHANNELS(&card->fe); //max_line_no; // + ec_dev_new->fe_stop_chan = ec_dev_new->fe_start_chan + ec_dev_new->fe_max_chans - 1; + /* Feb 14, 2008 + ** Ignore fe_port_mask for BRI cards. fe_port_mask is for full card, + ** but ec_dev created per module. In this case, we have always + ** 2 channels (1 and 2). Create fe_channel_map manually */ + if (fe_port_mask && ec_dev_new->fe_media != WAN_MEDIA_BRI){ + ec_dev_new->fe_channel_map = fe_port_mask; + }else{ + int fe_chan = 0; + for(fe_chan = ec_dev_new->fe_start_chan; fe_chan <= ec_dev_new->fe_stop_chan; fe_chan++){ + ec_dev_new->fe_channel_map |= (1 << fe_chan); + } + } if (!WAN_FE_TDMV_LAW(&card->fe)){ if (WAN_FE_MEDIA(&card->fe) == WAN_MEDIA_T1){ WAN_FE_TDMV_LAW(&card->fe) = WAN_TDMV_MULAW; @@ -1478,11 +1697,11 @@ static void* wanec_register(void *pcard, int max_channels) } } ec_dev_new->fe_tdmv_law = WAN_FE_TDMV_LAW(&card->fe); - ec_dev_new->state = WAN_OCT6100_STATE_RESET; + ec_dev_new->state = WAN_EC_STATE_RESET; /* Initialize hwec_bypass pointer */ card->wandev.ec_enable = wanec_enable; - card->wandev.ec_map = 0; + card->wandev.fe_ec_map = 0; memcpy(ec_dev_new->devname, card->devname, sizeof(card->devname)); sprintf(ec_dev_new->ecdev_name, "wp%dec", ec_dev_new->ecdev_no); @@ -1517,10 +1736,9 @@ static int wanec_unregister(void *arg, void *pcard) ec = ec_dev->ec; wan_spin_lock(&ec->lock); - DEBUG_EVENT("%s: Unregister interface from %s (chip id %d, usage %d)!\n", + DEBUG_EVENT("%s: Unregister interface from %s (usage %d)!\n", card->devname, ec->name, - ec->chip_no, ec->usage); wan_set_bit(WAN_EC_BIT_TIMER_KILL,(void*)&ec_dev->critical); @@ -1528,11 +1746,11 @@ static int wanec_unregister(void *arg, void *pcard) wan_set_bit(WAN_EC_BIT_CRIT,(void*)&ec_dev->critical); wan_del_timer(&ec_dev->timer); - if (ec_dev->state != WAN_OCT6100_STATE_RESET){ - PRINT1(global_verbose, - "%s: Forcing EC device release\n", + if (ec_dev->state != WAN_EC_STATE_RESET){ + DEBUG_EVENT( + "%s: Releasing EC device (force)!\n", card->devname); - wanec_release(ec_dev, NULL, global_verbose); + wanec_api_release(ec_dev, NULL, wanec_verbose); } ec_dev->card = NULL; ec->usage--; @@ -1552,10 +1770,12 @@ static int wanec_unregister(void *arg, void *pcard) card->ec_dev_ptr = NULL; #endif + ec_dev->ec = NULL; + wan_free(ec_dev); + wan_spin_unlock(&ec->lock); + /* FIXME: Remove character device */ if (!ec->usage){ - ec_dev->ec = NULL; - wan_free(ec_dev); #if !defined(__WINDOWS__) if (WAN_LIST_FIRST(&wan_ec_head) == ec){ WAN_LIST_FIRST(&wan_ec_head) = @@ -1566,77 +1786,56 @@ static int wanec_unregister(void *arg, void *pcard) } #endif + /* Free all custom configuration parameters */ + if (ec->custom_conf.params){ + wan_free(ec->custom_conf.params); + } + wan_free(ec); #if defined(__WINDOWS__) set_wan_ec_ptr(card, NULL); #endif - }else{ - ec_dev->ec = NULL; - wan_free(ec_dev); } - wan_spin_unlock(&ec->lock); WAN_DEBUG_FUNC_END; return 0; } -#if 0 -static int wanec_isr(void *arg, void *pcard) +#define WAN_EC_IRQ_TIMEOUT (HZ*60) +#define WAN_EC_DTMF_IRQ_TIMEOUT (HZ/32) +#define WAN_EC_PLAYOUT_IRQ_TIMEOUT (HZ/32) +static int wanec_isr(void *arg) { - wan_ec_t *ec = NULL; wan_ec_dev_t *ec_dev = (wan_ec_dev_t*)arg; - - WAN_ASSERT2(ec_dev == NULL, 0); - WAN_ASSERT2(ec_dev->ec == NULL, 0); - ec = ec_dev->ec; - -#if !defined(__WINDOWS__) - if (WAN_LIST_FIRST(&ec->ec_dev_head) != ec_dev){ - return 0; - } -#endif - - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ - return 0; - } - if (wan_test_bit(WAN_EC_BIT_CRIT_DOWN, &ec_dev->critical)){ - return 0; - } - if (wan_test_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->critical)){ - return 0; - } - if (wan_test_bit(WAN_EC_BIT_CRIT_CMD, &ec->critical)){ - return 0; - } - if (ec_dev->poll_cmd != WAN_EC_POLL_NONE){ - /* I'm still busy, return now */ - return 0; - } - - ec->intcount++; - /* Execute interrupt routine */ - if (wanec_ISR(ec, global_verbose)){ - wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec->critical); - wan_set_bit(WAN_EC_BIT_CRIT,(void*)&ec_dev->critical); + if (ec_dev == NULL || ec_dev->ec == NULL) return 0; + if (ec_dev->ec->state != WAN_EC_STATE_CHIP_READY){ + return 0; + } + if (wan_test_bit(WAN_EC_BIT_EVENT_DTMF, &ec_dev->events)){ + /* DTMF event is enabled */ + if ((SYSTEM_TICKS - ec_dev->lastint_ticks) > WAN_EC_DTMF_IRQ_TIMEOUT){ + ec_dev->lastint_ticks = SYSTEM_TICKS; + return 1; + } + return 0; + } + if (wan_test_bit(WAN_EC_BIT_EVENT_PLAYOUT, &ec_dev->events)){ + /* Playout event is enabled */ + if ((SYSTEM_TICKS - ec_dev->lastint_ticks) > WAN_EC_PLAYOUT_IRQ_TIMEOUT){ + ec_dev->lastint_ticks = SYSTEM_TICKS; + return 1; + } return 0; } - - PRINT1(global_verbose, - "%s: HW EC ISR-POLL (%d:%d)\n", - ec_dev->devname, ec->intcount, - (ec->f_InterruptFlag.fToneEventsPending == TRUE)?1:0); - if (ec->f_InterruptFlag.fToneEventsPending == TRUE && - wan_test_bit(WAN_EC_BIT_EVENT_DTMF, &ec_dev->events)){ - ec_dev->poll_cmd = WAN_EC_POLL_INTR; - /* Schedule poll */ - return 1; + if ((SYSTEM_TICKS - ec_dev->lastint_ticks) > WAN_EC_IRQ_TIMEOUT){ + ec_dev->lastint_ticks = SYSTEM_TICKS; + return 1; } return 0; } -#endif static int wanec_poll(void *arg, void *pcard) { @@ -1649,10 +1848,18 @@ static int wanec_poll(void *arg, void *pcard) ec = ec_dev->ec; WAN_DEBUG_FUNC_START; - + +#if defined(__WINDOWS__) wan_spin_lock(&ec->lock); +#else + if (!wan_spin_trylock(&ec->lock)){ + return -EBUSY; + } +#endif + wan_clear_bit(WAN_EC_BIT_TIMER_RUNNING,(void*)&ec_dev->critical); - if (wan_test_bit(WAN_EC_BIT_CRIT_DOWN, &ec_dev->critical)){ + if (wan_test_bit(WAN_EC_BIT_CRIT_DOWN, &ec_dev->critical) || + wan_test_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->critical)){ ec_dev->poll_cmd = WAN_EC_POLL_NONE; wan_spin_unlock(&ec->lock); return -EINVAL; @@ -1660,33 +1867,49 @@ static int wanec_poll(void *arg, void *pcard) switch(ec_dev->poll_cmd){ case WAN_EC_POLL_CHIPOPENPENDING: /* Chip open */ + if (ec->state != WAN_EC_STATE_CHIP_OPEN_PENDING){ + DEBUG_EVENT( + "%s: Invalid EC state at ChipOpenPending poll command (%02X)\n", + ec->name, ec->state); + ec->state = WAN_EC_STATE_READY; + ec_dev->state = ec->state; + ec_dev->poll_cmd = WAN_EC_POLL_NONE; + err = -EINVAL; + goto wanec_poll_done; + } if (wanec_ChipOpen(ec_dev, WAN_EC_VERBOSE_NONE)){ + ec->f_OpenChip.pbyImageFile = NULL; + if (ec->pImageData) wan_vfree(ec->pImageData); + ec->pImageData = NULL; /* Chip state is Ready state */ - ec->state = WAN_OCT6100_STATE_READY; + ec->state = WAN_EC_STATE_READY; ec_dev->state = ec->state; ec_dev->poll_cmd = WAN_EC_POLL_NONE; err = -EINVAL; goto wanec_poll_done; } - ec->state = WAN_OCT6100_STATE_CHIP_OPEN; + ec->state = WAN_EC_STATE_CHIP_OPEN; ec_dev->state = ec->state; + + ec->f_OpenChip.pbyImageFile = NULL; + if (ec->pImageData) wan_vfree(ec->pImageData); + ec->pImageData = NULL; break; case WAN_EC_POLL_INTR: default: /* by default, can be only schedule from interrupt */ - if (ec->state != WAN_OCT6100_STATE_CHIP_READY){ + if (ec->state != WAN_EC_STATE_CHIP_READY){ break; } - if ((wan_test_bit(WAN_EC_BIT_CRIT_DOWN, &ec_dev->critical)) || - (wan_test_bit(WAN_EC_BIT_CRIT_ERROR, &ec_dev->critical)) || - (wan_test_bit(WAN_EC_BIT_CRIT_CMD, &ec->critical))) { + if (wan_test_bit(WAN_EC_BIT_CRIT_CMD, &ec->critical)) { err = -EINVAL; break; } /* Execute interrupt routine */ - if (wanec_ISR(ec, global_verbose)){ + err = wanec_ISR(ec, wanec_verbose); + if (err < 0){ wan_set_bit(WAN_EC_BIT_CRIT_ERROR, &ec->critical); wan_set_bit(WAN_EC_BIT_CRIT,(void*)&ec_dev->critical); err = -EINVAL; @@ -1713,19 +1936,25 @@ static int wanec_event_ctrl(void *arg, void *pcard, wan_event_ctrl_t *event_ctrl WAN_ASSERT(event_ctrl == NULL); ec = ec_dev->ec; + wan_spin_lock(&ec->lock); if (wan_test_and_set_bit(WAN_EC_BIT_CRIT_CMD, &ec->critical)){ + wan_spin_unlock(&ec->lock); return -EBUSY; } switch(event_ctrl->type){ case WAN_EVENT_EC_DTMF: - DEBUG_EVENT("%s: %s DTMF events\n", - ec_dev->devname, - WAN_EVENT_MODE_DECODE(event_ctrl->mode)); if (event_ctrl->mode == WAN_EVENT_ENABLE){ - wan_set_bit(WAN_EC_BIT_EVENT_DTMF, &ec_dev->events); + wanec_channel_dtmf(ec_dev, event_ctrl->channel, WAN_TRUE, NULL, WAN_EC_VERBOSE_EXTRA2/*wanec_verbose*/); }else{ - wan_clear_bit(WAN_EC_BIT_EVENT_DTMF, &ec_dev->events); + wanec_channel_dtmf(ec_dev, event_ctrl->channel, WAN_FALSE, NULL, wanec_verbose); + } + break; + case WAN_EVENT_EC_H100_REPORT: + if (event_ctrl->mode == WAN_EVENT_DISABLE){ + ec->ignore_H100 = 1; + }else{ + ec->ignore_H100 = 0; } break; default: @@ -1738,6 +1967,7 @@ static int wanec_event_ctrl(void *arg, void *pcard, wan_event_ctrl_t *event_ctrl #endif } wan_clear_bit(WAN_EC_BIT_CRIT_CMD, &ec->critical); + wan_spin_unlock(&ec->lock); return err; } @@ -1768,39 +1998,57 @@ int wanec_init(void *arg) wanec_iface.reg = wanec_register; wanec_iface.unreg = wanec_unregister; wanec_iface.ioctl = NULL; - wanec_iface.isr = NULL; // wanec_isr; + wanec_iface.isr = wanec_isr; wanec_iface.poll = wanec_poll; wanec_iface.event_ctrl = wanec_event_ctrl; +#if defined(CONFIG_WANPIPE_HWEC) register_wanec_iface (&wanec_iface); - -#if defined(__FreeBSD__) || defined(__OpenBSD__) +# if defined(__FreeBSD__) || defined(__OpenBSD__) wp_cdev_reg(NULL, WANEC_DEV_NAME, wanec_ioctl); -#elif defined(__LINUX__) || defined(__WINDOWS__) +# elif defined(__LINUX__) || defined(__WINDOWS__) wanec_create_dev(); +# endif #endif return 0; } int wanec_exit (void *arg) { -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(CONFIG_WANPIPE_HWEC) +# if defined(__FreeBSD__) || defined(__OpenBSD__) wp_cdev_unreg(WANEC_DEV_NAME); -#elif defined(__LINUX__) || defined(__WINDOWS__) +# elif defined(__LINUX__) || defined(__WINDOWS__) wanec_remove_dev(); -#endif +# endif unregister_wanec_iface(); +#endif DEBUG_EVENT("WANEC Layer: Unloaded\n"); return 0; } +#if 0 +int wanec_shutdown(void *arg) +{ + DEBUG_EVENT("Shutting down WANEC module ...\n"); + return 0; +} + +int wanec_ready_unload(void *arg) +{ + DEBUG_EVENT("Is WANEC module ready to unload...\n"); + return 0; +} +#endif + #if !defined(__WINDOWS__) WAN_MODULE_DEFINE( wanec,"wanec", "Alex Feldman ", "Wanpipe Echo Canceller Layer - Sangoma Tech. Copyright 2006", "GPL", - wanec_init, wanec_exit, NULL); + wanec_init, wanec_exit, /*wanec_shutdown, wanec_ready_unload,*/ + NULL); WAN_MODULE_DEPEND(wanec, wanrouter, 1, WANROUTER_MAJOR_VER, WANROUTER_MAJOR_VER); diff --git a/patches/kdrivers/wanec/wanec_iface.h b/patches/kdrivers/wanec/wanec_iface.h index 346938e..3d9672f 100644 --- a/patches/kdrivers/wanec/wanec_iface.h +++ b/patches/kdrivers/wanec/wanec_iface.h @@ -1,5 +1,5 @@ /****************************************************************************** - * wanec_lip.h + * wanec_iface.h * * Author: Alex Feldman * @@ -13,10 +13,11 @@ ****************************************************************************** */ -#ifndef __WANEC_LIP_H -# define __WANEC_LIP_H +#ifndef __WANEC_IFACE_H +# define __WANEC_IFACE_H #if defined(__LINUX__) +# include # include #elif defined(__WINDOWS__) @@ -27,6 +28,8 @@ # include #endif +#define MAX_EC_CHANS 256 + # include # include # include @@ -34,21 +37,12 @@ #elif defined(__FreeBSD__) || defined(__OpenBSD__) # include #endif + +#if defined(__WINDOWS__) +#include +#else #include "oct6100api/oct6100_api.h" - -#define WANEC_BYDEFAULT_NORMAL - -#define WANEC_DEV_DIR "/dev/" -#define WANEC_DEV_NAME "wanec" - -#define MAX_CHANNELS_LEN 50 - -#define MAX_PARAM_LEN 50 -#define MAX_VALUE_LEN 50 - -#define WAN_NUM_DTMF_TONES 16 -#define WAN_NUM_PLAYOUT_TONES 16 -#define WAN_MAX_TONE_LEN 100 +#endif #define WAN_EC_VERBOSE_NONE 0x00 #define WAN_EC_VERBOSE_EXTRA1 0x01 @@ -57,206 +51,121 @@ #define WAN_EC_VERBOSE_MASK_EXTRA2 0x03 #define WAN_EC_VERBOSE(ec_api) (ec_api)?ec_api->verbose:WAN_EC_VERBOSE_NONE -#if defined(__WINDOWS__) -#define PRINT1 Debug -#define PRINT2 Debug -#else -#define PRINT(v, format,msg...) \ - DEBUG_EVENT(format, ##msg) -#define PRINT1(v,format,msg...) \ - if (v & WAN_EC_VERBOSE_EXTRA1) DEBUG_EVENT(format,##msg) -#define PRINT2(v,format,msg...) \ - if (v & WAN_EC_VERBOSE_EXTRA2) DEBUG_EVENT(format,##msg) -#endif +#define WAN_EC_RC_OK 0x0000 +#define WAN_EC_RC_CPU_INTERFACE_NO_RESPONSE 0x0001 +#define WAN_EC_RC_MEMORY 0x0002 -#define WAN_OCT6100_RC_OK 0x0000 -#define WAN_OCT6100_RC_CPU_INTERFACE_NO_RESPONSE 0x0001 -#define WAN_OCT6100_RC_MEMORY 0x0002 -/* WANPIPE EC API return code */ -#define WAN_EC_API_RC_OK 0x0000 -#define WAN_EC_API_RC_FAILED 0x0001 -#define WAN_EC_API_RC_INVALID_CMD 0x0002 -#define WAN_EC_API_RC_INVALID_STATE 0x0003 -#define WAN_EC_API_RC_INVALID_DEV 0x0004 -#define WAN_EC_API_RC_INVALID_CHANNELS 0x0005 -#define WAN_EC_API_RC_BUSY 0x0006 -#define WAN_EC_API_RC_NOACTION 0x0007 -#define WAN_EC_API_RC_DECODE(err) \ - (err == WAN_EC_API_RC_OK) ? "OK" : \ - (err == WAN_EC_API_RC_FAILED) ? "Failed" : \ - (err == WAN_EC_API_RC_INVALID_CMD) ? "Invalid Cmd" : \ - (err == WAN_EC_API_RC_INVALID_STATE) ? "Invalid State" : \ - (err == WAN_EC_API_RC_INVALID_DEV) ? "Invalid Device" : \ - (err == WAN_EC_API_RC_INVALID_CHANNELS) ? "Invalid Channels" : \ - (err == WAN_EC_API_RC_BUSY) ? "Busy" : \ - (err == WAN_EC_API_RC_NOACTION) ? "No action" : \ - "Unknown RC" - -/* OCT6100 state machine */ +/* Internal EC chip state machine */ enum { - WAN_OCT6100_STATE_NONE = 0x00, - WAN_OCT6100_STATE_RESET, - WAN_OCT6100_STATE_READY, - WAN_OCT6100_STATE_CHIP_OPEN_PENDING, - WAN_OCT6100_STATE_CHIP_OPEN, - WAN_OCT6100_STATE_CHIP_READY + WAN_EC_STATE_NONE = 0x00, + WAN_EC_STATE_RESET, + WAN_EC_STATE_READY, + WAN_EC_STATE_CHIP_OPEN_PENDING, + WAN_EC_STATE_CHIP_OPEN, + WAN_EC_STATE_CHIP_READY }; -#define WAN_OCT6100_STATE_DECODE(state) \ - (state == WAN_OCT6100_STATE_RESET) ? "Reset" : \ - (state == WAN_OCT6100_STATE_READY) ? "Ready" : \ - (state == WAN_OCT6100_STATE_CHIP_OPEN_PENDING) ? "Chip Open Pending" : \ - (state == WAN_OCT6100_STATE_CHIP_OPEN) ? "Chip Open" : \ - (state == WAN_OCT6100_STATE_CHIP_READY) ? "Chip Ready" : \ +#define WAN_EC_STATE_DECODE(state) \ + (state == WAN_EC_STATE_RESET) ? "Reset" : \ + (state == WAN_EC_STATE_READY) ? "Ready" : \ + (state == WAN_EC_STATE_CHIP_OPEN_PENDING) ? "Chip Open Pending" : \ + (state == WAN_EC_STATE_CHIP_OPEN) ? "Chip Open" : \ + (state == WAN_EC_STATE_CHIP_READY) ? "Chip Ready" : \ "Unknown" -#define WAN_EC_SOUT_DTMF_1 0x40000011 -#define WAN_EC_SOUT_DTMF_2 0x40000012 -#define WAN_EC_SOUT_DTMF_3 0x40000013 -#define WAN_EC_SOUT_DTMF_A 0x4000001A -#define WAN_EC_SOUT_DTMF_4 0x40000014 -#define WAN_EC_SOUT_DTMF_5 0x40000015 -#define WAN_EC_SOUT_DTMF_6 0x40000016 -#define WAN_EC_SOUT_DTMF_B 0x4000001B -#define WAN_EC_SOUT_DTMF_7 0x40000017 -#define WAN_EC_SOUT_DTMF_8 0x40000018 -#define WAN_EC_SOUT_DTMF_9 0x40000019 -#define WAN_EC_SOUT_DTMF_C 0x4000001C -#define WAN_EC_SOUT_DTMF_STAR 0x4000001E -#define WAN_EC_SOUT_DTMF_0 0x40000010 -#define WAN_EC_SOUT_DTMF_POUND 0x4000001F -#define WAN_EC_SOUT_DTMF_D 0x4000001D -#define WAN_EC_ROUT_DTMF_1 0x10000011 -#define WAN_EC_ROUT_DTMF_2 0x10000012 -#define WAN_EC_ROUT_DTMF_3 0x10000013 -#define WAN_EC_ROUT_DTMF_A 0x1000001A -#define WAN_EC_ROUT_DTMF_4 0x10000014 -#define WAN_EC_ROUT_DTMF_5 0x10000015 -#define WAN_EC_ROUT_DTMF_6 0x10000016 -#define WAN_EC_ROUT_DTMF_B 0x1000001B -#define WAN_EC_ROUT_DTMF_7 0x10000017 -#define WAN_EC_ROUT_DTMF_8 0x10000018 -#define WAN_EC_ROUT_DTMF_9 0x10000019 -#define WAN_EC_ROUT_DTMF_C 0x1000001C -#define WAN_EC_ROUT_DTMF_STAR 0x1000001E -#define WAN_EC_ROUT_DTMF_0 0x10000010 -#define WAN_EC_ROUT_DTMF_POUND 0x1000001F -#define WAN_EC_ROUT_DTMF_D 0x1000001D -#define WAN_EC_DECODE_DTMF_ID(id) \ - (id == WAN_EC_SOUT_DTMF_0) ? "SOUT_0" : \ - (id == WAN_EC_SOUT_DTMF_1) ? "SOUT_1" : \ - (id == WAN_EC_SOUT_DTMF_2) ? "SOUT_2" : \ - (id == WAN_EC_SOUT_DTMF_3) ? "SOUT_3" : \ - (id == WAN_EC_SOUT_DTMF_4) ? "SOUT_4" : \ - (id == WAN_EC_SOUT_DTMF_5) ? "SOUT_5" : \ - (id == WAN_EC_SOUT_DTMF_6) ? "SOUT_6" : \ - (id == WAN_EC_SOUT_DTMF_7) ? "SOUT_7" : \ - (id == WAN_EC_SOUT_DTMF_8) ? "SOUT_8" : \ - (id == WAN_EC_SOUT_DTMF_9) ? "SOUT_9" : \ - (id == WAN_EC_SOUT_DTMF_A) ? "SOUT_A" : \ - (id == WAN_EC_SOUT_DTMF_B) ? "SOUT_B" : \ - (id == WAN_EC_SOUT_DTMF_C) ? "SOUT_C" : \ - (id == WAN_EC_SOUT_DTMF_D) ? "SOUT_D" : \ - (id == WAN_EC_SOUT_DTMF_STAR) ? "SOUT_STAR" : \ - (id == WAN_EC_SOUT_DTMF_POUND) ? "SOUT_POUND" :\ - (id == WAN_EC_ROUT_DTMF_0) ? "ROUT_0" : \ - (id == WAN_EC_ROUT_DTMF_1) ? "ROUT_1" : \ - (id == WAN_EC_ROUT_DTMF_2) ? "ROUT_2" : \ - (id == WAN_EC_ROUT_DTMF_3) ? "ROUT_3" : \ - (id == WAN_EC_ROUT_DTMF_4) ? "ROUT_4" : \ - (id == WAN_EC_ROUT_DTMF_5) ? "ROUT_5" : \ - (id == WAN_EC_ROUT_DTMF_6) ? "ROUT_6" : \ - (id == WAN_EC_ROUT_DTMF_7) ? "ROUT_7" : \ - (id == WAN_EC_ROUT_DTMF_8) ? "ROUT_8" : \ - (id == WAN_EC_ROUT_DTMF_9) ? "ROUT_9" : \ - (id == WAN_EC_ROUT_DTMF_A) ? "ROUT_A" : \ - (id == WAN_EC_ROUT_DTMF_B) ? "ROUT_B" : \ - (id == WAN_EC_ROUT_DTMF_C) ? "ROUT_C" : \ - (id == WAN_EC_ROUT_DTMF_D) ? "ROUT_D" : \ - (id == WAN_EC_ROUT_DTMF_STAR) ? "ROUT_STAR" : \ - (id == WAN_EC_ROUT_DTMF_POUND) ? "ROUT_POUND" :\ - "Unknown" +#define WAN_NUM_DTMF_TONES 16 +#define WAN_NUM_PLAYOUT_TONES 16 +#define WAN_MAX_TONE_LEN 100 +typedef struct wanec_config_ +{ + u_int16_t max_channels; + int memory_chip_size; + UINT32 debug_data_mode; + PUINT8 imageData; + UINT32 imageSize; + int imageLast; -#if defined(__WINDOWS__) -# define WAN_EC_CMD_NONE 0 -# define WAN_EC_CMD_GETINFO 1 -# define WAN_EC_CMD_CONFIG 2 -# define WAN_EC_CMD_CHANNEL_OPEN 3 -# define WAN_EC_CMD_RELEASE 4 -# define WAN_EC_CMD_ENABLE 5 -# define WAN_EC_CMD_DISABLE 6 -# define WAN_EC_CMD_BYPASS_ENABLE 7 -# define WAN_EC_CMD_BYPASS_DISABLE 8 -# define WAN_EC_CMD_MODE_NORMAL 9 -# define WAN_EC_CMD_MODE_POWERDOWN 10 -# define WAN_EC_CMD_MODIFY_CHANNEL 11 -# define WAN_EC_CMD_DTMF_ENABLE 12 -# define WAN_EC_CMD_DTMF_DISABLE 13 -# define WAN_EC_CMD_STATS 14 -# define WAN_EC_CMD_STATS_FULL 15 -# define WAN_EC_CMD_TONE_LOAD 16 -# define WAN_EC_CMD_TONE_UNLOAD 17 -# define WAN_EC_CMD_PLAYOUT_START 18 -# define WAN_EC_CMD_PLAYOUT_STOP 19 -# define WAN_EC_CMD_MONITOR 20 -# define WAN_EC_CMD_RELEASE_ALL 21 -#else -# define WAN_EC_CMD_NONE _IOWR('E', 0, struct wan_ec_api_) -# define WAN_EC_CMD_GETINFO _IOWR('E', 1, wan_ec_api_t) -# define WAN_EC_CMD_CONFIG _IOWR('E', 2, struct wan_ec_api_) -# define WAN_EC_CMD_CHANNEL_OPEN _IOWR('E', 3, struct wan_ec_api_) -# define WAN_EC_CMD_RELEASE _IOWR('E', 4, struct wan_ec_api_) -# define WAN_EC_CMD_ENABLE _IOWR('E', 5, struct wan_ec_api_) -# define WAN_EC_CMD_DISABLE _IOWR('E', 6, struct wan_ec_api_) -# define WAN_EC_CMD_BYPASS_ENABLE _IOWR('E', 7, struct wan_ec_api_) -# define WAN_EC_CMD_BYPASS_DISABLE _IOWR('E', 8, struct wan_ec_api_) -# define WAN_EC_CMD_MODE_NORMAL _IOWR('E', 9, struct wan_ec_api_) -# define WAN_EC_CMD_MODE_POWERDOWN _IOWR('E', 10, struct wan_ec_api_) -# define WAN_EC_CMD_MODIFY_CHANNEL _IOWR('E', 11, struct wan_ec_api_) -# define WAN_EC_CMD_DTMF_ENABLE _IOWR('E', 12, struct wan_ec_api_) -# define WAN_EC_CMD_DTMF_DISABLE _IOWR('E', 13, struct wan_ec_api_) -# define WAN_EC_CMD_STATS _IOWR('E', 14, struct wan_ec_api_) -# define WAN_EC_CMD_STATS_FULL _IOWR('E', 15, struct wan_ec_api_) -# define WAN_EC_CMD_TONE_LOAD _IOWR('E', 16, struct wan_ec_api_) -# define WAN_EC_CMD_TONE_UNLOAD _IOWR('E', 17, struct wan_ec_api_) -# define WAN_EC_CMD_PLAYOUT_START _IOWR('E', 18, struct wan_ec_api_) -# define WAN_EC_CMD_PLAYOUT_STOP _IOWR('E', 19, struct wan_ec_api_) -# define WAN_EC_CMD_MONITOR _IOWR('E', 20, struct wan_ec_api_) -# define WAN_EC_CMD_RELEASE_ALL _IOWR('E', 21, struct wan_ec_api_) -#endif + wan_custom_conf_t custom_conf; +} wanec_config_t; -# define WAN_EC_CMD_DECODE(cmd) \ - (cmd == WAN_EC_CMD_GETINFO) ? "Get Info" : \ - (cmd == WAN_EC_CMD_CONFIG) ? "Config" : \ - (cmd == WAN_EC_CMD_CHANNEL_OPEN) ? "Channel Open" : \ - (cmd == WAN_EC_CMD_ENABLE) ? "Enable" : \ - (cmd == WAN_EC_CMD_DISABLE) ? "Disable" : \ - (cmd == WAN_EC_CMD_BYPASS_ENABLE) ? "Enable bypass" : \ - (cmd == WAN_EC_CMD_BYPASS_DISABLE) ? "Disable bypass" : \ - (cmd == WAN_EC_CMD_MODE_NORMAL) ? "Mode Normal" : \ - (cmd == WAN_EC_CMD_MODE_POWERDOWN) ? "Mode PowerDown" : \ - (cmd == WAN_EC_CMD_STATS) ? "Get stats" : \ - (cmd == WAN_EC_CMD_STATS_FULL) ? "Get stats" : \ - (cmd == WAN_EC_CMD_TONE_LOAD) ? "Tone load" : \ - (cmd == WAN_EC_CMD_TONE_UNLOAD) ? "Tone unload" : \ - (cmd == WAN_EC_CMD_PLAYOUT_START) ? "Playout start" : \ - (cmd == WAN_EC_CMD_PLAYOUT_STOP) ? "Playout stop" : \ - (cmd == WAN_EC_CMD_RELEASE) ? "Release" : \ - (cmd == WAN_EC_CMD_RELEASE_ALL) ? "Release all" : \ - (cmd == WAN_EC_CMD_MONITOR) ? "MONITOR" : \ - (cmd == WAN_EC_CMD_MODIFY_CHANNEL) ? "MODIFY" : \ - (cmd == WAN_EC_CMD_DTMF_ENABLE) ? "Enable DTMF" : \ - (cmd == WAN_EC_CMD_DTMF_DISABLE) ? "Disable DTMF" : \ - "Unknown" +typedef struct wanec_config_poll_ +{ + int cnt; +} wanec_config_poll_t; + +typedef struct wanec_chip_stats_ +{ + int reset; + tOCT6100_CHIP_STATS f_ChipStats; + tOCT6100_CHIP_IMAGE_INFO *f_ChipImageInfo; +} wanec_chip_stats_t; + +typedef struct wanec_chan_opmode_ +{ + UINT32 opmode; +} wanec_chan_opmode_t; + +typedef struct wanec_chan_mute_ +{ + unsigned char port_map; + +} wanec_chan_mute_t; + +typedef struct wanec_chan_custom_ +{ + int custom; + wan_custom_conf_t custom_conf; +} wanec_chan_custom_t; + +typedef struct wanec_chan_stats_ +{ + int reset; + tOCT6100_CHANNEL_STATS f_ChannelStats; +} wanec_chan_stats_t; + +#define MAX_MONITOR_DATA_LEN 1024 +typedef struct wanec_chan_monitor_ +{ + int fe_chan; + UINT32 remain_len; + UINT32 data_len; + UINT32 max_len; + UINT8 data[MAX_MONITOR_DATA_LEN+1]; +} wanec_chan_monitor_t; + +typedef struct wanec_buffer_config_ +{ + UINT8 buffer[WAN_MAX_TONE_LEN]; + PUINT8 data; + UINT32 size; + UINT32 pcmlaw; + UINT32 buffer_index; /* value return by ec */ +} wanec_buffer_config_t; + +#define MAX_EC_PLAYOUT_LEN 20 +typedef struct wanec_playout_ +{ + UINT32 index; + UINT8 port; + UINT32 duration; + BOOL repeat; + UINT32 repeat_cnt; + UINT32 buffer_length; + INT32 gaindb; + BOOL notifyonstop; + UINT32 user_event_id; + + CHAR str[MAX_EC_PLAYOUT_LEN]; + UINT32 delay; +} wanec_playout_t; + +typedef struct wanec_dtmf_config_ +{ + u_int8_t port_map; /* SOUT/ROUT */ + u_int8_t type; /* PRESENT or STOP */ +} wanec_dtmf_config_t; -#if 0 -enum { - WAN_OCT6100_BYPASS = 0x01, - WAN_OCT6100_BYPASS_FULL, - WAN_OCT6100_BYPASS_LINE, -}; -#endif /*===========================================================================*\ User process context - This would probably have to be defined elsewhere. @@ -297,103 +206,22 @@ typedef struct _OCTPCIDRV_USER_PROCESS_CONTEXT_ } tOCTPCIDRV_USER_PROCESS_CONTEXT, *tPOCTPCIDRV_USER_PROCESS_CONTEXT; -typedef struct wanec_config_ { - int max_channels; - int memory_chip_size; - UINT32 debug_data_mode; - PUINT8 imageData; - UINT32 imageSize; - int imageLast; -} wanec_config_t; - -typedef struct wanec_param_ { - char key[MAX_PARAM_LEN]; - char value[MAX_VALUE_LEN]; - UINT32 value1; -} wanec_param_t; - -typedef struct wanec_chip_stats_ { - int reset; - tOCT6100_CHIP_STATS f_ChipStats; - tOCT6100_CHIP_IMAGE_INFO *f_ChipImageInfo; -} wanec_chip_stats_t; - -typedef struct wanec_chan_stats_ { - int reset; - tOCT6100_CHANNEL_STATS f_ChannelStats; -} wanec_chan_stats_t; - -#define MAX_MONITOR_DATA_LEN 1024 -typedef struct wanec_chan_monitor_ { - UINT32 remain_len; - UINT32 data_len; - UINT32 max_len; - UINT8 data[MAX_MONITOR_DATA_LEN+1]; -} wanec_chan_monitor_t; - -typedef struct wanec_tone_config_ { - UINT8 tone[WAN_MAX_TONE_LEN]; - PUINT8 data; - UINT32 size; - UINT32 buffer_index; /* value return by ec */ -} wanec_tone_config_t; - -typedef struct wanec_dtmf_config { - u_int8_t port; /* SOUT or ROUT */ - u_int8_t type; /* PRESENT or STOP */ -} wanec_dtmf_config_t; - -#define MAX_EC_PLAYOUT_LEN 20 -typedef struct wanec_playout_ { - UINT32 index; - UINT32 duration; - BOOL repeat; - UINT32 repeat_count; - UINT32 buffer_length; - INT32 gaindb; - - CHAR str[MAX_EC_PLAYOUT_LEN]; - UINT32 delay; -} wanec_playout_t; - -typedef struct wan_ec_api_ { - char devname[WAN_DRVNAME_SZ+1]; - unsigned long cmd; - unsigned int type; - int err; - int verbose; - int state; - - int channel; - unsigned long channel_map; - - union { -#define u_info u_ec.info -#define u_config u_ec.config -#define u_chip_stats u_ec.chip_stats -#define u_chan_stats u_ec.chan_stats -#define u_chan_monitor u_ec.chan_monitor -#define u_tone_config u_ec.tone_config -#define u_dtmf_config u_ec.dtmf_config -#define u_playout u_ec.playout - struct info_ { - unsigned int max_channels; - } info; - wanec_config_t config; - wanec_chip_stats_t chip_stats; - wanec_chan_stats_t chan_stats; - wanec_chan_monitor_t chan_monitor; - wanec_tone_config_t tone_config; - wanec_dtmf_config_t dtmf_config; - wanec_playout_t playout; - } u_ec; - int param_no; - wanec_param_t param[2]; -} wan_ec_api_t; - - #if defined(WAN_KERNEL) +#if defined(__WINDOWS__) +# define PRINT1 if(0)Debug +# define PRINT2 if(0)Debug +#else +# define PRINT1(v,format,msg...) \ + if (v & WAN_EC_VERBOSE_EXTRA1) DEBUG_EVENT(format,##msg) +# define PRINT2(v,format,msg...) \ + if (v & WAN_EC_VERBOSE_EXTRA2) DEBUG_EVENT(format,##msg) +#endif + +#define WANEC_IGNORE (TRUE+1) + +#define WANEC_BYDEFAULT_NORMAL + /* Critical bit map */ #define WAN_EC_BIT_TIMER_RUNNING 1 #define WAN_EC_BIT_TIMER_KILL 2 @@ -403,13 +231,26 @@ typedef struct wan_ec_api_ { #define WAN_EC_BIT_CRIT 6 #define WAN_EC_BIT_EVENT_DTMF 4 +#define WAN_EC_BIT_EVENT_PLAYOUT 5 #define WAN_EC_POLL_NONE 0x00 #define WAN_EC_POLL_INTR 0x01 #define WAN_EC_POLL_CHIPOPENPENDING 0x02 +#define WAN_EC_POLL_DTMF_MUTE_ON 0x03 +#define WAN_EC_POLL_DTMF_MUTE_OFF 0x04 + +typedef +struct wan_ec_confbridge_ +{ + UINT32 ulHndl; + + WAN_LIST_ENTRY(wan_ec_confbridge_) next; +} wan_ec_confbridge_t; + struct wan_ec_; -typedef struct wan_ec_dev_ { +typedef struct wan_ec_dev_ +{ char *name; char devname[WAN_DRVNAME_SZ+1]; char ecdev_name[WAN_DRVNAME_SZ+1]; @@ -418,37 +259,51 @@ typedef struct wan_ec_dev_ { u_int8_t fe_media; u_int32_t fe_lineno; - u_int32_t fe_max_channels; + int fe_start_chan, fe_stop_chan; + int fe_max_chans; + u_int32_t fe_channel_map; + u_int32_t fe_ec_map; u_int32_t fe_tdmv_law; u_int32_t channel; int state; u_int32_t critical; wan_timer_t timer; + u_int8_t poll_cmd; + int poll_channel; u_int32_t events; /* enable events map */ - + wan_ticks_t lastint_ticks; + struct wan_ec_ *ec; WAN_LIST_ENTRY(wan_ec_dev_) next; } wan_ec_dev_t; -typedef struct wan_ec_ { +typedef struct wan_ec_ +{ char name[WAN_DRVNAME_SZ+1]; int usage; int chip_no; int state; int ec_active; - int max_channels; /* max number of ec channels (security) */ + u_int16_t max_channels; /* max number of ec channels (security) */ + int confbridges_no; /* number of opened conf bridges */ void *ec_dev; u_int32_t intcount; u_int32_t critical; + int ignore_H100; /* Temporary for BRI card */ + wan_spinlock_t lock; u_int32_t events; /* enable events map */ - + int tone_verbose; /* verbose mode for tone events */ + int playout_verbose; /* verbose mode for playout events */ + PUINT8 pImageData; + UINT32 ImageSize; int imageLast; + wan_custom_conf_t custom_conf; tOCT6100_CHIP_OPEN f_OpenChip; tOCTPCIDRV_USER_PROCESS_CONTEXT f_Context; @@ -459,9 +314,13 @@ typedef struct wan_ec_ { UINT32 ulDebugChannelHndl; INT DebugChannel; UINT32 ulDebugDataMode; - +#if defined(__WINDOWS__) + struct wan_ec_dev_ *pEcDevMap[MAX_EC_CHANS]; +#else struct wan_ec_dev_ **pEcDevMap; - WAN_LIST_HEAD(wan_ec_dev_head_, wan_ec_dev_) ec_dev_head; +#endif + WAN_LIST_HEAD(wan_ec_dev_head_, wan_ec_dev_) ec_dev_head; + WAN_LIST_HEAD(wan_ec_confbridge_head_, wan_ec_confbridge_) ec_confbridge_head; WAN_LIST_ENTRY(wan_ec_) next; } wan_ec_t; @@ -493,4 +352,4 @@ u32 wan_ec_req_read_burst(void*, u32 addr, u16 *data, u32 len); #endif -#endif /* __WANEC_LIP_H */ +#endif /* __WANEC_IFACE_H */ diff --git a/patches/kdrivers/wanec/wanec_iface_api.h b/patches/kdrivers/wanec/wanec_iface_api.h new file mode 100644 index 0000000..c7d3b06 --- /dev/null +++ b/patches/kdrivers/wanec/wanec_iface_api.h @@ -0,0 +1,197 @@ +/****************************************************************************** + * wanec_iface_api.h + * + * Author: Alex Feldman + * + * 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. + * ============================================================================ + ****************************************************************************** + */ + +#ifndef __WANEC_IFACE_API_H +# define __WANEC_IFACE_API_H + +#if defined(__LINUX__) +# include +# include +# include +#elif defined(__WINDOWS__) + +#if defined(__KERNEL__) +# define _DEBUG +# include +#else +# include +#endif + +# include +# include +# include + +# include + +#elif defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +#endif +#include "oct6100api/oct6100_api.h" + +#define WANEC_BYDEFAULT_NORMAL + +#define WANEC_API_MAX_CONFIG_POLL 20 + +#define WANEC_DEV_DIR "/dev/" +#define WANEC_DEV_NAME "wanec" + +/* WANPIPE EC API return code */ +#define WAN_EC_API_RC_OK 0x0000 +#define WAN_EC_API_RC_FAILED 0x0001 +#define WAN_EC_API_RC_INVALID_CMD 0x0002 +#define WAN_EC_API_RC_INVALID_STATE 0x0003 +#define WAN_EC_API_RC_INVALID_DEV 0x0004 +#define WAN_EC_API_RC_INVALID_CHANNELS 0x0005 +#define WAN_EC_API_RC_BUSY 0x0006 +#define WAN_EC_API_RC_NOACTION 0x0007 +#define WAN_EC_API_RC_INVALID_PORT 0x0008 +#define WAN_EC_API_RC_DECODE(err) \ + (err == WAN_EC_API_RC_OK) ? "OK" : \ + (err == WAN_EC_API_RC_FAILED) ? "Failed" : \ + (err == WAN_EC_API_RC_INVALID_CMD) ? "Invalid Cmd" : \ + (err == WAN_EC_API_RC_INVALID_STATE) ? "Invalid State" : \ + (err == WAN_EC_API_RC_INVALID_DEV) ? "Invalid Device" : \ + (err == WAN_EC_API_RC_INVALID_CHANNELS) ? "Invalid Channels" : \ + (err == WAN_EC_API_RC_BUSY) ? "Busy" : \ + (err == WAN_EC_API_RC_NOACTION) ? "No action" : \ + (err == WAN_EC_API_RC_INVALID_PORT) ? "Invalid Port" : \ + "Unknown RC" + +#if defined(__WINDOWS__) +# define WAN_EC_API_CMD_NONE 0 +# define WAN_EC_API_CMD_GETINFO 1 +# define WAN_EC_API_CMD_CONFIG 2 +# define WAN_EC_API_CMD_CHANNEL_OPEN 3 +# define WAN_EC_API_CMD_RELEASE 4 +# define WAN_EC_API_CMD_ENABLE 5 +# define WAN_EC_API_CMD_DISABLE 6 +# define WAN_EC_API_CMD_BYPASS_ENABLE 7 +# define WAN_EC_API_CMD_BYPASS_DISABLE 8 +# define WAN_EC_API_CMD_OPMODE 9 +# define WAN_EC_API_CMD_MODIFY_CHANNEL 10 +# define WAN_EC_API_CMD_DTMF_ENABLE 11 +# define WAN_EC_API_CMD_DTMF_DISABLE 12 +# define WAN_EC_API_CMD_STATS 13 +# define WAN_EC_API_CMD_STATS_FULL 14 +# define WAN_EC_API_CMD_BUFFER_LOAD 15 +# define WAN_EC_API_CMD_BUFFER_UNLOAD 16 +# define WAN_EC_API_CMD_PLAYOUT_START 17 +# define WAN_EC_API_CMD_PLAYOUT_STOP 18 +# define WAN_EC_API_CMD_MONITOR 19 +# define WAN_EC_API_CMD_RELEASE_ALL 20 +# define WAN_EC_API_CMD_CONFIG_POLL 21 +# define WAN_EC_API_CMD_CHANNEL_MUTE 22 +# define WAN_EC_API_CMD_CHANNEL_UNMUTE 23 +#else +# define WAN_EC_API_CMD_NONE _IOWR('E', 0, struct wan_ec_api_) +# define WAN_EC_API_CMD_GETINFO _IOWR('E', 1, wan_ec_api_t) +# define WAN_EC_API_CMD_CONFIG _IOWR('E', 2, struct wan_ec_api_) +# define WAN_EC_API_CMD_CHANNEL_OPEN _IOWR('E', 3, struct wan_ec_api_) +# define WAN_EC_API_CMD_RELEASE _IOWR('E', 4, struct wan_ec_api_) +# define WAN_EC_API_CMD_ENABLE _IOWR('E', 5, struct wan_ec_api_) +# define WAN_EC_API_CMD_DISABLE _IOWR('E', 6, struct wan_ec_api_) +# define WAN_EC_API_CMD_BYPASS_ENABLE _IOWR('E', 7, struct wan_ec_api_) +# define WAN_EC_API_CMD_BYPASS_DISABLE _IOWR('E', 8, struct wan_ec_api_) +# define WAN_EC_API_CMD_OPMODE _IOWR('E', 9, struct wan_ec_api_) +# define WAN_EC_API_CMD_MODIFY_CHANNEL _IOWR('E', 15, struct wan_ec_api_) +# define WAN_EC_API_CMD_DTMF_ENABLE _IOWR('E', 16, struct wan_ec_api_) +# define WAN_EC_API_CMD_DTMF_DISABLE _IOWR('E', 17, struct wan_ec_api_) +# define WAN_EC_API_CMD_STATS _IOWR('E', 18, struct wan_ec_api_) +# define WAN_EC_API_CMD_STATS_FULL _IOWR('E', 19, struct wan_ec_api_) +# define WAN_EC_API_CMD_BUFFER_LOAD _IOWR('E', 20, struct wan_ec_api_) +# define WAN_EC_API_CMD_BUFFER_UNLOAD _IOWR('E', 21, struct wan_ec_api_) +# define WAN_EC_API_CMD_PLAYOUT_START _IOWR('E', 22, struct wan_ec_api_) +# define WAN_EC_API_CMD_PLAYOUT_STOP _IOWR('E', 23, struct wan_ec_api_) +# define WAN_EC_API_CMD_MONITOR _IOWR('E', 24, struct wan_ec_api_) +# define WAN_EC_API_CMD_RELEASE_ALL _IOWR('E', 25, struct wan_ec_api_) +# define WAN_EC_API_CMD_CONFIG_POLL _IOWR('E', 26, struct wan_ec_api_) +# define WAN_EC_API_CMD_CHANNEL_MUTE _IOWR('E', 27, struct wan_ec_api_) +# define WAN_EC_API_CMD_CHANNEL_UNMUTE _IOWR('E', 28, struct wan_ec_api_) +#endif + +# define WAN_EC_API_CMD_DECODE(cmd) \ + (cmd == WAN_EC_API_CMD_GETINFO) ? "Get Info" : \ + (cmd == WAN_EC_API_CMD_CONFIG) ? "Config" : \ + (cmd == WAN_EC_API_CMD_CONFIG_POLL) ? "Config Poll" : \ + (cmd == WAN_EC_API_CMD_CHANNEL_OPEN) ? "Channel Open" : \ + (cmd == WAN_EC_API_CMD_ENABLE) ? "Enable" : \ + (cmd == WAN_EC_API_CMD_DISABLE) ? "Disable" : \ + (cmd == WAN_EC_API_CMD_BYPASS_ENABLE) ? "Enable bypass" : \ + (cmd == WAN_EC_API_CMD_BYPASS_DISABLE) ? "Disable bypass" : \ + (cmd == WAN_EC_API_CMD_OPMODE) ? "Modify EC OPMODE" : \ + (cmd == WAN_EC_API_CMD_STATS) ? "Get stats" : \ + (cmd == WAN_EC_API_CMD_STATS_FULL) ? "Get stats" : \ + (cmd == WAN_EC_API_CMD_BUFFER_LOAD) ? "Buffer load" : \ + (cmd == WAN_EC_API_CMD_BUFFER_UNLOAD) ? "Buffer unload" : \ + (cmd == WAN_EC_API_CMD_PLAYOUT_START) ? "Playout start" : \ + (cmd == WAN_EC_API_CMD_PLAYOUT_STOP) ? "Playout stop" : \ + (cmd == WAN_EC_API_CMD_RELEASE) ? "Release" : \ + (cmd == WAN_EC_API_CMD_RELEASE_ALL) ? "Release all" : \ + (cmd == WAN_EC_API_CMD_MONITOR) ? "MONITOR" : \ + (cmd == WAN_EC_API_CMD_MODIFY_CHANNEL) ? "MODIFY" : \ + (cmd == WAN_EC_API_CMD_DTMF_ENABLE) ? "Enable DTMF" : \ + (cmd == WAN_EC_API_CMD_DTMF_DISABLE) ? "Disable DTMF" : \ + (cmd == WAN_EC_API_CMD_CHANNEL_MUTE) ? "Channel Mute" : \ + (cmd == WAN_EC_API_CMD_CHANNEL_UNMUTE) ? "Channel Un-mute" : \ + "Unknown" + +#define WAN_ + +typedef struct wan_ec_api_ { + char devname[WAN_DRVNAME_SZ+1]; + unsigned long cmd; + unsigned int type; + int err; + int verbose; + int state; + + int fe_chan; + unsigned long fe_chan_map; + + union { +#define u_info u_ec.info +#define u_config u_ec.config +#define u_config_poll u_ec.config_poll +#define u_chip_stats u_ec.chip_stats +#define u_chan_opmode u_ec.chan_opmode +#define u_chan_mute u_ec.chan_mute +#define u_chan_custom u_ec.chan_custom +#define u_chan_stats u_ec.chan_stats +#define u_chan_monitor u_ec.chan_monitor +#define u_buffer_config u_ec.buffer_config +#define u_playout u_ec.playout +#define u_dtmf_config u_ec.dtmf_config + struct info_ { + u_int16_t max_channels; + } info; + wanec_config_t config; + wanec_config_poll_t config_poll; + wanec_chip_stats_t chip_stats; + wanec_chan_opmode_t chan_opmode; + wanec_chan_mute_t chan_mute; + wanec_chan_custom_t chan_custom; + wanec_chan_stats_t chan_stats; + wanec_chan_monitor_t chan_monitor; + wanec_buffer_config_t buffer_config; + wanec_playout_t playout; + wanec_dtmf_config_t dtmf_config; + } u_ec; + + wan_custom_conf_t custom_conf; +} wan_ec_api_t; + + +#endif /* __WANEC_IFACE_API_H */ diff --git a/patches/kdrivers/wanec/wanec_utils.c b/patches/kdrivers/wanec/wanec_utils.c index ac91c4b..2f4d73f 100644 --- a/patches/kdrivers/wanec/wanec_utils.c +++ b/patches/kdrivers/wanec/wanec_utils.c @@ -29,6 +29,7 @@ #include "oct6100_version.h" #include "wanec_iface.h" +#include "wanec_iface_api.h" /****************************************************************************** ** DEFINES AND MACROS @@ -50,6 +51,12 @@ typedef struct key_word /* Keyword table entry */ u_int16_t dtype; /* data type */ } key_word_t; +typedef struct value_word /* Keyword table entry */ +{ + u_int8_t *sValue; /* -> keyword */ + u_int32_t dValue; /* offset of the related parameter */ +} value_word_t; + /****************************************************************************** ** GLOBAL VARIABLES ******************************************************************************/ @@ -58,7 +65,19 @@ extern int verbose; key_word_t chip_param[] = { - { "fEnableAcousticEcho", + { "WANEC_TailDisplacement", + offsetof(tOCT6100_CHIP_OPEN, ulTailDisplacement), + DTYPE_UINT32 }, + { "WANEC_MaxPlayoutBuffers", + offsetof(tOCT6100_CHIP_OPEN, ulMaxPlayoutBuffers), + DTYPE_UINT32 }, + { "WANEC_MaxConfBridges", + offsetof(tOCT6100_CHIP_OPEN, ulMaxConfBridges), + DTYPE_UINT32 }, + { "WANEC_EnableExtToneDetection", + offsetof(tOCT6100_CHIP_OPEN, fEnableExtToneDetection), + DTYPE_BOOL }, + { "WANEC_EnableAcousticEcho", offsetof(tOCT6100_CHIP_OPEN, fEnableAcousticEcho), DTYPE_BOOL }, { NULL, 0, 0 } @@ -66,137 +85,178 @@ key_word_t chip_param[] = key_word_t ChannelModifyParam[] = { - { "ulEchoOperationMode", + { "WANEC_EchoOperationMode", offsetof(tOCT6100_CHANNEL_MODIFY, ulEchoOperationMode), DTYPE_UINT32 }, - { "fEnableToneDisabler", + { "WANEC_EnableToneDisabler", offsetof(tOCT6100_CHANNEL_MODIFY, fEnableToneDisabler), DTYPE_BOOL }, - { "fApplyToAllChannels", + { "WANEC_ApplyToAllChannels", offsetof(tOCT6100_CHANNEL_MODIFY, fApplyToAllChannels), DTYPE_BOOL }, - { "fEnableNlp", + { "WANEC_DisableToneDetection", + offsetof(tOCT6100_CHANNEL_MODIFY, fDisableToneDetection), + DTYPE_BOOL }, + /**************** tOCT6100_CHANNEL_MODIFY_TDM **********************/ + /**************** tOCT6100_CHANNEL_MODIFY_VQE **********************/ + { "WANEC_EnableNlp", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fEnableNlp), DTYPE_BOOL }, - { "fEnableTailDisplacement", + { "WANEC_EnableTailDisplacement", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fEnableTailDisplacement), DTYPE_BOOL }, - { "ulTailDisplacement", + { "WANEC_TailDisplacement", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,ulTailDisplacement), DTYPE_UINT32 }, - { "fRinLevelControl", + { "WANEC_RinLevelControl", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fRinLevelControl), DTYPE_BOOL }, - { "lRinLevelControlGainDb", + { "WANEC_RinLevelControlGainDb", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,lRinLevelControlGainDb), DTYPE_INT32 }, - { "fSoutLevelControl", + { "WANEC_SoutLevelControl", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fSoutLevelControl), DTYPE_BOOL }, - { "lSoutLevelControlGainDb", + { "WANEC_SoutLevelControlGainDb", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,lSoutLevelControlGainDb), DTYPE_INT32 }, - { "fRinAutomaticLevelControl", + { "WANEC_RinAutomaticLevelControl", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fRinAutomaticLevelControl), DTYPE_BOOL }, - { "lRinAutomaticLevelControlTargetDb", + { "WANEC_RinAutomaticLevelControlTargetDb", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,lRinAutomaticLevelControlTargetDb), DTYPE_INT32 }, - { "fSoutAutomaticLevelControl", + { "WANEC_SoutAutomaticLevelControl", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fSoutAutomaticLevelControl), DTYPE_BOOL }, - { "lSoutAutomaticLevelControlTargetDb", + { "WANEC_SoutAutomaticLevelControlTargetDb", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,lSoutAutomaticLevelControlTargetDb), DTYPE_INT32 }, #if 0 - { "ulAlcNoiseBleedOutTime", + { "WANEC_AlcNoiseBleedOutTime", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,ulAlcNoiseBleedOutTime), DTYPE_UINT32 }, #endif - { "fRinHighLevelCompensation", + { "WANEC_RinHighLevelCompensation", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fRinHighLevelCompensation), DTYPE_BOOL }, - { "lRinHighLevelCompensationThresholdDb", + { "WANEC_RinHighLevelCompensationThresholdDb", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,lRinHighLevelCompensationThresholdDb), DTYPE_INT32 }, - { "fSoutAdaptiveNoiseReduction", + { "WANEC_SoutAdaptiveNoiseReduction", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fSoutAdaptiveNoiseReduction), DTYPE_BOOL }, - { "fRoutNoiseReduction", + { "WANEC_RoutNoiseReduction", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fRoutNoiseReduction), DTYPE_BOOL }, - { "ulComfortNoiseMode", + { "WANEC_ComfortNoiseMode", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,ulComfortNoiseMode), DTYPE_UINT32 }, - { "fAcousticEcho", + { "WANEC_DtmfToneRemoval", + offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fDtmfToneRemoval), + DTYPE_BOOL }, + { "WANEC_AcousticEcho", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fAcousticEcho), DTYPE_BOOL }, - { "fSoutNoiseBleaching", + { "WANEC_SoutNoiseBleaching", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,fSoutNoiseBleaching), DTYPE_BOOL }, - { "ulNonLinearityBehaviorA", + { "WANEC_NonLinearityBehaviorA", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,ulNonLinearityBehaviorA), DTYPE_UINT32 }, - { "ulNonLinearityBehaviorB", + { "WANEC_NonLinearityBehaviorB", offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,ulNonLinearityBehaviorB), DTYPE_UINT32 }, + { "WANEC_DoubleTalkBehavior", + offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,ulDoubleTalkBehavior), + DTYPE_UINT32 }, + { "WANEC_AnrSnrEnhancementDb", + offsetof(tOCT6100_CHANNEL_MODIFY, VqeConfig)+offsetof(tOCT6100_CHANNEL_MODIFY_VQE,lAnrSnrEnhancementDb), + DTYPE_INT32 }, + { NULL, 0, 0 } }; +value_word_t ValueParamList[] = +{ + { "OPMODE_NORMAL", cOCT6100_ECHO_OP_MODE_NORMAL }, + { "OPMODE_HT_FREEZE", cOCT6100_ECHO_OP_MODE_HT_FREEZE }, + { "OPMODE_HT_RESET", cOCT6100_ECHO_OP_MODE_HT_RESET }, + { "OPMODE_POWER_DOWN", cOCT6100_ECHO_OP_MODE_POWER_DOWN }, + { "OPMODE_EXTERNAL", cOCT6100_ECHO_OP_MODE_EXTERNAL }, + { "OPMODE_NO_ECHO", cOCT6100_ECHO_OP_MODE_NO_ECHO }, + { "OPMODE_SPEECH_RECOGNITION", cOCT6100_ECHO_OP_MODE_SPEECH_RECOGNITION }, + { "OPMODE_G169_ALC", cOCT6100_ECHO_OP_MODE_G169_ALC }, + { "COMFORT_NOISE_NORMAL", cOCT6100_COMFORT_NOISE_NORMAL }, + { "COMFORT_NOISE_FAST_LATCH", cOCT6100_COMFORT_NOISE_FAST_LATCH }, + { "COMFORT_NOISE_EXTENDED", cOCT6100_COMFORT_NOISE_EXTENDED }, + { "COMFORT_NOISE_OFF", cOCT6100_COMFORT_NOISE_OFF }, + { "DT_BEH_NORMAL", cOCT6100_DOUBLE_TALK_BEH_NORMAL }, + { "DT_BEH_LESS_AGGRESSIVE", cOCT6100_DOUBLE_TALK_BEH_LESS_AGGRESSIVE }, + + { NULL, 0, } +}; + /****************************************************************************** ** FUNCTION PROTOTYPES ******************************************************************************/ -int wanec_ChipParam(wan_ec_t*,tPOCT6100_CHIP_OPEN, wan_ec_api_t*); -int wanec_ChanParam(wan_ec_t*,tPOCT6100_CHANNEL_MODIFY, wan_ec_api_t*); +int wanec_ChipParam(wan_ec_t*,tPOCT6100_CHIP_OPEN, wan_custom_conf_t*, int); +int wanec_ChanParam(wan_ec_t*,tPOCT6100_CHANNEL_MODIFY, wan_custom_conf_t*, int); int wanec_ChanParamList(wan_ec_t *ec); /****************************************************************************** ** FUNCTION DEFINITIONS ******************************************************************************/ static int -set_conf_param ( wan_ec_t *ec, - wanec_param_t *param, - key_word_t *dtab, - void *conf) +set_conf_param ( wan_ec_t *ec, + wan_custom_param_t *param, + key_word_t *dtab, + void *conf, + int verbose) { /* Search a keyword in configuration definition table */ - for (; dtab->key && strcmp(dtab->key, param->key); ++dtab); - + for (; dtab->key && strncasecmp(dtab->key, param->name, strlen(param->name)); ++dtab); if (dtab->key == NULL){ - DEBUG_EVENT("%s: param=%s\n", ec->name, param->key); + DEBUG_EVENT("%s: Failed to find EC parameter (name=%s)\n", + ec->name, param->name); return -EINVAL; /* keyword not found */ } - DEBUG_EVENT(" * Setting %s to %s\n", param->key, param->value); + /* Search a keyword in configuration definition table */ + if (dtab->dtype != DTYPE_BOOL && strlen(param->sValue)){ + value_word_t *ValueParam = ValueParamList; + for (; ValueParam->sValue && strncasecmp(ValueParam->sValue, param->sValue, strlen(param->sValue)); ++ValueParam); + if (ValueParam->sValue == NULL){ + DEBUG_EVENT("%s: Failed to find EC parameter value (sValue=%s)\n", + ec->name, param->sValue); + return -EINVAL; /* keyword not found */ + } + param->dValue = ValueParam->dValue; + } switch (dtab->dtype) { case DTYPE_BOOL: - if (memcmp(param->value, "TRUE", 4) == 0){ - DEBUG_EVENT( - "%s: *** Modify %s to %s\n", - ec->name, param->key, param->value); + if (memcmp(param->sValue, "TRUE", 4) == 0){ *(BOOL*)((char*)conf + dtab->offset) = TRUE; - }else if (memcmp(param->value, "FALSE", 5) == 0){ - DEBUG_EVENT( - "%s: *** Modify %s to %s\n", - ec->name, param->key, param->value); + }else if (memcmp(param->sValue, "FALSE", 5) == 0){ *(BOOL*)((char*)conf + dtab->offset) = FALSE; }else{ - DEBUG_EVENT( - "%s: Invalid parameter type (%d)\n", + PRINT1(verbose, "%s: Invalid parameter type (%d)\n", ec->name, dtab->dtype); return -EINVAL; } + PRINT1(verbose, "%s: * Setting %s to %s\n", + ec->name, param->name, param->sValue); break; case DTYPE_UINT32: - DEBUG_EVENT("%s: *** Modify %s to %d\n", - ec->name, param->key, param->value1); - *(UINT32*)((char*)conf + dtab->offset) = param->value1; + PRINT1(verbose, "%s: * Setting %s to %d\n", + ec->name, param->name, param->dValue); + *(UINT32*)((char*)conf + dtab->offset) = param->dValue; break; case DTYPE_INT32: - DEBUG_EVENT("%s: *** Modify %s to %d\n", - ec->name, param->key, param->value1); - *(INT32*)((char*)conf + dtab->offset) = param->value1; + PRINT1(verbose, "%s: * Setting %s to %d\n", + ec->name, param->name, param->dValue); + *(INT32*)((char*)conf + dtab->offset) = param->dValue; break; default: return -EINVAL; @@ -205,18 +265,20 @@ set_conf_param ( wan_ec_t *ec, } int wanec_ChipParam( wan_ec_t *ec, - tPOCT6100_CHIP_OPEN f_pOpenChip, - wan_ec_api_t *ec_api) + tPOCT6100_CHIP_OPEN f_pOpenChip, + wan_custom_conf_t *custom_conf, + int verbose) { - int iParam=0; + unsigned int iParam=0; - DEBUG_EVENT( - "%s: Parsing advanced Chip params\n", ec->name); - while(iParam < ec_api->param_no){ + PRINT1(verbose, "%s: Parsing advanced Chip params\n", + ec->name); + while(iParam < custom_conf->param_no){ set_conf_param( ec, - &ec_api->param[iParam], + &custom_conf->params[iParam], chip_param, - f_pOpenChip); + f_pOpenChip, + verbose); iParam++; } return 0; @@ -224,18 +286,21 @@ int wanec_ChipParam( wan_ec_t *ec, int wanec_ChanParam( wan_ec_t *ec, - tPOCT6100_CHANNEL_MODIFY f_pChannelModify, - wan_ec_api_t *ec_api) + tPOCT6100_CHANNEL_MODIFY f_pChannelModify, + wan_custom_conf_t *custom_conf, + int verbose) { - int iParam=0, err; + unsigned int iParam=0; + int err; - DEBUG_EVENT( - "%s: Parsing advanced Channel params\n", ec->name); - while(iParam < ec_api->param_no){ + PRINT1(verbose, "%s: Parsing advanced Channel params\n", + ec->name); + while(iParam < custom_conf->param_no){ err = set_conf_param( ec, - &ec_api->param[iParam], + &custom_conf->params[iParam], ChannelModifyParam, - f_pChannelModify); + f_pChannelModify, + verbose); if (err < 0) return -EINVAL; if (err < offsetof(tOCT6100_CHANNEL_MODIFY, TdmConfig)){ /* no extra action */ diff --git a/rpmspec/wanpipe-mod.spec b/rpmspec/wanpipe-mod.spec index 2e677cb..56a6516 100644 --- a/rpmspec/wanpipe-mod.spec +++ b/rpmspec/wanpipe-mod.spec @@ -1,6 +1,6 @@ %define WANPIPE_VER wanpipe-modules %define name %{WANPIPE_VER} -%define version 3.2.7.1 +%define version 3.3.2 %define release 0 %define serial 1 %define MODULES_DIR /lib/modules @@ -50,150 +50,140 @@ echo "Wanpipe Modules located in %{MODULES_DIR}/%{KVERSION}" %changelog -* Thu Jul 16 2008 Nenad Corbic - Stable - 3.2.7 -======================================================================== -- Removed the Excessive Error check that disables the port. - This feature was introduced in 3.2.6 release. - Some lines are extremely noisy on startup which can cause - excessive crc errors (5000 per sec). In this case driver would - take the port down for few sec before bringing it back up in order to - avoid irq overlaod. This release will only print the - warning but will not take any up/down actions. +* Wed Feb 12 2008 Nenad Corbic - Beta - 3.3.2 +====================================================================== -- Added support for new PLX2 or TUNDRA PCIe chip. +- Support for A500 hardware support with NetBricks BRI Stack +- Major A500 driver updates and fixes +- Serial A142/A144 hardware support +- AFT A056 56K hardware support +- Support for HW DTMF -* Thu Jun 4 2008 Nenad Corbic - Stable - 3.2.6 -======================================================================== +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. -- Updated hwprobe to add A056 card + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands -- Updated for 2.6.25 kernel +- Updated loopback commands for AFT Maxim cards -- wanpipemon PRI/BRI wireshark tracing - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - -- LIP Layer Update - Optimized packet handling in bh - -- Fixed WAN Protocol for 2.6.24 kernels and higher - -- AFT TE1 Code - Defaulted Maxim T1 Rx Level to 36DB - Defaulted Maxim E1 Rx Level to 42DB - This will improve T1/E1 connectivity on noisy or low power lines. - -- Wanpipemon PRI/BRI PCAP Tracing for Wireshark - Using wanpipemon dchan trace one can now capture - pcap files that can be opened by Wireshark. - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - - -- Add pci parity check to wanrouter - wanrouter parity -> displays current system pci parity - wanrouter parity off -> disables system pci parity - wanrouter parity on -> enables system pci parity +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols - /etc/wanpipe/wanrouter.rc - WAN_PCI_PARITY=OFF -> on wanrouter start disable pci parity - -> event logged in /var/log/wanrouter +- Updated legacy protocols for new front end architecture - On some servers pci parity can cause NMI interrupts that - can lead to reboots. Parity can be caused by unsuported - or buggy pci/bridge chipsets. The above commands can be used - to combat pci parity reboots. - - Another option is to disable PCI parity in BIOS :) +- +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p8 +====================================================================== -* Thu Apr 4 2008 Nenad Corbic - Stable - 3.2.5.1 -======================================================================== +- wancfg_zaptel now asks for the default_tei value for +- BRI cards in TE mode -- RTP TAP Bug fix - The driver was sending out invalid rtp tap header - http://wiki.sangoma.com/wanpipe-voice-rtp-tap +- Fix for HWEC not being enabled when non-consecutive modules are using +- in BRI cards + +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p4 +====================================================================== + +- Fixed AFT memory leak + Memory leak introduced in 3.3 release +- Fixed AFT 56K bug + Bug introduced in 3.3 releae -* Thu Apr 2 2008 Nenad Corbic - Stable - 3.2.5 -======================================================================== +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p3 +====================================================================== -- T3/E3 Update - Fixed T3 Loopback commands +- Fix bug in BRI protocol for fast local hangups. -- Updated T3/E3 Driver - Performance improvement on T3/E3 drivers when handling - VOIP and Data traffic. +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.2.p1 +====================================================================== -- Update ifconfig MTU change from protocol interface - - -* Thu Mar 6 2008 Nenad Corbic - Stable - 3.2.4 -======================================================================== - -- Updated for 2.6.24 kernels - TDM Voice (Zaptel) tested with 2.6.24 kernel. - Known issues: WAN protocols are broken for 2.6.24 kernels. - Its a compilation issue that will be fixed ASAP. - -- TDM API bug fix - Check for max frame size on audio stream - -- Updated for Zaptel 1.4.9 - -- AFT IRQ Throttling feature - This feature is use to protect the server from - terrible lines. In some cases a bad hdlc line can - cause thousands of interrupts per sec. Rx errors are now - throttled so that system does not get compromized. - -- AFT RTP TAP Feature - RTP TAP Feature allows user to tap voice channels during - Asterisk-Zaptel/TMD API operation at the driver/kernel level. - Each voice stream is encapsulated in UDP/RTP header and transmitted over - neghbouring ethernet address directly from kenrel space. - Tapping 4E1s worth of voice channels adds estra 2% system load :) - http://wiki.sangoma.com/wanpipe-voice-rtp-tap - -- AFT Software Ring Buffers on A200/A400 Analog Cards - This feature improves analog preformance under Asterisk/TDM API - mode. In particualr it improves faxing reliability and - minimizes frame slippage due to system load or bad incoming - clock from the line. - Note: All AFT T1/E1 cards have this feature in hardare :) +- Bug fix in Hardware EC code for E1. + Bug introduced in 3.3 release. -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.3 -======================================================================== +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.1 +==================================================================== -- No changes from 3.2.2 - Version updated for versioning sake. -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 -======================================================================== +* Mon Jan 16 2008 Nenad Corbic - Beta - 3.3.0.22 +==================================================================== -- AFT Maxim Front end update - Implemented graceful recovery on short circuit. +- BRI protocol:Increased internal timer that could cause issue in systems with +- more than 8 BRI spans -- AFT Driver update - Added a check for TDM IRQ timeout. - On some machines its possible for TDM IRQ to timeout. +* Mon Jan 15 2008 Nenad Corbic - Beta - 3.3.0.21 +==================================================================== -- SMG updated - Fixed wancfg_smg - MTU not properly set on ports 2 and up - Voice only ports were not being added to startup sequence - Updated for callweaver +- BRI protocol:Fix for smg_brid daemon crashing on race condition +- BRI protocol:default_tei parameter is not ignored when using point to +- multipoint anymore -- Added Zaptel 1.4 HW HDLC Support - No Sangoma zaptel patch needed with Zaptel 1.4 +* Mon Jan 14 2008 Nenad Corbic - Beta - 3.3.0.20 +==================================================================== -- Added HWEC Noise flag in wanpipe config file +- BRI protocol: Additional prefix options. +- BRI protocol: Check is caller ID number is all digits on incoming calls +- Sangoma MGD: Removed dynamic user period causing skb panics +- chan_woomera: Fixed issue with rxgain and txgain values set to 0 if +- coding not set in woomera.conf +- wancfg_zaptel: Support for fractional T1/E1 spans. +- wancfg_zaptel: fix issue BRI always being configured as bri_net introduced in v3.3.0.19 -- Updated SMG -- Updated E1 Unframed on Maxim Cards +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.19 +==================================================================== +- Support for national/international prefix in BRI stack + +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.18 +==================================================================== + +- Changed Makefile in wanpipe/api/fr causing compilation errors + + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.17 +==================================================================== + +- Fix for smg_ctrl boot script starting before network services on some systems +- Support for language parameter in chan_woomera + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.16 +==================================================================== + +- Fix for Sangoma BRI Daemon crashing on incoming call if chan_woomera is not installed on that system + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.15 +==================================================================== + +- Fix for caller ID value being corrupted sometimes +- Support for call confirmation in chan_woomera + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.14 +==================================================================== + +- Fix in smg_brid not releasing some b-channels properly +- Fix in wancfg_smg not setting MTU to 80 when configuring cards for SS7 + +* Fri Dec 14 2007 Nenad Corbic - Beta - 3.3.0.13 +==================================================================== + +- Fix for Kernel panic on 64-bit systems when enabling hardware echo canceller + + +* Thu Dec 5 2007 Nenad Corbic - Beta - 3.3.0.11 +==================================================================== + +- Support for AFT Serial Cards - Updates for AFT PMC and MAXIM framers PMC - lowered LOS sensitivity Fixes fake up/down state changes on @@ -226,216 +216,37 @@ echo "Wanpipe Modules located in %{MODULES_DIR}/%{KVERSION}" - Updated Setup script -* Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 -===================================================================== -- Setup Zap Chunk Size Patch updated for Zaptel 1.4 - Patch allows running zaptel in 8,16,40,80 chunk size. - However wct drivers must be removed from compilation :) - Patch is now fixed for Zaptel 1.4 - -- Update to All AFT drivers for 64bit 2.6.22 kernel. - Updated affects: AFT A101/2/4/8/200/400 (all cards) - The major 2.6.20+ updates extend to 64bit as well. - Previous drivers segfaulted under 2.6.22 64bit - kernels. This does not affect you if you are running - kennels lower than 2.6.22. - -- Updated legacy drivers for 2.6.22 kernel - - - -* Wed Oct 3 2007 Nenad Corbic - Stable - 3.2.0 -===================================================================== - -- The Beta 3.1.X releases has now been declared as STABLE 3.2.X - -- Fixed AMI/D4 on MAXIM (A101/2/4/8D) cards -- Fixed A200/A400 tip/ring no dial tone issues. -- Fixed 2.6.22 support and above -- Fixed RPM Build post install issue -- Updated Setup install script - Option to build for zaptel: ./Setup zaptel -- Working E&M/RBS/CAS Channel Bank support for MAXIM (A101/2/4/8) cards. -- Fixed wanpipe crashing on system shutdown on some machines. - Caused by RedHat /var/lock/subsys mandatory lock file. -- New Firmware for all MAXIM Cards (A101/2/4/8D) - Firmware V33: Fixes EC Chip Security errors that can cause - PRI to go down on some computers. Firmware is backward compatible - to any previous release. -- Faxes/Modems working through hardware echo canceler. - Tested at 56K from one port to another. - New octasic update. -- Analog Network SYNC Feature for Fax Support - Analog cards can be synced to T1/E1 clock - from adjacent A101/2/4/8 cards for flawless faxing - from FXO/FXS to T1/E1. - -- Known Issues: - T1/E1 High Impedance Tap for MAXIM (A101/2/4/8D) cards. - It works on original PMC A101/2/4 cards - -For more info: http://wiki.sangoma.com - - -* Mon Oct 1 2007 Nenad Corbic - Beta - 3.1.4.6 -==================================================================== - -- Fixed Makefile for 2.6.22.9 kernel. -- Fixed all gcc4 warnings. - - -* Tue Sep 26 2007 Nenad Corbic - Beta - 3.1.4.5 -==================================================================== - -- Updated Setup install script -- A200/A400 Analog driver update - Fixed noise issue introduced in 3.1.4.3 release -- Updated SMG for Asterisk 1.4 & Callweaver - - -* Tue Sep 18 2007 Nenad Corbic - Beta - 3.1.4.3 -==================================================================== - -- A200/A400 Analog driver update - Fixed a problem where analog port starts up without - dialtone. - -* Tue Sep 14 2007 Nenad Corbic - Beta - 3.1.4.2 -==================================================================== - -- Update for 2.6.22 kernel. -- wanrouter startup script update for redhat distros. - Fixes the issue on system shutdown, where wanpipe - module sometimes do not unload due to /var/lock/subsys/ - lockfile check. This issue is only related or RedHat style distros. - - -* Tue Aug 15 2007 Nenad Corbic - Beta - 3.1.4 -==================================================================== - -- Added A101-SH old config support. - So onld A101u or A101c config file can be used with new A101-SH cards. - -- Updated KATM support in the LIP Layer. - Used to connect Kernel ATM Layer to Wanpipe ATM AAL5 layer - over all AFT cards. - -- Added a sanity checker for enabling HWEC. - Used to prevent duble hwec enable. - -- Added wancfg_tdmapi configurator - -- Updated SMG - - -* Mon Jun 30 2007 Nenad Corbic - Beta - 3.1.3 -==================================================================== - -- Update to Ocatsic Hardware Echo Canceler Library - Turned of the NOISE suppression because it can interfere - with faxes. If you faxes did not work properly on 3.1.2 - release they will work fine with this one. - -- Cleaned up the Setup installation script. - - -* Mon Jun 16 2007 Nenad Corbic - Beta - 3.1.2 -==================================================================== - -- Update to Octasic Hardware Echo Canceler library - This is a very important update that affects all AFT cards - with octasic hardware echo canceler. The new octasic update - fixes faxing/modem issues over octasic hwec. The previous - release contained a bug that limited the faxing/modem speeds - to 26k. The new update properly detects fax/modem and works - with full speed of 33k fax and 56k modem. - -- A200/A400 Updated - This update fixes the offhook startup failure. - On startup if fxs is offhook driver will start correctly - -- Wanpipe Startup order changed - The wanpipe startup scripts on bootup were previously - set too early "S03wanrouter". This caused unpredictable - behaviour on some systems. We have now moved wanrouter - startup on boot up to "S11wanrouter", after networking - code. - -- Zaptel Adjustable Chunk Size Feature - Wanpipe drivers can work with 1,2,5 and 10ms - chunk size. Zaptel also supports this, however - the wct4xx driver breaks compilation when chunk - size is changed. ./Setup can how change the - zaptel chunk size for you and update zaptel - Makefiles to remove wct4xx driver out. - - Zaptel with 1ms generates 1000 interrupts per sec - Zaptel with 10ms generates 100 interrupts per sec. - - As you can see its a drastic interrupt performance - increase. - - NOTE: This breaks software echo cancelation, but - its not needed since we have hwec. - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.1 -==================================================================== - -- A101/2/4/8 (MAXIM) AFT Update IMPORTANT - A major bug fix for AFT Maxim E1 cards for E1 CRC4 Mode. - On some lines the E1/CRC4 mode causes line errors on - the telco side which results in PRI not coming up. - - Symptiom: E1 is up (no alarms) on local side but pri is - not coming up! (Only in E1 CRC4 Mode) - -- A101/2/4/8 (MAXIM) Mandatory Firmware Update - An echo canceler bug has been fixed for all AFT - MAXIM Cards A101/2/4/8dm. New firmware version is V31. - If you are running MAXIM cards with hwec wiht older - firmware version you must upgrade. - -- Updated SMG - Fixed DTMF synchronization - - - -- Updated SMG - Fixed DTMF synchronization - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.0.1 -==================================================================== - -- Minor release -- Contains zaptel patch for zaptel 1.2.17 and above. -- No driver changes - -* Fri May 17 2007 Nenad Corbic - Beta - 3.1.0 +* Thu Nov 8 2007 Nenad Corbic - Beta - 3.3.0.4 ==================================================================== -- Major new BETA wanpipe release - Changed wanpipe versioning: - Release: A.B.C.D - A - Major Relase number - B - Indicates Stable or Beta - Odd number is Beta - Even number is Stable - C - Minor Release number - D - Optional pre-release and custom releases - -- Fixed RBS Support for all Maxim cards A101/2/4/8. +- Fixed A101/2 (Old) bug introduced in previous releaes -- Support for 2.6.20 kernels. +* Mon Oct 31 2007 Nenad Corbic - Beta - 3.3.0.4 +==================================================================== -- Support for New: A101D A102D A104D Maxim cards - : -- Support for New: AFT 56K DDS card +- Updated BRI caller name +- Updaged Setup -- Redesigned TDM API Events -- TDM API Analog Support +* Mon Oct 15 2007 Nenad Corbic - Beta - 3.3.0.1 +==================================================================== +- Major Updates +- New BRI architecture/support + SMG with Netbricks BRI Stack +- Support for Hardware DTMF + + +* Thu Aug 22 2007 Nenad Corbic - Beta - 3.3.0.p3 +====================================================================== + +- Updated wancfg_zaptel to support HW DTMF + + +* Thu Aug 21 2007 Nenad Corbic - Beta - 3.3.0.p2 +====================================================================== + +- Major Updates +- Hardware DTMF for Asterisk and TDM API - - END - diff --git a/rpmspec/wanpipe-util.spec b/rpmspec/wanpipe-util.spec index a87ba6c..02b5f7c 100644 --- a/rpmspec/wanpipe-util.spec +++ b/rpmspec/wanpipe-util.spec @@ -1,7 +1,7 @@ %define KERNEL_VERSION %{?kern_ver} %define WANPIPE_VER wanpipe-util %define name %{WANPIPE_VER} -%define version 3.2.7.1 +%define version 3.3.2 %define release 0 %define serial 1 %define ETC_DIR /etc @@ -179,9 +179,90 @@ ENDOFTEXT install_init() { ln -s /usr/sbin/wanrouter /etc/init.d/wanrouter - chkconfig wanrouter on + chkconfig --add wanrouter + chkconfig wanrouter on } +# ---------------------------------------------------------------------------- +# Enable MGD and BRI log for A500-BRI +# ---------------------------------------------------------------------------- +enable_smg_log() +{ +if [ -e /etc/syslog.conf ]; then + eval "grep "local2.*sangoma_mgd" /etc/syslog.conf" > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + eval "grep "local2" /etc/syslog.conf " > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + echo + echo "Warning : local2 is already used in syslog.conf" + echo + fi + echo -e "\n# Sangoma Media Gateway log" > tmp.$$ + echo -e "local2.* /var/log/sangoma_mgd.log\n" >> tmp.$$ + eval "cat /etc/syslog.conf tmp.$$ > tmp1.$$" + \cp -f tmp1.$$ /etc/syslog.conf + eval "/etc/init.d/syslog restart" > /dev/null 2>/dev/null + fi + eval "grep "local3.*sangoma_bri" /etc/syslog.conf" > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + eval "grep "local3" /etc/syslog.conf " > /dev/null 2> /dev/null + if [ $? -eq 0 ]; then + echo + echo "Warning : local3 is already used in syslog.conf" + echo + fi + echo -e "\n# Sangoma BRI Daemon (smg_bri) log" > tmp.$$ + echo -e "local3.* /var/log/sangoma_bri.log\n" >> tmp.$$ + eval "cat /etc/syslog.conf tmp.$$ > tmp1.$$" + \cp -f tmp1.$$ /etc/syslog.conf + eval "/etc/init.d/syslog restart" > /dev/null 2> /dev/null + fi +else + echo "Warning: /etc/syslog.conf not found" +fi + +if [ -f tmp1.$$ ]; then + rm -f tmp1.$$ +fi +if [ -f tmp.$$ ]; then + rm -f tmp.$$ +fi + +echo "Ok" +echo + +echo "Checking logrotate ..." +eval "type logrotate" > /dev/null 2> /dev/null +if [ $? -ne 0 ]; then + echo "Error: Logrotate not found !" +fi + +if [ -e /etc/logrotate.d ] && [ -e /etc/logrotate.d/syslog ]; then + + eval "grep sangoma_mgd /etc/logrotate.d/syslog" > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + eval "sed -e 's/messages/messages \/var\/log\/sangoma_mgd.log/' /etc/logrotate.d/syslog >tmp2.$$ 2>/dev/null" + eval "cp -f tmp2.$$ /etc/logrotate.d/syslog" + eval "logrotate -f /etc/logrotate.d/syslog" + if [ $? -ne 0 ]; then + echo "Error: logrotate restart failed!"; + exit 1; + fi + echo "Logrotate is being changed and restarted!" + else + echo "Logrotate is configured!" + fi + +else + echo "Error: Logrotate dir: /etc/logrotate.d not found !" +fi +echo "OK." +echo + +} + + + install_init_old() { #Examine system bootstrap files. @@ -234,7 +315,7 @@ EOM install_init; #create wanrouter.rc in /etc/wanpipe #create_metaconf; - +enable_smg_log; %files @@ -246,150 +327,140 @@ install_init; %changelog -* Thu Jul 16 2008 Nenad Corbic - Stable - 3.2.7 -======================================================================== -- Removed the Excessive Error check that disables the port. - This feature was introduced in 3.2.6 release. - Some lines are extremely noisy on startup which can cause - excessive crc errors (5000 per sec). In this case driver would - take the port down for few sec before bringing it back up in order to - avoid irq overlaod. This release will only print the - warning but will not take any up/down actions. +* Wed Feb 12 2008 Nenad Corbic - Beta - 3.3.2 +====================================================================== -- Added support for new PLX2 or TUNDRA PCIe chip. +- Support for A500 hardware support with NetBricks BRI Stack +- Major A500 driver updates and fixes +- Serial A142/A144 hardware support +- AFT A056 56K hardware support +- Support for HW DTMF -* Thu Jun 4 2008 Nenad Corbic - Stable - 3.2.6 -======================================================================== +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. -- Updated hwprobe to add A056 card + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands -- Updated for 2.6.25 kernel +- Updated loopback commands for AFT Maxim cards -- wanpipemon PRI/BRI wireshark tracing - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - -- LIP Layer Update - Optimized packet handling in bh - -- Fixed WAN Protocol for 2.6.24 kernels and higher - -- AFT TE1 Code - Defaulted Maxim T1 Rx Level to 36DB - Defaulted Maxim E1 Rx Level to 42DB - This will improve T1/E1 connectivity on noisy or low power lines. - -- Wanpipemon PRI/BRI PCAP Tracing for Wireshark - Using wanpipemon dchan trace one can now capture - pcap files that can be opened by Wireshark. - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - - -- Add pci parity check to wanrouter - wanrouter parity -> displays current system pci parity - wanrouter parity off -> disables system pci parity - wanrouter parity on -> enables system pci parity +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols - /etc/wanpipe/wanrouter.rc - WAN_PCI_PARITY=OFF -> on wanrouter start disable pci parity - -> event logged in /var/log/wanrouter +- Updated legacy protocols for new front end architecture - On some servers pci parity can cause NMI interrupts that - can lead to reboots. Parity can be caused by unsuported - or buggy pci/bridge chipsets. The above commands can be used - to combat pci parity reboots. - - Another option is to disable PCI parity in BIOS :) +- +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p8 +====================================================================== -* Thu Apr 4 2008 Nenad Corbic - Stable - 3.2.5.1 -======================================================================== +- wancfg_zaptel now asks for the default_tei value for +- BRI cards in TE mode -- RTP TAP Bug fix - The driver was sending out invalid rtp tap header - http://wiki.sangoma.com/wanpipe-voice-rtp-tap +- Fix for HWEC not being enabled when non-consecutive modules are using +- in BRI cards + +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p4 +====================================================================== + +- Fixed AFT memory leak + Memory leak introduced in 3.3 release +- Fixed AFT 56K bug + Bug introduced in 3.3 releae -* Thu Apr 2 2008 Nenad Corbic - Stable - 3.2.5 -======================================================================== +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p3 +====================================================================== -- T3/E3 Update - Fixed T3 Loopback commands +- Fix bug in BRI protocol for fast local hangups. -- Updated T3/E3 Driver - Performance improvement on T3/E3 drivers when handling - VOIP and Data traffic. +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.2.p1 +====================================================================== -- Update ifconfig MTU change from protocol interface - - -* Thu Mar 6 2008 Nenad Corbic - Stable - 3.2.4 -======================================================================== - -- Updated for 2.6.24 kernels - TDM Voice (Zaptel) tested with 2.6.24 kernel. - Known issues: WAN protocols are broken for 2.6.24 kernels. - Its a compilation issue that will be fixed ASAP. - -- TDM API bug fix - Check for max frame size on audio stream - -- Updated for Zaptel 1.4.9 - -- AFT IRQ Throttling feature - This feature is use to protect the server from - terrible lines. In some cases a bad hdlc line can - cause thousands of interrupts per sec. Rx errors are now - throttled so that system does not get compromized. - -- AFT RTP TAP Feature - RTP TAP Feature allows user to tap voice channels during - Asterisk-Zaptel/TMD API operation at the driver/kernel level. - Each voice stream is encapsulated in UDP/RTP header and transmitted over - neghbouring ethernet address directly from kenrel space. - Tapping 4E1s worth of voice channels adds estra 2% system load :) - http://wiki.sangoma.com/wanpipe-voice-rtp-tap - -- AFT Software Ring Buffers on A200/A400 Analog Cards - This feature improves analog preformance under Asterisk/TDM API - mode. In particualr it improves faxing reliability and - minimizes frame slippage due to system load or bad incoming - clock from the line. - Note: All AFT T1/E1 cards have this feature in hardare :) +- Bug fix in Hardware EC code for E1. + Bug introduced in 3.3 release. -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.3 -======================================================================== +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.1 +==================================================================== -- No changes from 3.2.2 - Version updated for versioning sake. -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 -======================================================================== +* Mon Jan 16 2008 Nenad Corbic - Beta - 3.3.0.22 +==================================================================== -- AFT Maxim Front end update - Implemented graceful recovery on short circuit. +- BRI protocol:Increased internal timer that could cause issue in systems with +- more than 8 BRI spans -- AFT Driver update - Added a check for TDM IRQ timeout. - On some machines its possible for TDM IRQ to timeout. +* Mon Jan 15 2008 Nenad Corbic - Beta - 3.3.0.21 +==================================================================== -- SMG updated - Fixed wancfg_smg - MTU not properly set on ports 2 and up - Voice only ports were not being added to startup sequence - Updated for callweaver +- BRI protocol:Fix for smg_brid daemon crashing on race condition +- BRI protocol:default_tei parameter is not ignored when using point to +- multipoint anymore -- Added Zaptel 1.4 HW HDLC Support - No Sangoma zaptel patch needed with Zaptel 1.4 +* Mon Jan 14 2008 Nenad Corbic - Beta - 3.3.0.20 +==================================================================== -- Added HWEC Noise flag in wanpipe config file +- BRI protocol: Additional prefix options. +- BRI protocol: Check is caller ID number is all digits on incoming calls +- Sangoma MGD: Removed dynamic user period causing skb panics +- chan_woomera: Fixed issue with rxgain and txgain values set to 0 if +- coding not set in woomera.conf +- wancfg_zaptel: Support for fractional T1/E1 spans. +- wancfg_zaptel: fix issue BRI always being configured as bri_net introduced in v3.3.0.19 -- Updated SMG -- Updated E1 Unframed on Maxim Cards +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.19 +==================================================================== +- Support for national/international prefix in BRI stack + +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.18 +==================================================================== + +- Changed Makefile in wanpipe/api/fr causing compilation errors + + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.17 +==================================================================== + +- Fix for smg_ctrl boot script starting before network services on some systems +- Support for language parameter in chan_woomera + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.16 +==================================================================== + +- Fix for Sangoma BRI Daemon crashing on incoming call if chan_woomera is not installed on that system + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.15 +==================================================================== + +- Fix for caller ID value being corrupted sometimes +- Support for call confirmation in chan_woomera + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.14 +==================================================================== + +- Fix in smg_brid not releasing some b-channels properly +- Fix in wancfg_smg not setting MTU to 80 when configuring cards for SS7 + +* Fri Dec 14 2007 Nenad Corbic - Beta - 3.3.0.13 +==================================================================== + +- Fix for Kernel panic on 64-bit systems when enabling hardware echo canceller + + +* Thu Dec 5 2007 Nenad Corbic - Beta - 3.3.0.11 +==================================================================== + +- Support for AFT Serial Cards - Updates for AFT PMC and MAXIM framers PMC - lowered LOS sensitivity Fixes fake up/down state changes on @@ -422,216 +493,37 @@ install_init; - Updated Setup script -* Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 -===================================================================== -- Setup Zap Chunk Size Patch updated for Zaptel 1.4 - Patch allows running zaptel in 8,16,40,80 chunk size. - However wct drivers must be removed from compilation :) - Patch is now fixed for Zaptel 1.4 - -- Update to All AFT drivers for 64bit 2.6.22 kernel. - Updated affects: AFT A101/2/4/8/200/400 (all cards) - The major 2.6.20+ updates extend to 64bit as well. - Previous drivers segfaulted under 2.6.22 64bit - kernels. This does not affect you if you are running - kennels lower than 2.6.22. - -- Updated legacy drivers for 2.6.22 kernel - - - -* Wed Oct 3 2007 Nenad Corbic - Stable - 3.2.0 -===================================================================== - -- The Beta 3.1.X releases has now been declared as STABLE 3.2.X - -- Fixed AMI/D4 on MAXIM (A101/2/4/8D) cards -- Fixed A200/A400 tip/ring no dial tone issues. -- Fixed 2.6.22 support and above -- Fixed RPM Build post install issue -- Updated Setup install script - Option to build for zaptel: ./Setup zaptel -- Working E&M/RBS/CAS Channel Bank support for MAXIM (A101/2/4/8) cards. -- Fixed wanpipe crashing on system shutdown on some machines. - Caused by RedHat /var/lock/subsys mandatory lock file. -- New Firmware for all MAXIM Cards (A101/2/4/8D) - Firmware V33: Fixes EC Chip Security errors that can cause - PRI to go down on some computers. Firmware is backward compatible - to any previous release. -- Faxes/Modems working through hardware echo canceler. - Tested at 56K from one port to another. - New octasic update. -- Analog Network SYNC Feature for Fax Support - Analog cards can be synced to T1/E1 clock - from adjacent A101/2/4/8 cards for flawless faxing - from FXO/FXS to T1/E1. - -- Known Issues: - T1/E1 High Impedance Tap for MAXIM (A101/2/4/8D) cards. - It works on original PMC A101/2/4 cards - -For more info: http://wiki.sangoma.com - - -* Mon Oct 1 2007 Nenad Corbic - Beta - 3.1.4.6 -==================================================================== - -- Fixed Makefile for 2.6.22.9 kernel. -- Fixed all gcc4 warnings. - - -* Tue Sep 26 2007 Nenad Corbic - Beta - 3.1.4.5 -==================================================================== - -- Updated Setup install script -- A200/A400 Analog driver update - Fixed noise issue introduced in 3.1.4.3 release -- Updated SMG for Asterisk 1.4 & Callweaver - - -* Tue Sep 18 2007 Nenad Corbic - Beta - 3.1.4.3 -==================================================================== - -- A200/A400 Analog driver update - Fixed a problem where analog port starts up without - dialtone. - -* Tue Sep 14 2007 Nenad Corbic - Beta - 3.1.4.2 -==================================================================== - -- Update for 2.6.22 kernel. -- wanrouter startup script update for redhat distros. - Fixes the issue on system shutdown, where wanpipe - module sometimes do not unload due to /var/lock/subsys/ - lockfile check. This issue is only related or RedHat style distros. - - -* Tue Aug 15 2007 Nenad Corbic - Beta - 3.1.4 -==================================================================== - -- Added A101-SH old config support. - So onld A101u or A101c config file can be used with new A101-SH cards. - -- Updated KATM support in the LIP Layer. - Used to connect Kernel ATM Layer to Wanpipe ATM AAL5 layer - over all AFT cards. - -- Added a sanity checker for enabling HWEC. - Used to prevent duble hwec enable. - -- Added wancfg_tdmapi configurator - -- Updated SMG - - -* Mon Jun 30 2007 Nenad Corbic - Beta - 3.1.3 -==================================================================== - -- Update to Ocatsic Hardware Echo Canceler Library - Turned of the NOISE suppression because it can interfere - with faxes. If you faxes did not work properly on 3.1.2 - release they will work fine with this one. - -- Cleaned up the Setup installation script. - - -* Mon Jun 16 2007 Nenad Corbic - Beta - 3.1.2 -==================================================================== - -- Update to Octasic Hardware Echo Canceler library - This is a very important update that affects all AFT cards - with octasic hardware echo canceler. The new octasic update - fixes faxing/modem issues over octasic hwec. The previous - release contained a bug that limited the faxing/modem speeds - to 26k. The new update properly detects fax/modem and works - with full speed of 33k fax and 56k modem. - -- A200/A400 Updated - This update fixes the offhook startup failure. - On startup if fxs is offhook driver will start correctly - -- Wanpipe Startup order changed - The wanpipe startup scripts on bootup were previously - set too early "S03wanrouter". This caused unpredictable - behaviour on some systems. We have now moved wanrouter - startup on boot up to "S11wanrouter", after networking - code. - -- Zaptel Adjustable Chunk Size Feature - Wanpipe drivers can work with 1,2,5 and 10ms - chunk size. Zaptel also supports this, however - the wct4xx driver breaks compilation when chunk - size is changed. ./Setup can how change the - zaptel chunk size for you and update zaptel - Makefiles to remove wct4xx driver out. - - Zaptel with 1ms generates 1000 interrupts per sec - Zaptel with 10ms generates 100 interrupts per sec. - - As you can see its a drastic interrupt performance - increase. - - NOTE: This breaks software echo cancelation, but - its not needed since we have hwec. - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.1 -==================================================================== - -- A101/2/4/8 (MAXIM) AFT Update IMPORTANT - A major bug fix for AFT Maxim E1 cards for E1 CRC4 Mode. - On some lines the E1/CRC4 mode causes line errors on - the telco side which results in PRI not coming up. - - Symptiom: E1 is up (no alarms) on local side but pri is - not coming up! (Only in E1 CRC4 Mode) - -- A101/2/4/8 (MAXIM) Mandatory Firmware Update - An echo canceler bug has been fixed for all AFT - MAXIM Cards A101/2/4/8dm. New firmware version is V31. - If you are running MAXIM cards with hwec wiht older - firmware version you must upgrade. - -- Updated SMG - Fixed DTMF synchronization - - - -- Updated SMG - Fixed DTMF synchronization - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.0.1 -==================================================================== - -- Minor release -- Contains zaptel patch for zaptel 1.2.17 and above. -- No driver changes - -* Fri May 17 2007 Nenad Corbic - Beta - 3.1.0 +* Thu Nov 8 2007 Nenad Corbic - Beta - 3.3.0.4 ==================================================================== -- Major new BETA wanpipe release - Changed wanpipe versioning: - Release: A.B.C.D - A - Major Relase number - B - Indicates Stable or Beta - Odd number is Beta - Even number is Stable - C - Minor Release number - D - Optional pre-release and custom releases - -- Fixed RBS Support for all Maxim cards A101/2/4/8. +- Fixed A101/2 (Old) bug introduced in previous releaes -- Support for 2.6.20 kernels. +* Mon Oct 31 2007 Nenad Corbic - Beta - 3.3.0.4 +==================================================================== -- Support for New: A101D A102D A104D Maxim cards - : -- Support for New: AFT 56K DDS card +- Updated BRI caller name +- Updaged Setup -- Redesigned TDM API Events -- TDM API Analog Support +* Mon Oct 15 2007 Nenad Corbic - Beta - 3.3.0.1 +==================================================================== +- Major Updates +- New BRI architecture/support + SMG with Netbricks BRI Stack +- Support for Hardware DTMF + + +* Thu Aug 22 2007 Nenad Corbic - Beta - 3.3.0.p3 +====================================================================== + +- Updated wancfg_zaptel to support HW DTMF + + +* Thu Aug 21 2007 Nenad Corbic - Beta - 3.3.0.p2 +====================================================================== + +- Major Updates +- Hardware DTMF for Asterisk and TDM API - - END - diff --git a/rpmspec/wanpipe.spec b/rpmspec/wanpipe.spec index fb9a621..8dd13b5 100644 --- a/rpmspec/wanpipe.spec +++ b/rpmspec/wanpipe.spec @@ -1,7 +1,7 @@ %define KERNEL_VERSION %{?kern_ver} %define WANPIPE_VER wanpipe %define name %{WANPIPE_VER} -%define version 3.2.7.1 +%define version 3.3.2 %define release 0 %define serial 1 %define UTILS_DIR /usr/sbin @@ -254,150 +254,140 @@ install_init; %changelog -* Thu Jul 16 2008 Nenad Corbic - Stable - 3.2.7 -======================================================================== -- Removed the Excessive Error check that disables the port. - This feature was introduced in 3.2.6 release. - Some lines are extremely noisy on startup which can cause - excessive crc errors (5000 per sec). In this case driver would - take the port down for few sec before bringing it back up in order to - avoid irq overlaod. This release will only print the - warning but will not take any up/down actions. +* Wed Feb 12 2008 Nenad Corbic - Beta - 3.3.2 +====================================================================== -- Added support for new PLX2 or TUNDRA PCIe chip. +- Support for A500 hardware support with NetBricks BRI Stack +- Major A500 driver updates and fixes +- Serial A142/A144 hardware support +- AFT A056 56K hardware support +- Support for HW DTMF -* Thu Jun 4 2008 Nenad Corbic - Stable - 3.2.6 -======================================================================== +- Updates for AFT PMC and MAXIM framers + PMC - lowered LOS sensitivity + Fixes fake up/down state changes on + started inactive lines. -- Updated hwprobe to add A056 card + MAXIM - lowered sensistivy + Fixes cable cross talk on 8 port cards. + - Enabled Unframed E1 + - Enabled Tri-State Mode + - Fixed loopback commands -- Updated for 2.6.25 kernel +- Updated loopback commands for AFT Maxim cards -- wanpipemon PRI/BRI wireshark tracing - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - -- LIP Layer Update - Optimized packet handling in bh - -- Fixed WAN Protocol for 2.6.24 kernels and higher - -- AFT TE1 Code - Defaulted Maxim T1 Rx Level to 36DB - Defaulted Maxim E1 Rx Level to 42DB - This will improve T1/E1 connectivity on noisy or low power lines. - -- Wanpipemon PRI/BRI PCAP Tracing for Wireshark - Using wanpipemon dchan trace one can now capture - pcap files that can be opened by Wireshark. - http://wiki.sangoma.com/wanpipe-wireshark-pcap-pri-bri-wan-t1-e1-tracing - - -- Add pci parity check to wanrouter - wanrouter parity -> displays current system pci parity - wanrouter parity off -> disables system pci parity - wanrouter parity on -> enables system pci parity +- Updated for AstLinux + The make file can now build all WAN and Voice Protocols - /etc/wanpipe/wanrouter.rc - WAN_PCI_PARITY=OFF -> on wanrouter start disable pci parity - -> event logged in /var/log/wanrouter +- Updated legacy protocols for new front end architecture - On some servers pci parity can cause NMI interrupts that - can lead to reboots. Parity can be caused by unsuported - or buggy pci/bridge chipsets. The above commands can be used - to combat pci parity reboots. - - Another option is to disable PCI parity in BIOS :) +- +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p8 +====================================================================== -* Thu Apr 4 2008 Nenad Corbic - Stable - 3.2.5.1 -======================================================================== +- wancfg_zaptel now asks for the default_tei value for +- BRI cards in TE mode -- RTP TAP Bug fix - The driver was sending out invalid rtp tap header - http://wiki.sangoma.com/wanpipe-voice-rtp-tap +- Fix for HWEC not being enabled when non-consecutive modules are using +- in BRI cards + +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p4 +====================================================================== + +- Fixed AFT memory leak + Memory leak introduced in 3.3 release +- Fixed AFT 56K bug + Bug introduced in 3.3 releae -* Thu Apr 2 2008 Nenad Corbic - Stable - 3.2.5 -======================================================================== +* Fri Feb 01 2008 Nenad Corbic - Beta - 3.3.2.p3 +====================================================================== -- T3/E3 Update - Fixed T3 Loopback commands +- Fix bug in BRI protocol for fast local hangups. -- Updated T3/E3 Driver - Performance improvement on T3/E3 drivers when handling - VOIP and Data traffic. +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.2.p1 +====================================================================== -- Update ifconfig MTU change from protocol interface - - -* Thu Mar 6 2008 Nenad Corbic - Stable - 3.2.4 -======================================================================== - -- Updated for 2.6.24 kernels - TDM Voice (Zaptel) tested with 2.6.24 kernel. - Known issues: WAN protocols are broken for 2.6.24 kernels. - Its a compilation issue that will be fixed ASAP. - -- TDM API bug fix - Check for max frame size on audio stream - -- Updated for Zaptel 1.4.9 - -- AFT IRQ Throttling feature - This feature is use to protect the server from - terrible lines. In some cases a bad hdlc line can - cause thousands of interrupts per sec. Rx errors are now - throttled so that system does not get compromized. - -- AFT RTP TAP Feature - RTP TAP Feature allows user to tap voice channels during - Asterisk-Zaptel/TMD API operation at the driver/kernel level. - Each voice stream is encapsulated in UDP/RTP header and transmitted over - neghbouring ethernet address directly from kenrel space. - Tapping 4E1s worth of voice channels adds estra 2% system load :) - http://wiki.sangoma.com/wanpipe-voice-rtp-tap - -- AFT Software Ring Buffers on A200/A400 Analog Cards - This feature improves analog preformance under Asterisk/TDM API - mode. In particualr it improves faxing reliability and - minimizes frame slippage due to system load or bad incoming - clock from the line. - Note: All AFT T1/E1 cards have this feature in hardare :) +- Bug fix in Hardware EC code for E1. + Bug introduced in 3.3 release. -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.3 -======================================================================== +* Mon Jan 18 2008 Nenad Corbic - Beta - 3.3.1 +==================================================================== -- No changes from 3.2.2 - Version updated for versioning sake. -* Thu Jan 18 2008 Nenad Corbic - Stable - 3.2.2 -======================================================================== +* Mon Jan 16 2008 Nenad Corbic - Beta - 3.3.0.22 +==================================================================== -- AFT Maxim Front end update - Implemented graceful recovery on short circuit. +- BRI protocol:Increased internal timer that could cause issue in systems with +- more than 8 BRI spans -- AFT Driver update - Added a check for TDM IRQ timeout. - On some machines its possible for TDM IRQ to timeout. +* Mon Jan 15 2008 Nenad Corbic - Beta - 3.3.0.21 +==================================================================== -- SMG updated - Fixed wancfg_smg - MTU not properly set on ports 2 and up - Voice only ports were not being added to startup sequence - Updated for callweaver +- BRI protocol:Fix for smg_brid daemon crashing on race condition +- BRI protocol:default_tei parameter is not ignored when using point to +- multipoint anymore -- Added Zaptel 1.4 HW HDLC Support - No Sangoma zaptel patch needed with Zaptel 1.4 +* Mon Jan 14 2008 Nenad Corbic - Beta - 3.3.0.20 +==================================================================== -- Added HWEC Noise flag in wanpipe config file +- BRI protocol: Additional prefix options. +- BRI protocol: Check is caller ID number is all digits on incoming calls +- Sangoma MGD: Removed dynamic user period causing skb panics +- chan_woomera: Fixed issue with rxgain and txgain values set to 0 if +- coding not set in woomera.conf +- wancfg_zaptel: Support for fractional T1/E1 spans. +- wancfg_zaptel: fix issue BRI always being configured as bri_net introduced in v3.3.0.19 -- Updated SMG -- Updated E1 Unframed on Maxim Cards +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.19 +==================================================================== +- Support for national/international prefix in BRI stack + +* Mon Jan 07 2008 Nenad Corbic - Beta - 3.3.0.18 +==================================================================== + +- Changed Makefile in wanpipe/api/fr causing compilation errors + + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.17 +==================================================================== + +- Fix for smg_ctrl boot script starting before network services on some systems +- Support for language parameter in chan_woomera + +* Thu Dec 20 2007 Nenad Corbic - Beta - 3.3.0.16 +==================================================================== + +- Fix for Sangoma BRI Daemon crashing on incoming call if chan_woomera is not installed on that system + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.15 +==================================================================== + +- Fix for caller ID value being corrupted sometimes +- Support for call confirmation in chan_woomera + +* Tue Dec 18 2007 Nenad Corbic - Beta - 3.3.0.14 +==================================================================== + +- Fix in smg_brid not releasing some b-channels properly +- Fix in wancfg_smg not setting MTU to 80 when configuring cards for SS7 + +* Fri Dec 14 2007 Nenad Corbic - Beta - 3.3.0.13 +==================================================================== + +- Fix for Kernel panic on 64-bit systems when enabling hardware echo canceller + + +* Thu Dec 5 2007 Nenad Corbic - Beta - 3.3.0.11 +==================================================================== + +- Support for AFT Serial Cards - Updates for AFT PMC and MAXIM framers PMC - lowered LOS sensitivity Fixes fake up/down state changes on @@ -430,216 +420,37 @@ install_init; - Updated Setup script -* Wed Oct 6 2007 Nenad Corbic - Stable - 3.2.1 -===================================================================== -- Setup Zap Chunk Size Patch updated for Zaptel 1.4 - Patch allows running zaptel in 8,16,40,80 chunk size. - However wct drivers must be removed from compilation :) - Patch is now fixed for Zaptel 1.4 - -- Update to All AFT drivers for 64bit 2.6.22 kernel. - Updated affects: AFT A101/2/4/8/200/400 (all cards) - The major 2.6.20+ updates extend to 64bit as well. - Previous drivers segfaulted under 2.6.22 64bit - kernels. This does not affect you if you are running - kennels lower than 2.6.22. - -- Updated legacy drivers for 2.6.22 kernel - - - -* Wed Oct 3 2007 Nenad Corbic - Stable - 3.2.0 -===================================================================== - -- The Beta 3.1.X releases has now been declared as STABLE 3.2.X - -- Fixed AMI/D4 on MAXIM (A101/2/4/8D) cards -- Fixed A200/A400 tip/ring no dial tone issues. -- Fixed 2.6.22 support and above -- Fixed RPM Build post install issue -- Updated Setup install script - Option to build for zaptel: ./Setup zaptel -- Working E&M/RBS/CAS Channel Bank support for MAXIM (A101/2/4/8) cards. -- Fixed wanpipe crashing on system shutdown on some machines. - Caused by RedHat /var/lock/subsys mandatory lock file. -- New Firmware for all MAXIM Cards (A101/2/4/8D) - Firmware V33: Fixes EC Chip Security errors that can cause - PRI to go down on some computers. Firmware is backward compatible - to any previous release. -- Faxes/Modems working through hardware echo canceler. - Tested at 56K from one port to another. - New octasic update. -- Analog Network SYNC Feature for Fax Support - Analog cards can be synced to T1/E1 clock - from adjacent A101/2/4/8 cards for flawless faxing - from FXO/FXS to T1/E1. - -- Known Issues: - T1/E1 High Impedance Tap for MAXIM (A101/2/4/8D) cards. - It works on original PMC A101/2/4 cards - -For more info: http://wiki.sangoma.com - - -* Mon Oct 1 2007 Nenad Corbic - Beta - 3.1.4.6 -==================================================================== - -- Fixed Makefile for 2.6.22.9 kernel. -- Fixed all gcc4 warnings. - - -* Tue Sep 26 2007 Nenad Corbic - Beta - 3.1.4.5 -==================================================================== - -- Updated Setup install script -- A200/A400 Analog driver update - Fixed noise issue introduced in 3.1.4.3 release -- Updated SMG for Asterisk 1.4 & Callweaver - - -* Tue Sep 18 2007 Nenad Corbic - Beta - 3.1.4.3 -==================================================================== - -- A200/A400 Analog driver update - Fixed a problem where analog port starts up without - dialtone. - -* Tue Sep 14 2007 Nenad Corbic - Beta - 3.1.4.2 -==================================================================== - -- Update for 2.6.22 kernel. -- wanrouter startup script update for redhat distros. - Fixes the issue on system shutdown, where wanpipe - module sometimes do not unload due to /var/lock/subsys/ - lockfile check. This issue is only related or RedHat style distros. - - -* Tue Aug 15 2007 Nenad Corbic - Beta - 3.1.4 -==================================================================== - -- Added A101-SH old config support. - So onld A101u or A101c config file can be used with new A101-SH cards. - -- Updated KATM support in the LIP Layer. - Used to connect Kernel ATM Layer to Wanpipe ATM AAL5 layer - over all AFT cards. - -- Added a sanity checker for enabling HWEC. - Used to prevent duble hwec enable. - -- Added wancfg_tdmapi configurator - -- Updated SMG - - -* Mon Jun 30 2007 Nenad Corbic - Beta - 3.1.3 -==================================================================== - -- Update to Ocatsic Hardware Echo Canceler Library - Turned of the NOISE suppression because it can interfere - with faxes. If you faxes did not work properly on 3.1.2 - release they will work fine with this one. - -- Cleaned up the Setup installation script. - - -* Mon Jun 16 2007 Nenad Corbic - Beta - 3.1.2 -==================================================================== - -- Update to Octasic Hardware Echo Canceler library - This is a very important update that affects all AFT cards - with octasic hardware echo canceler. The new octasic update - fixes faxing/modem issues over octasic hwec. The previous - release contained a bug that limited the faxing/modem speeds - to 26k. The new update properly detects fax/modem and works - with full speed of 33k fax and 56k modem. - -- A200/A400 Updated - This update fixes the offhook startup failure. - On startup if fxs is offhook driver will start correctly - -- Wanpipe Startup order changed - The wanpipe startup scripts on bootup were previously - set too early "S03wanrouter". This caused unpredictable - behaviour on some systems. We have now moved wanrouter - startup on boot up to "S11wanrouter", after networking - code. - -- Zaptel Adjustable Chunk Size Feature - Wanpipe drivers can work with 1,2,5 and 10ms - chunk size. Zaptel also supports this, however - the wct4xx driver breaks compilation when chunk - size is changed. ./Setup can how change the - zaptel chunk size for you and update zaptel - Makefiles to remove wct4xx driver out. - - Zaptel with 1ms generates 1000 interrupts per sec - Zaptel with 10ms generates 100 interrupts per sec. - - As you can see its a drastic interrupt performance - increase. - - NOTE: This breaks software echo cancelation, but - its not needed since we have hwec. - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.1 -==================================================================== - -- A101/2/4/8 (MAXIM) AFT Update IMPORTANT - A major bug fix for AFT Maxim E1 cards for E1 CRC4 Mode. - On some lines the E1/CRC4 mode causes line errors on - the telco side which results in PRI not coming up. - - Symptiom: E1 is up (no alarms) on local side but pri is - not coming up! (Only in E1 CRC4 Mode) - -- A101/2/4/8 (MAXIM) Mandatory Firmware Update - An echo canceler bug has been fixed for all AFT - MAXIM Cards A101/2/4/8dm. New firmware version is V31. - If you are running MAXIM cards with hwec wiht older - firmware version you must upgrade. - -- Updated SMG - Fixed DTMF synchronization - - - -- Updated SMG - Fixed DTMF synchronization - - -* Fri Jun 06 2007 Nenad Corbic - Beta - 3.1.0.1 -==================================================================== - -- Minor release -- Contains zaptel patch for zaptel 1.2.17 and above. -- No driver changes - -* Fri May 17 2007 Nenad Corbic - Beta - 3.1.0 +* Thu Nov 8 2007 Nenad Corbic - Beta - 3.3.0.4 ==================================================================== -- Major new BETA wanpipe release - Changed wanpipe versioning: - Release: A.B.C.D - A - Major Relase number - B - Indicates Stable or Beta - Odd number is Beta - Even number is Stable - C - Minor Release number - D - Optional pre-release and custom releases - -- Fixed RBS Support for all Maxim cards A101/2/4/8. +- Fixed A101/2 (Old) bug introduced in previous releaes -- Support for 2.6.20 kernels. +* Mon Oct 31 2007 Nenad Corbic - Beta - 3.3.0.4 +==================================================================== -- Support for New: A101D A102D A104D Maxim cards - : -- Support for New: AFT 56K DDS card +- Updated BRI caller name +- Updaged Setup -- Redesigned TDM API Events -- TDM API Analog Support +* Mon Oct 15 2007 Nenad Corbic - Beta - 3.3.0.1 +==================================================================== +- Major Updates +- New BRI architecture/support + SMG with Netbricks BRI Stack +- Support for Hardware DTMF + + +* Thu Aug 22 2007 Nenad Corbic - Beta - 3.3.0.p3 +====================================================================== + +- Updated wancfg_zaptel to support HW DTMF + + +* Thu Aug 21 2007 Nenad Corbic - Beta - 3.3.0.p2 +====================================================================== + +- Major Updates +- Hardware DTMF for Asterisk and TDM API - - END - diff --git a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u b/samples/wanpipe1.rtp similarity index 51% rename from util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u rename to samples/wanpipe1.rtp index 379d36e..472f547 100644 --- a/util/tmp_davidy/wancfg_zaptel/templates/ss7_a10u/wanpipe.tdmvoiceapi.a10u +++ b/samples/wanpipe1.rtp @@ -15,36 +15,46 @@ #================================================ [devices] -wanpipeDEVNUM = WAN_AFT, Comment +wanpipe1 = WAN_AFT_TE1, Comment [interfaces] -wDEVNUMg1 = wanpipeDEVNUM, , TDM_VOICE_API, Comment +w1g1 = wanpipe1, , TDM_VOICE_API, Comment -[wanpipeDEVNUM] +[wanpipe1] CARD_TYPE = AFT -S514CPU = FECPU +S514CPU = A CommPort = PRI -AUTO_PCISLOT = NO -PCISLOT = SLOTNUM -PCIBUS = BUSNUM -FE_MEDIA = FEMEDIA -FE_LCODE = FELCODE -FE_FRAME = FEFRAME -FE_LINE = 1 -TE_CLOCK = FECLOCK +AUTO_PCISLOT = YES +PCISLOT = 1 +PCIBUS = 3 +FE_MEDIA = E1 +FE_LCODE = HDB3 +FE_FRAME = CRC4 +FE_LINE = 2 +TE_CLOCK = NORMAL TE_REF_CLOCK = 0 TE_HIGHIMPEDANCE = NO -LBO = FELBO +LBO = 120OH FE_TXTRISTATE = NO MTU = 1500 UDPPORT = 9000 TTL = 255 IGNORE_FRONT_END = NO -TDMV_SPAN = TDMVSPANNO -TDMV_DCHAN = 0 +TDMV_SPAN = 1 +TDMV_DCHAN = 16 -[wDEVNUMg1] +RTP_TAP_IP=192.168.1.1 #Remote IP Address on local network +RTP_TAP_PORT=9000 #Remote UDP Port +RTP_TAP_MAC=00:04:23:B0:24:CE #Remote MAC Address on local network + +RTP_TAP_SAMPLE=100 #RTP sample in millisec. (Default: 100ms) + #100ms = 800bytes = 100 * 8 byte/ms (ulaw/alaw) + +RTP_TAP_DEV=eth0 #Ethernet device on your local machine + #that is connected to the local network + + +[w1g1] ACTIVE_CH = ALL TDMV_ECHO_OFF = NO -TDMV_HWEC = NO -MTU = 80 +TDMV_HWEC = NO diff --git a/samples/wanrouter b/samples/wanrouter index d5b9cec..fac85c0 100644 --- a/samples/wanrouter +++ b/samples/wanrouter @@ -1,6 +1,6 @@ -#!/bin/bash -p +#!/bin/sh # chkconfig: 2345 7 9 -# description: Starts and stop Wanpipe devices +# Description: WANPIPE WAN Router Initialization Script. # # copyright (c) 1999-2002, Sangoma Technologies Inc. # @@ -8,7 +8,8 @@ # 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. -# ============================================================================ +# ========================================================================== +# Sep 19, 2007 Alex Feldman Add DEPMOD=NO support for FreeBSD OS. # July 28,2004 Alex Feldman Do not run 'ztcfg' after interface # configuration. Run ztcfg script manually # after all Voip interfaces loaded. @@ -55,7 +56,8 @@ prompt() return 0 fi - echo -ne "$*" >&2 + # BASH echo -ne "$*" >&2 + echo -n "$*" >&2 read CMD rest return 0 } @@ -87,7 +89,8 @@ getyn() pause() { - [ $# -ne 0 ] && echo -e $* >&2 + # BASH [ $# -ne 0 ] && echo -e $* >&2 + [ $# -ne 0 ] && echo -e "$*" >&2 echo -e "Press [Enter] to continue...\c" >&2 read tmp return 0 @@ -117,7 +120,7 @@ check_awk () fi } -function cleanup () +cleanup () { eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" @@ -140,7 +143,8 @@ check_list() val=$1 shift - for i in $* + # BASH for i in $* + for i in "$*" do [ "$val" = "$i" ] && return 0 done return 1 @@ -149,13 +153,15 @@ check_list() # ---------------------------------------------------------------------------- # Display error message. # ---------------------------------------------------------------------------- -error() { +error() +{ echo -e "$SCRIPT: $*!" [ -f "$WAN_LOG" ] && echo -e "$*!" >> $WAN_LOG return 0 } -file_exist() { +file_exist() +{ local ret eval "ls $1.* > /dev/null 2> /dev/null" ret=$? @@ -195,14 +201,16 @@ interface_up() return 0 fi fi - source $WAN_INTR_DIR/ifcfg-$1 + # BASH source $WAN_INTR_DIR/ifcfg-$1 + . $WAN_INTR_DIR/ifcfg-$1 else if [ ! -f $WAN_INTR_DIR/$1 ]; then ifconfig $1 up return 0; fi - source $WAN_INTR_DIR/$1 + # BASH source $WAN_INTR_DIR/$1" + . $WAN_INTR_DIR/$1 fi @@ -274,7 +282,7 @@ interface_up() return 0 } -function check_module () { +check_module () { if [ $OSYSTEM = "Linux" ]; then [ -d "$ROUTER_PROC" ] && { @@ -297,7 +305,24 @@ function check_module () { return 1; } -function load_driver () { +get_mod_name() +{ + local path=$1 + local name=$2 + + if [ "$DEPMOD" = "YES" ]; then + if [ "$OSYSTEM" = "Linux" ]; then + module_name=$name + else + module_name=$name$MODULE_EXT + fi + else + module_name=$path/$name$MODULE_EXT + fi + return 0 +} + +load_driver () { local err @@ -307,17 +332,17 @@ function load_driver () { elif [ $OSYSTEM = "FreeBSD" ]; then err=`$MODULE_LOAD $1 >/dev/null` elif [ $OSYSTEM = "OpenBSD" -o $OSYSTEM = "NetBSD" ]; then - err=`$MODULE_LOAD -o $MODULE_DIR/$1.out -e$1 -p$MODULE_DIR/$POSTINSTALL $MODULE_DIR/$1.o 1> /dev/null` + err=`$MODULE_LOAD -o ${WAN_MODULE_DIR}/$1.out -e$1 -p${WAN_MODULE_DIR}/$POSTINSTALL ${WAN_MODULE_DIR}/$1.o 1> /dev/null` fi return $err } -function unload_driver () { +unload_driver () { local err if [ $OSYSTEM = "OpenBSD" -o $OSYSTEM = "NetBSD" ]; then - \rm -rf $MODULE_DIR/$1.out + \rm -rf ${WAN_MODULE_DIR}/$1.out err=`$MODULE_UNLOAD -n $1 2> /dev/null` else err=`$MODULE_UNLOAD $1 2> /dev/null` @@ -396,7 +421,7 @@ echo "Error: Your securelevel does not allow to load kernel modules!" for i in $MODULES do - module_name=$i${MODULE_EXT} + module_name=$i$MODULE_EXT if [ ! -f $module_name ]; then if [ $OSYSTEM = "Linux" ]; then eval "echo $OPT_MODULES | grep $i > /dev/null 2> /dev/null" @@ -452,14 +477,15 @@ echo "Error: Your securelevel does not allow to load kernel modules!" for i in $MODULES do - if load_driver "$i" + module_name=$i$MODULE_EXT + if load_driver "$module_name" then if [ $opt != silent ]; then echo "ok" >> $WAN_LOG fi else if [ $opt != silent ]; then - echo -e "\nFailed to load wanpipe modules !\n" + echo -e "\nFailed to load $module_name modules !\n" echo "fail" >> $WAN_LOG fi unload_module @@ -577,8 +603,8 @@ interf_config() INTERFACES=`grep ".*=.*$device" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` # fi - INTERFACES=${INTERFACES// /} - + # BASH INTERFACES=${INTERFACES// /} + INTERFACES=${INTERFACES%% } if [ -z "$INTERFACES" ]; then error "No interface definitions found in $WAN_CONF" @@ -620,7 +646,8 @@ interf_config() if [ "$AWK_SUPPORT" = YES ]; then API=`echo $API | awk '{ gsub(" ", "") ; print }'` elif [ "$BASH_SUPPORT" -gt 1 ]; then - API=${API// /} + # BASH API=${API// /} + API=${API%% } fi if [ "$API" = API ] || [ "$API" = TDM_API ] || [ "$API" = TDM_VOICE_API ]; then @@ -742,7 +769,8 @@ interf_down() # ---------------------------------------------------------------------------- config_devices() { - local devices=$* + # bASH local devices=$* + local devices="$*" for dev in $devices; do if [ $OSYSTEM = "Linux" ] && [ ! -e "$ROUTER_PROC/$dev" ]; then @@ -799,7 +827,8 @@ config_devices() # ---------------------------------------------------------------------------- unconfig_devices() { - local devices=$* + # bASH local devices=$* + local devices="$*" #Stop all routers but check if device #is running first @@ -832,6 +861,16 @@ unconfig_devices() remove_cdev unload_module + for dev in $devices; do + WAN_CONF=$WAN_CONF_DIR/$dev.conf + + INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` + for ifname in $INTERFACES; do + ifname=${ifname%%=*} + done + + done + return 0 } @@ -840,7 +879,8 @@ unconfig_devices() # ---------------------------------------------------------------------------- config_interfaces() { - local devices=$* + # bASH local devices=$* + local devices="$*" for dev in $devices; do @@ -877,7 +917,8 @@ config_interfaces() # ---------------------------------------------------------------------------- unconfig_interfaces() { - local devices=$* + # bASH local devices=$* + local devices="$*" #Stop all interfaces, but check whether #device is running first @@ -1000,17 +1041,14 @@ wanec_config () return 0 fi - if [ $DEPMOD != YES ]; then - return 0 - fi - if [ $opt = UNLOAD ]; then lsmods=`$MODULE_STAT` for i in $WANEC_UNLOAD_DRIVERS do echo "$lsmods" | grep -q "$i" && { - if ! unload_driver $i + get_mod_name $WANEC_MOD_DIR $i + if ! unload_driver $module_name then return 1 fi @@ -1022,7 +1060,8 @@ wanec_config () do $MODULE_STAT | grep -q $i && continue - if ! load_driver $i + get_mod_name $WANEC_MOD_DIR $i + if ! load_driver $module_name then return 1 fi @@ -1045,23 +1084,19 @@ lip_config () return 0 fi - file_exist $MOD9 if [ $? -ne 0 ]; then return 0 fi - if [ $DEPMOD != YES ]; then - return 0 - fi - if [ $opt = UNLOAD ]; then lsmods=`$MODULE_STAT` for i in $LIP_UNLOAD_DRIVERS do echo "$lsmods" | grep -q "$i" && { - if ! unload_driver $i + get_mod_name $WANPIPE_LIP_MOD_DIR $i + if ! unload_driver $module_name then return 1 fi @@ -1073,7 +1108,8 @@ lip_config () do $MODULE_STAT | grep -q $i && continue - if ! load_driver $i + get_mod_name $WANPIPE_LIP_MOD_DIR $i + if ! load_driver $module_name then return 1 fi @@ -1147,8 +1183,8 @@ print_active_devices() local silent=${1:-0} local devices - echo -e "Devices currently active:" - echo -en "\t" + echo "Devices currently active:" + echo -n " " if [ $OSYSTEM = "Linux" ]; then #If /proc directory doesn't exist nothing @@ -1176,7 +1212,7 @@ print_active_devices() return $rc } -function check_exists () { +check_exists () { local device=$1 @@ -1196,7 +1232,7 @@ function check_exists () { } -function check_dev_running () +check_dev_running () { local device=$1 local res @@ -1243,7 +1279,8 @@ check_and_print_still_running () if [ ! -z "$devices" ]; then echo "Devices Still Running:" - echo -ne "\t" + # BASH echo -en "\t" + echo -n " " echo $devices echo return 0 @@ -1264,7 +1301,8 @@ create_ft1_conf () { if [ $AWK_SUPPORT = YES ]; then eval "wandev=`echo $wandev | awk '{ gsub(" ", "") ; print }'`" elif [ $BASH_SUPPORT -gt 1 ]; then - wandev=${wandev// /} + # BASH wandev=${wandev// /} + wandev=${wandev%% } fi else echo -e "Error: Device name not found in $WAN_CONF_DIR/$dev.conf\n" @@ -1362,7 +1400,8 @@ check_config_opt () if [ $AWK_SUPPORT = YES ]; then dev=`echo $dev | awk '{ gsub(" ", "") ; print }'` elif [ $BASH_SUPPORT -gt 1 ]; then - dev=${dev// /} + # BASH dev=${dev// /} + dev=${dev%% } fi return $dev ;; @@ -1449,11 +1488,11 @@ wansock_config () fi if [ $opt = UNLOAD ]; then - $MODULE_STAT | grep -q "$AF_WANPIPE" && { - unload_driver $AF_WANPIPE + $MODULE_STAT | grep -q "$AF_WANPIPE_DRIVERS" && { + unload_driver $AF_WANPIPE_DRIVERS } else - load_driver $AF_WANPIPE + load_driver $AF_WANPIPE_DRIVERS fi return 0 } @@ -1510,7 +1549,7 @@ annexg_config () } -function print_wanpipe_config () { +print_wanpipe_config () { echo -e "Wanpipe Config:\n" if [ $OSYSTEM = "Linux" ]; then @@ -1520,7 +1559,7 @@ function print_wanpipe_config () { fi } -function print_wanrouter_status () { +print_wanrouter_status () { echo -e "\nWanrouter Status:\n" if [ $OSYSTEM = "Linux" ]; then @@ -1531,7 +1570,7 @@ function print_wanrouter_status () { } -function print_config_summary () +print_config_summary () { local pfiles; local pfile; @@ -1545,7 +1584,7 @@ function print_config_summary () return; fi - echo -e "Configuration File Summary in : $WAN_HOME\n" + echo -e "Configuration File Summary in : $WAN_HOME/\n" echo -e "Device\t\tProtocol\tType Cpu/Io Slot/Irq Bus\tState" echo -e "------------------------------------------------------------------------" @@ -1568,7 +1607,7 @@ function print_config_summary () continue fi - echo -e -n "$pdev\t" + echo -n "$pdev " pprot=`grep "^wanpiped*=*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` if [ $? -ne 0 ]; then @@ -1580,52 +1619,53 @@ function print_config_summary () fi if [ $pprot = WAN_X25 ] || [ $pprot = WAN_PPP ] || [ $pprot = WAN_FR ] || [ $pprot = WAN_MFR ] || [ $pprot = WAN_BSC ] || [ $pprot = WAN_AFT ] || [ $pprot = WAN_SS7 ] || [ $pprot = WAN_POS ] || [ $pprot = WAN_ATM ]; then - echo -e -n "$pprot\t\t" + #echo -e -n "$pprot\t\t" + echo -n "$pprot " else - echo -e -n "$pprot\t" + echo -n "$pprot " fi phw=`grep "^S514CPU*" $pfile` if [ $? -eq 0 ]; then - echo -e -n "PCI\t" + echo -n "PCI " pcpu=`grep -i "^S514CPU*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pcpu\t" + echo -n "$pcpu " pslot=`grep -i "^PCISLOT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pslot\t" + echo -n "$pslot " pbus=`grep -i "^PCIBUS*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` if [ -z $pbus ]; then - echo -e -n "0\t" + echo -n "0 " else - echo -e -n "$pbus\t" + echo -n "$pbus " fi else if [ $pprot = WAN_ADSL ]; then - echo -e -n "PCI\t" + echo -n "PCI " - echo -e -n "N/A\t" + echo -n "N/A " pslot=`grep -i "^PCISLOT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pslot\t" + echo -n "$pslot " pbus=`grep -i "^PCIBUS*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` if [ -z $pbus ]; then - echo -e -n "0\t" + echo -n "0 " else - echo -e -n "$pbus\t" + echo -n "$pbus " fi else - echo -n -e "ISA\t" + echo -n "ISA " pport=`grep -i "^IOPORT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pport\t" + echo -n "$pport " pport=`grep -i "^IRQ*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pport\t" + echo -n "$pport " - echo -e -n "n/a\t" + echo -n "n/a " fi fi @@ -1646,9 +1686,9 @@ function print_config_summary () fi fi if [ -z $pstate ]; then - echo -e -n "Inactive\t" + echo -n "Inactive" else - echo -e -n "$pstate\t" + echo -n "$pstate" fi echo @@ -1656,7 +1696,7 @@ function print_config_summary () done } -function wanrouter_if_debug() +wanrouter_if_debug() { echo echo "Debug Info for $1" @@ -1752,85 +1792,13 @@ function wanrouter_if_debug() fi } - - -pci_parity_ctrl () -{ - local parity_cmd; - local pdev; - local IDS; - local verbosity=${2:-1} - - if [ $OSYSTEM != "Linux" ]; then - echo "Error: PCI Parity Ctrl only available on Linux" - echo - return - fi - - IDS=`lspci | cut -d' ' -f1` - - if [ -z $1 ]; then - echo "Displaying System PCI Parity Configuration"; - echo "==========================================" - echo - lspci -vvv | grep Parity - echo - echo "==========================================" - return - fi - - parity_cmd=${1:-"off"} - - if [ $parity_cmd != "on" ]; then - parity_cmd="off"; - fi - - eval "type setpci 2> /dev/null > /dev/null" - if [ $? -ne 0 ]; then - echo "Parity Set Error: setpci utility not found!" - return - fi - - if [ $verbosity -gt 0 ]; then - echo "Setting PCI Parity to $parity_cmd"; - fi - - for pdev in $IDS - do - if [ "$parity_cmd" = "on" ]; then - eval "setpci -s $pdev 3e.b=0x7" - else - eval "setpci -s $pdev 3e.b=0x4" - fi - - done - - return -} - -wanrouter_pre_start() -{ - - if [ "$WAN_PCI_PARITY" = "OFF" ]; then - echo "Wanrouter: Disabling PCI Parity on Start!" >> $WAN_LOG; - pci_parity_ctrl "off" 0 - elif [ "$WAN_PCI_PARITY" = "ON" ]; then - echo "Wanrouter: Enabling PCI Parity on Start!" >> $WAN_LOG; - pci_parity_ctrl "on" 0 - fi -} - - - - - -function wanrouter_debug () +wanrouter_debug () { local err=0 echo - if [ ! -d ${WAN_HOME} ]; then - echo "Error: ${WAN_HOME} not found" + if [ ! -d $WAN_HOME ]; then + echo "Error: $WAN_HOME not found" echo "Reason: Wanpipe not installed properly" echo "Solution: Re-install wanpipe" return @@ -1852,7 +1820,7 @@ function wanrouter_debug () unload_module fi - if [ ! -f ${WAN_HOME}/wanpipe1.conf ]; then + if [ ! -f $WAN_HOME/wanpipe1.conf ]; then echo "Warning: wanpipe1.conf configuration file not found" echo "Reason: did not run /usr/sbin/wancfg to create it" echo "Solution: run /usr/sbin/wancfg :)" @@ -1908,7 +1876,7 @@ function wanrouter_debug () echo } -function check_command_exist () +check_command_exist () { local cmd=$1 local cmd_rc @@ -1923,7 +1891,7 @@ function check_command_exist () return $cmd_rc } -function init_meta_conf () +init_meta_conf () { ROUTER_BOOT= WANPIPE_CONF_DIR= @@ -1948,7 +1916,7 @@ function init_meta_conf () WAN_DEVICES= } -function read_meta_conf () +read_meta_conf () { if [ $OSYSTEM = "Linux" ]; then @@ -1976,7 +1944,7 @@ function read_meta_conf () return 0 } -function meta_conf_compatiblity () +meta_conf_compatiblity () { WAN_CONF_DIR=$WANPIPE_CONF_DIR WAN_INTR_DIR=$WANPIPE_INTR_DIR @@ -1989,7 +1957,7 @@ function meta_conf_compatiblity () } -function wanrouter_script() +wanrouter_script() { local cmd=$1 local dev=$2 @@ -2016,7 +1984,7 @@ function wanrouter_script() fi } -function generate_adsl_list() +generate_adsl_list() { local vci=0; local vpi=0; @@ -2048,10 +2016,10 @@ function generate_adsl_list() } # FIXME: Add code for BSD -function wan_force_unload_modules() +wan_force_unload_modules() { if [ $OSYSTEM = "Linux" ]; then - if [ -e "$ROUTER_PROC/status" ]; then + if [ -e "$ROUTER_PROC" ] && [ -e "$ROUTER_PROC/status" ]; then wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` if [ -z $list ]; then mod_list=`cat /proc/modules | grep wan | cut -d ' ' -f1 | xargs` @@ -2065,7 +2033,7 @@ function wan_force_unload_modules() } # FIXME: Add code for BSD -function stop_running_wanpipes () +stop_running_wanpipes () { if [ $OSYSTEM = "Linux" ]; then @@ -2074,7 +2042,8 @@ function stop_running_wanpipes () for list in $wp_list do - list=${list// /}; + # BASH list=${list// /}; + list=${list%% }; if [ ! -z $list ]; then eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" wanrouter stop $list @@ -2086,7 +2055,7 @@ function stop_running_wanpipes () fi } -function config_wanrouter_rc () +config_wanrouter_rc () { local sequence local num @@ -2147,6 +2116,209 @@ fi } +init_global_params() +{ + + if [ $OSYSTEM = "Linux" ]; then + ROUTER_VERSION=3.3.2 + IFCONFIG_LIST=ifconfig + MODULE_STAT=lsmod + WAN_DRIVERS="wanpipe" + AF_WANPIPE_DRIVERS=af_wanpipe + ANNEXG_LOAD_DRIVERS="wanpipe_lapb wanpipe_x25 wanpipe_dsp" + ANNEXG_UNLOAD_DRIVERS="wanpipe_dsp wanpipe_x25 wanpipe_lapb" + LIP_LOAD_DRIVERS="wanpipe_lip" + LIP_UNLOAD_DRIVERS="wanpipe_lip" + WANEC_LOAD_DRIVERS="wanec" + WANEC_UNLOAD_DRIVERS="wanec" + MODULE_LOAD=modprobe + MODULE_UNLOAD="modprobe -r" + MODULE_EXT=".ko" + DEPMOD=YES + + check_command_exist modprobe + if [ $? -ne 0 ]; then + check_command_exist insmod + if [ $? -eq 0 ]; then + DEPMOD=NO + MODULE_LOAD=insmod + MODULE_UNLOAD=rmmod + fi + fi + + MOD1=/lib/modules/sdladrv + MOD2=/lib/modules/wanrouter + MOD3=/lib/modules/wanpipe_syncppp + MOD4=/lib/modules/wanpipe + MOD5=/lib/modules/af_wanpipe + + if [ -d /lib/modules/$(uname -r) ]; then + uname -r | grep "^2.4.*" > /dev/null + if [ $? -eq 0 ]; then + MODULE_EXT=".o" + if [ -d /lib/modules/$(uname -r)/kernel ]; then + MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv + MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter + MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp + MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe + MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe + + MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb + MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 + MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp + + MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip + WANPIPE_LIP_MOD_DIR=/lib/modules/$(uname -r)/kernel/net/wanrouter + MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec + WANEC_MOD_DIR=/lib/modules/$(uname -r)/kernel/net/wanrouter + + fi + else + + uname -r | grep "^2.6.*" > /dev/null + if [ $? -eq 0 ]; then + if [ -d /lib/modules/$(uname -r)/kernel ]; then + MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv + MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter + MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp + MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe + MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe + + MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb + MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 + MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp + + MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip + WANPIPE_LIP_MOD_DIR=/lib/modules/$(uname -r)/kernel/net/wanrouter + MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec + WANEC_MOD_DIR=/lib/modules/$(uname -r)/kernel/net/wanrouter + fi + else + if [ -d /lib/modules/$(uname -r)/net ]; then + MOD1=/lib/modules/$(uname -r)/net/sdladrv + MOD2=/lib/modules/$(uname -r)/misc/wanrouter + MOD3=/lib/modules/$(uname -r)/net/wanpipe_syncppp + MOD4=/lib/modules/$(uname -r)/net/wanpipe + MOD5=/lib/modules/$(uname -r)/misc/af_wanpipe + + MOD6=/lib/modules/$(uname -r)/net/wanpipe_lapb + MOD7=/lib/modules/$(uname -r)/net/wanpipe_x25 + MOD8=/lib/modules/$(uname -r)/net/wanpipe_dsp + + MOD9=/lib/modules/$(uname -r)/misc/wanpipe_lip + WANPIPE_LIP_MOD_DIR=/lib/modules/$(uname -r)/misc + MOD10=/lib/modules/$(uname -r)/misc/wanec + WANEC_MOD_DIR=/lib/modules/$(uname -r)/misc + fi + fi + fi + fi + + MODULES="$MOD1 $MOD2 $MOD3 $MOD4 $MOD5" + OPT_MODULES="$MOD3 $MOD5" + UMODULES="af_wanpipe wanpipe wanpipe_syncppp wanrouter sdladrv" + + elif [ $OSYSTEM = "FreeBSD" ]; then + + SYSCTL=/sbin/sysctl + AWK=/usr/bin/awk + PKGINFO=/usr/sbin/pkg_info + major_ver=${RELEASE%%.*} + ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` + IFCONFIG_LIST=ifconfig + CDEV_WANROUTER=/dev/$SCRIPT + CDEV_MAJOR=139 + CDEV_MINOR=0 + MODULE_STAT=kldstat + MODULE_LOAD=kldload + MODULE_UNLOAD=kldunload + MODULE_EXT=".ko" + DEPMOD=YES + if [ "$major_ver" = "5" -o "$major_ver" = "6" ]; then + MODULE_DIR=/boot/modules + else + MODULE_DIR=/modules + fi + + if [ -z ${WAN_MODULE_DIR} ]; then + WAN_MODULE_DIR=${MODULE_DIR} + else + if [ "${WAN_MODULE_DIR}" != ${MODULE_DIR} ]; then + DEPMOD=NO + fi + fi + + MOD9="${WAN_MODULE_DIR}/wanpipe_lip" + WANPIPE_LIP_MOD_DIR=${WAN_MODULE_DIR} + MOD10="${WAN_MODULE_DIR}/wanec" + WANEC_MOD_DIR=${WAN_MODULE_DIR} + MODULES="${WAN_MODULE_DIR}/sdladrv ${WAN_MODULE_DIR}/wanrouter ${WAN_MODULE_DIR}/wanpipe" + UMODULES="wanpipe_lip wanec wanpipe wanrouter sdladrv" + WAN_DRIVERS="wanpipe" + LIP_LOAD_DRIVERS="wanpipe_lip" + LIP_UNLOAD_DRIVERS="wanpipe_lip" + WANEC_LOAD_DRIVERS="wanec" + WANEC_UNLOAD_DRIVERS="wanec" + + elif [ $OSYSTEM = "OpenBSD" ]; then + + SYSCTL=/sbin/sysctl + AWK=/usr/bin/awk + PKGINFO=/usr/sbin/pkg_info + SECURELEVEL=`$SYSCTL -n kern.securelevel` + ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` + IFCONFIG_LIST="ifconfig -a" + CDEV_WANROUTER=/dev/$SCRIPT + CDEV_MAJOR=139 + CDEV_MINOR=0 + POSTINSTALL=create_cdev + MODULE_STAT=modstat + MODULE_LOAD=modload + MODULE_UNLOAD=modunload + MODULE_DIR=/usr/lkm + DEPMOD=YES + if [ -z ${WAN_MODULE_DIR} ]; then + WAN_MODULE_DIR=${MODULE_DIR} + else + if [ "${WAN_MODULE_DIR}" != ${MODULE_DIR} ]; then + DEPMOD=NO + fi + fi + MODULE_EXT=".o" + MODULES="${WAN_MODULE_DIR}/wanpipe" + UMODULES="wanpipe" + WAN_DRIVERS="wanpipe" + elif [ $OSYSTEM = "NetBSD" ]; then + + SYSCTL=/sbin/sysctl + AWK=/usr/bin/awk + PKGINFO=/usr/sbin/pkg_info + SECURELEVEL=`$SYSCTL -n kern.securelevel` + ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` + IFCONFIG_LIST="ifconfig -a" + CDEV_WANROUTER=/dev/$SCRIPT + CDEV_MAJOR=139 + CDEV_MINOR=0 + POSTINSTALL=create_cdev + MODULE_STAT=modstat + MODULE_LOAD=modload + MODULE_UNLOAD=modunload + MODULE_DIR=/usr/lkm + DEPMOD=YES + if [ -z ${WAN_MODULE_DIR} ]; then + WAN_MODULE_DIR=${MODULE_DIR} + else + if [ "${WAN_MODULE_DIR}" != ${MODULE_DIR} ]; then + DEPMOD=NO + fi + fi + MODULE_EXT=".o" + MODULES="${WAN_MODULE_DIR}/wanpipe" + UMODULES="wanpipe" + WAN_DRIVERS="wanpipe" + fi + return 0 +} ####### MAIN ################################################################# # set -x @@ -2163,13 +2335,6 @@ PROD=wanpipe SCRIPT=wanrouter REDHAT=/usr/src/redhat ROUTER_PROC=/proc/net/wanrouter -AF_WANPIPE=af_wanpipe -ANNEXG_LOAD_DRIVERS="wanpipe_lapb wanpipe_x25 wanpipe_dsp" -ANNEXG_UNLOAD_DRIVERS="wanpipe_dsp wanpipe_x25 wanpipe_lapb" -LIP_LOAD_DRIVERS="wanpipe_lip" -LIP_UNLOAD_DRIVERS="wanpipe_lip" -WANEC_LOAD_DRIVERS="wanec" -WANEC_UNLOAD_DRIVERS="wanec" WAN_PROG_LOCK=/var/lock/wanrouter_lock DEPMOD=YES LINEPROBE_PATH=/usr/sbin/lineprobe @@ -2177,157 +2342,9 @@ WANPIPE_IS_RUNNING=/var/run/wanpipe_is_running RUGGEDCOM=No -if [ $OSYSTEM = "Linux" ]; then - ROUTER_VERSION=3.2.7.1 - IFCONFIG_LIST=ifconfig - MODULE_STAT=lsmod - WAN_DRIVERS="wanpipe" - MODULE_LOAD=modprobe - MODULE_UNLOAD="modprobe -r" - MODULE_EXT=".*" - DEPMOD=YES - - check_command_exist modprobe - if [ $? -ne 0 ]; then - check_command_exist insmod - if [ $? -eq 0 ]; then - DEPMOD=NO - MODULE_LOAD=insmod - MODULE_UNLOAD=rmmod - fi - fi - - MOD1=/lib/modules/sdladrv - MOD2=/lib/modules/wanrouter - MOD3=/lib/modules/wanpipe_syncppp - MOD4=/lib/modules/wanpipe - MOD5=/lib/modules/af_wanpipe - - if [ -d /lib/modules/$(uname -r) ]; then - uname -r | grep "^2.4.*" > /dev/null - if [ $? -eq 0 ]; then - if [ -d /lib/modules/$(uname -r)/kernel ]; then - MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv - MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter - MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp - MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe - MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe - - MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb - MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 - MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp - MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip - MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec - fi - else - - uname -r | grep "^2.6.*" > /dev/null - if [ $? -eq 0 ]; then - if [ -d /lib/modules/$(uname -r)/kernel ]; then - MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv - MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter - MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp - MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe - MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe - - MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb - MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 - MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp - MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip - MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec - fi - else - if [ -d /lib/modules/$(uname -r)/net ]; then - MOD1=/lib/modules/$(uname -r)/net/sdladrv - MOD2=/lib/modules/$(uname -r)/misc/wanrouter - MOD3=/lib/modules/$(uname -r)/net/wanpipe_syncppp - MOD4=/lib/modules/$(uname -r)/net/wanpipe - MOD5=/lib/modules/$(uname -r)/misc/af_wanpipe - - MOD6=/lib/modules/$(uname -r)/net/wanpipe_lapb - MOD7=/lib/modules/$(uname -r)/net/wanpipe_x25 - MOD8=/lib/modules/$(uname -r)/net/wanpipe_dsp - MOD9=/lib/modules/$(uname -r)/misc/wanpipe_lip - MOD10=/lib/modules/$(uname -r)/misc/wanec - fi - fi - fi - fi - - MODULES="$MOD1 $MOD2 $MOD3 $MOD4 $MOD5" - OPT_MODULES="$MOD3 $MOD5" - UMODULES="af_wanpipe wanpipe wanpipe_syncppp wanrouter sdladrv" - -elif [ $OSYSTEM = "FreeBSD" ]; then - - SYSCTL=/sbin/sysctl - AWK=/usr/bin/awk - PKGINFO=/usr/sbin/pkg_info - major_ver=${RELEASE%%.*} - ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` - IFCONFIG_LIST=ifconfig - CDEV_WANROUTER=/dev/$SCRIPT - CDEV_MAJOR=139 - CDEV_MINOR=0 - MODULE_STAT=kldstat - MODULE_LOAD=kldload - MODULE_UNLOAD=kldunload - MODULE_EXT=".*" - - if [ "$major_ver" = "5" -o "$major_ver" = "6" ]; then - MODULE_DIR=/boot/modules - else - MODULE_DIR=/modules - fi - MOD9="$MODULE_DIR/wanpipe_lip" - MOD10="$MODULE_DIR/wanec" - MODULES="$MODULE_DIR/wanrouter $MODULE_DIR/sdladrv $MODULE_DIR/wanpipe" - WAN_DRIVERS="wanpipe" - -elif [ $OSYSTEM = "OpenBSD" ]; then - - SYSCTL=/sbin/sysctl - AWK=/usr/bin/awk - PKGINFO=/usr/sbin/pkg_info - SECURELEVEL=`$SYSCTL -n kern.securelevel` - ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` - IFCONFIG_LIST="ifconfig -a" - CDEV_WANROUTER=/dev/$SCRIPT - CDEV_MAJOR=139 - CDEV_MINOR=0 - POSTINSTALL=create_cdev - MODULE_STAT=modstat - MODULE_LOAD=modload - MODULE_UNLOAD=modunload - MODULE_DIR=/usr/lkm - MODULE_EXT=".o" - MODULES="$MODULE_DIR/wanpipe" - WAN_DRIVERS="wanpipe" -elif [ $OSYSTEM = "NetBSD" ]; then - - SYSCTL=/sbin/sysctl - AWK=/usr/bin/awk - PKGINFO=/usr/sbin/pkg_info - SECURELEVEL=`$SYSCTL -n kern.securelevel` - ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` - IFCONFIG_LIST="ifconfig -a" - CDEV_WANROUTER=/dev/$SCRIPT - CDEV_MAJOR=139 - CDEV_MINOR=0 - POSTINSTALL=create_cdev - MODULE_STAT=modstat - MODULE_LOAD=modload - MODULE_UNLOAD=modunload - MODULE_DIR=/usr/lkm - MODULE_EXT=".o" - MODULES="$MODULE_DIR/wanpipe" - WAN_DRIVERS="wanpipe" -fi - check_bash check_awk - # Return code RC=$(pwd)/return_code GET_RC="cat $RC" @@ -2347,6 +2364,8 @@ if [ "$WANPIPE_CONF_DIR" != "" -a "$WAN_CONF_DIR" = "" ] || [ "$WAN_ADSL_LIST" = meta_conf_compatiblity fi +init_global_params + WAN_LIP_LOAD=YES WANEC_LOAD=YES WAN_ANNEXG_LOAD=${WAN_ANNEXG_LOAD:-NO} @@ -2427,7 +2446,6 @@ if [ $OSYSTEM = "Linux" ]; then fi fi - echo # If modules doesn't loaded remove all lock file from WAN_LOCK_DIR. check_module @@ -2447,8 +2465,6 @@ case "$1" in cleanup 2 fi - wanrouter_pre_start - config_devices $WAN_DEVICES config_interfaces $WAN_DEVICES @@ -2485,8 +2501,6 @@ case "$1" in dev="wanpipe$ft1_or_wanpipe" fi - wanrouter_pre_start - config_devices $dev if [ $? -ne 0 ]; then cleanup 3 @@ -2532,8 +2546,6 @@ case "$1" in echo -e "\nInterface $if_name is already up!\n" cleanup 1 fi - - wanrouter_pre_start echo "Configuring interface: $if_name" @@ -2591,8 +2603,9 @@ case "$1" in WAN_DEVICES=$tmp_dev_list fi + wanrouter_script stop - + unconfig_interfaces $WAN_DEVICES unconfig_devices $WAN_DEVICES @@ -2655,7 +2668,7 @@ case "$1" in WAN_CONF=$WAN_CONF_DIR/$dev.conf check_file $WAN_CONF || cleanup 1 - + wanrouter_script stop $dev $if_name eval "$IFCONFIG_LIST | grep -w $if_name > /dev/null 2> /dev/null" @@ -2746,7 +2759,6 @@ case "$1" in unconfig_devices $WAN_DEVICES - wanrouter_script stop elif [ -z $3 ]; then #WANROUTER STOP_DEV WANPIPE @@ -2929,11 +2941,6 @@ case "$1" in cleanup 0; ;; - parity) - pci_parity_ctrl $2 - ;; - - wanrc) config_wanrouter_rc diff --git a/samples/wanrouter.org b/samples/wanrouter.org deleted file mode 100644 index 1f02e8f..0000000 --- a/samples/wanrouter.org +++ /dev/null @@ -1,2986 +0,0 @@ -#!/bin/bash -p -# chkconfig: 2345 7 9 -# wanrouter WANPIPE WAN Router Initialization Script. -# -# copyright (c) 1999-2002, Sangoma Technologies Inc. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# ============================================================================ -# July 28,2004 Alex Feldman Do not run 'ztcfg' after interface -# configuration. Run ztcfg script manually -# after all Voip interfaces loaded. -# Jan 16, 2004 David Rokhvarg Added 'lineprobe' option -# Mar 12, 2001 Nenad Corbic Added new if support -# Feb 20, 2001 Nenad Corbic Use /proc/net/wanrouter/status to determine -# the active devices. -# Jul 17, 2000 Nenad Corbic Added version option. -# Fixed the shutdown bug. If all interfaces -# are down but modules loaded, unload -# modules. -# May 30, 2000 Nenad Corbic Updated for v2.1.4 -# Enable IP Forwarding Option -# Apr 05, 2000 Nenad Corbic Updated for v2.1.3 -# Feb 22. 2000 Nenad Corbic Updated for v2.1.2 -# Feb 15, 2000 Nenad Corbic Load WANPIPE socket module along -# with router modules. -# Jan 18, 2000 Nenad Corbic No interface files are needed for API, -# interfaces. No IP addresses neccessary. -# Nov 09, 1999 Nenad Corbic Updated for v2.1.1 -# Enabled starting and stoping -# each wanpipe device separately. -# Nov 09, 1999 Nenad Corbic Updated for v2.1.1 -# Oct 04, 1999 Nenad Corbic Updated for v2.1.0 -# Aug 04, 1999 Nenad Corbic Updated for v2.0.5 -# Oct 15, 1998 Jaspreet Singh Updated for v2.0.4 -# Dec 09, 1997 Jaspreet Singh Updated for v2.0.2 -# Nov 28, 1997 Jaspreet Singh Updated for v2.0.1 -# Nov 06, 1997 Jaspreet Singh Updated for v2.0.0 -# Jul 28, 1997 Jaspreet Singh Updated for v1.0.5 -# Jul 10, 1997 Jaspreet Singh Updated for v1.0.4 -# Dec 15, 1996 Gene Kozin Initial version based on Sangoma's WANPIPE(tm) -# ============================================================================ - -####### FUNCTION DEFINITIONS ################################################# - - -# ---------------------------------------------------------------------------- -# Prompt user for input. -# ---------------------------------------------------------------------------- -prompt() -{ - if test $NONINTERACTIVE; then - return 0 - fi - - echo -ne "$*" >&2 - read CMD rest - return 0 -} - -# ---------------------------------------------------------------------------- -# Get Yes/No -# ---------------------------------------------------------------------------- -getyn() -{ - if test $NONINTERACTIVE; then - return 0 - fi - - while prompt "$* (y/n) " - do case $CMD in - [yY]) return 0 - ;; - [nN]) return 1 - ;; - *) echo -e "\nPlease answer y or n" >&2 - ;; - esac - done -} - -# ---------------------------------------------------------------------------- -# Pause. -# ---------------------------------------------------------------------------- -pause() -{ - - [ $# -ne 0 ] && echo -e $* >&2 - echo -e "Press [Enter] to continue...\c" >&2 - read tmp - return 0 -} - -check_bash () -{ - BASH_SUPPORT=`echo $BASH_VERSION | cut -d'.' -f1 2> /dev/null` -} - -check_awk () -{ - major_ver=${RELEASE%%.*} - if [ $OSYSTEM = "Linux" ]; then - eval "type awk 2> /dev/null > /dev/null" - elif [ $OSYSTEM = "FreeBSD" -a "$major_ver" = "5" ]; then - eval "type awk 2> /dev/null > /dev/null" - elif [ $OSYSTEM = "FreeBSD" -a "$major_ver" = "6" ]; then - eval "type awk 2> /dev/null > /dev/null" - else - eval "awk 2> /dev/null > /dev/null" - fi - if [ $? -eq 0 ]; then - AWK_SUPPORT=YES - else - AWK_SUPPORT=NO - fi -} - -function cleanup () -{ - eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" - - #Check module checks if modules are loaded and updates - #the subsys lock for LINUX - check_module - - exit $1 -} - - -# ---------------------------------------------------------------------------- -# Check to see if a value belongs to the list. -# Return: 0 - yes -# 1 - no -# ---------------------------------------------------------------------------- -check_list() -{ - [ $# -lt 2 ] && return 1 - - val=$1 - shift - for i in $* - do [ "$val" = "$i" ] && return 0 - done - return 1 -} - -# ---------------------------------------------------------------------------- -# Display error message. -# ---------------------------------------------------------------------------- -error() { - echo -e "$SCRIPT: $*!" - [ -f "$WAN_LOG" ] && echo -e "$*!" >> $WAN_LOG - return 0 -} - -file_exist() { - local ret - eval "ls $1.* > /dev/null 2> /dev/null" - ret=$? - return $ret -} - -# ---------------------------------------------------------------------------- -# Configure network interface. -# This routine performs TCP/IP-level interface configuration. Interface name -# is given as an argument. It reads a configuration file with the same name in -# and calls ifconfig and route to do the job. -# -# Configuration file is actually a shell script containing only variables: -# -# ONBOOT=yes if not 'yes' then skip this file -# IPADDR=xxx.xxx.xxx.xxx IP address of this interface -# NETMASK=xxx.xxx.xxx.xxx Network mask for this interface -# NETWORK=xxx.xxx.xxx.xxx Network address -# BROADCAST=xxx.xxx.xxx.xxx Broadcast address -# POINTOPOINT=xxx.xxx.xxx.xxx Point-to-point address -# GATEWAY=xxx.xxx.xxx.xxx Gateway address -# ---------------------------------------------------------------------------- -interface_up() -{ - ONBOOT= - IPADDR= - NETMASK= - NETWORK= - BROADCAST= - POINTOPOINT= - GATEWAY= - - if [ $NEW_IF_TYPE = YES ]; then - if [ $LINUX_DISTR = redhat ]; then - if [ $WAN_INTR_DIR = "/etc/sysconfig/network-scripts" ]; then - ifup $1 - return 0 - fi - fi - source $WAN_INTR_DIR/ifcfg-$1 - else - if [ ! -f $WAN_INTR_DIR/$1 ]; then - ifconfig $1 up - return 0; - fi - - source $WAN_INTR_DIR/$1 - fi - - - # Configure interface. - if [ "$IPADDR" -a "$IPADDR" != "0.0.0.0" ]; then - # Prepare ifconfig options. - OPTIONS= - if [ $OSYSTEM = "Linux" ]; then - [ "$POINTOPOINT" ] && OPTIONS="$OPTIONS pointopoint $POINTOPOINT" - else - [ "$POINTOPOINT" ] && OPTIONS="$OPTIONS $POINTOPOINT" - fi - [ "$NETMASK" ] && OPTIONS="$OPTIONS netmask $NETMASK" - [ "$BROADCAST" ] && OPTIONS="$OPTIONS broadcast $BROADCAST" - - if [ $OSYSTEM = "Linux" ]; then - ifconfig $1 $IPADDR $OPTIONS - else - ifconfig $1 inet $IPADDR $OPTIONS - fi - ifconfig $1 up - else - ifconfig $1 up - fi - - if [ "$GATEWAY" ]; then - check_command_exist route - if [ $? -eq 0 ]; then - if [ $OSYSTEM = "Linux" ]; then - if [ "$GATEWAY" = 0 ] || [ "$GATEWAY" = "0.0.0.0" ]; then - if [ "$IPADDR" -a "$IPADDR" != "0" -a "$IPADDR" != "0.0.0.0" ]; then - route add default dev $1 - fi - else - route add default gw $GATEWAY - fi - else - if [ "$GATEWAY" = 0 ] || [ "$GATEWAY" = "0.0.0.0" ]; then - if [ "$IPADDR" -a "$IPADDR" != "0" -a "$IPADDR" != "0.0.0.0" ]; then - route add -net 0.0.0.0 -interface $1 - fi - else - route add -net 0.0.0.0 $GATEWAY - fi - fi - else - if [ $OSYSTEM = "Linux" ]; then - check_command_exist ip - if [ $? -eq 0 ]; then - if [ "$GATEWAY" = 0 ] || [ "$GATEWAY" = "0.0.0.0" ]; then - ip route add default dev $1 - else - ip route add default via $GATEWAY - fi - return 0 - fi - fi - echo - echo "Error: Failed to set route, no route or ip cmd found" - echo - fi - fi - - if [ $OSYSTEM = "Linux" ] && [ $LINUX_DISTR = redhat ]; then - /etc/sysconfig/network-scripts/ifup-routes $1 - fi - - - return 0 -} - -function check_module () { - - if [ $OSYSTEM = "Linux" ]; then - [ -d "$ROUTER_PROC" ] && { - touch $WAN_LOCK 2> /dev/null - return 0 - } - else - for i in $WAN_DRIVERS - do $MODULE_STAT | grep -q $i && { - touch $WAN_LOCK 2> /dev/null - return 0 - } - done - fi - - # Driver is not loaded - if [ -e $WAN_LOCK ]; then - rm -f $WAN_LOCK 2> /dev/null - fi - return 1; -} - -function load_driver () { - - local err - - if [ $OSYSTEM = "Linux" ]; then - $MODULE_LOAD $1 > /dev/null - err=$? - elif [ $OSYSTEM = "FreeBSD" ]; then - err=`$MODULE_LOAD $1 >/dev/null` - elif [ $OSYSTEM = "OpenBSD" -o $OSYSTEM = "NetBSD" ]; then - err=`$MODULE_LOAD -o $MODULE_DIR/$1.out -e$1 -p$MODULE_DIR/$POSTINSTALL $MODULE_DIR/$1.o 1> /dev/null` - fi - return $err -} - -function unload_driver () { - - local err - - if [ $OSYSTEM = "OpenBSD" -o $OSYSTEM = "NetBSD" ]; then - \rm -rf $MODULE_DIR/$1.out - err=`$MODULE_UNLOAD -n $1 2> /dev/null` - else - err=`$MODULE_UNLOAD $1 2> /dev/null` - err=`$MODULE_UNLOAD sdladrv 2> /dev/null` - fi - - -#Deprecated: Confirm Alex -#FIXME -# if [ $OSYSTEM = "Linux" ]; then -# # try to unload Echo Canceller module -# eval "wan_ec_client unload 2>/dev/null" -# fi - - return $err -} - -#-------------------------------------------------------------------------- -# Create character device /dev/wanrouter -#-------------------------------------------------------------------------- -create_cdev() -{ - if [ $OSYSTEM = "FreeBSD" ]; then - [ ! -e "$CDEV_WANROUTER" ] && { - mknod $CDEV_WANROUTER c $CDEV_MAJOR $CDEV_MINOR - } - fi -} - - -# ---------------------------------------------------------------------------- -# Start WAN wanrouter. -# o create log file -# o check configuration file presence -# o load WAN drivers (using modprobe) -# o configure drivers -# o configure interfaces -# ---------------------------------------------------------------------------- -load_module() -{ - local opt=${1:-NO} - - check_module - if [ $? -eq 0 ]; then - return 0 - fi - - if [ $opt != silent ]; then - echo "Starting WAN Router..." - echo "`date`: starting WAN router" >> $WAN_LOG - fi - - if [ $OSYSTEM = "Linux" ]; then - if [ -e "/proc/net/wanrouter" ]; then - - #Make sure to load optionl modules - wansock_config LOAD - annexg_config LOAD - lip_config LOAD - wanec_config LOAD - - #RuggedCom LedTask - touch $WANPIPE_IS_RUNNING - return 0 - fi - fi - - # Check if SecureLevel allows to load module. - if [ $OSYSTEM = "OpenBSD" ]; then - if [ $SECURELEVEL -gt 0 ]; then -echo "Error: Your securelevel does not allow to load kernel modules!" - return 1 - fi - fi - - for i in $MODULES - do - - module_name=$i${MODULE_EXT} - if [ ! -f $module_name ]; then - if [ $OSYSTEM = "Linux" ]; then - eval "echo $OPT_MODULES | grep $i > /dev/null 2> /dev/null" - if [ $? -ne 0 ]; then - mod_error $i - return 1 - fi - else - mod_error $i - return 1 - fi - fi - done - - [ "$ROUTER_BOOT" = "NO" -o -z "$WAN_DRIVERS" ] && { - - echo -e "\n\nERROR in $WAN_CONF_DIR/wanrouter.rc file !!!" - echo -e " ROUTER_BOOT is set to NO, OR" - echo -e " WAN_DRIVERS must be set to wanpipe\n" - echo -e " wanrouter start failed !!!\n" - return 1 - } - - if [ $DEPMOD = YES ]; then - if [ $opt != silent ]; then - echo -n "Loading WAN drivers: " - fi - for i in $WAN_DRIVERS - do - $MODULE_STAT | grep -q $i && continue - - if [ $opt != silent ]; then - echo -n "$i " - echo -n "Loading driver $i ... " >> $WAN_LOG - fi - - if load_driver $i - then - echo "ok" >> $WAN_LOG - else - if [ $opt != silent ]; then - echo -e "\nFailed to load wanpipe modules !\n" - echo "fail" >> $WAN_LOG - fi - unload_module - return 1 - fi - done - else - if [ $opt != silent ]; then - echo -n "Loading WAN drivers: " - fi - - for i in $MODULES - do - if load_driver "$i" - then - if [ $opt != silent ]; then - echo "ok" >> $WAN_LOG - fi - else - if [ $opt != silent ]; then - echo -e "\nFailed to load wanpipe modules !\n" - echo "fail" >> $WAN_LOG - fi - unload_module - return 1 - fi - done - fi - - if [ $OSYSTEM = "Linux" ]; then - wansock_config LOAD - annexg_config LOAD - fi - - if ! lip_config LOAD - then - unload_module - return 1 - fi - - if ! wanec_config LOAD - then - lip_config UNLOAD - unload_module - return 1 - fi - - if [ $opt != silent ]; then - echo "done." - fi - - # Create char devices (if needed) - create_cdev - - touch $WANPIPE_IS_RUNNING - return 0 -} - -router_config() -{ - # Configure router. - if [ $OSYSTEM != "Linux" ]; then - [ -e "$CDEV_WANROUTER" ] || { - return 1 - } - fi - - # $1 = /etc/wanpipe#.conf where # is an integer - if [ "$WAN_DYN_WANCONFIG" = YES ]; then - eval "/usr/sbin/wanconfig_client cmd=start,card=$2" - else - wanconfig -v -f $1 -a $WAN_ADSL_LIST >> $WAN_LOG - fi -} - -interf_config() -{ - local device=$1 - local WAN_CONF=$2 - local int_file - local INTERFACES - local voip_flag - - - #echo "============ iterf_config ================" - - # Configure network interfaces. - if [ ! -d "$WAN_INTR_DIR" ]; then - error "Directory $WAN_INTR_DIR not found" - return 1 - fi - - #If TTY is defined there are no network interfaces - eval "grep \"TTY.*=.*YES\" -i $WAN_CONF > /dev/null" - if [ $? -eq 0 ]; then - echo -e "done." - return 0 - fi - - #eval "grep \"WAN_EDU_KIT\" -i $WAN_CONF > /dev/null" - #if [ $? -eq 0 ]; then - # echo -e "done." - # return 0 - #fi - - eval "grep \"WAN_DEBUG\" -i $WAN_CONF > /dev/null" - if [ $? -eq 0 ]; then - echo -e "done." - return 0 - fi - - eval "grep \"WAN_MLINK_PPP\" -i $WAN_CONF > /dev/null" - if [ $? -eq 0 ]; then - echo -e "done." - return 0 - fi - -#NC: Used to be when we used PPPD but now we -# use syncppp for PPPOA. This is just legacy -# the code should be deleted once we are sure -# we will never go back to tty model -# eval "grep \"WAN_ADSL\" -i $WAN_CONF > /dev/null" -# if [ $? -eq 0 ]; then -# eval "grep \"PPP_.*_OA\" -i $WAN_CONF > /dev/null" -# if [ $? -eq 0 ]; then -# echo -e "done." -# return 0 -# fi -# fi - - cd $WAN_INTR_DIR - -# if [ -f $WAN_INTERFACE_PROC_FILE ]; then -# INTERFACES=`cat $WAN_INTERFACE_PROC_FILE | grep $device | cut -d' ' -f1` -# else - INTERFACES=`grep ".*=.*$device" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` -# fi - - INTERFACES=${INTERFACES// /} - - - if [ -z "$INTERFACES" ]; then - error "No interface definitions found in $WAN_CONF" - return 1 - fi - - echo -n "Configuring interfaces: " - for i in $INTERFACES - do - int_file=${i%%=*} - - #Not every system has egrep. Egrep uses the regular expression matching. - - check_command_exist egrep - if [ $? -eq 0 ]; then - API=`egrep "$int_file[[:space:]]*=" -i $WAN_CONF | cut -d',' -f3 2> /dev/null` - else - API=`grep "$int_file =" -i $WAN_CONF | cut -d',' -f3 2> /dev/null` - fi - - #If the card is in backup mode, it will be used to monitor - #the primary link. We don't want IP information, thus - #we set the API field. This will cause the interface to - #come up without IP information. - eval "grep \"BACKUP.*=.*YES\" -i $WAN_CONF > /dev/null" - if [ $? -eq 0 ]; then - API=API - fi - - #Substitution and replacement are no supported - #on bash versions lower than 2.0 - - #if the card is configured as API, bring up all - #interfaces without IP information. - - if [ ! -z $API ]; then - - #Remove all white spaces - if [ "$AWK_SUPPORT" = YES ]; then - API=`echo $API | awk '{ gsub(" ", "") ; print }'` - elif [ "$BASH_SUPPORT" -gt 1 ]; then - API=${API// /} - fi - - if [ "$API" = API ] || [ "$API" = TDM_API ] || [ "$API" = TDM_VOICE_API ]; then - echo -n "$int_file " - ifconfig $int_file up - continue - fi - - - - if [ "$API" = TTY ]; then - continue - fi - - #brings up (for example wp1_fr16 and wp1_fr16e) - #with IP addresses 0.0.0.0 - if [ $API = "BRIDGE" ];then - - # Bring up BRIDGE interface - echo -n "$int_file " - ifconfig $int_file up - continue - fi - - if [ $API = "TRUNK" ];then - - # Bring up Trunk interface - echo -n "$int_file " - ifconfig $int_file up - continue - fi - - if [ $API = "SWITCH" ];then - - # Bring up SWITCH interface - echo -n "$int_file " - ifconfig $int_file up - continue - fi - - if [ $API = "ANNEXG" ];then - - # Bring up SWITCH interface - echo -n "$int_file " - ifconfig $int_file up - continue - fi - - if [ $API = "VoIP" ] || [ $API = "TDM_VOICE" ] || [ $API = "TDM_VOICE_API" ] ;then - - # Bring up VoIP interface - echo -n "$int_file " - ifconfig $int_file up - voip_flag=1 - continue - fi - - if [ $API = "PPPoE" ] || [ $API = "STACK" ];then - - # Bring up SWITCH interface - echo -n "$int_file " - ifconfig $int_file up - continue - fi - - fi - if [ $NEW_IF_TYPE = YES ]; then - if_file=ifcfg-$int_file; - else - if_file=$int_file; - fi - - if [ -s $if_file ]; then - echo -n "$int_file " - interface_up $int_file || { - error "Failed to configure interface $int_file" - continue - } - else - echo "Error Interface File $int_file not found" - return 1; - fi - - done - echo -e "\ndone." - - return 0 -} - -# ---------------------------------------------------------------------------- -# Stop WAN router. -# o shut down interfaces -# o unload WAN drivers -# o remove lock file -# ---------------------------------------------------------------------------- -interf_down() -{ - local device=$1 - local WAN_CONF=$2 - local int_file - local INTERFACES - - # Shut down network interfaces. - [ -d "$WAN_INTR_DIR" ] && { - cd $WAN_INTR_DIR - INTERFACES=`grep ".*=.*$device" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` - for i in $INTERFACES - do - int_file=${i%%=*} - echo "Shutting down $device interface: $int_file" - ifconfig $int_file down - done - } -} - -# ---------------------------------------------------------------------------- -# Configure devices (all or single). -# ---------------------------------------------------------------------------- -config_devices() -{ - local devices=$* - - for dev in $devices; do - if [ $OSYSTEM = "Linux" ] && [ ! -e "$ROUTER_PROC/$dev" ]; then - echo -e "Error: Device $dev is not supported by kernel\n" - continue - fi - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - check_file $WAN_CONF || cleanup 1 - - check_exists $dev - if [ $? -ne 0 ]; then - echo "Error: Device $dev does not exist/not allocated." - echo " Check the messages log for the number of probed " - echo " devices." - echo - continue - fi - - check_dev_running $dev - if [ $? -eq 0 ]; then - echo "Error: Device $dev is already running" - echo -e " Run 'wanrouter stop $dev' first\n" - continue - fi - - #Since we changed the name of dev above, - #we must check if we are running ft1 device, - #output a correct message - if [ $ft1_or_wanpipe -gt 0 ]; then - echo "Starting up device: $dev, FT1 config mode" - echo "Starting up device: $dev, FT1 config mode" >> $WAN_LOG - else - echo "Starting up device: $dev" - echo "Starting up device: $dev" >> $WAN_LOG - fi - - router_config $WAN_CONF $dev -#NC: Jul 22 2003 -#Just because one card -#fails to load do not stop -#other cards from loading -# if [ $? -ne 0 ]; then -# #echo "Exiting rc = 3" -# cleanup 3 -# fi - done - - return 0 -} - -# ---------------------------------------------------------------------------- -# Unconfigure devices (all or single). -# ---------------------------------------------------------------------------- -unconfig_devices() -{ - local devices=$* - - #Stop all routers but check if device - #is running first - for dev in $devices; do - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - #If we are starting ft1 device there are no - #interfaces. - if [ $ft1_or_wanpipe -gt 0 ]; then - echo "Shutting down device: $dev, FT1 config mode" - echo "Shutting down device: $dev, FT1 config mode" >> $WAN_LOG - else - echo "Shutting down device: $dev" - echo "Shutting down device: $dev" >> $WAN_LOG - fi - router_unconfig $WAN_CONF $dev - - done - - #Check if any devices are still running - # If YES: don't unload the modules, just printout - # the list of active devices - # If NO: unload modules - - check_and_print_still_running && cleanup 0 - - cd $WAN_HOME - echo -e "No devices running, Unloading Modules" - remove_cdev - unload_module - - for dev in $devices; do - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` - for ifname in $INTERFACES; do - ifname=${ifname%%=*} - wanrouter_script stop $dev $ifname - done - wanrouter_script stop $dev - - done - - return 0 -} - -# ---------------------------------------------------------------------------- -# Configure wan interfaces (all or single). -# ---------------------------------------------------------------------------- -config_interfaces() -{ - local devices=$* - - for dev in $devices; do - - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - check_file $WAN_CONF || cleanup 1 - - interf_config $dev $WAN_CONF - -#NC: Jul 22 2003 -#Just because one interface -#fails to load, do not stop all -#other interfaces. -# if [ $? -ne 0 ]; then -# cleanup 4 -# fi - done - - for dev in $devices; do - WAN_CONF=$WAN_CONF_DIR/$dev.conf - INTERFACES=`grep ".*=.*$dev" -i $WAN_CONF | cut -d' ' -f1 2> /dev/null` - for ifname in $INTERFACES; do - ifname=${ifname%%=*} - wanrouter_script start $dev $ifname - done - wanrouter_script start $dev - done - - return 0 -} - -# ---------------------------------------------------------------------------- -# unconfigure interface (all or single). -# ---------------------------------------------------------------------------- -unconfig_interfaces() -{ - local devices=$* - - #Stop all interfaces, but check whether - #device is running first - for dev in $devices; do - - if [ "$dev" = "" ]; then - continue; - fi - - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - #Check that all configuration files exist - check_file $WAN_CONF || cleanup 1 - - check_exists $dev - if [ $? -eq 0 ]; then - check_dev_running $dev - if [ $? -eq 0 ]; then - WAN_CONF=$WAN_CONF_DIR/$dev.conf - interf_down $dev $WAN_CONF - fi - fi - done - - return 0 -} - - -router_unconfig() -{ - if [ $OSYSTEM != "Linux" ]; then - [ -e "$CDEV_WANROUTER" ] || { - return - } - fi - - - if [ "$WAN_DYN_WANCONFIG" = YES ]; then - eval "/usr/sbin/wanconfig_client cmd=stop,card=$2" - else - wanconfig -v -d $1 -a $WAN_ADSL_LIST >> $WAN_LOG - fi - # Unload WAN drivers. -} - - -#---------------------------------------------------------------------------- -# Remove character device /dev/wanrouter -#---------------------------------------------------------------------------- -remove_cdev() -{ - if [ $OSYSTEM = "FreeBSD" ]; then - [ -e "$CDEV_WANROUTER" ] && { - rm $CDEV_WANROUTER - } - fi -} - -unload_module() -{ - cd $WAN_HOME - - rm -f $WANPIPE_IS_RUNNING - if [ $RUGGEDCOM = "Yes" ]; then - sleep 2 - if lsof | grep '/proc/net/wanrouter' -q; then - echo "/proc/net/wanrouter still busy! Failed to make ledtask release..." - touch $WANPIPE_IS_RUNNING - return 0 - fi - fi - - if [ $OSYSTEM = "Linux" ]; then - check_and_print_still_running && cleanup 1 - wansock_config UNLOAD - annexg_config UNLOAD - elif [ $OSYSTEM = "OpenBSD" ]; then - if [ $SECURELEVEL -gt 0 ]; then -echo "Error: Your securelevel does not allow to load kernel modules!" - return 1 - fi - fi - - wanec_config UNLOAD - lip_config UNLOAD - - if [ $DEPMOD = YES ]; then - - for i in $WAN_DRIVERS - do $MODULE_STAT | grep -q $i && { - unload_driver $i - } - done - - else - for i in $UMODULES - do - unload_driver $i - done - fi - - wan_force_unload_modules -} - - -wanec_config () -{ - local opt=$1 - - if [ "$WANEC_LOAD" != "YES" ]; then - return 0 - fi - - if [ $OSYSTEM != "FreeBSD" -a $OSYSTEM != "Linux" ]; then - return 0 - fi - - file_exist $MOD10 - if [ $? -ne 0 ]; then - return 0 - fi - - if [ $DEPMOD != YES ]; then - return 0 - fi - - if [ $opt = UNLOAD ]; then - lsmods=`$MODULE_STAT` - - for i in $WANEC_UNLOAD_DRIVERS - do - echo "$lsmods" | grep -q "$i" && { - if ! unload_driver $i - then - return 1 - fi - } - done - else - - for i in $WANEC_LOAD_DRIVERS - do - $MODULE_STAT | grep -q $i && continue - - if ! load_driver $i - then - return 1 - fi - done - fi - - return 0 -} - - -lip_config () -{ - local opt=$1 - - if [ "$WAN_LIP_LOAD" != "YES" ]; then - return 0 - fi - - if [ $OSYSTEM != "FreeBSD" -a $OSYSTEM != "Linux" ]; then - return 0 - fi - - - file_exist $MOD9 - if [ $? -ne 0 ]; then - return 0 - fi - - if [ $DEPMOD != YES ]; then - return 0 - fi - - if [ $opt = UNLOAD ]; then - lsmods=`$MODULE_STAT` - - for i in $LIP_UNLOAD_DRIVERS - do - echo "$lsmods" | grep -q "$i" && { - if ! unload_driver $i - then - return 1 - fi - } - done - else - - for i in $LIP_LOAD_DRIVERS - do - $MODULE_STAT | grep -q $i && continue - - if ! load_driver $i - then - return 1 - fi - done - fi - - return 0 -} - - - -mod_error() -{ - echo -e "\n" - error "Wanpipe Module: $1 not found !!!" - if [ $OSYSTEM = "Linux" ]; then - echo -e " WANPIPE drivers must be compiled as modules" - echo -e " Check kernel configuration in /usr/src/linux/.config: " - echo -e " CONFIG_WAN_ROUTER=m" - echo -e " CONFIG_VENDOR_SANGOMA=m\n" - else - echo -e "WANPIPE drivers are modules files. " - echo -e "Try to re-compile WANPIPE drivers." - fi -} - -get_distrib() -{ - grep -i "red *hat" "/etc/issue" > /dev/null - if [ $? -eq 0 ] - then - return 1; #RedHat Found - else - return 0; - fi - -} - -check_config() -{ - for dev in $WAN_DEVICES; do - check_file "$WAN_CONF_DIR/$dev.conf" || { - echo -e "\n$SCRIPT: Error, $WAN_CONF_DIR/$dev.conf not found!\n"; - return 1; - } - done - return 0; -} - -check_file() -{ - local file=$1 - - [ ! -f "$file" ] && { - if [ ! -z $file ]; - then - echo -e "ERROR: Wanpipe configuration file not found: $file\n" - else - echo -e "ERROR: Wanpipe configuration file not found in $WAN_CONF_DIR\n" - fi - return 1; - } - return 0; -} - -print_active_devices() -{ - local ac_list; - local ac_wan; - local rc=0; - local silent=${1:-0} - local devices - - echo -e "Devices currently active:" - echo -en "\t" - - if [ $OSYSTEM = "Linux" ]; then - #If /proc directory doesn't exist nothing - #to print, thus exit - [ ! -d "$ROUTER_PROC" ] && return 0 - - devices=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort` - else - check_module - if [ $? -ne 0 ]; then - return 0 - fi - devices=`wanconfig status | cut -d' ' -f1 | grep wanpipe | sort` - fi - - if [ ! -z "$devices" ]; then - if [ $silent -ne 0 ]; then - echo $devices - fi - rc=1; - fi - - echo -e "\n" - - return $rc -} - -function check_exists () { - - local device=$1 - - if [ $OSYSTEM = "Linux" ]; then - [ ! -d "$ROUTER_PROC" ] && return 1 #Device not running - - if [ ! -f $ROUTER_PROC/$device ]; then - echo "Error: Device $device does not exist/not allocated." - echo " Check the messages log for the number of probed devices." - echo - return 1 - fi - fi - - # Device exists - return 0 - -} - -function check_dev_running () -{ - local device=$1 - local res - - if [ $OSYSTEM = "Linux" ]; then - [ ! -d "$ROUTER_PROC" ] && return 1 #Device not running - - res=`cat $ROUTER_PROC/status | grep "$device "` - else - check_module - if [ $? -ne 0 ]; then - return 1 - fi - res=`wanconfig status | grep "$device "` - fi - - [ ! -z "$res" ] && { - #Device running - return 0 - } - - #Device not running - return 1; -} - -check_and_print_still_running () -{ - local devices - - if [ $OSYSTEM = "Linux" ]; then - if [ ! -d $ROUTER_PROC ]; then - return 1 - fi - - devices=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort` - else - check_module - if [ $? -ne 0 ]; then - return 1 - fi - - devices=`wanconfig status | cut -d' ' -f1 | grep wanpipe | sort` - fi - - if [ ! -z "$devices" ]; then - echo "Devices Still Running:" - echo -ne "\t" - echo $devices - echo - return 0 - fi - - return 1 -} - -create_ft1_conf () { - - local dev=$1 - local res - - wandev=`grep "wanpipe.*=" $WAN_CONF_DIR/$dev.conf 2> /dev/null` - res=$? - if [ $res -eq 0 ]; then - wandev=${wandev%%=*} - if [ $AWK_SUPPORT = YES ]; then - eval "wandev=`echo $wandev | awk '{ gsub(" ", "") ; print }'`" - elif [ $BASH_SUPPORT -gt 1 ]; then - wandev=${wandev// /} - fi - else - echo -e "Error: Device name not found in $WAN_CONF_DIR/$dev.conf\n" - cleanup 1 - fi - - wancard=`grep "CARD_TYPE.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` - wancpu=`grep "S514CPU.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` - wanslot_auto=`grep "AUTO_PCISLOT.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` - wanslot=`grep "PCISLOT.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` - wanbus=`grep "PCIBUS.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` - wanio=`grep "IOPORT.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` - wanirq=`grep "IRQ.*=.*" -i $WAN_CONF_DIR/$dev.conf 2> /dev/null` - - if [ -z "$wancard" ]; then - echo -e "Error: Missing fileds in $WAN_CONF_DIR/$dev.conf" - echo -e " configuraton file, in [$wandev] section.\n " - cleanup 1 - fi - - if [ -z "$wancpu" -o -z "$wanslot" ]; then - if [ -z "$wanio" -o -z "$wanirq" ]; then - echo -e "Error: Missing fileds in $WAN_CONF_DIR/$dev.conf" - echo -e " configuraton file, in [$wandev] section.\n " - cleanup 1 - fi - fi - - cat < $WAN_CONF_DIR/$FT1_CONF - -#FT1 Configuration File -# -# Note: This file was automatically generated by wanrouter -# script. -# DO NOT CHANGE IT -# -# CHDLC Protocol is used since, its firmware is the -# only one with FT1 configuration functions. - -[devices] - -$wandev = WAN_CHDLC, Cisco HDLC Firmware - -[$wandev] - -$wancard -$wancpu -$wanslot_auto -$wanslot -$wanbus - -$wanio -$wanirq - -Firmware = $WAN_HOME/firmware/cdual514.sfm # adapter firmware - -#--------------------- END OF FT1 CONFIGURATION ------------------------ - -EOM - -} - - -check_config_opt () -{ - local dev=$1 - local opt=$2 - - case $dev in - - ft1_wanpipe*) - - #Strip off 'ft1_' from 'ft1_wanpipe#' - dev=${dev##ft1_} - - #Check if wanpipe#.conf file exists - check_file "$WAN_CONF_DIR/$dev.conf" - if [ $? -gt 0 ]; then - cleanup 1 - fi - - #If we are starting the router up, create - #the ft1.conf file in $WAN_CONF_DIR directory - if [ $opt -eq 0 ]; then - create_ft1_conf $dev - fi - - #Return string ft1 - result "ft1" - - #Get the wanpipe device number, and return it - #as a return code. This indicates that we want - #to setup ft1 device - dev=${dev##wanpipe} - if [ $AWK_SUPPORT = YES ]; then - dev=`echo $dev | awk '{ gsub(" ", "") ; print }'` - elif [ $BASH_SUPPORT -gt 1 ]; then - dev=${dev// /} - fi - return $dev - ;; - - wanpipe*) - #Check if wanpipe#.conf file exists - check_file "$WAN_CONF_DIR/$dev.conf" - if [ $? -gt 0 ]; then - cleanup 1 - fi - - #return string wanpipe# - result $dev - - #return zero which indicates that we - #want to startup reglar wanpipe device - #not ft1 device - return 0 - ;; - - *) - #Illegal syntax obtained - echo "Error: Incorrect device name syntax !" - cleanup 1 - ;; - esac - -} - -check_ft1_config () -{ - local ft1=$1 - - if [ $ft1 = ft1 ]; then - return 0 - else - return 1 - fi -} - -result () { - echo $1 > $RC -} - -check_osystem () { - - if [ $OSYSTEM = "Linux" ]; then - - if [ -d $WAN_LOCK_DIR ]; then - return 0 - else - echo - echo "Warning: WAN_LOCK_DIR = $WAN_LOCK_DIR does not exist!" - echo "Please update the WAN_LOCK_DIR in /etc/wanpipe/wanrouter.rc" - echo - fi - - if [ -d /var/lock/subsys ]; then - WAN_LOCK_DIR=/var/lock/subsys - elif [ -d /var/lock ]; then - WAN_LOCK_DIR=/var/lock - else - WAN_LOCK_DIR=$WAN_CONF_DIR - fi - fi - -} - -wansock_config () -{ - local opt=$1 - - if [ $OSYSTEM != "Linux" ]; then - return 0 - fi - - file_exist $MOD5 - if [ $? -ne 0 ]; then - return 0 - fi - - if [ $DEPMOD != YES ]; then - return 0 - fi - - if [ $opt = UNLOAD ]; then - $MODULE_STAT | grep -q "$AF_WANPIPE" && { - unload_driver $AF_WANPIPE - } - else - load_driver $AF_WANPIPE - fi - return 0 -} - -annexg_config () -{ - local opt=$1 - - if [ $OSYSTEM != "Linux" ]; then - return 0 - fi - - if [ "$WAN_ANNEXG_LOAD" != "YES" ]; then - return 0 - fi - - file_exist $MOD6 - if [ $? -ne 0 ]; then - return 0 - fi - - file_exist $MOD7 - if [ $? -ne 0 ]; then - return 0 - fi - - file_exist $MOD8 - if [ $? -ne 0 ]; then - return 0 - fi - - if [ $DEPMOD != YES ]; then - return 0 - fi - - if [ $opt = UNLOAD ]; then - lsmods=`$MODULE_STAT` - - for i in $ANNEXG_UNLOAD_DRIVERS - do - echo "$lsmods" | grep -q "$i" && { - unload_driver $i - } - done - else - - for i in $ANNEXG_LOAD_DRIVERS - do - load_driver $i - done - fi - - return 0 -} - - -function print_wanpipe_config () { - - echo -e "Wanpipe Config:\n" - if [ $OSYSTEM = "Linux" ]; then - cat /proc/net/wanrouter/config | sort - else - wanconfig config - fi -} - -function print_wanrouter_status () { - - echo -e "\nWanrouter Status:\n" - if [ $OSYSTEM = "Linux" ]; then - cat /proc/net/wanrouter/status | sort - else - wanconfig status - fi -} - - -function print_config_summary () -{ - local pfiles; - local pfile; - local pdev; - - cd $WAN_HOME - - pfiles=`ls wanpipe*\.conf 2> /dev/null` - if [ $? -ne 0 ]; then - echo "No Wanpipe configuration files found in $WAN_HOME"; - return; - fi - - echo -e "Configuration File Summary in : $WAN_HOME\n" - - echo -e "Device\t\tProtocol\tType Cpu/Io Slot/Irq Bus\tState" - echo -e "------------------------------------------------------------------------" - - for pfile in $pfiles - do - - #Test for invalid file: wanpipe1.conf.tmp" - echo $pfile | grep ".*\..*\..*" > /dev/null 2> /dev/null - if [ $? -eq 0 ]; then - continue - fi - - - pdev=`grep "^wanpipe*=*" $pfile | cut -d'=' -f1 | cut -d' ' -f1 2> /dev/null` - if [ $? -ne 0 ]; then - continue - fi - if [ -z "$pdev" ]; then - continue - fi - - echo -e -n "$pdev\t" - - pprot=`grep "^wanpiped*=*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - if [ $? -ne 0 ]; then - continue - fi - - if [ -z $pprot ]; then - continue - fi - - if [ $pprot = WAN_X25 ] || [ $pprot = WAN_PPP ] || [ $pprot = WAN_FR ] || [ $pprot = WAN_MFR ] || [ $pprot = WAN_BSC ] || [ $pprot = WAN_AFT ] || [ $pprot = WAN_SS7 ] || [ $pprot = WAN_POS ] || [ $pprot = WAN_ATM ]; then - echo -e -n "$pprot\t\t" - else - echo -e -n "$pprot\t" - fi - - phw=`grep "^S514CPU*" $pfile` - if [ $? -eq 0 ]; then - echo -e -n "PCI\t" - - pcpu=`grep -i "^S514CPU*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pcpu\t" - - pslot=`grep -i "^PCISLOT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pslot\t" - pbus=`grep -i "^PCIBUS*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - if [ -z $pbus ]; then - echo -e -n "0\t" - else - echo -e -n "$pbus\t" - fi - - else - if [ $pprot = WAN_ADSL ]; then - - echo -e -n "PCI\t" - - echo -e -n "N/A\t" - - pslot=`grep -i "^PCISLOT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pslot\t" - pbus=`grep -i "^PCIBUS*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - if [ -z $pbus ]; then - echo -e -n "0\t" - else - echo -e -n "$pbus\t" - fi - - else - - echo -n -e "ISA\t" - pport=`grep -i "^IOPORT*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pport\t" - pport=`grep -i "^IRQ*" $pfile | cut -d'=' -f2 | awk '{ gsub(" ", "") ; print }' | cut -d',' -f1` - echo -e -n "$pport\t" - - echo -e -n "n/a\t" - - fi - fi - - if [ $OSYSTEM = "Linux" ]; then - if [ -e /proc/net/wanrouter ]; then - pstate=`cat /proc/net/wanrouter/status | grep $pdev | cut -d'|' -f4 | awk '{ gsub(" ", "") ; print }'` - else - pstate="" - fi - else - - check_module - if [ $? -eq 0 ]; then - pstate=`wanconfig status | grep $pdev | cut -d'|' -f4 | awk '{ gsub(" ", "") ; print }'` - else - pstate="" - fi - fi - if [ -z $pstate ]; then - echo -e -n "Inactive\t" - else - echo -e -n "$pstate\t" - fi - - echo - - done -} - -function wanrouter_if_debug() -{ - echo - echo "Debug Info for $1" - echo - - echo "WANPIPE Release: $ROUTER_VERSION" - echo - echo - - eval "$IFCONFIG_LIST | grep -w $1 >> /dev/null 2>>/dev/null" - if [ $? -ne 0 ]; then - check_dev_running $1 - if [ $? -eq 0 ]; then - wanconfig -D $1 - return; - fi - - echo - echo "Error: Interface $1 does not exist!" - echo - cleanup 1 - return; - fi - - if [ ! -f /usr/sbin/wanpipemon ]; then - echo - echo "Error: /usr/sbin/wanpipemon not found" - echo "Solution: Re-install latest wanpipe release" - echo - return; - fi - - eval "/usr/sbin/wanpipemon -i $1 -c xm 2>> /dev/null" - if [ $? -ne 0 ]; then - echo - echo "Error: /usr/sbin/wanpipemon failed!" - echo " Make sure $1 is a valid wanpipe interface" - echo " Otherwise call Sangoma Tech Support" - echo - return - fi - - sleep 3 - - eval "/usr/sbin/wanpipemon -i $1 -c sc" - if [ $? -ne 0 ]; then - echo - echo "Error: /usr/sbin/wanpipemon failed!" - echo " Make sure $1 is a valid wanpipe interface" - echo " Otherwise call Sangoma Tech Support" - echo - return - fi - sleep 2 - eval "/usr/sbin/wanpipemon -i $1 -c sc" - if [ $? -ne 0 ]; then - echo - echo "Error: /usr/sbin/wanpipemon failed!" - echo " Make sure $1 is a valid wanpipe interface" - echo " Otherwise call Sangoma Tech Support" - echo - return - fi - - sleep 5 - - echo "Start WANPIPE /var/log/messages" - echo - if [ $OSYSTEM = "Linux" ]; then - eval "tail -n 200 /var/log/messages | grep -i \"[wanpipe|sdladrv]\" " - else - eval "tail -n 200 /var/log/messages | grep -i \"wanpipe\|sdladrv\" " - fi - echo - echo "End of WANPIPE /var/log/messages" - echo - - sleep 5 - - - echo - echo "---------- Starting Trace [ PRESS ENTER TO STOP ] ---------" - echo - sleep 3 - - eval "/usr/sbin/wanpipemon -i $1 -c tr" - if [ $? -ne 0 ]; then - echo - echo "Error: /usr/sbin/wanpipemon failed!" - echo " Make sure $1 is a valid wanpipe interface" - echo " Otherwise call Sangoma Tech Support" - echo - fi -} - -function wanrouter_debug () -{ - local err=0 - echo - - if [ ! -d ${WAN_HOME} ]; then - echo "Error: ${WAN_HOME} not found" - echo "Reason: Wanpipe not installed properly" - echo "Solution: Re-install wanpipe" - return - fi - - check_module - if [ $? -ne 0 ]; then - load_module - if [ $? -ne 0 ]; then - if [ $OSYSTEM = "Linux" ]; then - echo "Error: /proc/net/wanrouter not found" - fi - echo "Reason: Wanpipe kernel modules failed to load" - echo "Solution: Run 'wanrouter hwprobe' or 'wanrouter start'" - echo " Contact Sangoma Tech Support" - echo - return - fi - unload_module - fi - - if [ ! -f ${WAN_HOME}/wanpipe1.conf ]; then - echo "Warning: wanpipe1.conf configuration file not found" - echo "Reason: did not run /usr/sbin/wancfg to create it" - echo "Solution: run /usr/sbin/wancfg :)" - echo - err=1 - fi - - eval "grep -i invalid $WAN_LOG" - if [ $? -eq 0 ]; then - echo - echo "Error: Configuration file syntax error in $WAN_LOG" - echo "Reason: Miss-configuration: run 'wanrouter conflog'" - echo "Solution: Re-run /usr/sbin/wancfg and configure all variables " - echo - err=1 - fi - - eval "tail -n 20 /var/log/messages | grep -i \"wanpipe.*error[,:]\" " - if [ $? -eq 0 ]; then - echo "------------------------------------------" - echo "Error: Error occured during wanrouter startup/shutdown" - echo "Reason: Check /var/log/messages file: run 'wanrouter messages'" - echo "Solution: Review /var/log/messages and contact Sangoma Tech Support" - echo - err=1 - else - - eval "tail -n 20 /var/log/messages | grep -i \"sdladrv.*invalid[,:]\"" - if [ $? -eq 0 ]; then - echo "------------------------------------------" - echo "Error: Config error occured during wanrouter startup/shutdown" - echo "Reason: Check /var/log/messages file: run 'wanrouter messages'" - echo "Solution: Review /var/log/messages and contact Sangoma Tech Support" - echo - err=1 - else - - eval "tail -n 20 /var/log/messages | grep -i \"wanpipe.*warning\" " - if [ $? -eq 0 ]; then - echo "------------------------------------------" - echo "Warning: Warning occured during wanrouter startup/shutdown" - echo "Reason: Check /var/log/messages file" - echo "Solution: Review /var/log/messages and contact Sangoma Tech Support" - echo - err=1 - fi - fi - fi - - if [ $err -eq 0 ]; then - echo "Wanpipe environment/utilites/modules/operation OK" - fi - echo -} - -function check_command_exist () -{ - local cmd=$1 - local cmd_rc - - if [ $OSYSTEM = "Linux" ]; then - eval "type $1 > /dev/null 2> /dev/null" - else - eval "which $1 > /dev/null 2> /dev/null" - fi - cmd_rc=$? - - return $cmd_rc -} - -function init_meta_conf () -{ - ROUTER_BOOT= - WANPIPE_CONF_DIR= - WANPIPE_INTR_DIR= - ROUTER_LOG= - ROUTER_LOCK= - ROUTER_IP_FORWARD= - NEW_IF_TYPE= - WANCFG_LIB= - WAN_DEVICES= - - ROUTER_BOOT= - WAN_CONF_DIR= - WAN_INTR_DIR= - WAN_LOG= - WAN_LOCK= - WAN_LOCK_DIR= - WAN_IP_FORWARD= - NEW_IF_TYPE= - WAN_LIB_DIR= - WAN_ADSL_LIST= - WAN_DEVICES= -} - -function read_meta_conf () -{ - - if [ $OSYSTEM = "Linux" ]; then - WAN_HOME=/etc/wanpipe - elif [ $OSYSTEM = "FreeBSD" -o $OSYSTEM = "OpenBSD" ]; then - WAN_HOME=/usr/local/etc/wanpipe - wanrouter_rc_file="" - if [ -r /etc/rc.conf ]; then - . /etc/rc.conf - fi - if [ -n "$wanrouter_rc_file" ]; then - WAN_HOME=${wanrouter_rc_file%/*} - fi - fi - WAN_CONF_DIR=$WAN_HOME - META_CONF=$WAN_HOME/wanrouter.rc - WAN_INTR_DIR=$WAN_HOME/interfaces - - # Read meta-configuration file. - if [ -f $META_CONF ] - then . $META_CONF - else - return 1 - fi - return 0 -} - -function meta_conf_compatiblity () -{ - WAN_CONF_DIR=$WANPIPE_CONF_DIR - WAN_INTR_DIR=$WANPIPE_INTR_DIR - WAN_LOG=$ROUTER_LOG - WAN_LOCK=$ROUTER_LOCK - WAN_LOCK_DIR=${ROUTER_LOCK%/*} - WAN_IP_FORWARD=$ROUTER_IP_FORWARD - WAN_LIB_DIR=$WANCFG_LIB - WAN_ADSL_LIST=$WANPIPE_CONF_DIR/wan_adsl.list - -} - -function wanrouter_script() -{ - local cmd=$1 - local dev=$2 - local ifname=$3 - - #echo "Starting Script: $WAN_SCRIPTS_DIR/$dev-$ifname-$cmd" - - if [ "$ifname" != "" ]; then - #Interface name exists - if [ -f "$WAN_SCRIPTS_DIR/$dev-$ifname-$cmd" ]; then - eval "sh $WAN_SCRIPTS_DIR/$dev-$ifname-$cmd $dev $ifname" - fi - - elif [ "$dev" != "" ]; then - #Device name exists - if [ -f "$WAN_SCRIPTS_DIR/$dev-$cmd" ]; then - eval "sh $WAN_SCRIPTS_DIR/$dev-$cmd $dev" - fi - else - #Global Cmd - if [ -f "$WAN_SCRIPTS_DIR/$cmd" ]; then - eval "sh $WAN_SCRIPTS_DIR/$cmd" - fi - fi -} - -function generate_adsl_list() -{ - local vci=0; - local vpi=0; - - echo "35 0" > $WAN_ADSL_LIST - echo "35 8" >> $WAN_ADSL_LIST - - vci=30 - vpi=0 - while [ 1 ]; do - while [ 1 ]; do - - echo "$vci $vpi" >> $WAN_ADSL_LIST - - vpi=$((vpi+1)) - if [ $vpi = 10 ]; then - vpi=0 - break; - fi - done - - vci=$((vci+1)) - - if [ $vci -eq 40 ]; then - vci=30 - break; - fi - done -} - -# FIXME: Add code for BSD -function wan_force_unload_modules() -{ - if [ $OSYSTEM = "Linux" ]; then - if [ -e "$ROUTER_PROC/status" ]; then - wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` - if [ -z $list ]; then - mod_list=`cat /proc/modules | grep wan | cut -d ' ' -f1 | xargs` - for tmp_mod in $mod_list - do - eval "rmmod $tmp_mod >> /dev/null 2>> /dev/null" - done - fi - fi - fi -} - -# FIXME: Add code for BSD -function stop_running_wanpipes () -{ - - if [ $OSYSTEM = "Linux" ]; then - if [ -e "$ROUTER_PROC/status" ]; then - wp_list=`cat $ROUTER_PROC/status | cut -d' ' -f1 | grep wanpipe | sort -r` - - for list in $wp_list - do - list=${list// /}; - if [ ! -z $list ]; then - eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" - wanrouter stop $list - fi - done - - wan_force_unload_modules - fi - fi -} - -function config_wanrouter_rc () -{ - local sequence - local num - local val - - cat << EOM - -WANPIPE STARTUP CONFIG - -Current Wanpipe devices configured -to start on bootup: - -$WAN_DEVICES - - Please specify new startup string: - eg: wanpipe1 wanpipe2 ... - - Note: Single space must exist between - device names. - -EOM - -echo -n "Enter Wanpipe Startup Sequence: " - -read sequence - -if [ -z "$sequence" ]; then - echo - echo "Error: startup sequence must contain at least one device name" - echo " eg: wanpipe1" - echo - return -fi - -eval "echo $sequence | grep \"wanpipe\d*\" > /dev/null 2> /dev/null" -if [ $? -ne 0 ]; then - echo - echo "Error: startup sequence must contain at least one device name" - echo " eg: wanpipe1" - echo - return -fi - -echo -echo "New Sequence is: $sequence" -echo - -getyn "Is the above sequence correct ?" - -if [ $? -eq 0 ]; then - echo - echo "Setting wanpipe startup sequence to: $sequence" - echo - cat $META_CONF | grep "WAN_DEVICES=" -v > $WAN_HOME/tmp.$$ - echo "WAN_DEVICES=\"$sequence\"" >> $WAN_HOME/tmp.$$ - cat $WAN_HOME/tmp.$$ > $META_CONF -fi - -} - - -####### MAIN ################################################################# -# set -x - -RCDLINKS="0,K10 1,K10 2,S20 3,S20 4,S20 5,S20 6,K10" - - -export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/loca/bin:/usr/local/sbin -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib - -OSYSTEM=`uname -s` -RELEASE=`uname -r` -PROD=wanpipe -SCRIPT=wanrouter -REDHAT=/usr/src/redhat -ROUTER_PROC=/proc/net/wanrouter -AF_WANPIPE=af_wanpipe -ANNEXG_LOAD_DRIVERS="wanpipe_lapb wanpipe_x25 wanpipe_dsp" -ANNEXG_UNLOAD_DRIVERS="wanpipe_dsp wanpipe_x25 wanpipe_lapb" -LIP_LOAD_DRIVERS="wanpipe_lip" -LIP_UNLOAD_DRIVERS="wanpipe_lip" -WANEC_LOAD_DRIVERS="wanec" -WANEC_UNLOAD_DRIVERS="wanec" -WAN_PROG_LOCK=/var/lock/wanrouter_lock -DEPMOD=YES -LINEPROBE_PATH=/usr/sbin/lineprobe -WANPIPE_IS_RUNNING=/var/run/wanpipe_is_running - -RUGGEDCOM=No - -if [ $OSYSTEM = "Linux" ]; then - ROUTER_VERSION=3.2.1 - IFCONFIG_LIST=ifconfig - MODULE_STAT=lsmod - WAN_DRIVERS="wanpipe" - MODULE_LOAD=modprobe - MODULE_UNLOAD="modprobe -r" - MODULE_EXT=".*" - DEPMOD=YES - - check_command_exist modprobe - if [ $? -ne 0 ]; then - check_command_exist insmod - if [ $? -eq 0 ]; then - DEPMOD=NO - MODULE_LOAD=insmod - MODULE_UNLOAD=rmmod - fi - fi - - MOD1=/lib/modules/sdladrv - MOD2=/lib/modules/wanrouter - MOD3=/lib/modules/wanpipe_syncppp - MOD4=/lib/modules/wanpipe - MOD5=/lib/modules/af_wanpipe - - if [ -d /lib/modules/$(uname -r) ]; then - uname -r | grep "^2.4.*" > /dev/null - if [ $? -eq 0 ]; then - if [ -d /lib/modules/$(uname -r)/kernel ]; then - MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv - MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter - MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp - MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe - MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe - - MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb - MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 - MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp - MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip - MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec - fi - else - - uname -r | grep "^2.6.*" > /dev/null - if [ $? -eq 0 ]; then - if [ -d /lib/modules/$(uname -r)/kernel ]; then - MOD1=/lib/modules/$(uname -r)/kernel/drivers/net/wan/sdladrv - MOD2=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanrouter - MOD3=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_syncppp - MOD4=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe - MOD5=/lib/modules/$(uname -r)/kernel/net/wanrouter/af_wanpipe - - MOD6=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_lapb - MOD7=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_x25 - MOD8=/lib/modules/$(uname -r)/kernel/drivers/net/wan/wanpipe_dsp - MOD9=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanpipe_lip - MOD10=/lib/modules/$(uname -r)/kernel/net/wanrouter/wanec - fi - else - if [ -d /lib/modules/$(uname -r)/net ]; then - MOD1=/lib/modules/$(uname -r)/net/sdladrv - MOD2=/lib/modules/$(uname -r)/misc/wanrouter - MOD3=/lib/modules/$(uname -r)/net/wanpipe_syncppp - MOD4=/lib/modules/$(uname -r)/net/wanpipe - MOD5=/lib/modules/$(uname -r)/misc/af_wanpipe - - MOD6=/lib/modules/$(uname -r)/net/wanpipe_lapb - MOD7=/lib/modules/$(uname -r)/net/wanpipe_x25 - MOD8=/lib/modules/$(uname -r)/net/wanpipe_dsp - MOD9=/lib/modules/$(uname -r)/misc/wanpipe_lip - MOD10=/lib/modules/$(uname -r)/misc/wanec - fi - fi - fi - fi - - MODULES="$MOD1 $MOD2 $MOD3 $MOD4 $MOD5" - OPT_MODULES="$MOD3 $MOD5" - UMODULES="af_wanpipe wanpipe wanpipe_syncppp wanrouter sdladrv" - -elif [ $OSYSTEM = "FreeBSD" ]; then - - SYSCTL=/sbin/sysctl - AWK=/usr/bin/awk - PKGINFO=/usr/sbin/pkg_info - major_ver=${RELEASE%%.*} - ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` - IFCONFIG_LIST=ifconfig - CDEV_WANROUTER=/dev/$SCRIPT - CDEV_MAJOR=139 - CDEV_MINOR=0 - MODULE_STAT=kldstat - MODULE_LOAD=kldload - MODULE_UNLOAD=kldunload - MODULE_EXT=".*" - - if [ "$major_ver" = "5" -o "$major_ver" = "6" ]; then - MODULE_DIR=/boot/modules - else - MODULE_DIR=/modules - fi - MOD9="$MODULE_DIR/wanpipe_lip" - MOD10="$MODULE_DIR/wanec" - MODULES="$MODULE_DIR/wanrouter $MODULE_DIR/sdladrv $MODULE_DIR/wanpipe" - WAN_DRIVERS="wanpipe" - -elif [ $OSYSTEM = "OpenBSD" ]; then - - SYSCTL=/sbin/sysctl - AWK=/usr/bin/awk - PKGINFO=/usr/sbin/pkg_info - SECURELEVEL=`$SYSCTL -n kern.securelevel` - ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` - IFCONFIG_LIST="ifconfig -a" - CDEV_WANROUTER=/dev/$SCRIPT - CDEV_MAJOR=139 - CDEV_MINOR=0 - POSTINSTALL=create_cdev - MODULE_STAT=modstat - MODULE_LOAD=modload - MODULE_UNLOAD=modunload - MODULE_DIR=/usr/lkm - MODULE_EXT=".o" - MODULES="$MODULE_DIR/wanpipe" - WAN_DRIVERS="wanpipe" -elif [ $OSYSTEM = "NetBSD" ]; then - - SYSCTL=/sbin/sysctl - AWK=/usr/bin/awk - PKGINFO=/usr/sbin/pkg_info - SECURELEVEL=`$SYSCTL -n kern.securelevel` - ROUTER_VERSION=`$PKGINFO | $AWK '$1~/wanpipe/ {$1=""; print }'` - IFCONFIG_LIST="ifconfig -a" - CDEV_WANROUTER=/dev/$SCRIPT - CDEV_MAJOR=139 - CDEV_MINOR=0 - POSTINSTALL=create_cdev - MODULE_STAT=modstat - MODULE_LOAD=modload - MODULE_UNLOAD=modunload - MODULE_DIR=/usr/lkm - MODULE_EXT=".o" - MODULES="$MODULE_DIR/wanpipe" - WAN_DRIVERS="wanpipe" -fi - -check_bash -check_awk - - -# Return code -RC=$(pwd)/return_code -GET_RC="cat $RC" -FT1_CONF=ft1.conf - -# Ignore interrupt signals. -trap '' 2 - -init_meta_conf -read_meta_conf -if [ $? -ne 0 ]; then - echo "$SCRIPT: Error: $META_CONF not found!" - exit 1; -fi - -if [ "$WANPIPE_CONF_DIR" != "" -a "$WAN_CONF_DIR" = "" ] || [ "$WAN_ADSL_LIST" = "" ]; then - meta_conf_compatiblity -fi - -WAN_LIP_LOAD=YES -WANEC_LOAD=YES -WAN_ANNEXG_LOAD=${WAN_ANNEXG_LOAD:-NO} -WAN_DYN_WANCONFIG=${WAN_DYN_WANCONFIG:-NO} -NEW_IF_TYPE=${NEW_IF_TYPE:-NO} -WAN_INTR_DIR=$WAN_INTR_DIR -LINUX_DISTR=unknown - - -if [ -f $WAN_PROG_LOCK ]; then - echo -e "\nERROR: wanrouter script already running!\n"; - cleanup 0; -fi - -touch $WAN_PROG_LOCK - -check_osystem - -#Check osystem confirms the WAN_LOCK directory -WAN_LOCK=$WAN_LOCK_DIR/wanrouter - - -if [ ! -f $WAN_ADSL_LIST ]; then - generate_adsl_list -fi - -if [ $OSYSTEM = "Linux" ]; then - eval "grep \"Debian\" -i /etc/issue > /dev/null" - if [ $? -eq 0 ]; then - LINUX_DISTR=debian - fi - eval "grep \"Red *Hat\" -i /etc/issue > /dev/null" - if [ $? -eq 0 ]; then - LINUX_DISTR=redhat - fi - eval "grep \"Mandrake\" -i /etc/issue > /dev/null" - if [ $? -eq 0 ]; then - LINUX_DISTR=redhat - fi - - if [ "$WAN_DYN_WANCONFIG" = "YES" ]; then - if [ ! -e "/etc/wanpipe/wanconfig_socket" ]; then - echo "Starting wanconfig dameon" - eval "/usr/sbin/wanconfig -x >> $WAN_LOG 2>> $WAN_LOG &" - if [ $? -ne 0 ]; then - echo "Failed to start wanconfig daemon!" - cleanup 0; - fi - else - if [ ! -e "/var/run/wanconfig.pid" ]; then - echo "Starting wanconfig dameon" - \rm -f /etc/wanpipe/wanconfig_socket - eval "/usr/sbin/wanconfig -x >> $WAN_LOG 2>> $WAN_LOG &" - if [ $? -ne 0 ]; then - echo "Failed to start wanconfig daemon!" - cleanup 0; - fi - else - kill -USR1 $(cat /var/run/wanconfig.pid) >> /dev/null 2>> /dev/null - if [ $? -ne 0 ]; then - echo "Starting wanconfig dameon" - \rm -f /etc/wanpipe/wanconfig_socket - eval "/usr/sbin/wanconfig -x >> $WAN_LOG 2>> $WAN_LOG &" - if [ $? -ne 0 ]; then - echo "Failed to start wanconfig daemon!" - cleanup 0; - fi - fi - fi - fi - else - if [ -e "/etc/wanpipe/wanconfig_socket" ]; then - if [ -f /var/run/wanconfig.pid ]; then - eval "kill -TERM $(cat /var/run/wanconfig.pid)" - echo "Killing wanconfig daemon" - fi - fi - fi -fi - - -echo -# If modules doesn't loaded remove all lock file from WAN_LOCK_DIR. -check_module - -ft1_or_wanpipe=0 -# See how we were called. -case "$1" in - start) - - # WANROUTER START - if [ -z $2 ]; then - - check_config || cleanup 1 - - load_module - if [ $? -ne 0 ]; then - cleanup 2 - fi - - config_devices $WAN_DEVICES - - config_interfaces $WAN_DEVICES - - wanrouter_script start - - elif [ -z $3 ]; then - #ROUTER START WANPIPE - - [ -f $WAN_CONF_DIR/$FT1_CONF ] && rm -f $WAN_CONF_DIR/$FT1_CONF - dev=$2 - - #Parse the dev name, and if it starts with - #ft1 than it means we should load the ft1 - #driver. - check_config_opt $dev 0 - ft1_or_wanpipe=$? - dev=$($GET_RC) - rm -f $RC - - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - check_file $WAN_CONF || cleanup 1 - - load_module - if [ $? -ne 0 ]; then - cleanup 2 - fi - - #If we are starting FT1 driver, we have to check - #wether the actual wanpipe# device is running or - #not, thus name dev has to be changed to 'wanpipe#' - if [ $ft1_or_wanpipe -gt 0 ]; then - dev="wanpipe$ft1_or_wanpipe" - fi - - config_devices $dev - if [ $? -ne 0 ]; then - cleanup 3 - fi - - #When loading ft1 device there are not interfaces - if [ $ft1_or_wanpipe -eq 0 ]; then - config_interfaces $dev - if [ $? -ne 0 ]; then - cleanup 4 - fi - fi - - else - #ROUTER START WANPIPE INTERFACE - - if [ $OSYSTEM != "Linux" ]; then - echo " This option doesn't supported yet!" - cleanup 0 - fi - dev=$2 - if_name=$3 - - #Parse the dev name, and if it starts with - #ft1 than it means we should load the ft1 - #driver. - check_config_opt $dev 0 - ft1_or_wanpipe=$? - dev=$($GET_RC) - rm -f $RC - - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - check_file $WAN_CONF || cleanup 1 - - load_module - if [ $? -ne 0 ]; then - cleanup 2 - fi - - eval "$IFCONFIG_LIST | grep -w $if_name > /dev/null 2> /dev/null" - if [ $? -eq 0 ]; then - echo -e "\nInterface $if_name is already up!\n" - cleanup 1 - fi - - echo "Configuring interface: $if_name" - - if [ "$WAN_DYN_WANCONFIG" = YES ]; then - eval "/usr/sbin/wanconfig_client cmd=start,card=$dev,dev=$if_name" - else - eval "/usr/sbin/wanconfig -v card $dev dev $if_name up >> $WAN_LOG" - fi - - - #Regardles of config try to bring up the interface - #Interface up command will fail on its own - #if [ $? -ne 0 ]; then - # cleanup 1 - #fi - - interface_up $if_name - if [ $? -ne 0 ]; then - echo -e "\nInterface $if_name start error: ip setup failure!\n" - cleanup 1 - else - echo "Interface $if_name up." - fi - - wanrouter_script start $dev $if_name - fi - ;; - stop) - - #WANROUTER STOP - if [ -z $2 ]; then - - check_module - if [ $? -ne 0 ]; then - unload_module - remove_cdev - echo -e "Router is already stopped !\n" - cleanup 1 - fi - - #Check that all wanpipe#.conf file defined in - # WAN_DEVICES exist - check_config || { - unload_module - remove_cdev - echo -e "No devices running, Unloading Modules" - cleanup 1 - } - - if [ "$WAN_DEVICES_REV_STOP_ORDER" = "YES" ]; then - tmp_dev_list= - for dev in $WAN_DEVICES; do - tmp_dev_list="$dev ""$tmp_dev_list" - done - WAN_DEVICES=$tmp_dev_list - fi - - unconfig_interfaces $WAN_DEVICES - - unconfig_devices $WAN_DEVICES - - wanrouter_script stop - - elif [ -z $3 ]; then - #WANROUTER STOP WANPIPE - - dev=$2 - - if [ "$dev" = "all" ]; then - stop_running_wanpipes - cleanup 0 - fi - - check_config_opt $dev 1 - ft1_or_wanpipe=$? - dev=$($GET_RC) - rm -f $RC - - #Check that modules are up and running - check_module - if [ $? -ne 0 ]; then - unload_module - echo -e "Router is already stopped !\n"; - cleanup 1; - fi - - #If we are stopping FT1 driver, we have to check - #whether the actual wanpipe# device is running or - #not, thus name dev has to be changed to 'wanpipe#' - if [ $ft1_or_wanpipe -gt 0 ]; then - dev="wanpipe$ft1_or_wanpipe" - fi - - if [ $ft1_or_wanpipe -eq 0 ]; then - unconfig_interfaces $dev - fi - - unconfig_devices $dev - - [ -f $WAN_CONF_DIR/$FT1_CONF ] && rm -f $WAN_CONF_DIR/$FT1_CONF - - else - if [ $OSYSTEM != "Linux" ]; then - echo " This option doesn't supported yet!" - cleanup 0 - fi - dev=$2 - if_name=$3 - - #Parse the dev name, and if it starts with - #ft1 than it means we should load the ft1 - #driver. - check_config_opt $dev 0 - ft1_or_wanpipe=$? - dev=$($GET_RC) - rm -f $RC - - WAN_CONF=$WAN_CONF_DIR/$dev.conf - - check_file $WAN_CONF || cleanup 1 - - eval "$IFCONFIG_LIST | grep -w $if_name > /dev/null 2> /dev/null" - if [ $? -eq 0 ]; then - echo "Interface $if_name down" - eval "ifconfig $if_name down" - fi - - echo "Unconfiguring interface: $if_name" - if [ "$WAN_DYN_WANCONFIG" = YES ]; then - eval "/usr/sbin/wanconfig_client cmd=stop,card=$dev,dev=$if_name" - else - eval "/usr/sbin/wanconfig -v card $dev dev $if_name down >> $WAN_LOG" - fi - if [ $? -ne 0 ]; then - cleanup 1 - fi - - check_and_print_still_running && cleanup 0 - - cd $WAN_HOME - echo -e "No devices running, Unloading Modules" - unload_module - - wanrouter_script stop $dev $if_name - fi - ;; - - start_dev) - - if [ -z $2 ]; then - # WANROUTER START_DEV - - check_config || cleanup 1 - - load_module - if [ $? -ne 0 ]; then - cleanup 2 - fi - - config_devices $WAN_DEVICES - - elif [ -z $3 ]; then - #ROUTER START_DEV WANPIPE - - dev=$2 - - load_module - if [ $? -ne 0 ]; then - cleanup 2 - fi - - config_devices $dev - if [ $? -ne 0 ]; then - cleanup 3 - fi - fi - ;; - - stop_dev) - - if [ -z $2 ]; then - #WANROUTER STOP_DEV - - check_module - if [ $? -ne 0 ]; then - unload_module - remove_cdev - echo -e "Router is already stopped !\n" - cleanup 1 - fi - - #Check that all wanpipe#.conf file defined in - # WAN_DEVICES exist - check_config || { - unload_module - remove_cdev - echo -e "No devices running, Unloading Modules" - cleanup 1 - } - - if [ "$WAN_DEVICES_REV_STOP_ORDER" = "YES" ]; then - tmp_dev_list= - for dev in $WAN_DEVICES; do - tmp_dev_list="$dev ""$tmp_dev_list" - done - WAN_DEVICES=$tmp_dev_list - fi - - unconfig_devices $WAN_DEVICES - - wanrouter_script stop - - elif [ -z $3 ]; then - #WANROUTER STOP_DEV WANPIPE - - dev=$2 - - if [ "$dev" = "all" ]; then - stop_running_wanpipes - cleanup 0 - fi - - #Check that modules are up and running - check_module - if [ $? -ne 0 ]; then - unload_module - echo -e "Router is already stopped !\n"; - cleanup 1; - fi - - unconfig_devices $dev - fi - ;; - - start_ip) - - if [ -z $2 ]; then - # WANROUTER START_IP - check_config || cleanup 1 - - config_interfaces $WAN_DEVICES - - wanrouter_script start - - elif [ -z $3 ]; then - #ROUTER START_IP WANPIPE - config_interfaces $2 - fi - ;; - - stop_ip) - - if [ -z $2 ]; then - #WANROUTER STOP_IP - unconfig_interfaces $WAN_DEVICES - - elif [ -z $3 ]; then - #WANROUTER STOP_IP WANPIPE - unconfig_interfaces $2 - fi - ;; - - script) - - #Debug Statement, used to test the script option - #echo "WAN_ACTION=$WAN_ACTION WAN_DEVICE=$WAN_DEVICE WAN_INTERFACE=$WAN_INTERFACE" >> /var/log/messages - - #wanrouter script - if [ ! -z $WAN_ACTION ]; then - if [ ! -z $WAN_INTERFACE ]; then - wanrouter_script $WAN_ACTION $WAN_DEVICE $WAN_INTERFACE - elif [ ! -z $WAN_DEVICE ]; then - wanrouter_script $WAN_ACTION $WAN_DEVICE - else - wanrouter_script $WAN_ACTION - fi - fi - ;; - - list) - - check_module - if [ $? -ne 0 ]; then - echo -e "Router is stopped !\n"; - cleanup 0; - fi - - print_active_devices 1; - cleanup 0; - ;; - - restart) - eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" - if [ "$2" = "" ]; then - $0 stop; - $0 start; - elif [ "$3" = "" ]; then - $0 stop $2; - $0 start $2; - else - $0 stop $2 $3; - $0 start $2 $3; - fi - cleanup 0; - ;; - - restart_dev) - eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" - if [ "$2" = "" ]; then - $0 stop_dev; - $0 start_dev; - elif [ "$3" = "" ]; then - $0 stop_dev $2; - $0 start_dev $2; - fi - cleanup 0; - ;; - - restart_ip) - eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" - if [ "$2" = "" ]; then - $0 stop_ip; - $0 start_ip; - elif [ "$3" = "" ]; then - $0 stop_ip $2; - $0 start_ip $2; - fi - cleanup 0; - ;; - - modules) - - if [ $OSYSTEM = "Linux" ]; then - cat /proc/modules | grep wan; - else - $MODULE_STAT | grep -i "wan\|sdla"; - #$MODULE_STAT | grep sdla; - fi - cleanup 0; - - ;; - status) - - check_module - if [ $? -ne 0 ]; then - echo -e "Router is stopped !\n"; - cleanup 0; - fi - - print_active_devices 1; - print_wanpipe_config - print_wanrouter_status - echo "" - - cleanup 0; - ;; - - - summary) - print_config_summary; - cleanup 0; - ;; - - hwprobe) - load_module silent - if [ $? -ne 0 ]; then - cleanup 1 - fi - if [ "$2" = "verbose" ]; then - if [ $OSYSTEM = "Linux" ]; then - cat /proc/net/wanrouter/hwprobe_verbose - else - wanconfig hwprobe verbose - fi - else - if [ $OSYSTEM = "Linux" ]; then - cat /proc/net/wanrouter/hwprobe - else - wanconfig hwprobe - fi - fi - cleanup 0; - ;; - - debug) - if [ -z $2 ]; then - wanrouter_debug; - else - wanrouter_if_debug $2; - fi - cleanup 0; - ;; - - wanrc) - - config_wanrouter_rc - cleanup 0; - ;; - - messages) - echo - echo "Start WANPIPE /var/log/messages" - echo - if [ $OSYSTEM = "Linux" ]; then - eval "tail -n 200 /var/log/messages | grep -i \"[wanpipe|sdladrv]\" " - else - eval "tail -n 200 /var/log/messages | grep -i \"wanpipe\|sdladrv\" " - fi - echo - echo "End of WANPIPE /var/log/messages" - echo - cleanup 0; - ;; - - conflog) - echo - echo "Start WANPIPE $WAN_LOG" - echo - eval "cat $WAN_LOG" - echo - echo "End of WANPIPE $WAN_LOG" - echo - cleanup 0; - ;; - - version) - echo "WANPIPE Release: $ROUTER_VERSION" - ;; - - lineprobe) - if [ $OSYSTEM != "Linux" ]; then - echo -e "The 'lineprobe' option supported on Linux OS only.\n" - cleanup 1; - fi - - echo -e "Starting the lineprobe ...\n" - - #The lineprobe calls wanrouter internally. - #This instance of wanrouter will prevent the other from starting. - #Remove the lock. - eval "rm -f $WAN_PROG_LOCK 2> /dev/null > /dev/null" - - #Remove name of the program from command line. - shift 1 - #Pass rest of the arguments to lineprobe. - if [ -e $LINEPROBE_PATH ]; then - eval "lineprobe" "$@" - else - echo -e "File $LINEPROBE_PATH does not exist!" - echo -e "Please check 'lineprobe' was successfully compiled.\n" - fi - - ;; - - *) echo -e "\nWANPIPE: WAN Router startup script\n" - echo -e "Usage: $SCRIPT: {options} \n" - - echo -e " wanrouter start : Starts all devices specified in" - echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" - echo -e " wanrouter stop : Stops all devices specified in" - echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" - echo -e " wanrouter start wanpipe# : Start a single device\n" - echo -e " wanrouter stop wanpipe# : Stops a single device" - echo -e " (# can range from 1 to 16)\n" - if [ $OSYSTEM = "Linux" ]; then - echo -e " wanrouter start wanpipe# if_name : Start a single interface on device\n" - echo -e " wanrouter stop wanpipe# if_name : Stops a single interface on device" - echo -e " (# can range from 1 to 16)\n" - - fi - echo -e " wanrouter restart : Restart all devices specified in" - echo -e " $WAN_CONF_DIR/wanrouter.rc WAN_DEVICES\n" - echo -e " wanrouter restart wanpipe# : Restart a single device" - echo -e " (# can range from 1 to 16)\n" - echo - if [ $OSYSTEM = "Linux" ]; then - echo -e " wanrouter restart wanpipe# if_name : Restart a single interface on device" - echo -e " (# can range from 1 to 16)\n" - echo - fi - echo -e " wanrouter list : List all active devices\n" - echo -e " wanrouter modules : Show wanpipe kernel modules\n" - echo -e " wanrouter status : Display status for all active devices\n" - echo -e " wanrouter summary : Summary of config files in $WAN_HOME\n" - echo -e " wanrouter hwprobe : Display wanpipe hardware probe info.\n" - echo -e " wanrouter debug : Check current wanpipe environment." - echo -e " After a startup error run this command to" - echo -e " get a possible solution" - echo -e " i.e. wanrouter start; wanrouter debug;\n" - if [ $OSYSTEM = "Linux" ]; then - echo -e " wanrouter debug if_name : Display common debugging statistics" - echo -e " In case of line problems save to file," - echo -e " wait 2-5mi and send to Sangoma Tech Support" - echo -e " i.e. wanrouter debug wp1fr16 > debug_file;\n" - fi - echo -e " wanrouter messages : Display wanpipe kernel event messages" - echo -e " i.e. /var/log/messages\n" - echo -e " wanrouter conflog : Display wanpipe configuration parsing messages" - echo -e " i.e. $WAN_LOG\n" - echo -e " wanrouter wanrc : Configure the wanpipe boot startup order" - echo -e " in $META_CONF\n" - echo -e " wanrouter version : wanpipe version information.\n" - - if [ $OSYSTEM = "Linux" ]; then - echo -e " wanrouter lineprobe [-c wanpipe#] [options] " - echo -e " : Monitor/Debug a line connected to an" - echo -e " automatically detected or preconfigured card." - echo -e " i.e.: wanrouter lineprobe; or" - echo -e " : wanrouter lineprobe -c wanpipe1;" - echo -e " Type 'wanrouter lineprobe -help' to get the" - echo -e " list of 'lineprobe' options." - fi - cleanup 0 - ;; -esac -echo -cleanup 0 -exit 0 diff --git a/ssmg/sangoma_bri/Makefile b/ssmg/sangoma_bri/Makefile new file mode 100644 index 0000000..7f4df7d --- /dev/null +++ b/ssmg/sangoma_bri/Makefile @@ -0,0 +1,22 @@ + +INSTALLPREFIX= +ifndef ARCH + ARCH=$(shell uname -m) +endif + +SANGOMA_BRID=sangoma_brid.i686 +ifeq ($(ARCH),x86_64) + SANGOMA_BRID=sangoma_brid.x86_64 +endif +all: + +install: + install -D smg_ctrl $(INSTALLPREFIX)/usr/sbin/smg_ctrl + install -D $(SANGOMA_BRID) $(INSTALLPREFIX)/usr/sbin/sangoma_brid + + @echo + @echo "Sangoma BRI Install Done" + @echo "Run: /usr/sbin/wancfg_smg to configure wanpipe BRI" + @echo + + diff --git a/ssmg/sangoma_bri/install.sh b/ssmg/sangoma_bri/install.sh new file mode 100755 index 0000000..7c1a522 --- /dev/null +++ b/ssmg/sangoma_bri/install.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +home=$(pwd) +arch=`uname -m` + +echo "Installing Sangoma BRI Daemon for $arch" +case $arch in + i686) + install -D sangoma_brid.i686 /usr/sbin/sangoma_brid + ;; + x86_64) + install -D sangoma_brid.x86_64 /usr/sbin/sangoma_brid + ;; + *) + echo "Unsupported architecture $arch" + exit 1 + ;; +esac + +echo "Sangoma BRI Install Done" +echo +echo "Run: wancfg_smg to configure wanpipe BRI" +echo diff --git a/ssmg/sangoma_bri/sangoma_brid.i686 b/ssmg/sangoma_bri/sangoma_brid.i686 new file mode 100755 index 0000000000000000000000000000000000000000..7d41862b0bcbd939123df5dbe015efb35cf4df82 GIT binary patch literal 464184 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

    #S^n-}WitUS*${QD<>3eM&2AvB(l-9Vz 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�ZM#!cL7(#Wx6s>V;K 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 diff --git a/patches/kdrivers/src/wanrouter/.af_wanpipe_src.o.d b/patches/kdrivers/src/wanrouter/.af_wanpipe_src.o.d new file mode 100644 index 0000000..fdb8fcd --- /dev/null +++ b/patches/kdrivers/src/wanrouter/.af_wanpipe_src.o.d @@ -0,0 +1,186 @@ +af_wanpipe_src.o: \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/src/net/../wanrouter/af_wanpipe_src.c \ + include/linux/autoconf.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_includes.h \ + include/linux/init.h include/linux/compiler.h \ + include/linux/compiler-gcc4.h include/linux/compiler-gcc.h \ + include/linux/version.h include/linux/module.h include/linux/list.h \ + include/linux/stddef.h include/linux/poison.h include/linux/prefetch.h \ + include/linux/types.h include/linux/posix_types.h \ + include/asm/posix_types.h include/asm/posix_types_32.h \ + include/asm/types.h include/asm/processor.h include/asm/processor_32.h \ + include/asm/vm86.h include/asm/ptrace.h include/asm/ptrace-abi.h \ + include/asm/segment.h include/asm/segment_32.h include/asm/math_emu.h \ + include/asm/sigcontext.h include/asm/page.h include/asm/page_32.h \ + include/asm-generic/pgtable-nopmd.h include/asm-generic/pgtable-nopud.h \ + include/asm-generic/memory_model.h include/asm-generic/page.h \ + include/asm/cpufeature.h include/asm/cpufeature_32.h \ + include/linux/bitops.h include/asm/bitops.h include/asm/bitops_32.h \ + include/asm/alternative.h include/asm/alternative_32.h \ + include/asm-generic/bitops/sched.h include/asm-generic/bitops/hweight.h \ + include/asm-generic/bitops/fls64.h \ + include/asm-generic/bitops/ext2-non-atomic.h \ + include/asm-generic/bitops/le.h include/asm/byteorder.h \ + include/linux/byteorder/little_endian.h include/linux/byteorder/swab.h \ + include/linux/byteorder/generic.h include/asm-generic/bitops/minix.h \ + include/asm/required-features.h include/asm/msr.h \ + include/asm/msr-index.h include/asm/errno.h include/asm-generic/errno.h \ + include/asm-generic/errno-base.h include/linux/errno.h \ + include/asm/system.h include/asm/system_32.h include/linux/kernel.h \ + /usr/lib/gcc/i386-redhat-linux/4.1.1/include/stdarg.h \ + include/linux/linkage.h include/asm/linkage.h include/asm/linkage_32.h \ + include/linux/log2.h include/asm/bug.h include/asm-generic/bug.h \ + include/asm/div64.h include/asm/cmpxchg.h include/asm/cmpxchg_32.h \ + include/linux/irqflags.h include/asm/irqflags.h \ + include/asm/irqflags_32.h include/asm/processor-flags.h \ + include/linux/cache.h include/asm/cache.h include/linux/threads.h \ + include/asm/percpu.h include/asm/percpu_32.h include/linux/cpumask.h \ + include/linux/bitmap.h include/linux/string.h include/asm/string.h \ + include/asm/string_32.h include/linux/stat.h include/asm/stat.h \ + include/linux/time.h include/linux/seqlock.h include/linux/spinlock.h \ + include/linux/preempt.h include/linux/thread_info.h \ + include/asm/thread_info.h include/asm/thread_info_32.h \ + include/linux/stringify.h include/linux/bottom_half.h \ + include/linux/spinlock_types.h include/asm/spinlock_types.h \ + include/linux/lockdep.h include/asm/spinlock.h \ + include/asm/spinlock_32.h include/asm/atomic.h include/asm/atomic_32.h \ + include/asm-generic/atomic.h include/asm/rwlock.h \ + include/linux/spinlock_api_smp.h include/linux/kmod.h \ + include/linux/elf.h include/linux/elf-em.h include/asm/elf.h \ + include/asm/user.h include/asm/user_32.h include/asm/auxvec.h \ + include/asm/desc.h include/asm/desc_32.h include/asm/ldt.h \ + include/linux/smp.h include/asm/smp.h include/asm/smp_32.h \ + include/asm/mpspec.h include/asm/mpspec_32.h include/asm/mpspec_def.h \ + include/asm-x86/mach-generic/mach_mpspec.h include/asm/apic.h \ + include/asm/apic_32.h include/linux/pm.h include/linux/delay.h \ + include/asm/delay.h include/asm/fixmap.h include/asm/fixmap_32.h \ + include/asm/acpi.h include/asm/acpi_32.h include/acpi/pdc_intel.h \ + include/asm/apicdef.h include/asm/apicdef_32.h include/asm/kmap_types.h \ + include/asm/io_apic.h include/asm/io_apic_32.h \ + include/asm-x86/mach-generic/mach_apicdef.h include/asm/genapic.h \ + include/asm/genapic_32.h include/linux/percpu.h include/linux/slab.h \ + include/linux/gfp.h include/linux/mmzone.h include/linux/wait.h \ + include/asm/current.h include/asm/current_32.h include/linux/numa.h \ + include/linux/nodemask.h include/linux/pageblock-flags.h \ + include/linux/memory_hotplug.h include/linux/notifier.h \ + include/linux/mutex.h include/linux/rwsem.h include/asm/rwsem.h \ + include/linux/srcu.h include/linux/topology.h include/asm/topology.h \ + include/asm/topology_32.h include/asm-generic/topology.h \ + include/linux/slub_def.h include/linux/workqueue.h \ + include/linux/timer.h include/linux/ktime.h include/linux/jiffies.h \ + include/linux/calc64.h include/linux/timex.h include/asm/param.h \ + include/asm/timex.h include/asm/tsc.h include/linux/kobject.h \ + include/linux/sysfs.h include/linux/kref.h include/asm/mmu.h \ + include/linux/moduleparam.h include/linux/marker.h include/asm/local.h \ + include/asm/local_32.h include/asm/module.h include/asm/module_32.h \ + include/linux/sched.h include/linux/capability.h include/linux/rbtree.h \ + include/linux/mm_types.h include/linux/auxvec.h \ + include/linux/prio_tree.h include/linux/completion.h \ + include/asm/semaphore.h include/asm/semaphore_32.h \ + include/asm/cputime.h include/asm-generic/cputime.h include/linux/sem.h \ + include/linux/ipc.h include/asm/ipcbuf.h include/asm/sembuf.h \ + include/linux/signal.h include/asm/signal.h \ + include/asm-generic/signal.h include/asm/siginfo.h \ + include/asm-generic/siginfo.h include/linux/securebits.h \ + include/linux/fs_struct.h include/linux/pid.h include/linux/rcupdate.h \ + include/linux/proportions.h include/linux/percpu_counter.h \ + include/linux/seccomp.h include/asm/seccomp.h include/asm/seccomp_32.h \ + include/linux/unistd.h include/asm/unistd.h include/asm/unistd_32.h \ + include/linux/futex.h include/linux/rtmutex.h include/linux/plist.h \ + include/linux/param.h include/linux/resource.h include/asm/resource.h \ + include/asm-generic/resource.h include/linux/hrtimer.h \ + include/linux/task_io_accounting.h include/linux/aio.h \ + include/linux/aio_abi.h include/linux/uio.h include/linux/mm.h \ + include/linux/debug_locks.h include/linux/security.h include/linux/fs.h \ + include/linux/limits.h include/linux/ioctl.h include/asm/ioctl.h \ + include/asm-generic/ioctl.h include/linux/kdev_t.h \ + include/linux/dcache.h include/linux/namei.h include/linux/radix-tree.h \ + include/linux/quota.h include/linux/dqblk_xfs.h \ + include/linux/dqblk_v1.h include/linux/dqblk_v2.h \ + include/linux/nfs_fs_i.h include/linux/nfs.h \ + include/linux/sunrpc/msg_prot.h include/linux/fcntl.h \ + include/asm/fcntl.h include/asm-generic/fcntl.h include/linux/err.h \ + include/linux/binfmts.h include/linux/shm.h include/asm/shmparam.h \ + include/asm/shmbuf.h include/linux/msg.h include/asm/msgbuf.h \ + include/linux/key.h include/linux/xfrm.h include/net/flow.h \ + include/linux/in6.h include/asm/pgtable.h include/asm/pgtable_32.h \ + include/asm/paravirt.h include/asm/pgtable-2level-defs.h \ + include/asm/pgtable-2level.h include/asm-generic/pgtable.h \ + include/linux/page-flags.h include/linux/vmstat.h include/linux/ctype.h \ + include/net/ip.h include/linux/ip.h include/linux/skbuff.h \ + include/linux/net.h include/asm/socket.h include/asm/sockios.h \ + include/linux/random.h include/linux/sysctl.h \ + include/linux/textsearch.h include/net/checksum.h include/asm/uaccess.h \ + include/asm/uaccess_32.h include/asm/checksum.h \ + include/asm/checksum_32.h include/linux/dmaengine.h \ + include/linux/device.h include/linux/ioport.h include/linux/klist.h \ + include/asm/device.h include/linux/dma-mapping.h \ + include/asm/dma-mapping.h include/asm/dma-mapping_32.h \ + include/linux/scatterlist.h include/asm/scatterlist.h \ + include/asm/scatterlist_32.h include/asm/io.h include/asm/io_32.h \ + include/asm-generic/iomap.h include/linux/vmalloc.h include/linux/in.h \ + include/linux/socket.h include/linux/sockios.h include/net/inet_sock.h \ + include/linux/jhash.h include/net/sock.h include/linux/netdevice.h \ + include/linux/if.h include/linux/hdlc/ioctl.h include/linux/if_ether.h \ + include/linux/if_packet.h include/net/net_namespace.h \ + include/linux/interrupt.h include/linux/irqreturn.h \ + include/linux/hardirq.h include/linux/smp_lock.h include/asm/hardirq.h \ + include/asm/hardirq_32.h include/linux/irq.h include/asm/irq.h \ + include/asm/irq_32.h include/asm-x86/mach-default/irq_vectors.h \ + include/asm-x86/mach-default/irq_vectors_limits.h \ + include/asm/irq_regs.h include/asm/irq_regs_32.h include/asm/hw_irq.h \ + include/asm/hw_irq_32.h include/linux/profile.h include/asm/sections.h \ + include/asm-generic/sections.h include/linux/irq_cpustat.h \ + include/linux/filter.h include/net/dst.h include/linux/rtnetlink.h \ + include/linux/netlink.h include/linux/if_link.h include/linux/if_addr.h \ + include/linux/neighbour.h include/net/neighbour.h \ + include/linux/seq_file.h include/net/rtnetlink.h include/net/netlink.h \ + include/net/request_sock.h include/net/route.h include/net/inetpeer.h \ + include/linux/in_route.h include/linux/route.h include/net/snmp.h \ + include/linux/snmp.h include/linux/ipv6.h include/linux/icmpv6.h \ + include/linux/tcp.h include/net/inet_connection_sock.h \ + include/linux/poll.h include/asm/poll.h include/asm-generic/poll.h \ + include/net/inet_timewait_sock.h include/net/tcp_states.h \ + include/net/timewait_sock.h include/linux/udp.h include/net/protocol.h \ + include/linux/wireless.h include/linux/inet.h include/linux/pci.h \ + include/linux/pci_regs.h include/linux/mod_devicetable.h \ + include/linux/pci_ids.h include/linux/dmapool.h include/asm/pci.h \ + include/asm/pci_32.h include/asm-generic/pci-dma-compat.h \ + include/asm-generic/pci.h include/linux/if_arp.h \ + include/linux/pkt_sched.h include/linux/etherdevice.h \ + include/linux/inetdevice.h include/net/inet_common.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_defines.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_version.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_kernel.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_abstr_types.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_debug.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_common.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_events.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_cfg.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_56k.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_te1.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_te3.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_remora.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_remora_proslic.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_bri.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/xhfc24succ.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_serial.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_front_end.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanrouter.h \ + include/linux/proc_fs.h include/linux/magic.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdla_tdmv.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdlasfm.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/sdladrv.h \ + include/linux/serial.h include/linux/serialP.h include/linux/termios.h \ + include/asm/termios.h include/asm/termbits.h include/asm/ioctls.h \ + include/linux/circ_buf.h include/linux/serial_reg.h \ + include/asm/serial.h include/linux/tty.h include/linux/major.h \ + include/linux/tty_driver.h include/linux/cdev.h \ + include/linux/tty_ldisc.h include/linux/tty_flip.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/if_wanpipe_kernel.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/if_wanpipe.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/if_wanpipe_common.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_x25_kernel.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_dsp_kernel.h \ + /root/development/3.3/wanpipe-3.3.2.p16/patches/kdrivers/include/linux/wanpipe_x25_kernel.h diff --git a/patches/kdrivers/src/wanrouter/af_wanpipe.c b/patches/kdrivers/src/wanrouter/af_wanpipe.c index 0ec28ae..f1803f6 100644 --- a/patches/kdrivers/src/wanrouter/af_wanpipe.c +++ b/patches/kdrivers/src/wanrouter/af_wanpipe.c @@ -142,7 +142,7 @@ static atomic_t af_skb_alloc; atomic_t wanpipe_socks_nr; extern struct proto_ops wanpipe_ops; -static struct sock *wanpipe_alloc_socket(struct sock *, void *net); +static struct sock *wanpipe_alloc_socket(void); static void check_write_queue(struct sock *); @@ -305,6 +305,8 @@ dev_private_ioctl: /*NOTREACHED*/ } + + /*============================================================ * wanpipe_make_new * @@ -325,7 +327,7 @@ struct sock *wanpipe_make_new(struct sock *osk) if (osk->sk_type != SOCK_RAW) return NULL; - if ((sk = wanpipe_alloc_socket(osk,NULL)) == NULL) + if ((sk = wanpipe_alloc_socket()) == NULL) return NULL; sk->sk_family = osk->sk_family; @@ -711,10 +713,8 @@ static int wanpipe_api_sock_rcv(struct sk_buff *skb, netdevice_t *dev, struct s sll->sll_ifindex = dev->ifindex; sll->sll_halen = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) if (dev->hard_header_parse) sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr); -#endif /* * WAN_PACKET_DATA : Data which should be passed up the receive queue. @@ -770,7 +770,8 @@ static int wanpipe_api_sock_rcv(struct sk_buff *skb, netdevice_t *dev, struct s } break; default: - printk(KERN_INFO "af_wanpipe: BH Illegal Packet Type Dropping\n"); + printk(KERN_INFO "af_wanpipe: BH Illegal Packet Type Dropping %i\n",skb->pkt_type); + WARN_ON(1); KFREE_SKB(skb); break; } @@ -788,39 +789,22 @@ static int wanpipe_api_sock_rcv(struct sk_buff *skb, netdevice_t *dev, struct s * *===========================================================*/ -static struct sock *wanpipe_alloc_socket(struct sock *osk, void *net) +static struct sock *wanpipe_alloc_socket(void) { struct sock *sk; struct wanpipe_opt *wan_opt; #ifdef LINUX_2_6 - -# if defined(LINUX_FEAT_2624) - if (!osk && !net) { - DEBUG_EVENT("%s:%d ASSERT osk net pointer = NULL! \n", - __FUNCTION__,__LINE__); - return NULL; - } - - if (osk) { - net=osk->sk_net; - } - - sk = sk_alloc((struct net*)net, PF_WANPIPE, GFP_ATOMIC, &packet_proto); - -# elif defined(AF_WANPIPE_2612_UPDATE) - sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &packet_proto,1); -# else - sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, 1,NULL); -# endif +#ifdef AF_WANPIPE_2612_UPDATE + if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &packet_proto,1)) == NULL) #else - sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, 1); + if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, 1,NULL)) == NULL) +#endif +#else + if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, 1)) == NULL) #endif - - if (sk == NULL) { return NULL; - } if ((wan_opt = kmalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) { sk_free(sk); @@ -949,7 +933,6 @@ static int wanpipe_sendmsg(struct socket *sock, struct msghdr *msg, int len, goto out_free; } -#ifndef LINUX_FEAT_2624 if (dev->hard_header) { int res; err = -EINVAL; @@ -958,7 +941,6 @@ static int wanpipe_sendmsg(struct socket *sock, struct msghdr *msg, int len, goto out_free; } } -#endif skb->protocol = proto; skb->priority = sk->sk_priority; @@ -1328,7 +1310,7 @@ static int wanpipe_bind(struct socket *sock, struct sockaddr *uaddr, int addr_le * we are finshed with the device we should run * dev_put() to release it */ #if defined(LINUX_2_4)||defined(LINUX_2_6) - dev = wan_dev_get_by_name(name); + dev = dev_get_by_name(name); #else dev = dev_get(name); #endif @@ -1369,7 +1351,7 @@ wanpipe_svc_connect_skip: err=-EINVAL; }else{ sk->sk_state = WANSOCK_DISCONNECTED; - SK_PRIV(sk)->dev=wan_dev_get_by_index(sk->sk_bound_dev_if); + SK_PRIV(sk)->dev=dev_get_by_index(sk->sk_bound_dev_if); if (SK_PRIV(sk)->dev){ err=0; }else{ @@ -1395,7 +1377,7 @@ wanpipe_svc_connect_skip: * dev_put() to release it */ #if defined(LINUX_2_4)||defined(LINUX_2_6) - dev = wan_dev_get_by_name(name); + dev = dev_get_by_name(name); #else dev = dev_get(name); #endif @@ -1439,7 +1421,7 @@ wanpipe_svc_listen_skip: name[14]=0; #if defined(LINUX_2_4)||defined(LINUX_2_6) - dev = wan_dev_get_by_name(name); + dev = dev_get_by_name(name); #else dev = dev_get(name); #endif @@ -1509,26 +1491,17 @@ wanpipe_svc_listen_skip: * Crates AF_WANPIPE socket. *===========================================================*/ -#ifdef LINUX_FEAT_2624 -int wanpipe_create(struct net *net, struct socket *sock, int protocol) -#else int wanpipe_create(struct socket *sock, int protocol) -#endif { struct sock *sk; unsigned long flags; - -#ifndef LINUX_FEAT_2624 - /* Used to fake the net structure for lower kernels */ - void *net = NULL; -#endif - + if (sock->type != SOCK_RAW) return -ESOCKTNOSUPPORT; sock->state = SS_UNCONNECTED; - if ((sk = wanpipe_alloc_socket(NULL, net)) == NULL){ + if ((sk = wanpipe_alloc_socket()) == NULL){ return -ENOMEM; } diff --git a/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o b/patches/kdrivers/src/wanrouter/af_wanpipe_datascope.o index 7466552d7c87db8398aa3b6149d6f57b72bad9d3..a4a895526ffd5ea32c817f03ed15fad50e675827 100644 GIT binary patch literal 171944 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 RgzFGaVfobmf(F0W{{<+I_67g| literal 171168 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 diff --git a/patches/kdrivers/src/lip/bin/wanpipe_sppp.gcc3.i386.regparm.o b/patches/kdrivers/src/lip/bin/wanpipe_sppp.gcc3.i386.regparm.o index 5ae39daf20ac877fbf864a644dcb0d6a2c16afcf..f990f8dd073e6fcc7f3e391ea2e8da483da7454e 100644 GIT binary patch delta 298 zcmcc8$8@ESX~X$?D-&}IONRJ(w@^Rl5Kn)<_;@{_h#|U&xdFO}srh8i2H7|hQ!^7Z zDN_SeG!YX^3=uPQ15HdZM2yWRw=@`unOK;Zp&4jqVLbUvgG8u_iJ2)wQfZo=iG`st mlwoNIVOScV`^yr;QcF`K43o_#TQ(}On3$LtZ;o&L$_fDIWmHN4 delta 298 zcmcc8$8@ESX~X$?D`OL53x@c3w@^Rl5Kn)<_;@{_hyl8Yp(VPAf!Sov2H7}cBST{} zDMM2ebP*E_5d(As4JBn8E9;5H2F+}M5wW$p$S7$X&TVYW=0T( ksfhuUVT$fAGYm`33=A<$Hk)kOsKjDyU}>~DzVRz70IQ@^iP zhNRLoJrff%QwYPt&=|_FG=eZJ4bkneG(-2QrKvHh>sd_9EX*f2_9(HKn3x!EUf%PS F6#&*dTY>-p delta 318 zcmbQUlxfaVrVZlVR>mgA77X$6ZlQk8A)fwz@$q^<5d(A)LrZiK1GCA2-Li4UMux^{ zQii4`=prT3!-t(0e E0G5Ya9RL6T diff --git a/patches/kdrivers/src/lip/bin/wanpipe_sppp.gcc3.i686.regparm.o b/patches/kdrivers/src/lip/bin/wanpipe_sppp.gcc3.i686.regparm.o index 9ca5e8bf7b3a9ba7aab0e8123291f2f41bafaf5a..f281bb3236bb9bef635c10b8ed0a25e21ccc5fba 100644 GIT binary patch delta 318 zcmX>zhw025rVYp2tW3-;EE(eC-9r7GLp=Tc;^XyzB8KQ9<_72@rsk6w+hyZSOwCNt zq)ZJ=(L_uvF+|MJ4Ky*u5HU8NT+?n;Z(?DB?m{yQV}|m?yn@Vv)cE3pf`a(s(j>iP zhNRLoJrff%QwYPt&=|_FG=eZJ4bkneG(-2QrKvHh>sd_9EX*exb||r!n3x!E4)6HN F3IKi`TPpwn delta 318 zcmX>zhw025rVYp2tc*>JEg0hC-9r7GLp=Tc;^XyzA_nLphL-3e24<5P+hya7jSP*^ zqzp|>&_zrzL=4akG_b@Fu`rul({5C6Y+{M-LSthihVsO`g3N-{_~L?sg81UnB)w#Y zq|!7!V?#p|2*bq82*NNmF@!Qq(d{rZME9zhff1_fS&WU1%_bXmD6tqDSQ>2(@A%3J E06uA2#sB~S diff --git a/patches/kdrivers/src/lip/lip_katm/wanpipe_katm_iface.o b/patches/kdrivers/src/lip/lip_katm/wanpipe_katm_iface.o deleted file mode 100644 index 988815517e3a93f845a7967e9cf2e155100e3504..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140380 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 diff --git a/patches/kdrivers/src/lip/lip_katm/wanpipe_katm_sub.o b/patches/kdrivers/src/lip/lip_katm/wanpipe_katm_sub.o deleted file mode 100644 index b4a66962d8c7ca866082b4ef3d0c47ffa8ddc8a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144716 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 diff --git a/patches/kdrivers/src/lip/wanpipe_lip_bh.c b/patches/kdrivers/src/lip/wanpipe_lip_bh.c index 1619e63..bee2485 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_bh.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_bh.c @@ -13,13 +13,20 @@ void wplip_link_bh(void* data, int pending); static int wplip_bh_receive(wplip_link_t *lip_link) { netskb_t *skb; + unsigned long timeout_cnt = 2000; int err; while((skb=wan_skb_dequeue(&lip_link->rx_queue)) != NULL){ + err=wplip_prot_rx(lip_link,skb); if (err){ wan_skb_free(skb); } + + if (--timeout_cnt == 0){ + DEBUG_EVENT("%s: Link RxBH Time squeeze\n",lip_link->name); + break; + } } return 0; @@ -30,7 +37,7 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) netskb_t *skb; wplip_dev_t *lip_dev=NULL; int err=0; - unsigned long timeout_cnt=SYSTEM_TICKS; + unsigned int timeout_cnt=1000; if (wan_test_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working)){ if (wan_test_bit(WPLIP_KICK,&lip_link->tq_working)){ @@ -54,7 +61,7 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) goto wplip_bh_link_transmit_exit; } - if (SYSTEM_TICKS-timeout_cnt > 10){ + if (--timeout_cnt == 0){ DEBUG_EVENT("%s: Link TxBH Time squeeze\n",lip_link->name); goto wplip_bh_link_transmit_exit; } @@ -88,11 +95,9 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) } for (;;){ - - if (SYSTEM_TICKS-timeout_cnt > 10){ - if (WAN_NET_RATELIMIT()) { - DEBUG_EVENT("%s: LipDev TxBH Time squeeze --- Sanity\n",lip_link->name); - } + + if (--timeout_cnt == 0){ + DEBUG_EVENT("%s: LipDev TxBH Time squeeze\n",lip_link->name); goto wplip_bh_transmit_exit; } @@ -111,14 +116,14 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) goto wplip_bh_transmit_exit; } - lip_dev->ifstats.tx_packets++; - lip_dev->ifstats.tx_bytes += len; + WAN_NETIF_STATS_INC_TX_PACKETS(&lip_dev->common); //lip_dev->ifstats.tx_packets++; + WAN_NETIF_STATS_INC_TX_BYTES(&lip_dev->common,len); //lip_dev->ifstats.tx_bytes += len; } - if (!wan_test_bit(0,&lip_dev->if_down) && - WAN_NETIF_QUEUE_STOPPED(lip_dev->common.dev)){ + if (WAN_NETIF_QUEUE_STOPPED(lip_dev->common.dev)){ if (lip_dev->common.usedby == API){ + DEBUG_TEST("%s: Api waking stack!\n",lip_dev->name); WAN_NETIF_START_QUEUE(lip_dev->common.dev); #if defined(__LINUX__) wan_wakeup_api(lip_dev); @@ -131,13 +136,13 @@ static int wplip_bh_transmit(wplip_link_t *lip_link) WAN_NETIF_WAKE_QUEUE (lip_dev->common.dev); } } + + wplip_prot_kick(lip_link,lip_dev); if (wan_skb_queue_len(&lip_dev->tx_queue)){ wan_set_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working); } - wplip_prot_kick(lip_link,lip_dev); - wplip_bh_transmit_skip: lip_dev=WAN_LIST_NEXT(lip_dev,list_entry); @@ -146,25 +151,8 @@ wplip_bh_transmit_skip: } if (lip_dev == lip_link->cur_tx){ -#if 0 -/* This logic can be used to speed up tx - however it uses MUCH more CPU */ - ++tx_pkt_cnt; - if (tx_pkt_cnt > 2) { - break; - } - - if (SYSTEM_TICKS-timeout_cnt > 2){ - break; - } - - if (!wan_test_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working)) { - break; - } -#else /* We went through the whole list */ break; -#endif } } @@ -210,7 +198,7 @@ void wplip_link_bh(void* data, int pending) #endif { wplip_link_t *lip_link = (wplip_link_t *)data; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#ifndef __LINUX__ wan_smp_flag_t s; #endif @@ -221,10 +209,10 @@ void wplip_link_bh(void* data, int pending) return; } -#if defined(__LINUX__) +#ifdef __LINUX__ wan_spin_lock(&lip_link->bh_lock); #else - wan_spin_lock_irq(NULL, &s); + wan_spin_lock_irq(&lip_link->bh_lock, &s); #endif wan_set_bit(WPLIP_BH_RUNNING,&lip_link->tq_working); @@ -236,12 +224,11 @@ void wplip_link_bh(void* data, int pending) WAN_TASKLET_END((&lip_link->task)); -#if defined(__LINUX__) +#ifdef __LINUX__ wan_spin_unlock(&lip_link->bh_lock); #else - wan_spin_unlock_irq(NULL, &s); + wan_spin_unlock_irq(&lip_link->bh_lock, &s); #endif - wplip_retrigger_bh(lip_link); } diff --git a/patches/kdrivers/src/lip/wanpipe_lip_bh.c~ b/patches/kdrivers/src/lip/wanpipe_lip_bh.c~ deleted file mode 100644 index 13ae288..0000000 --- a/patches/kdrivers/src/lip/wanpipe_lip_bh.c~ +++ /dev/null @@ -1,237 +0,0 @@ -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# include -#else -#include -#endif - -#if defined(__LINUX__) -void wplip_link_bh(unsigned long data); -#else -void wplip_link_bh(void* data, int pending); -#endif - -static int wplip_bh_receive(wplip_link_t *lip_link) -{ - netskb_t *skb; - unsigned long timeout_cnt = 2000; - int err; - - while((skb=wan_skb_dequeue(&lip_link->rx_queue)) != NULL){ - - err=wplip_prot_rx(lip_link,skb); - if (err){ - wan_skb_free(skb); - } - - if (--timeout_cnt == 0){ - DEBUG_EVENT("%s: Link RxBH Time squeeze\n",lip_link->name); - break; - } - } - - return 0; -} - -static int wplip_bh_transmit(wplip_link_t *lip_link) -{ - netskb_t *skb; - wplip_dev_t *lip_dev=NULL; - int err=0; - unsigned int timeout_cnt=1000; - - if (wan_test_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working)){ - if (wan_test_bit(WPLIP_KICK,&lip_link->tq_working)){ - DEBUG_TEST("%s: KICK but await still set!\n", - lip_link->name); - }else{ - return 0; - } - } - - wan_clear_bit(WPLIP_KICK,&lip_link->tq_working); - wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); - - wan_clear_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working); - - while((skb=wan_skb_dequeue(&lip_link->tx_queue))){ - err=wplip_data_tx_down(lip_link,skb); - if (err != 0){ - wan_skb_queue_head(&lip_link->tx_queue,skb); - wan_set_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); - goto wplip_bh_link_transmit_exit; - } - - if (--timeout_cnt == 0){ - DEBUG_EVENT("%s: Link TxBH Time squeeze\n",lip_link->name); - goto wplip_bh_link_transmit_exit; - } - } - - if ((lip_dev=lip_link->cur_tx) != NULL){ - - if (lip_dev->magic != WPLIP_MAGIC_DEV){ - DEBUG_EVENT("%s: Error1: Invalid Dev Magic dev=%p Magic=0x%lX\n", - lip_link->name, - lip_dev, - lip_dev->magic); - goto wplip_bh_transmit_exit; - } - - }else{ - lip_dev=WAN_LIST_FIRST(&lip_link->list_head_ifdev); - if (!lip_dev){ - goto wplip_bh_transmit_exit; - } - - if (lip_dev->magic != WPLIP_MAGIC_DEV){ - DEBUG_EVENT("%s: Error2: Invalid Dev Magic dev=%p Magic=0x%lX\n", - lip_link->name, - lip_dev, - lip_dev->magic); - goto wplip_bh_transmit_exit; - } - - lip_link->cur_tx=lip_dev; - } - - for (;;){ - - if (--timeout_cnt == 0){ - DEBUG_EVENT("%s: LipDev TxBH Time squeeze\n",lip_link->name); - goto wplip_bh_transmit_exit; - } - - if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)){ - goto wplip_bh_transmit_skip; - } - - skb=wan_skb_dequeue(&lip_dev->tx_queue); - if (skb){ - int len=wan_skb_len(skb); - - err=wplip_data_tx_down(lip_link,skb); - if (err != 0){ - wan_skb_queue_head(&lip_dev->tx_queue,skb); - wan_set_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); - goto wplip_bh_transmit_exit; - } - - lip_dev->ifstats.tx_packets++; - lip_dev->ifstats.tx_bytes += len; - - } - - if (WAN_NETIF_QUEUE_STOPPED(lip_dev->common.dev)){ - if (lip_dev->common.usedby == API){ -#warning "NENAD" - DEBUG_EVENT("%s: Api waking stack!\n",lip_dev->name); - WAN_NETIF_START_QUEUE(lip_dev->common.dev); -#if defined(__LINUX__) - wan_wakeup_api(lip_dev); -#endif - }else if (lip_dev->common.lip){ /*STACK*/ - WAN_NETIF_START_QUEUE(lip_dev->common.dev); - wplip_kick(lip_dev->common.lip,0); - - }else{ - WAN_NETIF_WAKE_QUEUE (lip_dev->common.dev); - } - } - - if (wan_skb_queue_len(&lip_dev->tx_queue)){ - wan_set_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working); - } - - wplip_prot_kick(lip_link,lip_dev); - -wplip_bh_transmit_skip: - - lip_dev=WAN_LIST_NEXT(lip_dev,list_entry); - if (lip_dev == NULL){ - lip_dev=WAN_LIST_FIRST(&lip_link->list_head_ifdev); - } - - if (lip_dev == lip_link->cur_tx){ - /* We went through the whole list */ - break; - } - - } - -wplip_bh_transmit_exit: - - lip_link->cur_tx=lip_dev; - -wplip_bh_link_transmit_exit: - - if (wan_skb_queue_len(&lip_link->tx_queue)){ - wan_set_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working); - } - - if (wan_test_bit(WPLIP_MORE_LINK_TX,&lip_link->tq_working)){ - return 1; - } - - return 0; - -} - - -static int wplip_retrigger_bh(wplip_link_t *lip_link) -{ - if (wan_test_bit(WPLIP_MORE_LINK_TX, &lip_link->tq_working) || - wan_skb_queue_len(&lip_link->rx_queue)){ - return wplip_trigger_bh(lip_link); - } -#if 0 - if (gdbg_flag){ - DEBUG_EVENT("%s: Not triggered\n", __FUNCTION__); - } -#endif - return -EINVAL; -} - - -#if defined(__LINUX__) -void wplip_link_bh(unsigned long data) -#else -void wplip_link_bh(void* data, int pending) -#endif -{ - wplip_link_t *lip_link = (wplip_link_t *)data; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - wan_smp_flag_t s; -#endif - - DEBUG_TEST("%s: Link BH\n",__FUNCTION__); - - if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ - DEBUG_EVENT("%s: Link down in BH\n",__FUNCTION__); - return; - } - -#if defined(__LINUX__) - wan_spin_lock(&lip_link->bh_lock); -#else - wan_spin_lock_irq(NULL, &s); -#endif - wan_set_bit(WPLIP_BH_RUNNING,&lip_link->tq_working); - - wplip_bh_receive(lip_link); - - wplip_bh_transmit(lip_link); - - wan_clear_bit(WPLIP_BH_RUNNING,&lip_link->tq_working); - - WAN_TASKLET_END((&lip_link->task)); - - wplip_retrigger_bh(lip_link); - -#if defined(__LINUX__) - wan_spin_unlock(&lip_link->bh_lock); -#else - wan_spin_unlock_irq(NULL, &s); -#endif - -} - diff --git a/patches/kdrivers/src/lip/wanpipe_lip_iface.c b/patches/kdrivers/src/lip/wanpipe_lip_iface.c index c960f8e..4f983ab 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_iface.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_iface.c @@ -5,6 +5,8 @@ * * =========================================================== * + * Feb 09 2007 Joel M. Pareja Added link state notification + * for NETGRAPH failover support. * Dec 02 2003 Nenad Corbic Initial Driver */ @@ -23,13 +25,16 @@ * Definitions */ - /*============================================================= * Global Parameters */ /* Function interface between LIP layer and kernel */ extern wan_iface_t wan_iface; +#if defined(NETGRAPH) +extern void wan_ng_link_state(wanpipe_common_t *common, int state); +#endif + struct wplip_link_list list_head_link; wan_rwlock_t wplip_link_lock; unsigned char wplip_link_num[MAX_LIP_LINKS]; @@ -109,12 +114,15 @@ static int wplip_register (void **lip_link_ptr, wanif_conf_t *conf, char *devnam lip_link->state = WAN_DISCONNECTED; lip_link->carrier_state = WAN_DISCONNECTED; - lip_link->latency_qlen=100; - *lip_link_ptr = lip_link; +#if defined(__FreeBSD__) && defined(WPLIP_TQ_THREAD) + lip_link->tq = taskqueue_create_fast("wplip_taskq",M_NOWAIT, + taskqueue_thread_enqueue, &lip_link->tq); + taskqueue_start_threads(&lip_link->tq,1,PI_NET,"%s taskq",devname); +#endif return 0; } @@ -144,6 +152,14 @@ static int wplip_unreg(void *lip_link_ptr) return -ENODEV; } +#if defined(__FreeBSD__) && defined(WPLIP_TQ_THREAD) + if (lip_link->tq){ + WAN_TASKQUEUE_DRAIN(lip_link->tq, &lip_link->task); + WAN_TASKQUEUE_FREE(lip_link->tq); + lip_link->tq = NULL; + } +#endif + #ifdef WPLIP_TTY_SUPPORT if (lip_link->tty_opt && lip_link->tty_open){ tty_hangup(lip_link->tty); @@ -245,6 +261,10 @@ static int wplip_if_reg(void *lip_link_ptr, char *dev_name, wanif_conf_t *conf) #if defined(__OpenBSD__) }else if(strcmp(conf->usedby, "TRUNK") == 0){ usedby = TRUNK; +#endif +#if defined(__FreeBSD__) + }else if(strcmp(conf->usedby, "NETGRAPH") == 0){ + usedby = WP_NETGRAPH; #endif }else{ DEBUG_EVENT( "%s: LIP device invalid 'usedby': %s\n", @@ -310,6 +330,11 @@ static int wplip_if_reg(void *lip_link_ptr, char *dev_name, wanif_conf_t *conf) lip_dev->name); break; + case WP_NETGRAPH: + DEBUG_EVENT( "%s: Running in NETGRAPH mode\n", + lip_dev->name); + break; + default: DEBUG_EVENT( "%s: LIP device invalid 'usedby': %s\n", lip_dev->name, conf->usedby); @@ -426,12 +451,12 @@ static int wplip_if_unreg (netdevice_t *dev) return err; } } - + wan_set_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical); wan_clear_bit(WAN_DEV_READY,&lip_dev->interface_down); wplip_close_lipdev_prot(lip_dev); - + wan_spin_lock_irq(&lip_link->bh_lock,&flags); lip_link->cur_tx=NULL; wan_skb_queue_purge(&lip_dev->tx_queue); @@ -467,7 +492,6 @@ static int wplip_bind_link(void *lip_id,netdevice_t *dev) wplip_dev_list_t *lip_dev_list_el; wan_smp_flag_t flags; - if (!lip_id){ return -ENODEV; } @@ -476,11 +500,9 @@ static int wplip_bind_link(void *lip_id,netdevice_t *dev) return -ENODEV; } - if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ return -ENETDOWN; } - lip_dev_list_el=wan_malloc(sizeof(wplip_dev_list_t)); memset(lip_dev_list_el,0,sizeof(wplip_dev_list_t)); @@ -557,20 +579,14 @@ static int wplip_rx(void *wplip_id, void *skb) { wplip_link_t *lip_link = (wplip_link_t*)wplip_id; - DEBUG_RX("%s: LIP LINK %s() pkt=%d %p\n", lip_link->name,__FUNCTION__, - skb?wan_skb_len(skb):0, + wan_skb_len(skb), skb); if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ return -ENODEV; } - - if (skb == NULL) { - wplip_trigger_bh(lip_link); - return 0; - } #ifdef WPLIP_TTY_SUPPORT if (lip_link->tty_opt){ @@ -583,7 +599,7 @@ static int wplip_rx(void *wplip_id, void *skb) } } #endif - + if (wan_skb_queue_len(&lip_link->rx_queue) > MAX_RX_Q){ DEBUG_TEST("%s: Critical Rx Error: Rx buf overflow 0x%lX!\n", lip_link->name, @@ -592,7 +608,6 @@ static int wplip_rx(void *wplip_id, void *skb) return -ENOBUFS; } - wan_skb_queue_tail(&lip_link->rx_queue,skb); wplip_trigger_bh(lip_link); @@ -670,11 +685,11 @@ int wplip_data_rx_up(wplip_dev_t* lip_dev, void *skb) #else wan_skb_free(skb); #endif - lip_dev->ifstats.rx_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&lip_dev->common); //lip_dev->ifstats.rx_errors++; return 1; }else{ - lip_dev->ifstats.rx_packets++; - lip_dev->ifstats.rx_bytes+=len; + WAN_NETIF_STATS_INC_RX_PACKETS(&lip_dev->common); //lip_dev->ifstats.rx_packets++; + WAN_NETIF_STATS_INC_RX_BYTES(&lip_dev->common,len); //lip_dev->ifstats.rx_bytes+=len; } } break; @@ -685,24 +700,24 @@ int wplip_data_rx_up(wplip_dev_t* lip_dev, void *skb) int err=wplip_rx(lip_dev->common.lip,skb); if (err){ wan_skb_free(skb); - lip_dev->ifstats.rx_dropped++; + WAN_NETIF_STATS_INC_RX_DROPPED(&lip_dev->common); //lip_dev->ifstats.rx_dropped++; }else{ - lip_dev->ifstats.rx_packets++; - lip_dev->ifstats.rx_bytes+=len; + WAN_NETIF_STATS_INC_RX_PACKETS(&lip_dev->common); //lip_dev->ifstats.rx_packets++; + WAN_NETIF_STATS_INC_RX_BYTES(&lip_dev->common,len); //lip_dev->ifstats.rx_bytes+=len; } }else{ wan_skb_free(skb); - lip_dev->ifstats.rx_dropped++; + WAN_NETIF_STATS_INC_RX_DROPPED(&lip_dev->common); //lip_dev->ifstats.rx_dropped++; } break; default: if (wan_iface.input && wan_iface.input(lip_dev->common.dev, skb) == 0){ - lip_dev->ifstats.rx_packets++; - lip_dev->ifstats.rx_bytes += len; + WAN_NETIF_STATS_INC_RX_PACKETS(&lip_dev->common); //lip_dev->ifstats.rx_packets++; + WAN_NETIF_STATS_INC_RX_BYTES(&lip_dev->common,len); //lip_dev->ifstats.rx_bytes += len; }else{ wan_skb_free(skb); - lip_dev->ifstats.rx_dropped++; + WAN_NETIF_STATS_INC_RX_DROPPED(&lip_dev->common); //lip_dev->ifstats.rx_dropped++; } break; @@ -781,7 +796,9 @@ int wplip_data_tx_down(wplip_link_t *lip_link, void *skb) return dev->hard_start_xmit(skb,dev); #else - if (dev->if_output) return dev->if_output(dev, skb, NULL,NULL); + if (!(WAN_NETIF_QUEUE_STOPPED(dev)) && dev->if_output){ + return dev->if_output(dev, skb, NULL,NULL); + } wan_skb_free(skb); return 0; #endif @@ -798,10 +815,6 @@ int wplip_data_tx_down(wplip_link_t *lip_link, void *skb) int wplip_link_prot_change_state(void *wplip_id,int state, unsigned char *data, int len) { wplip_link_t *lip_link = (wplip_link_t *)wplip_id; - - if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)) { - return 0; - } if (lip_link->prot_state != state){ lip_link->prot_state=state; @@ -827,10 +840,11 @@ int wplip_link_prot_change_state(void *wplip_id,int state, unsigned char *data, } + int wplip_lipdev_prot_update_state_change(wplip_dev_t *lip_dev, unsigned char *data, int len) { int state = lip_dev->common.state; - + if (lip_dev->common.usedby == API) { if (data && len){ @@ -844,12 +858,12 @@ int wplip_lipdev_prot_update_state_change(wplip_dev_t *lip_dev, unsigned char *d WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); } - + wan_update_api_state(lip_dev); wplip_trigger_bh(lip_dev->lip_link); - } else if (lip_dev->common.lip) { /*STACK*/ + }else if (lip_dev->common.lip) { /*STACK*/ if (state == WAN_CONNECTED){ WAN_NETIF_CARRIER_ON(lip_dev->common.dev); @@ -857,31 +871,38 @@ int wplip_lipdev_prot_update_state_change(wplip_dev_t *lip_dev, unsigned char *d wplip_connect(lip_dev->common.lip,0); }else{ WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) +#if defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); #endif wplip_disconnect(lip_dev->common.lip,0); } - } else { + }else{ if (state == WAN_CONNECTED){ WAN_NETIF_CARRIER_ON(lip_dev->common.dev); WAN_NETIF_WAKE_QUEUE(lip_dev->common.dev); wplip_trigger_bh(lip_dev->lip_link); }else{ WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) +#if defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); #endif } wplip_trigger_if_task(lip_dev); +#if defined(NETGRAPH) + if (lip_dev->common.usedby == WP_NETGRAPH) { + /* Inform netgraph of status of node */ + wan_ng_link_state(&lip_dev->common, lip_dev->common.state); + } +#endif } - + return 0; - } + + int wplip_lipdev_prot_change_state(void *wplip_id,int state, unsigned char *data, int len) { @@ -911,7 +932,10 @@ int wplip_lipdev_prot_change_state(void *wplip_id,int state, static void wplip_connect(void *wplip_id,int reason) { - wplip_link_t *lip_link = (wplip_link_t *)wplip_id; + wplip_link_t *lip_link = (wplip_link_t *)wplip_id; +#if defined(NETGRAPH) + wanpipe_common_t *common = NULL; +#endif if (lip_link->carrier_state != WAN_CONNECTED){ wan_smp_flag_t flags; @@ -936,6 +960,11 @@ static void wplip_connect(void *wplip_id,int reason) lip_link->state = WAN_CONNECTED; } +#if defined(NETGRAPH) + /* Inform netgraph of status of node */ + common = &(WAN_LIST_FIRST(&lip_link->list_head_ifdev))->common; + wan_ng_link_state(common, WAN_CONNECTED); +#endif } /*============================================================== @@ -949,6 +978,9 @@ static void wplip_connect(void *wplip_id,int reason) static void wplip_disconnect(void *wplip_id,int reason) { wplip_link_t *lip_link = (wplip_link_t *)wplip_id; +#if defined(NETGRAPH) + wanpipe_common_t *common = NULL; +#endif if (lip_link->carrier_state != WAN_DISCONNECTED){ DEBUG_EVENT("%s: Lip Link Carrier Disconnected!\n", @@ -962,6 +994,10 @@ static void wplip_disconnect(void *wplip_id,int reason) lip_link->state = WAN_DISCONNECTED; DEBUG_EVENT("%s: Lip Link Disconnected!\n",lip_link->name); } +#if defined(NETGRAPH) + common = &(WAN_LIST_FIRST(&lip_link->list_head_ifdev))->common; + wan_ng_link_state(common, WAN_DISCONNECTED); +#endif } @@ -1081,7 +1117,7 @@ int wplip_callback_tx_down(void *wplip_id, void *skb) DEBUG_TEST("%s: %s() Error Lip Link Carrier not connected !\n", lip_dev->name,__FUNCTION__); wan_skb_free(skb); - lip_dev->ifstats.tx_carrier_errors++; + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&lip_dev->common); //lip_dev->ifstats.tx_carrier_errors++; return 0; } @@ -1477,6 +1513,8 @@ static unsigned char wplip_copyright[]="(c) 1995-2004 Sangoma Technologies Inc." int wanpipe_lip_init(void*); int wanpipe_lip_exit(void*); +int wanpipe_lip_shutdown(void*); +int wanpipe_lip_ready_unload(void*); int wanpipe_lip_init(void *arg) { @@ -1539,11 +1577,17 @@ int wanpipe_lip_exit (void *arg) } #if 0 -MODULE_AUTHOR("Nenad Corbic "); -MODULE_DESCRIPTION("Wanpipe L.I.P Network Layer - Sangoma Tech. Copyright 2004"); -MODULE_LICENSE("GPL"); -module_init(wanpipe_lip_init); -module_exit(wanpipe_lip_exit); +int wanpipe_lip_shutdown(void *arg) +{ + DEBUG_EVENT("Shutting down WANPIPE LIP module ...\n"); + return 0; +} + +int wanpipe_lip_ready_unload(void *arg) +{ + DEBUG_EVENT("Is WANPIPE LIP module ready to unload...\n"); + return 0; +} #endif WAN_MODULE_DEFINE( @@ -1551,7 +1595,8 @@ WAN_MODULE_DEFINE( "Nenad Corbic ", "Wanpipe L.I.P Network Layer - Sangoma Tech. Copyright 2004", "GPL", - wanpipe_lip_init, wanpipe_lip_exit, NULL); + wanpipe_lip_init, wanpipe_lip_exit,/* wanpipe_lip_shutdown, wanpipe_lip_ready_unload,*/ + NULL); WAN_MODULE_DEPEND(wanpipe_lip, wanrouter, 1, WANROUTER_MAJOR_VER, WANROUTER_MAJOR_VER); WAN_MODULE_DEPEND(wanpipe_lip, wanpipe, 1, diff --git a/patches/kdrivers/src/lip/wanpipe_lip_iface.c~ b/patches/kdrivers/src/lip/wanpipe_lip_iface.c~ deleted file mode 100644 index d031cd1..0000000 --- a/patches/kdrivers/src/lip/wanpipe_lip_iface.c~ +++ /dev/null @@ -1,1538 +0,0 @@ -/************************************************************* - * wanpipe_lip.c WANPIPE Link Interface Protocol Layer (LIP) - * - * - * - * =========================================================== - * - * Dec 02 2003 Nenad Corbic Initial Driver - */ - - -/*============================================================= - * Includes - */ - -#if defined(__FreeBSD__) || defined(__OpenBSD__) -#include -#elif defined(__LINUX__) -#include -#endif - -/*============================================================= - * Definitions - */ - - -/*============================================================= - * Global Parameters - */ -/* Function interface between LIP layer and kernel */ -extern wan_iface_t wan_iface; - -struct wplip_link_list list_head_link; -wan_rwlock_t wplip_link_lock; -unsigned char wplip_link_num[MAX_LIP_LINKS]; -#if 0 -int gdbg_flag=0; -#endif - -/*============================================================= - * Function Prototypes - */ - -static int wplip_if_unreg (netdevice_t *dev); -static int wplip_bind_link(void *lip_id,netdevice_t *dev); -static int wplip_unbind_link(void *lip_id,netdevice_t *dev); -static void wplip_disconnect(void *wplip_id,int reason); -static void wplip_connect(void *wplip_id,int reason); -static int wplip_rx(void *wplip_id, void *skb); -static int wplip_unreg(void *reg_ptr); - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -static void wplip_if_task (void *arg, int dummy); -#else -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -static void wplip_if_task (void *arg); -# else -static void wplip_if_task (struct work_struct *work); -# endif -#endif - -extern int register_wanpipe_lip_protocol (wplip_reg_t *lip_reg); -extern void unregister_wanpipe_lip_protocol (void); - - -/*============================================================= - * Global Module Interface Functions - */ - - -/*============================================================= - * wplip_register - * - * Description: - * - * Usedby: - */ -/* EXPORT_SYMBOL(wplip_register); */ -static int wplip_register (void **lip_link_ptr, wanif_conf_t *conf, char *devname) -{ - wplip_link_t *lip_link = (wplip_link_t*)*lip_link_ptr; - - /* Create the new X25 link for this Lapb - * connection */ - if (lip_link){ - return -EEXIST; - } - - lip_link = wplip_create_link(devname); - if (!lip_link){ - DEBUG_EVENT("%s: LIP register: Failed to create link\n", - MODNAME); - return -ENOMEM; - } - - DEBUG_TEST("%s: Registering LIP Link\n",lip_link->name); - - - if (conf){ - int err=wplip_reg_link_prot(lip_link,conf); - if (err){ - wplip_free_link(lip_link); - return err; - } - } - - wplip_insert_link(lip_link); - - lip_link->state = WAN_DISCONNECTED; - lip_link->carrier_state = WAN_DISCONNECTED; - - - lip_link->latency_qlen=100; - - - *lip_link_ptr = lip_link; - - return 0; -} - -/*============================================================== - * wplip_unreg - * - * Description: - * This function is called during system setup to - * remove the whole x25 link and all x25 svc defined - * within the x25 link. - * - * For each x25 link and x25 svc the proc file - * entry is removed. - * - * Usedby: - * Lapb layer. - */ - -static int wplip_unreg(void *lip_link_ptr) -{ - wplip_link_t *lip_link = (wplip_link_t*)lip_link_ptr; - wplip_dev_t *lip_dev; - wplip_dev_list_t *lip_dev_list_el; - int err; - - if (wplip_link_exists(lip_link) != 0){ - return -ENODEV; - } - -#ifdef WPLIP_TTY_SUPPORT - if (lip_link->tty_opt && lip_link->tty_open){ - tty_hangup(lip_link->tty); - return -EBUSY; - } -#endif - - wan_del_timer(&lip_link->prot_timer); - - wan_set_bit(WPLIP_LINK_DOWN,&lip_link->tq_working); - while((lip_dev = WAN_LIST_FIRST(&lip_link->list_head_ifdev)) != NULL){ - - DEBUG_EVENT("%s: Unregistering dev %s\n", - lip_link->name,lip_dev->name); - - - err=wplip_if_unreg(lip_dev->common.dev); - if (err<0){ - wan_clear_bit(WPLIP_LINK_DOWN,&lip_link->tq_working); - return err; - } - } - - - while((lip_dev_list_el = WAN_LIST_FIRST(&lip_link->list_head_tx_ifdev)) != NULL){ - - DEBUG_EVENT("%s: Unregistering master dev %s\n", - lip_link->name, - wan_netif_name(lip_dev_list_el->dev)); - - WAN_DEV_PUT(lip_dev_list_el->dev); - lip_dev_list_el->dev=NULL; - - WAN_LIST_REMOVE(lip_dev_list_el,list_entry); - lip_link->tx_dev_cnt--; - - wan_free(lip_dev_list_el); - lip_dev_list_el=NULL; - } - - - if (lip_link->protocol){ - wplip_unreg_link_prot(lip_link); - } - - wplip_remove_link(lip_link); - wplip_free_link(lip_link); - - return 0; -} - - -static int wplip_if_reg(void *lip_link_ptr, char *dev_name, wanif_conf_t *conf) -{ - wplip_link_t *lip_link = (wplip_link_t*)lip_link_ptr; - wplip_dev_t *lip_dev; - int usedby=0; - int err; - - if (!conf){ - DEBUG_EVENT("%s: LIP DEV: If Registartion without configuration!\n",dev_name); - return -EINVAL; - } - -#ifdef WPLIP_TTY_SUPPORT - if (lip_link->tty_opt){ - return 0; - } -#endif - - if (wplip_link_exists(lip_link) != 0){ - DEBUG_EVENT("%s: LIP: Invalid Link !\n", - dev_name); - return -EINVAL; - } - - if (dev_name == NULL){ - DEBUG_EVENT("%s: LIP: Invalid device name : NULL!\n", - lip_link->name); - return -EINVAL; - } - - if (!wplip_lipdev_exists(lip_link,dev_name)){ - DEBUG_EVENT("%s: LIP: Invalid lip link device %s!\n", - __FUNCTION__,dev_name); - return -EEXIST; - } - - if(strcmp(conf->usedby, "API") == 0) { - usedby = API; - }else if(strcmp(conf->usedby, "WANPIPE") == 0){ - usedby = WANPIPE; - }else if(strcmp(conf->usedby, "STACK") == 0){ - usedby = STACK; - }else if(strcmp(conf->usedby, "BRIDGE") == 0){ - usedby = BRIDGE; - }else if(strcmp(conf->usedby, "BRIDGE_NODE") == 0){ - usedby = BRIDGE_NODE; -#if defined(__OpenBSD__) - }else if(strcmp(conf->usedby, "TRUNK") == 0){ - usedby = TRUNK; -#endif - }else{ - DEBUG_EVENT( "%s: LIP device invalid 'usedby': %s\n", - dev_name, conf->usedby); - return -EINVAL; - } - - if ((lip_dev = wplip_create_lipdev(dev_name, usedby)) == NULL){ - DEBUG_EVENT("%s: LIP: Failed to create lip priv device %s\n", - lip_link->name,dev_name); - return -ENOMEM; - } - -#if defined(__LINUX__) - if (conf->mtu){ - lip_dev->common.dev->mtu = conf->mtu; - } -#endif - - WAN_HOLD(lip_link); - lip_dev->lip_link = lip_link; - lip_dev->protocol = conf->protocol; - lip_dev->common.usedby = usedby; - lip_dev->common.state = WAN_DISCONNECTED; - WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); - -#if defined(__LINUX__) - if (conf->true_if_encoding){ - DEBUG_EVENT("%s: LIP: Setting IF Type to Broadcast\n",dev_name); - lip_dev->common.dev->flags &= ~IFF_POINTOPOINT; - lip_dev->common.dev->flags |= IFF_BROADCAST; - } -#endif - - switch (usedby){ - - case API: - wan_reg_api(lip_dev, lip_dev->common.dev, lip_link->name); - DEBUG_EVENT( "%s: Running in API mode\n", - lip_dev->name); - break; - case WANPIPE: - DEBUG_EVENT( "%s: Running in WANPIPE mode\n", - lip_dev->name); - break; - case STACK: - DEBUG_EVENT( "%s: Running in STACK mode\n", - lip_dev->name); - break; - - case BRIDGE: - DEBUG_EVENT( "%s: Running in BRIDGE mode\n", - lip_dev->name); - break; - - case BRIDGE_NODE: - DEBUG_EVENT( "%s: Running in BRIDGE Node mode\n", - lip_dev->name); - break; - - case TRUNK: - DEBUG_EVENT( "%s: Running in TRUNK mode\n", - lip_dev->name); - break; - - default: - DEBUG_EVENT( "%s: LIP device invalid 'usedby': %s\n", - lip_dev->name, conf->usedby); - __WAN_PUT(lip_link); - lip_dev->lip_link = NULL; - wplip_free_lipdev(lip_dev); - return -EINVAL; - } - - lip_dev->ipx_net_num = conf->network_number; - if (lip_dev->ipx_net_num) { - DEBUG_EVENT("%s: IPX Network Number = 0x%lX\n", - lip_dev->name, lip_dev->ipx_net_num); - } - - lip_dev->max_mtu_sz=MAX_TX_BUF; - lip_dev->max_mtu_sz_orig=MAX_TX_BUF; - - err=wplip_reg_lipdev_prot(lip_dev,conf); - if (err){ - __WAN_PUT(lip_link); - lip_dev->lip_link = NULL; - wplip_free_lipdev(lip_dev); - return err; - } - - wplip_insert_lipdev(lip_link,lip_dev); - WAN_TASKQ_INIT((&lip_dev->if_task),0,wplip_if_task,lip_dev); - - err=wplip_open_lipdev_prot(lip_dev); - if (err){ - wplip_remove_lipdev(lip_link,lip_dev); - __WAN_PUT(lip_link); - lip_dev->lip_link = NULL; - wplip_free_lipdev(lip_dev); - return err; - } - -#ifdef __LINUX__ - if (conf->if_down && usedby != API && usedby != STACK){ - wan_set_bit(DYN_OPT_ON,&lip_dev->interface_down); - DEBUG_EVENT("%s: Dynamic interface configuration enabled\n", - dev_name); - }else{ - wan_clear_bit(DYN_OPT_ON,&lip_dev->interface_down); - } - lip_link->latency_qlen=lip_dev->common.dev->tx_queue_len; -#endif - - if (lip_link->state == WAN_CONNECTED){ - DEBUG_TEST("%s: LIP CREATE Link already on!\n", - lip_dev->name); - WAN_NETIF_CARRIER_ON(lip_dev->common.dev); - WAN_NETIF_WAKE_QUEUE(lip_dev->common.dev); - wplip_trigger_bh(lip_dev->lip_link); - } - - DEBUG_TEST("%s: LIP LIPDEV Created %p Magic 0x%lX\n", - lip_link->name, - lip_dev, - lip_dev->magic); - return 0; -} - -/*============================================================== - * wplip_if_unreg - * - * Description: - * This function is called during system setup to - * remove the x25 link and each x25 svc defined - * in the wanpipe configuration file. - * - * For each x25 link and x25 svc the proc file - * entry is removed. - * - * Usedby: - * Lapb layer. - */ - -static int wplip_if_unreg (netdevice_t *dev) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); - wplip_link_t *lip_link = NULL; - wplip_link_t *stack_lip_link = NULL; - wan_smp_flag_t flags; - - if (!lip_dev) - return -ENODEV; - - if (WAN_NETIF_UP(dev)){ - DEBUG_EVENT("%s: Failed to unregister: Device UP!\n", - wan_netif_name(dev)); - return -EBUSY; - } - - lip_link = lip_dev->lip_link; - - if (wplip_link_exists(lip_link) != 0){ - DEBUG_EVENT("%s: Failed to unregister: no link device\n", - wan_netif_name(dev)); - return -ENODEV; - } - - /* Check for a Higher Lip Link layer attached - * to this device. If exists, call unregister to - * remove it before unregistering this device */ - stack_lip_link=lip_dev->common.lip; /*STACK*/ - if (stack_lip_link){ - int err; - DEBUG_TEST("%s: IF UNREG: Calling Top Layer LIP UNREG\n", - lip_dev->name); - err=wplip_unreg(stack_lip_link); - if (err){ - return err; - } - } - - wplip_close_lipdev_prot(lip_dev); - - wan_set_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical); - wan_clear_bit(WAN_DEV_READY,&lip_dev->interface_down); - - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - lip_link->cur_tx=NULL; - wan_skb_queue_purge(&lip_dev->tx_queue); - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - - DEBUG_EVENT("%s: Unregistering LIP device\n", - wan_netif_name(dev)); - - if (lip_dev->common.prot_ptr){ - wplip_unreg_lipdev_prot(lip_dev); - } - - if (lip_dev->common.usedby == API){ - wan_unreg_api(lip_dev, lip_link->name); - } - - wplip_remove_lipdev(lip_link,lip_dev); - - __WAN_PUT(lip_dev->lip_link); - lip_dev->lip_link=NULL; - - wplip_free_lipdev(lip_dev); - - return 0; -} - - - -static int wplip_bind_link(void *lip_id,netdevice_t *dev) -{ - - wplip_link_t *lip_link = (wplip_link_t*)lip_id; - wplip_dev_list_t *lip_dev_list_el; - wan_smp_flag_t flags; - - if (!lip_id){ - return -ENODEV; - } - - if (wplip_link_exists(lip_link) != 0){ - return -ENODEV; - } - - if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ - return -ENETDOWN; - } - - lip_dev_list_el=wan_malloc(sizeof(wplip_dev_list_t)); - memset(lip_dev_list_el,0,sizeof(wplip_dev_list_t)); - - lip_dev_list_el->magic=WPLIP_MAGIC_DEV_EL; - - WAN_DEV_HOLD(dev); - - lip_dev_list_el->dev=dev; - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - - WAN_LIST_INSERT_HEAD(&lip_link->list_head_tx_ifdev,lip_dev_list_el,list_entry); - lip_link->tx_dev_cnt++; - - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - - return 0; -} - -static int wplip_unbind_link(void *lip_id,netdevice_t *dev) -{ - wplip_link_t *lip_link = (wplip_link_t*)lip_id; - wplip_dev_list_t *lip_dev_list_el=NULL; - wan_smp_flag_t flags; - int err=-ENODEV; - - if (!lip_id){ - return -EFAULT; - } - - if (wplip_link_exists(lip_link) != 0){ - return -EFAULT; - } - - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - - WAN_LIST_FOREACH(lip_dev_list_el,&lip_link->list_head_tx_ifdev,list_entry){ - if (lip_dev_list_el->dev == dev){ - WAN_LIST_REMOVE(lip_dev_list_el,list_entry); - lip_link->tx_dev_cnt--; - err=0; - break; - } - } - - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - - if (err==0){ - WAN_DEV_PUT(lip_dev_list_el->dev); - lip_dev_list_el->dev=NULL; - wan_free(lip_dev_list_el); - } - - return err; -} - - - - - -/*============================================================== - * wplip_rx - * - * Description: - * - * - * Usedby: - * Lower layer to pass us an rx packet. - */ - -static int wplip_rx(void *wplip_id, void *skb) -{ - wplip_link_t *lip_link = (wplip_link_t*)wplip_id; - - DEBUG_RX("%s: LIP LINK %s() pkt=%d %p\n", - lip_link->name,__FUNCTION__, - wan_skb_len(skb), - skb); - - if (wan_test_bit(WPLIP_LINK_DOWN,&lip_link->tq_working)){ - return -ENODEV; - } - -#ifdef WPLIP_TTY_SUPPORT - if (lip_link->tty_opt){ - if (lip_link->tty && lip_link->tty_open){ - wplip_tty_receive(lip_link,skb); - wanpipe_tty_trigger_poll(lip_link); - return 0; - }else{ - return -ENODEV; - } - } -#endif - - if (wan_skb_queue_len(&lip_link->rx_queue) > MAX_RX_Q){ - DEBUG_TEST("%s: Critical Rx Error: Rx buf overflow 0x%lX!\n", - lip_link->name, - lip_link->tq_working); - wplip_trigger_bh(lip_link); - return -ENOBUFS; - } - - wan_skb_queue_tail(&lip_link->rx_queue,skb); - wplip_trigger_bh(lip_link); - - return 0; -} - -/*============================================================== - * wplip_data_rx_up - * - * Description: - * This function is used to pass data to the upper - * layer. If the lip dev is used by TCP/IP the packet - * is passed up the the TCP/IP stack, otherwise - * it is passed to the upper protocol layer. - * - * Locking: - * This function will ALWAYS get called from - * the BH handler with the bh_lock, thus - * its protected. - * - * Usedby: - */ - -int wplip_data_rx_up(wplip_dev_t* lip_dev, void *skb) -{ - int len=wan_skb_len(skb); - - DEBUG_TEST("LIP LINK %s() pkt=%i\n", - __FUNCTION__,wan_skb_len(skb)); - -#if 0 - DEBUG_EVENT("%s: %s() Packet Len=%d (DEBUG DROPPED)\n", - lip_dev->name, __FUNCTION__,wan_skb_len(skb)); - - wan_skb_free(skb); - return 0; -#endif - - switch (lip_dev->common.usedby){ - -#if defined(__LINUX__) - case API: - { - unsigned char *buf; - int err; - - if (wan_skb_headroom(skb) < sizeof(wan_api_rx_hdr_t)){ - DEBUG_EVENT("%s: Critical Error Rx pkt Hdrm=%d < ApiHdrm=%d\n", - lip_dev->name,wan_skb_headroom(skb), - sizeof(wan_api_rx_hdr_t)); - wan_skb_free(skb); - break; - } - - buf=wan_skb_push(skb,sizeof(wan_api_rx_hdr_t)); - memset(buf,0,sizeof(wan_api_rx_hdr_t)); - - ((netskb_t *)skb)->protocol = htons(PVC_PROT); - wan_skb_reset_mac_header(((netskb_t *)skb)); - wan_skb_reset_network_header(((netskb_t *)skb)); - ((netskb_t *)skb)->dev = lip_dev->common.dev; - ((netskb_t *)skb)->pkt_type = WAN_PACKET_DATA; - - if ((err=wan_api_rx(lip_dev,skb)) != 0){ -#if 0 - if (net_ratelimit()){ - DEBUG_EVENT("%s: Error: Rx Socket busy err=%i!\n", - lip_dev->name,err); - } -#endif - -#if 0 - #LAPB SHOULD PUSH BACK TO THE STACK - wan_skb_pull(skb,sizeof(wan_api_rx_hdr_t)); -#else - wan_skb_free(skb); -#endif - lip_dev->ifstats.rx_errors++; - return 1; - }else{ - lip_dev->ifstats.rx_packets++; - lip_dev->ifstats.rx_bytes+=len; - } - } - break; -#endif - - case STACK: - if (lip_dev->common.lip){ - int err=wplip_rx(lip_dev->common.lip,skb); - if (err){ - wan_skb_free(skb); - lip_dev->ifstats.rx_dropped++; - }else{ - lip_dev->ifstats.rx_packets++; - lip_dev->ifstats.rx_bytes+=len; - } - }else{ - wan_skb_free(skb); - lip_dev->ifstats.rx_dropped++; - } - - break; - default: - if (wan_iface.input && wan_iface.input(lip_dev->common.dev, skb) == 0){ - lip_dev->ifstats.rx_packets++; - lip_dev->ifstats.rx_bytes += len; - }else{ - wan_skb_free(skb); - lip_dev->ifstats.rx_dropped++; - } - - break; - } - return 0; -} - - -/*============================================================== - * wplip_data_tx_down - * - * Description: - * This function is used to pass data down to the - * lower layer. - * - * Locking: - * This function will ALWAYS get called from - * the BH handler with the bh_lock, thus - * its protected. - * - * Return Codes: - * - * 0: Packet send successful, lower layer - * will deallocate packet - * - * Non 0: Packet send failed, upper layer - * must handle the packet - * - */ - -int wplip_data_tx_down(wplip_link_t *lip_link, void *skb) -{ - wplip_dev_list_t *lip_dev_list_el; - netdevice_t *dev; - - DEBUG_TEST("%s: LIP LINK %s() pkt=%d\n", - lip_link->name,__FUNCTION__,wan_skb_len(skb)); - - - if (!lip_link->tx_dev_cnt){ - DEBUG_EVENT("%s: %s: Tx Dev List empty! dropping...\n", - __FUNCTION__,lip_link->name); - return -ENODEV; - } - - /* FIXME: - * For now, we can only transmit on a FIRST Tx device */ - lip_dev_list_el=WAN_LIST_FIRST(&lip_link->list_head_tx_ifdev); - if (!lip_dev_list_el){ - DEBUG_EVENT("%s: %s: Tx Dev List empty! dropping...\n", - __FUNCTION__,lip_link->name); - return -ENODEV; - } - - if (lip_dev_list_el->magic != WPLIP_MAGIC_DEV_EL){ - DEBUG_EVENT("%s: %s: Error: Invalid dev magic number! dropping...\n", - __FUNCTION__,lip_link->name); - return -EFAULT; - } - - dev=lip_dev_list_el->dev; - if (!dev){ - DEBUG_EVENT("%s: %s: Error: No dev! dropping...\n", - __FUNCTION__,lip_link->name); - return -ENODEV; - } - - if (WAN_NETIF_QUEUE_STOPPED(dev)){ - return -EBUSY; - } - -#if defined(__LINUX__) - if (lip_link->latency_qlen != dev->tx_queue_len) { - dev->tx_queue_len=lip_link->latency_qlen; - } - - return dev->hard_start_xmit(skb,dev); -#else - if (dev->if_output) return dev->if_output(dev, skb, NULL,NULL); - wan_skb_free(skb); - return 0; -#endif -} - -/*============================================================== - * wplip_link_prot_change_state - * - * Description: - * The lower layer calls this function, when it - * becomes disconnected. - */ - -int wplip_link_prot_change_state(void *wplip_id,int state, unsigned char *data, int len) -{ - wplip_link_t *lip_link = (wplip_link_t *)wplip_id; - - if (lip_link->prot_state != state){ - lip_link->prot_state=state; - - DEBUG_EVENT("%s: Lip Link Protocol State %s!\n", - lip_link->name, STATE_DECODE(state)); - - if (lip_link->prot_state == WAN_CONNECTED && - lip_link->carrier_state == WAN_CONNECTED){ - DEBUG_EVENT("%s: Lip Link Connected!\n", - lip_link->name); - lip_link->state = WAN_CONNECTED; - } - - if (lip_link->prot_state != WAN_CONNECTED){ - DEBUG_EVENT("%s: Lip Link Disconnected!\n", - lip_link->name); - lip_link->state = WAN_DISCONNECTED; - } - } - - return 0; -} - -int wplip_lipdev_prot_change_state(void *wplip_id,int state, - unsigned char *data, int len) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; - - DEBUG_EVENT("%s: Lip Dev Prot State %s!\n", - lip_dev->name, STATE_DECODE(state)); - - lip_dev->common.state = state; - - if (lip_dev->common.usedby == API) { - - if (data && len){ - wplip_prot_oob(lip_dev,data,len); - } - - if (state == WAN_CONNECTED){ - lip_dev->common.state = state; - WAN_NETIF_CARRIER_ON(lip_dev->common.dev); - WAN_NETIF_START_QUEUE(lip_dev->common.dev); - }else{ - lip_dev->common.state = state; - WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); - WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); - } - - wan_update_api_state(lip_dev); - - wplip_trigger_bh(lip_dev->lip_link); - - }else if (lip_dev->common.lip) { /*STACK*/ - - if (state == WAN_CONNECTED){ - lip_dev->common.state = state; - WAN_NETIF_CARRIER_ON(lip_dev->common.dev); - WAN_NETIF_START_QUEUE(lip_dev->common.dev); - wplip_connect(lip_dev->common.lip,0); - }else{ - lip_dev->common.state = state; - WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) - WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); -#endif - wplip_disconnect(lip_dev->common.lip,0); - } - - }else{ - if (state == WAN_CONNECTED){ - lip_dev->common.state = state; - WAN_NETIF_CARRIER_ON(lip_dev->common.dev); - WAN_NETIF_WAKE_QUEUE(lip_dev->common.dev); - wplip_trigger_bh(lip_dev->lip_link); - }else{ - lip_dev->common.state = state; - WAN_NETIF_CARRIER_OFF(lip_dev->common.dev); -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) - WAN_NETIF_STOP_QUEUE(lip_dev->common.dev); -#endif - } - wplip_trigger_if_task(lip_dev); - } - - return 0; -} - - -/*============================================================== - * wplip_connect - * - * Description: - * The lowyer layer calls this function, when it - * becomes connected. - */ - -static void wplip_connect(void *wplip_id,int reason) -{ - wplip_link_t *lip_link = (wplip_link_t *)wplip_id; - - if (lip_link->carrier_state != WAN_CONNECTED){ - wan_smp_flag_t flags; - - DEBUG_EVENT("%s: Lip Link Carrier Connected! \n", - lip_link->name); - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - wan_skb_queue_purge(&lip_link->tx_queue); - wan_skb_queue_purge(&lip_link->rx_queue); - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - - wplip_kick(lip_link,0); - - lip_link->carrier_state = WAN_CONNECTED; - } - - if (lip_link->prot_state == WAN_CONNECTED){ - - DEBUG_EVENT("%s: Lip Link Connected! \n", - lip_link->name); - - lip_link->state = WAN_CONNECTED; - } -} - -/*============================================================== - * wplip_disconnect - * - * Description: - * The lowyer layer calls this function, when it - * becomes disconnected. - */ - -static void wplip_disconnect(void *wplip_id,int reason) -{ - wplip_link_t *lip_link = (wplip_link_t *)wplip_id; - - if (lip_link->carrier_state != WAN_DISCONNECTED){ - DEBUG_EVENT("%s: Lip Link Carrier Disconnected!\n", - lip_link->name); - lip_link->carrier_state = WAN_DISCONNECTED; - } - - /* state = carrier_state & prot_state - * Therefore, the overall state is down */ - if (lip_link->state != WAN_DISCONNECTED){ - lip_link->state = WAN_DISCONNECTED; - DEBUG_EVENT("%s: Lip Link Disconnected!\n",lip_link->name); - } -} - - - -/*============================================================== - * wplip_kick - * - * Description: - */ - -void wplip_kick(void *wplip_id,int reason) -{ - wplip_link_t *lip_link = (wplip_link_t *)wplip_id; - -#warning "NENAD" - DEBUG_EVENT("%s: LIP Kick!\n", - lip_link->name); - -#ifdef WPLIP_TTY_SUPPORT - if (lip_link->tty_opt){ - wanpipe_tty_trigger_poll(lip_link); - }else -#endif - { - wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); - wan_set_bit(WPLIP_KICK,&lip_link->tq_working); - wplip_kick_trigger_bh(lip_link); - } -} - -#define INTERFACES_FRM "%-15s| %-12s| %-6u| %-18s|\n" -static int wplip_get_if_status(void *wplip_id, void *mptr) -{ -#if defined(__LINUX__) - wplip_link_t *lip_link = (wplip_link_t *)wplip_id; - struct seq_file *m = (struct seq_file *)mptr; - wplip_dev_t *cur_dev; - unsigned long flag; - - WP_READ_LOCK(&lip_link->dev_list_lock,flag); - - WAN_LIST_FOREACH(cur_dev,&lip_link->list_head_ifdev,list_entry){ - PROC_ADD_LINE(m, - INTERFACES_FRM, - cur_dev->name, lip_link->name, - cur_dev->prot_addr, - STATE_DECODE(cur_dev->common.state)); - } - - WP_READ_UNLOCK(&lip_link->dev_list_lock,flag); - - return m->count; -#else - return -EINVAL; -#endif -} - - -int wplip_link_callback_tx_down(void *wplink_id, void *skb) -{ - wplip_link_t *lip_link = (wplip_link_t *)wplink_id; - - if (!lip_link || !skb){ - DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", - __FUNCTION__); - return 1; - } - - DEBUG_TEST("%s:%s: Protocol Packet Len=%i\n", - lip_link->name,__FUNCTION__,wan_skb_len(skb)); - - - if (lip_link->carrier_state != WAN_CONNECTED){ - DEBUG_TEST("%s: %s() Error Lip Link Carrier not connected !\n", - lip_link->name,__FUNCTION__); - wan_skb_free(skb); - return 0; - } - - if (wan_skb_queue_len(&lip_link->tx_queue) >= MAX_TX_BUF){ - DEBUG_TEST("%s: %s() Error Protocol Tx queue full !\n", - lip_link->name,__FUNCTION__); - wplip_trigger_bh(lip_link); - return 1; - } - - wan_skb_unlink(skb); - wan_skb_queue_tail(&lip_link->tx_queue,skb); - wplip_trigger_bh(lip_link); - - return 0; -} -int wplip_callback_tx_down(void *wplip_id, void *skb) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; - - if (!lip_dev){ - DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", - __FUNCTION__); - return 1; - } - - if (!skb){ - int free_space=lip_dev->max_mtu_sz - wan_skb_queue_len(&lip_dev->tx_queue); - if (free_space < 0) { - return 0; - } else { - return free_space; - } - } - - - DEBUG_TEST("%s:%s: Packet Len=%i\n", - lip_dev->name,__FUNCTION__,wan_skb_len(skb)); - - - if (lip_dev->lip_link->carrier_state != WAN_CONNECTED){ - DEBUG_TEST("%s: %s() Error Lip Link Carrier not connected !\n", - lip_dev->name,__FUNCTION__); - wan_skb_free(skb); - lip_dev->ifstats.tx_carrier_errors++; - return 0; - } - - if (wan_skb_queue_len(&lip_dev->tx_queue) >= lip_dev->max_mtu_sz){ - wplip_trigger_bh(lip_dev->lip_link); - DEBUG_TEST("%s: %s() Error Tx queue full Kick=%d!\n", - lip_dev->name,__FUNCTION__, - wan_test_bit(WPLIP_BH_AWAITING_KICK,&lip_dev->lip_link->tq_working)); - return 1; - } - - wan_skb_unlink(skb); - wan_skb_queue_tail(&lip_dev->tx_queue,skb); - wplip_trigger_bh(lip_dev->lip_link); - - return 0; -} - -int wplip_callback_kick_prot_task (void *wplink_id) -{ - wplip_link_t *lip_link = (wplip_link_t *)wplink_id; - - if (!lip_link){ - DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", - __FUNCTION__); - return 1; - } - - WAN_TASKQ_SCHEDULE((&lip_link->prot_task)); - - return 0; -} - -unsigned int wplip_get_ipv4_addr (void *wplip_id, int type) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; -#ifdef __LINUX__ - - struct in_ifaddr *ifaddr; - struct in_device *in_dev; - - if ((in_dev = in_dev_get(lip_dev->common.dev)) == NULL){ - return 0; - } - - if ((ifaddr = in_dev->ifa_list)== NULL ){ - in_dev_put(in_dev); - return 0; - } - in_dev_put(in_dev); - - switch (type){ - - case WAN_LOCAL_IP: - return ifaddr->ifa_local; - break; - - case WAN_POINTOPOINT_IP: - return ifaddr->ifa_address; - break; - - case WAN_NETMASK_IP: - return ifaddr->ifa_mask; - break; - - case WAN_BROADCAST_IP: - return ifaddr->ifa_broadcast; - break; - default: - return 0; - } -#else - netdevice_t *ifp = NULL; - struct ifaddr *ifa = NULL; - struct sockaddr_in *si; - - ifp = lip_dev->common.dev; - for (ifa = WAN_TAILQ_FIRST(ifp); ifa; ifa = WAN_TAILQ_NEXT(ifa)){ - if (ifa->ifa_addr->sa_family == AF_INET) { - si = (struct sockaddr_in *)ifa->ifa_addr; - if (si) break; - } - } - - if (ifa) { - switch (type){ - case WAN_LOCAL_IP: - if (ifa->ifa_addr){ - return (satosin(ifa->ifa_addr))->sin_addr.s_addr; - } - break; - case WAN_POINTOPOINT_IP: - if (ifa->ifa_dstaddr){ - return (satosin(ifa->ifa_dstaddr))->sin_addr.s_addr; - } - break; - case WAN_NETMASK_IP: - if (ifa->ifa_netmask){ - return (satosin(ifa->ifa_netmask))->sin_addr.s_addr; - } - break; - case WAN_BROADCAST_IP: - if (ifa->ifa_broadaddr){ - return (satosin(ifa->ifa_broadaddr))->sin_addr.s_addr; - } - break; - } - } -#endif - return 0; -} - - -/* PROTOCOL MUST CALL THIS ONLY - * FROM A PROT TASK */ - -int wplip_set_ipv4_addr (void *wplip_id, - unsigned int local, - unsigned int remote, - unsigned int netmask, - unsigned int dns) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; -#if defined(__LINUX__) - struct sockaddr_in *if_data; - struct ifreq if_info; - int err=0; - mm_segment_t fs; - netdevice_t *dev=lip_dev->common.dev; - - /* Setup a structure for adding/removing routes */ - memset(&if_info, 0, sizeof(if_info)); - strcpy(if_info.ifr_name, dev->name); - - if_data = (struct sockaddr_in *)&if_info.ifr_addr; - if_data->sin_addr.s_addr = local; - if_data->sin_family = AF_INET; - - fs = get_fs(); /* Save file system */ - set_fs(get_ds()); - err = wp_devinet_ioctl(SIOCSIFADDR, &if_info); - set_fs(fs); - - memset(&if_info, 0, sizeof(if_info)); - strcpy(if_info.ifr_name, dev->name); - - if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr; - if_data->sin_addr.s_addr = remote; - if_data->sin_family = AF_INET; - - fs = get_fs(); /* Save file system */ - set_fs(get_ds()); - err = wp_devinet_ioctl(SIOCSIFDSTADDR, &if_info); - set_fs(fs); - - return 0; -#else - netdevice_t *ifp = NULL; - struct ifaddr *ifa = NULL; - struct sockaddr_in *si = NULL; - - ifp = lip_dev->common.dev; - for (ifa = WAN_TAILQ_FIRST(ifp); ifa; ifa = WAN_TAILQ_NEXT(ifa)){ - if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET){ - si = (struct sockaddr_in *)ifa->ifa_addr; - if (si) break; - } - } - if (ifa && si){ - int error; -#if defined(__FreeBSD__) - struct in_ifaddr *ia; -#endif - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 103080000) - struct sockaddr_in new_sin = *si; - - new_sin.sin_addr.s_addr = htonl(src); - error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 1); -#else - /* delete old route */ - error = rtinit(ifa, (int)RTM_DELETE, RTF_HOST); - - /* set new address */ - si->sin_addr.s_addr = local; -#if defined(__FreeBSD__) - ia = ifatoia(ifa); - LIST_REMOVE(ia, ia_hash); - LIST_INSERT_HEAD(INADDR_HASH(si->sin_addr.s_addr), ia, ia_hash); -#endif -#if 0 - /* Local IP address */ - si = (struct sockaddr_in*)ifa->ifa_addr; - if (si){ - /* write new local IP address */ - si->sin_addr.s_addr = local; - } -#endif - /* Remote IP address */ - si = (struct sockaddr_in*)ifa->ifa_dstaddr; - if (si){ - /* write new remote IP address */ - si->sin_addr.s_addr = remote; - } - /* Netmask */ - si = (struct sockaddr_in*)ifa->ifa_netmask; - if (si){ - /* write new remote IP address */ - si->sin_addr.s_addr = htonl(0xFFFFFFFC); - } - - /* add new route */ - error = rtinit(ifa, (int)RTM_ADD, RTF_HOST); -#endif - } - return 0; -#endif -} - -void wplip_add_gateway(void *wplip_id) -{ - -#if 0 - wplip_dev_t *lip_dev = (wplip_dev_t *)wplip_id; -#endif - return; -} - - -int wplip_set_hw_idle_frame (void *liplink_ptr, unsigned char *data, int len) -{ - - wplip_link_t *lip_link = (wplip_link_t *)liplink_ptr; - - if (!lip_link){ - DEBUG_EVENT("%s: Assertion error lip_dev=NULL!\n", - __FUNCTION__); - return 1; - } - - DEBUG_EVENT("%s: Warning: %s Not supported!\n", - lip_link->name,__FUNCTION__); - - return 0; -} - - -/*************************************************************** - * Private Device Functions - */ - -#ifdef __LINUX__ -static int wplip_change_dev_flags (netdevice_t *dev, unsigned flags) -{ - struct ifreq if_info; - mm_segment_t fs = get_fs(); - int err; - - memset(&if_info, 0, sizeof(if_info)); - strcpy(if_info.ifr_name, dev->name); - if_info.ifr_flags = flags; - - set_fs(get_ds()); /* get user space block */ - err = wp_devinet_ioctl(SIOCSIFFLAGS, &if_info); - set_fs(fs); - - return err; -} -#endif - - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -static void wplip_if_task (void *arg, int dummy) -#else -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -static void wplip_if_task (void *arg) -# else -static void wplip_if_task (struct work_struct *work) -# endif -#endif -{ -#if defined(__LINUX__) - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) - wplip_dev_t *lip_dev=(wplip_dev_t *)container_of(work, wplip_dev_t, if_task); -#else - wplip_dev_t *lip_dev=(wplip_dev_t *)arg; -#endif - wplip_link_t *lip_link; - netdevice_t *dev; - - if (!lip_dev || !lip_dev->common.dev){ - return; - } - - if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)){ - return; - } - - if (!wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) || - !wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)){ - return; - } - - DEBUG_TEST("%s:%d: Device %s\n",__FUNCTION__,__LINE__,lip_dev->name); - - lip_link = lip_dev->lip_link; - dev=lip_dev->common.dev; - - switch (lip_dev->common.state){ - - case WAN_DISCONNECTED: - - /* If the dynamic interface configuration is on, and interface - * is up, then bring down the netowrk interface */ - - if (wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) && - !wan_test_bit(DEV_DOWN, &lip_dev->interface_down) && - dev->flags & IFF_UP){ - - DEBUG_EVENT("%s: Interface %s down.\n", - lip_link->name,dev->name); - wplip_change_dev_flags(dev,(dev->flags&~IFF_UP)); - wan_set_bit(DEV_DOWN,&lip_dev->interface_down); - - } - - break; - - case WAN_CONNECTED: - - /* In SMP machine this code can execute before the interface - * comes up. In this case, we must make sure that we do not - * try to bring up the interface before dev_open() is finished */ - - - /* DEV_DOWN will be set only when we bring down the interface - * for the very first time. This way we know that it was us - * that brought the interface down */ - - if (wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) && - wan_test_bit(DEV_DOWN, &lip_dev->interface_down) && - !(dev->flags & IFF_UP)){ - - DEBUG_EVENT("%s: Interface %s up.\n", - lip_link->name,dev->name); - wplip_change_dev_flags(dev,(dev->flags|IFF_UP)); - wan_clear_bit(DEV_DOWN,&lip_dev->interface_down); - } - - break; - } - -#endif - -} - -void wplip_trigger_if_task(wplip_dev_t *lip_dev) -{ - - if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)){ - return; - } - - if (wan_test_bit(DYN_OPT_ON,&lip_dev->interface_down) && - wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)){ - WAN_TASKQ_SCHEDULE((&lip_dev->if_task)); - } - - return; -} - -/*************************************************************** - * Module Interface Functions - * - */ - -/*============================================================== - * wanpipe_lip_init - * - * Description: - * This function is called on module startup. - * (ex: modprobe wanpipe_lip) - * - * Register the lip callback functions to the - * wanmain which are used by the socket or - * upper layer. - */ - - -static unsigned char wplip_fullname[]="WANPIPE(tm) L.I.P Network Layer"; -static unsigned char wplip_copyright[]="(c) 1995-2004 Sangoma Technologies Inc."; - -int wanpipe_lip_init(void*); -int wanpipe_lip_exit(void*); - -int wanpipe_lip_init(void *arg) -{ - wplip_reg_t reg; - int err; - - if (WANPIPE_VERSION_BETA){ - DEBUG_EVENT("%s Beta %s.%s %s\n", - wplip_fullname, WANPIPE_VERSION, WANPIPE_SUB_VERSION,wplip_copyright); - }else{ - DEBUG_EVENT("%s Stable %s.%s %s\n", - wplip_fullname, WANPIPE_VERSION, WANPIPE_SUB_VERSION, wplip_copyright); - } - - err=wplip_init_prot(); - if (err){ - wplip_free_prot(); - return err; - } - - wplip_link_lock=RW_LOCK_UNLOCKED; - - memset(®,0,sizeof(wplip_reg_t)); - - reg.wplip_bind_link = wplip_bind_link; - reg.wplip_unbind_link = wplip_unbind_link; - - reg.wplip_if_reg = wplip_if_reg; - reg.wplip_if_unreg = wplip_if_unreg; - - reg.wplip_disconnect = wplip_disconnect; - reg.wplip_connect = wplip_connect; - - reg.wplip_rx = wplip_rx; - reg.wplip_kick = wplip_kick; - - reg.wplip_register = wplip_register; - reg.wplip_unreg = wplip_unreg; - - reg.wplip_get_if_status = wplip_get_if_status; - - register_wanpipe_lip_protocol(®); - - memset(&wplip_link_num,0,sizeof(wplip_link_num)); - - return 0; -} - -int wanpipe_lip_exit (void *arg) -{ - if (!WAN_LIST_EMPTY(&list_head_link)){ - DEBUG_EVENT("%s: Major error: List not empty!\n",__FUNCTION__); - } - - unregister_wanpipe_lip_protocol(); - wplip_free_prot(); - - DEBUG_EVENT("WANPIPE L.I.P: Unloaded\n"); - return 0; -} - -#if 0 -MODULE_AUTHOR("Nenad Corbic "); -MODULE_DESCRIPTION("Wanpipe L.I.P Network Layer - Sangoma Tech. Copyright 2004"); -MODULE_LICENSE("GPL"); -module_init(wanpipe_lip_init); -module_exit(wanpipe_lip_exit); -#endif - -WAN_MODULE_DEFINE( - wanpipe_lip,"wanpipe_lip", - "Nenad Corbic ", - "Wanpipe L.I.P Network Layer - Sangoma Tech. Copyright 2004", - "GPL", - wanpipe_lip_init, wanpipe_lip_exit, NULL); -WAN_MODULE_DEPEND(wanpipe_lip, wanrouter, 1, - WANROUTER_MAJOR_VER, WANROUTER_MAJOR_VER); -WAN_MODULE_DEPEND(wanpipe_lip, wanpipe, 1, - WANPIPE_MAJOR_VER, WANPIPE_MAJOR_VER); - diff --git a/patches/kdrivers/src/lip/wanpipe_lip_netdev.c b/patches/kdrivers/src/lip/wanpipe_lip_netdev.c index 7ed8cb8..57f09b5 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_netdev.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_netdev.c @@ -29,10 +29,6 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct char* get_master_dev_name(wplip_link_t *lip_link); -#ifdef __LINUX__ -static int wplip_change_mtu(netdevice_t *dev, int new_mtu); -#endif - /*============================================================== * wplip_open_dev * @@ -59,23 +55,18 @@ int wplip_open_dev(netdevice_t *dev) if (!lip_dev || !lip_dev->lip_link){ return -ENODEV; } - + if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical)) { return -ENODEV; } #if defined(__LINUX__) - # if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) if (netif_running(dev)) return -EBUSY; # endif - - /* Updated the lower level MTU based on the interface MTU */ - wplip_change_mtu(lip_dev->common.dev, dev->mtu); #endif - wan_clear_bit(0,&lip_dev->if_down); #if 0 @@ -87,7 +78,7 @@ int wplip_open_dev(netdevice_t *dev) } #endif -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) +#if defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) if (lip_dev->lip_link->state == WAN_CONNECTED){ WAN_NETIF_CARRIER_ON(dev); WAN_NETIF_WAKE_QUEUE(dev); @@ -100,7 +91,8 @@ int wplip_open_dev(netdevice_t *dev) #endif /* Its possible for state update to be skipped if interface was down */ - wplip_lipdev_prot_update_state_change(lip_dev,NULL,0); + wplip_lipdev_prot_update_state_change(lip_dev,NULL,0); + if (!wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)) { wan_set_bit(WAN_DEV_READY,&lip_dev->interface_down); @@ -135,8 +127,6 @@ int wplip_stop_dev(netdevice_t *dev) return 0; } - wan_set_bit(0,&lip_dev->if_down); - #ifdef WPLIP_TTY_SUPPORT if (lip_dev->lip_link->tty_opt && lip_dev->lip_link->tty_open){ tty_hangup(lip_dev->lip_link->tty); @@ -144,6 +134,8 @@ int wplip_stop_dev(netdevice_t *dev) } #endif + wan_set_bit(0,&lip_dev->if_down); + #if 0 /* Done in if register now, do it interface up down * feature on 2.4 kernels */ @@ -154,7 +146,7 @@ int wplip_stop_dev(netdevice_t *dev) } - +#if defined(__LINUX__) /*============================================================== * wplip_ifstats * @@ -176,12 +168,12 @@ struct net_device_stats* wplip_ifstats (netdevice_t *dev) wan_netif_name(dev),__FUNCTION__); if (lip_dev){ - return &lip_dev->ifstats; + return &lip_dev->common.if_stats; } return &gstats; } - +#endif /*============================================================== @@ -224,7 +216,6 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct return 1; } - #if 1 if (lip_dev->common.state != WAN_CONNECTED){ #else @@ -232,18 +223,18 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct lip_dev->common.state != WAN_CONNECTED){ #endif -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) +#if defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) /* This causes a buffer starvations on some * applications like OSPF, since packets are * trapped in the Interface TX queue */ WAN_NETIF_STOP_QUEUE(dev); wan_netif_set_ticks(dev, SYSTEM_TICKS); - ++lip_dev->ifstats.tx_carrier_errors; + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&lip_dev->common); //++lip_dev->ifstats.tx_carrier_errors; return 1; #else wan_skb_free(skb); - lip_dev->ifstats.tx_carrier_errors++; + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&lip_dev->common); //lip_dev->ifstats.tx_carrier_errors++; WAN_NETIF_START_QUEUE(dev); wan_netif_set_ticks(dev, SYSTEM_TICKS); return 0; @@ -264,7 +255,7 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct if (lip_dev->common.usedby == API){ if (wan_skb_len(skb) <= sizeof(wan_api_tx_hdr_t)){ wan_skb_free(skb); - lip_dev->ifstats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&lip_dev->common); //lip_dev->ifstats.tx_errors++; WAN_NETIF_START_QUEUE(dev); wan_netif_set_ticks(dev, SYSTEM_TICKS); return 0; @@ -300,7 +291,7 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct default: /* Packet dropped due to error */ WAN_NETIF_START_QUEUE(dev); - lip_dev->ifstats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&lip_dev->common); //lip_dev->ifstats.tx_errors++; wan_netif_set_ticks(dev, SYSTEM_TICKS); wan_skb_free(skb); err=0; @@ -332,55 +323,6 @@ int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct } #if defined(__LINUX__) - -static int wplip_change_mtu(netdevice_t *dev, int new_mtu) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); - wplip_link_t *lip_link = lip_dev->lip_link; - netdevice_t *hw_dev; - wplip_dev_list_t *lip_dev_list_el; - int err = 0; - - if (!lip_link->tx_dev_cnt){ - DEBUG_EVENT("%s: %s: Tx Dev not available\n", - __FUNCTION__,lip_link->name); - return -ENODEV; - } - - /* FIXME: - * For now, we can only transmit on a FIRST Tx device */ - lip_dev_list_el=WAN_LIST_FIRST(&lip_link->list_head_tx_ifdev); - if (!lip_dev_list_el){ - DEBUG_EVENT("%s: %s: Tx Dev List empty!\n", - __FUNCTION__,lip_link->name); - return -ENODEV; - } - - if (lip_dev_list_el->magic != WPLIP_MAGIC_DEV_EL){ - DEBUG_EVENT("%s: %s: Error: Invalid dev magic number!\n", - __FUNCTION__,lip_link->name); - return -EFAULT; - } - - hw_dev=lip_dev_list_el->dev; - if (!hw_dev){ - DEBUG_EVENT("%s: %s: Error: No dev! dropping...\n", - __FUNCTION__,lip_link->name); - return -ENODEV; - } - - if (hw_dev->change_mtu) { - err = hw_dev->change_mtu(hw_dev,new_mtu); - } - - if (err == 0) { - dev->mtu = new_mtu; - } - - return err; -} - - static void wplip_tx_timeout (netdevice_t *dev) { wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); @@ -408,7 +350,8 @@ static void wplip_tx_timeout (netdevice_t *dev) } #endif -static int wplip_ioctl (netdevice_t *dev, struct ifreq *ifr, int cmd) +static int +wplip_ioctl (netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t cmd) { wplip_dev_t *lip_dev= wplip_get_lipdev(dev); @@ -438,15 +381,6 @@ static int wplip_ioctl (netdevice_t *dev, struct ifreq *ifr, int cmd) err= -EINVAL; break; } - - if (!WAN_NETIF_UP(dev)){ - return -ENETDOWN; - } - - if (wan_test_bit(WPLIP_DEV_UNREGISTER,&lip_dev->critical) || - wan_test_bit(0,&lip_dev->if_down)) { - return -ENETDOWN; - } wan_spin_lock_irq(&lip_link->bh_lock,&flags); @@ -651,8 +585,6 @@ int wplip_if_init(netdevice_t *dev) lip_dev->common.iface.ioctl = &wplip_ioctl; lip_dev->common.iface.tx_timeout= &wplip_tx_timeout; lip_dev->common.iface.get_stats = &wplip_ifstats; - lip_dev->common.iface.get_stats = &wplip_ifstats; - lip_dev->common.iface.change_mtu = &wplip_change_mtu; return 0; #else diff --git a/patches/kdrivers/src/lip/wanpipe_lip_netdev.c~ b/patches/kdrivers/src/lip/wanpipe_lip_netdev.c~ deleted file mode 100644 index a47a1c9..0000000 --- a/patches/kdrivers/src/lip/wanpipe_lip_netdev.c~ +++ /dev/null @@ -1,612 +0,0 @@ -/************************************************************* - * wanpipe_lip_netdev.c WANPIPE Link Interface Protocol Layer (LIP) - * - * - * - * =========================================================== - * - * Mar 30 2004 Nenad Corbic Initial Driver - */ - - -/*============================================================= - * Includes - */ - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# include -#else -# include -#endif - - -/*============================================================= - * Definitions - */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct rtentry* rt); -#endif - -char* get_master_dev_name(wplip_link_t *lip_link); - -/*============================================================== - * wplip_open_dev - * - * Description: - * This function enables the svc network device, and - * sets it up for data transfer. - * - * It is called by the kernel during interfaces - * startup via ifconfig: - * ex: ifconfig wp1_svc up - * - * If the network device contains IP data, its - * operation mode is set to TCP/IP otherwise, - * the opteration mode is API. - * - * Usedby: - * Kernel during ifconfig system call. - */ - -int wplip_open_dev(netdevice_t *dev) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); - - if (!lip_dev || !lip_dev->lip_link){ - return -ENODEV; - } - -#if defined(__LINUX__) -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) - if (netif_running(dev)) - return -EBUSY; -# endif -#endif - - -#if 0 - /* Done in if register now, do it interface up down - * feature on 2.4 kernels */ - err=wplip_open_lipdev_prot(lip_dev); - if (err){ - return err; - } -#endif - -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) - if (lip_dev->lip_link->state == WAN_CONNECTED){ - WAN_NETIF_CARRIER_ON(dev); - WAN_NETIF_WAKE_QUEUE(dev); - } -#else - if (lip_dev->lip_link->state == WAN_CONNECTED){ - WAN_NETIF_CARRIER_ON(dev); - } - WAN_NETIF_WAKE_QUEUE(dev); -#endif - - if (!wan_test_bit(WAN_DEV_READY,&lip_dev->interface_down)) { - wan_set_bit(WAN_DEV_READY,&lip_dev->interface_down); - wplip_trigger_if_task(lip_dev); - } - return 0; -} - -/*============================================================== - * wplip_stop_dev - * - * Description: - * This function disables the svc network device. - * - * It is called by the kernel during interfaces - * shutdown via ifconfig: - * ex: ifconfig wp1_svc down - * - * If the svc is in connected state, the call - * will be disconnected. - * - * Usedby: - * Kernel during ifconfig system call. - */ - -int wplip_stop_dev(netdevice_t *dev) -{ - - wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); - - if (!lip_dev || !lip_dev->lip_link){ - return 0; - } - -#ifdef WPLIP_TTY_SUPPORT - if (lip_dev->lip_link->tty_opt && lip_dev->lip_link->tty_open){ - tty_hangup(lip_dev->lip_link->tty); - return -EBUSY; - } -#endif - -#if 0 - /* Done in if register now, do it interface up down - * feature on 2.4 kernels */ - wplip_close_lipdev_prot(lip_dev); -#endif - - return 0; -} - - - -/*============================================================== - * wplip_ifstats - * - * Description: - * This fucntion interfaces the /proc file system - * to the svc device. The svc keeps protocol and - * packet statistcs. This function passes these - * statistics to the /proc file system. - * - * Usedby: - * Kernel /proc/net/dev file system - */ -static struct net_device_stats gstats; -struct net_device_stats* wplip_ifstats (netdevice_t *dev) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); - - DEBUG_TEST("%s: LIP %s()\n", - wan_netif_name(dev),__FUNCTION__); - - if (lip_dev){ - return &lip_dev->ifstats; - } - - return &gstats; -} - - - -/*============================================================== - * wplip_if_send - * - * Description: - * Call back function used by the kernel or the - * upper protocol layer to transmit data for each - * svc withing the x25 link. - * - * Data can only be tranmsitted if the svc state - * is connected. - * - * If state != CONNECTED && If svc mode=TCP/IP - * place an x25 call and try to establish - * connection. - * - * If state != CONNECTED && If svc mode=API - * refuse the packet, and indicate to - * the upper layer that the connection has - * not been made. - * - * - * Usedby: - * Kernel TCP/IP stack or upper layers to transmit data. - */ - -#if defined(__LINUX__) -int wplip_if_send (netskb_t* skb, netdevice_t* dev) -#else -int wplip_if_output (netdevice_t* dev,netskb_t* skb,struct sockaddr* sa, struct rtentry* rt) -#endif -{ - wplip_dev_t *lip_dev =wplip_get_lipdev(dev); - wan_api_tx_hdr_t *api_tx_hdr =NULL; - int err, type; - - if (!lip_dev || !lip_dev->lip_link){ - WAN_NETIF_STOP_QUEUE(dev); - return 1; - } - - -#if 1 - if (lip_dev->common.state != WAN_CONNECTED){ -#else - if (lip_dev->lip_link->carrier_state != WAN_CONNECTED || - lip_dev->common.state != WAN_CONNECTED){ -#endif - -#if defined(WANPIPE_LIP_IFNET_QUEUE_POLICY_INIT_OFF) - /* This causes a buffer starvations on some - * applications like OSPF, since packets are - * trapped in the Interface TX queue */ - - WAN_NETIF_STOP_QUEUE(dev); - wan_netif_set_ticks(dev, SYSTEM_TICKS); - ++lip_dev->ifstats.tx_carrier_errors; - return 1; -#else - wan_skb_free(skb); - lip_dev->ifstats.tx_carrier_errors++; - WAN_NETIF_START_QUEUE(dev); - wan_netif_set_ticks(dev, SYSTEM_TICKS); - return 0; -#endif - } - - /*if (wan_skb_check(skb)){ - ** if (wan_skb2buffer((void**)&skb)){ - ** wan_skb_free(skb); - ** lip_dev->ifstats.tx_errors++; - ** WAN_NETIF_START_QUEUE(dev); - ** wan_netif_set_ticks(dev, SYSTEM_TICKS); - ** return 0; - ** - ** } - **} */ - - if (lip_dev->common.usedby == API){ - if (wan_skb_len(skb) <= sizeof(wan_api_tx_hdr_t)){ - wan_skb_free(skb); - lip_dev->ifstats.tx_errors++; - WAN_NETIF_START_QUEUE(dev); - wan_netif_set_ticks(dev, SYSTEM_TICKS); - return 0; - } - api_tx_hdr=(wan_api_tx_hdr_t*)wan_skb_pull(skb,sizeof(wan_api_tx_hdr_t)); - - type = WPLIP_RAW; - }else{ -#if defined(__LINUX__) - type = wplip_decode_protocol(lip_dev,skb); -#else - type = wplip_decode_protocol(lip_dev,sa); -#endif - } - - - err=wplip_prot_tx(lip_dev, api_tx_hdr, skb, type); - switch (err){ - - case 0: - /* Packet queued ok */ - wan_netif_set_ticks(dev, SYSTEM_TICKS); - WAN_NETIF_START_QUEUE(dev); - err=0; - break; - - case 1: - /* Packet failed to queue layer busy */ -#warning "NENAD" - DEBUG_EVENT("%s: Api Dev BUSY!\n",lip_dev->name); - WAN_NETIF_STOP_QUEUE(dev); - err=1; - break; - - default: - /* Packet dropped due to error */ - WAN_NETIF_START_QUEUE(dev); - lip_dev->ifstats.tx_errors++; - wan_netif_set_ticks(dev, SYSTEM_TICKS); - wan_skb_free(skb); - err=0; - break; - } - - wplip_trigger_bh(lip_dev->lip_link); - -#if defined(__LINUX__) - if (lip_dev->protocol != WANCONFIG_LIP_ATM) { - if (dev->tx_queue_len < lip_dev->max_mtu_sz && - dev->tx_queue_len > 0) { - DEBUG_EVENT("%s: Resizing Tx Queue Len to %li\n", - lip_dev->name,dev->tx_queue_len); - lip_dev->max_mtu_sz = dev->tx_queue_len; - wplip_lipdev_latency_change(lip_dev->lip_link); - - } else if (dev->tx_queue_len > lip_dev->max_mtu_sz && - lip_dev->max_mtu_sz != lip_dev->max_mtu_sz_orig) { - DEBUG_EVENT("%s: Resizing Tx Queue Len to %i\n", - lip_dev->name,lip_dev->max_mtu_sz_orig); - lip_dev->max_mtu_sz = lip_dev->max_mtu_sz_orig; - wplip_lipdev_latency_change(lip_dev->lip_link); - } - } -#endif - - return err; -} - -#if defined(__LINUX__) -static void wplip_tx_timeout (netdevice_t *dev) -{ - wplip_dev_t *lip_dev = (wplip_dev_t *)wan_netif_priv(dev); - wplip_link_t *lip_link = lip_dev->lip_link; - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - -#if 0 - gdbg_flag=1; -#endif - wan_clear_bit(WPLIP_BH_AWAITING_KICK,&lip_link->tq_working); - wplip_kick_trigger_bh(lip_link); - - WAN_NETIF_WAKE_QUEUE (dev); - - if (lip_dev->common.usedby == API){ - wan_update_api_state(lip_dev); - } - - wan_netif_set_ticks(dev, SYSTEM_TICKS); -} -#endif - -static int wplip_ioctl (netdevice_t *dev, struct ifreq *ifr, int cmd) -{ - - wplip_dev_t *lip_dev= wplip_get_lipdev(dev); - wplip_link_t *lip_link; - wan_smp_flag_t flags; - int err=0; - wan_udp_pkt_t *wan_udp_pkt; - - if (!lip_dev || !lip_dev->lip_link){ - DEBUG_EVENT("%s:%d: Assertion Error on lip_dev (%s)!\n", - __FUNCTION__,__LINE__, wan_netif_name(dev)); - return -EINVAL; - } - - lip_link = lip_dev->lip_link; - if (lip_link == NULL){ - DEBUG_EVENT("%s:%d: Assertion Error on lip_dev (%s)!\n", - __FUNCTION__,__LINE__, wan_netif_name(dev)); - return -EINVAL; - } - - switch (cmd){ - -#if defined(__LINUX__) - case SIOC_WANPIPE_BIND_SK: - if (ifr == NULL){ - err= -EINVAL; - break; - } - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - - if (lip_dev->common.usedby == API){ - dev->watchdog_timeo=HZ*60; - } - - err=wan_bind_api_to_svc(lip_dev,ifr->ifr_data); - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - break; - - case SIOC_WANPIPE_UNBIND_SK: - if (ifr == NULL){ - err= -EINVAL; - break; - } - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - err=wan_unbind_api_from_svc(lip_dev,ifr->ifr_data); - if (lip_dev->common.usedby == API && - lip_dev->protocol == WANCONFIG_XDLC){ - wplip_close_lipdev_prot(lip_dev); - } - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - break; - - case SIOC_WANPIPE_CHECK_TX: - case SIOC_ANNEXG_CHECK_TX: - err=0; - break; - - case SIOC_WANPIPE_DEV_STATE: - err = lip_dev->common.state; - break; - - case SIOC_ANNEXG_KICK: - break; -#endif - - case SIOC_WANPIPE_PIPEMON: - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - if (lip_dev->udp_pkt_len != 0){ - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - return -EBUSY; - } - lip_dev->udp_pkt_len = sizeof(wan_udp_hdr_t); - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - - wan_udp_pkt=(wan_udp_pkt_t*)&lip_dev->udp_pkt_data; - if (WAN_COPY_FROM_USER(&wan_udp_pkt->wan_udp_hdr,ifr->ifr_data,sizeof(wan_udp_hdr_t))){ - lip_dev->udp_pkt_len=0; - return -EFAULT; - } - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - - if(wan_udp_pkt->wan_udp_command == WAN_GET_MASTER_DEV_NAME){ - char* master_dev_name; - - master_dev_name = get_master_dev_name(lip_link); - if(master_dev_name == NULL){ - - wan_udp_pkt->wan_udp_return_code = 1; - wan_udp_pkt->wan_udp_data_len = 1; - }else{ - strncpy(&wan_udp_pkt->wan_udp_data[0], - master_dev_name, - strlen(master_dev_name)); - wan_udp_pkt->wan_udp_return_code = 0; - wan_udp_pkt->wan_udp_data_len = strlen(master_dev_name); - } - }else{ - if (wplip_prot_udp_mgmt_pkt(lip_dev,wan_udp_pkt) <= 0){ - lip_dev->udp_pkt_len=0; - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - return -EINVAL; - } - } - - if (lip_dev->udp_pkt_len > sizeof(wan_udp_pkt_t)){ - DEBUG_EVENT("%s: Error: Pipemon buf too bit on the way up! %i\n", - lip_dev->name,lip_dev->udp_pkt_len); - lip_dev->udp_pkt_len=0; - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - return -EINVAL; - } - - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - - /* This area will still be critical to other - * PIPEMON commands due to udp_pkt_len - * thus we can release the irq */ - - if (WAN_COPY_TO_USER(ifr->ifr_data,&wan_udp_pkt->wan_udp_hdr,sizeof(wan_udp_hdr_t))){ - lip_dev->udp_pkt_len=0; - return -EFAULT; - } - - lip_dev->udp_pkt_len=0; - return 0; - - case SIOC_WANPIPE_SNMP: - wplip_prot_udp_snmp_pkt(lip_dev,cmd,ifr); - return 0; - - case SIOC_WANPIPE_SNMP_IFSPEED: - DEBUG_EVENT("%s: SNMP Speed not supported on protocol interface!\n", - lip_dev->name); - return -1; - - default: - -#if defined(__LINUX__) - if (cmd >= SIOC_WANPIPE_DEVPRIVATE) - { - - wan_spin_lock_irq(&lip_link->bh_lock,&flags); - cmd-=SIOC_WANPIPE_DEVPRIVATE; - if (ifr == NULL){ - err=wplip_prot_ioctl(lip_dev,cmd,NULL); - }else{ - err=wplip_prot_ioctl(lip_dev,cmd,ifr->ifr_data); - } - wan_spin_unlock_irq(&lip_link->bh_lock,&flags); - - return err; - } -#endif - -# if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) - return 1; -#else - DEBUG_TEST("%s: Command %x not supported!\n", - lip_link->name,cmd); - return -EOPNOTSUPP; -#endif - } - - return err; - -} - -char* get_master_dev_name(wplip_link_t *lip_link) -{ - wplip_dev_list_t *lip_dev_list_el; - netdevice_t *dev; - - if (!lip_link->tx_dev_cnt){ - DEBUG_EVENT("%s: %s: Tx Dev List empty!\n", - __FUNCTION__,lip_link->name); - return NULL; - } - - lip_dev_list_el=WAN_LIST_FIRST(&lip_link->list_head_tx_ifdev); - if (!lip_dev_list_el){ - DEBUG_EVENT("%s: %s: Tx Dev List empty!\n", - __FUNCTION__,lip_link->name); - return NULL; - } - - if (lip_dev_list_el->magic != WPLIP_MAGIC_DEV_EL){ - DEBUG_EVENT("%s: %s: Error: Invalid dev magic number!\n", - __FUNCTION__,lip_link->name); - return NULL; - } - - dev=lip_dev_list_el->dev; - if (!dev){ - DEBUG_EVENT("%s: %s: Error: No dev!\n", - __FUNCTION__,lip_link->name); - return NULL; - } - - return wan_netif_name(dev); -} - -/*============================================================== - * wplip_if_init - * - * Description: - * During device registration, this function is - * called to fill in the call back functions - * used in nework device setup and operation. - * - * The kernel interfaces the driver, using the - * call back functions below. - * - * Usedby: - * Kernel during register_netdevice() in x25_register - * function. - */ -int wplip_if_init(netdevice_t *dev) -{ - wplip_dev_t* lip_dev= wplip_get_lipdev(dev); - -#if defined(__LINUX__) - lip_dev->common.is_netdev = 1; - lip_dev->common.iface.open = &wplip_open_dev; - lip_dev->common.iface.close = &wplip_stop_dev; - lip_dev->common.iface.send = &wplip_if_send; - lip_dev->common.iface.ioctl = &wplip_ioctl; - lip_dev->common.iface.tx_timeout= &wplip_tx_timeout; - lip_dev->common.iface.get_stats = &wplip_ifstats; - - return 0; -#else - DEBUG_EVENT("%s: Initialize network interface...\n", - wan_netif_name(dev)); - - lip_dev->common.is_netdev = 1; - lip_dev->common.iface.open = &wplip_open_dev; - lip_dev->common.iface.close = &wplip_stop_dev; - lip_dev->common.iface.output = &wplip_if_output; - lip_dev->common.iface.ioctl = &wplip_ioctl; - - dev->if_type = IFT_PPP; - dev->if_mtu = 1500; -#if 0 -/* Remove this later (wanpipe_bsd_iface.c doing this) */ - dev->if_output = NULL; - dev->if_start = &wplip_if_start; - dev->if_ioctl = NULL; /* &wplip_ioctl; */ - - /* Initialize media-specific parameters */ - dev->if_flags |= IFF_POINTOPOINT; - dev->if_flags |= IFF_NOARP; - - dev->if_mtu = 1500; - WAN_IFQ_SET_MAXLEN(&dev->if_snd, 100); - dev->if_snd.ifq_len = 0; - dev->if_type = IFT_PPP; -#endif - return 0; -#endif -} - - diff --git a/patches/kdrivers/src/lip/wanpipe_lip_prot.c b/patches/kdrivers/src/lip/wanpipe_lip_prot.c index 37cbebf..f72d2c5 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_prot.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_prot.c @@ -140,7 +140,6 @@ int wplip_reg_lipdev_prot(wplip_dev_t *lip_dev, wanif_conf_t *conf) return -EINVAL; } - WPLIP_PROT_EXIST(lip_dev->protocol,-ENODEV); prot_iface=wplip_prot_ops[lip_dev->protocol]; diff --git a/patches/kdrivers/src/lip/wanpipe_lip_sub.c b/patches/kdrivers/src/lip/wanpipe_lip_sub.c index fccc73c..bd5d785 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_sub.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_sub.c @@ -60,7 +60,7 @@ wplip_link_t *wplip_create_link(char *devname) wan_skb_queue_init(&lip_link->tx_queue); wan_skb_queue_init(&lip_link->rx_queue); - wan_spin_lock_init(&lip_link->bh_lock); + wan_spin_lock_irq_init(&lip_link->bh_lock, "wan_lip_bh_lock"); wan_atomic_set(&lip_link->refcnt,0); diff --git a/patches/kdrivers/src/lip/wanpipe_lip_tty.c b/patches/kdrivers/src/lip/wanpipe_lip_tty.c index 2ab095a..52b8897 100644 --- a/patches/kdrivers/src/lip/wanpipe_lip_tty.c +++ b/patches/kdrivers/src/lip/wanpipe_lip_tty.c @@ -303,7 +303,7 @@ void wplip_tty_receive(wplip_link_t *lip_link, void *skb) if (WAN_NET_RATELIMIT()){ DEBUG_EVENT( "%s: Received packet size too big: %d bytes, Max: %d!\n", - lip_link->name,wan_skb_len(skb),TTY_MAX_MTU); + lip_link->name,wan_skb_len(skb),TTY_FLIPBUF_SIZE); } wan_skb_free(skb); return; diff --git a/patches/kdrivers/src/net/Makefile b/patches/kdrivers/src/net/Makefile index 9730673..d13010c 100644 --- a/patches/kdrivers/src/net/Makefile +++ b/patches/kdrivers/src/net/Makefile @@ -17,33 +17,31 @@ CONFIG_WANPIPE_MULTPPP=n EXTRA_CFLAGS=$(EXTRA_FLAGS) -PRODUCT_DEFINES= -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_AFT +PRODUCT_DEFINES= -DCONFIG_PRODUCT_WANPIPE_BASE -DCONFIG_PRODUCT_WANPIPE_AFT -DCONFIG_PRODUCT_WANPIPE_AFT_CORE PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_AFT_TE1 -DCONFIG_PRODUCT_WANPIPE_AFT_TE3 -PRODUCT_DEFINES+= -DCONFIG_WANPIPE_HWEC -DCONFIG_PRODUCT_WANPIPE_SOCK_DATASCOPE +PRODUCT_DEFINES+= -DCONFIG_WANPIPE_HWEC -DCONFIG_PRODUCT_WANPIPE_SOCK_DATASCOPE -DCONFIG_PRODUCT_WANPIPE_AFT_BRI -DCONFIG_PRODUCT_WANPIPE_AFT_SERIAL PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN -DCONFIG_PRODUCT_WANPIPE_CODEC_SLINEAR_LAW -PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_MULTPROT wanpipe-y := sdlamain.o ifneq (,$(ZAPDIR)) PRODUCT_DEFINES += -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE -wanpipe-y += sdla_tdmv.o sdla_remora_tdmv.o +wanpipe-y += sdla_tdmv.o sdla_remora_tdmv.o sdla_bri_tdmv.o ifneq (,$(wildcard $(ZAPHDLC))) PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL endif endif - wanpipe-y += sdla_ft1.o sdla_te1.o sdla_te3.o sdla_56k.o sdla_8te1.o wanpipe-y += wanpipe_tdm_api.o wanpipe-y += sdla_xilinx.o sdla_aft_te1.o aft_a104.o wanpipe-y += aft_analog.o sdla_aft_te3.o wanpipe_utils.o wanpipe-y += wanpipe_abstr.o wanpipe_linux_iface.o wanpipe-y += wanpipe_tdm_api.o sdla_remora.o +wanpipe-y += sdla_bri.o aft_bri.o sdla_serial.o wanpipe-y += wanpipe_codec.o wanpipe_codec_law.o -wanpipe-y += wanpipe_multppp.o EXTRA_CFLAGS += $(PRODUCT_DEFINES) @@ -76,7 +74,7 @@ wanec-y += $(OCTAPIDIR)/oct6100_user.o wanec-objs := $(wanec-y) -sdladrv-objs := sdladrv_src.o sdladrv_fe.o +sdladrv-objs := sdladrv_src.o sdladrv_fe.o sdladrv_utils.o wanrouter-objs := ../wanrouter/wanmain.o ../wanrouter/wanproc.o ../wanrouter/waniface.o diff --git a/patches/kdrivers/src/net/Module.symvers b/patches/kdrivers/src/net/Module.symvers index a072c79..bf2445d 100644 --- a/patches/kdrivers/src/net/Module.symvers +++ b/patches/kdrivers/src/net/Module.symvers @@ -1,56 +1,56 @@ -0xf7567a8a wanpipe_api_buf_check /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xf27fa082 wanpipe_lip_connect /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x9d773de8 sdla_register /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0xc0ef42f1 wp_sppp_input /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x57e6ed60 wanpipe_api_sock_rx /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xf0688524 wanrouter_proc_add_interface /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x59fb2682 sdla_hw_probe /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0x9a7a6658 wanpipe_lip_rx /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x8f31cdeb proc_router /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x94be524d register_wanec_iface /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x1036a1ab bind_api_listen_to_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x524e2f20 register_wanpipe_fw_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x9ce78a9e register_wan_device /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x84824c8d wanrouter_proc_add_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x90a9f616 wp_sppp_detach /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0xc9b2c3fb wp_sppp_attach /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x56712648 wanpipe_ec_event_ctrl /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x7cd3c2bc wanpipe_ec_poll /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xd23480a3 wanrouter_proc_delete_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xdfd0f6c6 sdla_get_hw_adptr_cnt /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0x10723cdb wanpipe_ec_register /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x1e82f485 wp_sppp_change_mtu /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x02364d27 wanrouter_encapsulate /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x136b2537 wan_skb_destructor /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xfa083e32 register_wanpipe_api_socket /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xade2d0d7 sdla_get_hw_probe /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0xef48df91 proc_add_line /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x22a2999f sdla_unregister /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0x85c05713 wanrouter_type_trans /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xfd74fadb wan_set_ip_address /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xc98aebe6 wan_get_ip_address /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x7d68ed07 protocol_disconnected /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xc5224c15 bind_api_to_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x38eb6851 unregister_wanpipe_api_socket /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xaac011d2 wanpipe_lip_kick /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x3b604364 unbind_api_listen_from_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x6df6c4e0 wan_run_wanrouter /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xeb418feb sdla_hw_bridge_probe /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL -0x04df932b unregister_wanec_iface /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x19823ac0 wanpipe_ec_isr /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x13405f6b unregister_wanpipe_fw_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xe72f44cb wanpipe_api_listen_rx /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xe6bc2d6d wp_sppp_open /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x238f240b wp_sppp_reopen /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x72ddd010 wp_sppp_do_ioctl /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x5b7efb57 wanpipe_api_poll_wake /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x651a840a wan_add_gateway /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x805cbe1e wp_sppp_close /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL -0x2f21a326 unregister_wanpipe_lip_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xa4d9f3e3 wanrouter_proc_delete_interface /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x0ebe03d1 unregister_wan_device /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x22317d82 wanpipe_lip_disconnect /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0xed6a48f7 protocol_connected /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x53350bd4 wanpipe_ec_unregister /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x49a433d4 register_wanpipe_lip_protocol /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL -0x00525339 protocol_connecting /root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xf7567a8a wanpipe_api_buf_check /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xf27fa082 wanpipe_lip_connect /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x345b760c sdla_register /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL +0xc0ef42f1 wp_sppp_input /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x57e6ed60 wanpipe_api_sock_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xc4376a57 wanrouter_proc_add_interface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x59fb2682 sdla_hw_probe /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL +0x9a7a6658 wanpipe_lip_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x8f31cdeb proc_router /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x1f1e3c4b register_wanec_iface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x1036a1ab bind_api_listen_to_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x524e2f20 register_wanpipe_fw_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x3eeca618 register_wan_device /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xf7820561 wanrouter_proc_add_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xc9b2c3fb wp_sppp_attach /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x90a9f616 wp_sppp_detach /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x01530a2f wanpipe_ec_event_ctrl /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x7cd3c2bc wanpipe_ec_poll /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x0ffb17c1 wanrouter_proc_delete_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xdfd0f6c6 sdla_get_hw_adptr_cnt /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL +0xc2143791 wanpipe_ec_register /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x1e82f485 wp_sppp_change_mtu /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x02364d27 wanrouter_encapsulate /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x136b2537 wan_skb_destructor /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xfa083e32 register_wanpipe_api_socket /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xade2d0d7 sdla_get_hw_probe /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL +0xef48df91 proc_add_line /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x22a2999f sdla_unregister /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL +0x85c05713 wanrouter_type_trans /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xc98aebe6 wan_get_ip_address /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xfd74fadb wan_set_ip_address /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x7d68ed07 protocol_disconnected /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xc5224c15 bind_api_to_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x38eb6851 unregister_wanpipe_api_socket /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xaac011d2 wanpipe_lip_kick /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x3b604364 unbind_api_listen_from_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x6df6c4e0 wan_run_wanrouter /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xeb418feb sdla_hw_bridge_probe /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/sdladrv EXPORT_SYMBOL +0x04df932b unregister_wanec_iface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x562d2ade wanpipe_ec_isr /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x13405f6b unregister_wanpipe_fw_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xe72f44cb wanpipe_api_listen_rx /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xe6bc2d6d wp_sppp_open /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x238f240b wp_sppp_reopen /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x72ddd010 wp_sppp_do_ioctl /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0x5b7efb57 wanpipe_api_poll_wake /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x651a840a wan_add_gateway /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x805cbe1e wp_sppp_close /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanpipe_syncppp EXPORT_SYMBOL +0xc7f525d5 wanrouter_proc_delete_interface /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x2f21a326 unregister_wanpipe_lip_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x0ebe03d1 unregister_wan_device /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x22317d82 wanpipe_lip_disconnect /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0xed6a48f7 protocol_connected /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x53350bd4 wanpipe_ec_unregister /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x11fbf1e8 register_wanpipe_lip_protocol /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL +0x00525339 protocol_connecting /hda5/wanpipe/3.1.X/wanpipe-3.1.0.p7/patches/kdrivers/src/net/wanrouter EXPORT_SYMBOL diff --git a/patches/kdrivers/src/net/aft_a104.c b/patches/kdrivers/src/net/aft_a104.c index 0f28735..6b7fe3c 100644 --- a/patches/kdrivers/src/net/aft_a104.c +++ b/patches/kdrivers/src/net/aft_a104.c @@ -26,17 +26,16 @@ # include # include # include +# include #elif defined(__WINDOWS__) -# include -# include -# include -# include +# include +# include # include /* Socket Driver common area */ # include # include - -# include +# include +# include extern void @@ -46,6 +45,7 @@ sdla_te_timer( void*, void* ); + #else # include # include @@ -55,19 +55,24 @@ sdla_te_timer( # include /* Socket Driver common area */ # include # include +# include //# include # include # include # include +# include + #endif #define INIT_FE_ONLY 0 +#if !defined(__WINDOWS__) #if 1 #define AFT_FUNC_DEBUG() #else #define AFT_FUNC_DEBUG() DEBUG_EVENT("%s:%d\n",__FUNCTION__,__LINE__) #endif +#endif /*============================================== * PRIVATE FUNCITONS @@ -75,7 +80,7 @@ sdla_te_timer( */ #if defined(CONFIG_WANPIPE_HWEC) static int aft_hwec_reset(void *pcard, int reset); -static int aft_hwec_enable(void *pcard, int enable, int channel); +static int aft_hwec_enable(void *pcard, int enable, int fe_chan); #endif int __a104_write_fe (void *pcard, ...); @@ -98,7 +103,11 @@ static int request_fifo_baddr_and_size(sdla_t *card, private_area_t *chan) /* Calculate the optimal fifo size based * on the number of time slots requested */ - if (IS_T1_CARD(card)){ + if (IS_SERIAL_CARD(card)) { + + req_fifo_size=32; + + } else if (IS_T1_CARD(card)){ if (chan->num_of_time_slots == NUM_OF_T1_CHANNELS){ req_fifo_size=32; @@ -448,6 +457,10 @@ int a104_led_ctrl(sdla_t *card, int color, int led_pos, int on) AFT_FUNC_DEBUG(); #if INIT_FE_ONLY #else + if (IS_SERIAL_CARD(card)) { + return 0; + } + if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ /* INSERT LED CODE */ @@ -528,7 +541,8 @@ int a104_global_chip_config(sdla_t *card) wan_set_bit(AFT_CHIPCFG_TE1_CFG_BIT,®); }else if (IS_56K_CARD(card)){ wan_set_bit(AFT_CHIPCFG_56K_CFG_BIT,®); - + }else if (IS_SERIAL_CARD(card)) { + /* No bit to set nere */ }else{ DEBUG_EVENT("%s: Error: Xilinx doesn't support non T1/E1 interface!\n", card->devname); @@ -536,6 +550,7 @@ int a104_global_chip_config(sdla_t *card) } /* Enable FRONT END Interrupt */ + wan_set_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); DEBUG_CFG("--- Chip enable/config. -- \n"); @@ -551,6 +566,10 @@ int a104_global_chip_config(sdla_t *card) wan_spin_unlock_irq(&card->wandev.lock,&flags); card->hw_iface.hw_unlock(card->hw,&smp_flags); + }else if (IS_SERIAL_CARD(card)) { + + /* There is no CPLD reset for Serial card */ + }else if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ wan_smp_flag_t smp_flags,flags; @@ -566,7 +585,7 @@ int a104_global_chip_config(sdla_t *card) wan_spin_unlock_irq(&card->wandev.lock,&flags); card->hw_iface.hw_unlock(card->hw,&smp_flags); } - + err=aft_test_hdlc(card); if (err != 0){ DEBUG_EVENT("%s: Error: HDLC Core Not Ready (0x%X)!\n", @@ -598,7 +617,6 @@ int a104_global_chip_config(sdla_t *card) card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); } } - #endif/*INIT_FE_ONLY*/ return 0; } @@ -682,6 +700,7 @@ static int aft_ds_set_clock_ref(sdla_t *card, u32 *reg, u32 master_port) return 0; } + static void aft_set_hwec_clock_src(sdla_t *card) { wan_smp_flag_t smp_flags, flags; @@ -708,26 +727,23 @@ static void aft_set_hwec_clock_src(sdla_t *card) } } -int a104_chip_config(sdla_t *card) + +int a104_chip_config(sdla_t *card, wandev_conf_t *conf) { u32 reg=0, ctrl_ram_reg=0; int i,err=0, max_channels; wan_smp_flag_t smp_flags, flags; AFT_FUNC_DEBUG(); -#if INIT_FE_ONLY - err = -EINVAL; - - if (card->wandev.fe_iface.config){ - err=card->wandev.fe_iface.config(&card->fe); - } -#else + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); if (!wan_test_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®)){ + DEBUG_EVENT("%s: Error: Physical Port %d is busy!\n", card->devname, card->wandev.comm_port+1); return -EBUSY; } + /* On A108 Cards the T1/E1 will be configured per PORT * not per CARD */ @@ -754,6 +770,15 @@ int a104_chip_config(sdla_t *card) aft_fe_intr_ctrl(card, 0); + if(card->adptr_type == AFT_ADPTR_56K){ + + aft_56k_write_cpld(card, 0x00,0x00);//reset_on_LXT441PE(card); + WP_DELAY(1000); + + aft_56k_write_cpld(card, 0x00, 0x03);//reset_off_LXT441PE(card); + WP_DELAY(1000); + } + err = -EINVAL; if (card->wandev.fe_iface.config){ err=card->wandev.fe_iface.config(&card->fe); @@ -771,7 +796,7 @@ int a104_chip_config(sdla_t *card) card->devname, (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; - } + } /* Run rest of initialization not from lock */ if (card->wandev.fe_iface.post_init){ err=card->wandev.fe_iface.post_init(&card->fe); @@ -903,6 +928,7 @@ int a104_chip_config(sdla_t *card) card->devname,reg); } + card->wandev.ec_dev = NULL; card->wandev.hwec_reset = NULL; card->wandev.hwec_enable = NULL; @@ -914,7 +940,6 @@ int a104_chip_config(sdla_t *card) card->hw_iface.getcfg(card->hw, SDLA_HWEC_NO, &max_ec_chans); - card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG, &cfg_reg); if (max_ec_chans > aft_chipcfg_get_ec_channels(cfg_reg)){ DEBUG_EVENT("%s: Critical Error: Exceeded Maximum Available Echo Channels!\n", @@ -930,12 +955,22 @@ int a104_chip_config(sdla_t *card) #if defined(CONFIG_WANPIPE_HWEC) card->wandev.hwec_reset = aft_hwec_reset; card->wandev.hwec_enable = aft_hwec_enable; - card->wandev.ec_dev = wanpipe_ec_register(card, max_ec_chans); + card->wandev.ec_dev = wanpipe_ec_register( + card, + 0, + WAN_FE_MAX_CHANNELS(&card->fe), + max_ec_chans, + (void*)&conf->oct_conf); if (!card->wandev.ec_dev) { - return -EINVAL; + DEBUG_EVENT( + "%s: Failed to register device in HW Echo Canceller module!\n", + card->devname); + return -EINVAL; } + aft_set_hwec_clock_src(card); + #else DEBUG_EVENT("%s: Wanpipe HW Echo Canceller module is not compiled!\n", @@ -1007,7 +1042,7 @@ int a104_chip_config(sdla_t *card) aft_wdt_reset(card); aft_wdt_set(card,AFT_WDTCTRL_TIMEOUT); -#endif + AFT_FUNC_DEBUG(); return 0; @@ -1064,6 +1099,10 @@ int a104_chip_unconfig(sdla_t *card) __aft_fe_intr_ctrl(card,0); wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); card->hw_iface.hw_unlock(card->hw,&smp_flags1); + }else if (IS_56K_CARD(card)) { + //reset_on_LXT441PE(card); + aft_56k_write_cpld(card, 0x00,0x00); + WP_DELAY(1000); } wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); @@ -1285,289 +1324,6 @@ int a104_check_ec_security(sdla_t *card) } -/*============================================================================ - * Read TE1/56K Front end registers - */ -int __a104_write_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int port_no, org_off, off, value; - u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; - - va_start(args, pcard); - port_no = va_arg(args, int); - off = va_arg(args, int); - value = va_arg(args, int); - va_end(args); - - if (card->u.aft.firm_id == AFT_PMC_FE_CORE_ID){ - off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - }else if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID){ - if (off & 0x800) off |= 0x2000; - if (off & 0x1000) off |= 0x4000; - off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - if ((card->adptr_type == A101_ADPTR_2TE1 || card->adptr_type == A101_ADPTR_1TE1) && - port_no == 1){ - off |= AFT8_BIT_DEV_MAXIM_ADDR_CPLD; - } - } - - card->hw_iface.bus_read_2(card->hw, - AFT_MCPU_INTERFACE_ADDR, - (u16*)&org_off); - - card->hw_iface.bus_write_2(card->hw,AFT_MCPU_INTERFACE_ADDR, (u16)off); - - - /* AF: Sep 10, 2003 - * IMPORTANT - * This delays are required to avoid bridge optimization - * (combining two writes together) - */ - if (!qaccess){ - WP_DELAY(5); - } - - card->hw_iface.bus_write_1(card->hw,AFT_MCPU_INTERFACE, (u8)value); - if (!qaccess){ - WP_DELAY(5); - } - - card->hw_iface.bus_write_2( card->hw, - AFT_MCPU_INTERFACE_ADDR, - (u16)org_off); - - - if (!qaccess){ - WP_DELAY(5); - } - - return 0; -} - -int a104_write_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int port_no, off, value; - - if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT( - "%s: %s:%d: Critical Error: Re-entry in FE!\n", - card->devname, - __FUNCTION__,__LINE__); - } - return -EINVAL; - } - - va_start(args, pcard); - port_no = va_arg(args, int); - off = va_arg(args, int); - value = va_arg(args, int); - va_end(args); - - __a104_write_fe(card, port_no, off, value); - - card->hw_iface.fe_clear_bit(card->hw,0); - - return 0; -} - - -/*============================================================================ - * Read TE1 Front end registers - */ -unsigned char __a104_read_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int port_no, org_off, off, tmp; - u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; - - va_start(args, pcard); - port_no = (int)va_arg(args, int); - off = (int)va_arg(args, int); - va_end(args); - - if (card->u.aft.firm_id == AFT_PMC_FE_CORE_ID){ - off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - }else if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID){ - if (off & 0x0800) off |= 0x2000; - if (off & 0x1000) off |= 0x4000; - off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - if ((card->adptr_type == A101_ADPTR_2TE1 || card->adptr_type == A101_ADPTR_1TE1) && - port_no == 1){ - off |= AFT8_BIT_DEV_MAXIM_ADDR_CPLD; - } - } - - card->hw_iface.bus_read_2(card->hw, - AFT_MCPU_INTERFACE_ADDR, - (u16*)&org_off); - - card->hw_iface.bus_write_2(card->hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); - - card->hw_iface.bus_read_1(card->hw,AFT_MCPU_INTERFACE, (u8*)&tmp); - if (!qaccess){ - WP_DELAY(5); - } - - card->hw_iface.bus_write_2(card->hw, - AFT_MCPU_INTERFACE_ADDR, - (u16)org_off); - - if (!qaccess){ - WP_DELAY(5); - } - - return (u8)tmp; -} - -unsigned char a104_read_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int port_no, off; - unsigned char tmp; - - - if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", - card->devname, __FUNCTION__,__LINE__); - } - return 0x00; - } - - va_start(args, pcard); - port_no = (int)va_arg(args, int); - off = (int)va_arg(args, int); - va_end(args); - - - tmp = __a104_read_fe(card, port_no, off); - - card->hw_iface.fe_clear_bit(card->hw,0); - return tmp; -} - -/*============================================================================ - * Read/Write 56k Front End registers. Different from TE1!! - */ -unsigned char __a56k_read_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int port_no, off, tmp; - u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; - - va_start(args, pcard); - port_no = (int)va_arg(args, int); - off = (int)va_arg(args, int); - va_end(args); - - off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - - card->hw_iface.bus_write_2(card->hw, AFT56K_MCPU_INTERFACE_ADDR, (u16)off); - - card->hw_iface.bus_read_4(card->hw, AFT56K_MCPU_INTERFACE, &tmp); - - if (!qaccess){ - WP_DELAY(5); - } -#if 0 - DEBUG_56K("%s(): port_no: 0x%X, off: 0x%X, cpld_data: 0x%X\n", - __FUNCTION__, port_no, off, tmp); -#endif - return (u8)tmp; -} - -unsigned char a56k_read_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - unsigned int port_no, off; - unsigned int cpld_data=0; - - if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", - card->devname, __FUNCTION__,__LINE__); - } - return 0x00; - } - - va_start(args, pcard); - port_no = (int)va_arg(args, int); - off = (int)va_arg(args, int); - va_end(args); - - cpld_data = __a56k_read_fe(card, port_no, off); - - card->hw_iface.fe_clear_bit(card->hw,0); - - return (unsigned char)cpld_data; -} - -int __a56k_write_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int port_no, off, value; - u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; - - va_start(args, pcard); - port_no = va_arg(args, int); - off = va_arg(args, int); - value = va_arg(args, int); - va_end(args); - - off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - - card->hw_iface.bus_write_2(card->hw, AFT56K_MCPU_INTERFACE_ADDR, (u16)off); - - card->hw_iface.bus_write_2(card->hw, AFT56K_MCPU_INTERFACE, (u16)value); - if (!qaccess){ - WP_DELAY(5); - } -#if 0 - DEBUG_56K("%s(): port_no: 0x%X, off: 0x%X, value: 0x%X\n", - __FUNCTION__, port_no, off, value); -#endif - return 0; -} - -int a56k_write_fe (void *pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int port_no, off, value; - - if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT( - "%s: %s:%d: Critical Error: Re-entry in FE!\n", - card->devname, - __FUNCTION__,__LINE__); - } - return -EINVAL; - } - - va_start(args, pcard); - port_no = va_arg(args, int); - off = va_arg(args, int); - value = va_arg(args, int); - va_end(args); - - __a56k_write_fe(card, port_no, off, value); - - card->hw_iface.fe_clear_bit(card->hw,0); - - return 0; -} - /*============================================================================ * Read/Write 56k CPLD. Different from TE1!! */ @@ -1708,7 +1464,7 @@ int a108m_write_cpld(sdla_t *card, unsigned short off,u_int16_t data) card->hw_iface.bus_write_1(card->hw, AFT_MCPU_INTERFACE, - data); + (u8)data); /*ALEX: Restore the original address */ card->hw_iface.bus_write_2(card->hw, AFT_MCPU_INTERFACE_ADDR, @@ -1755,11 +1511,10 @@ static int aft_hwec_reset(void *pcard, int reset) card->devname); if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { - if(card->adptr_type == A108_ADPTR_8TE1){ - aft_te1_write_cpld(card,0x00,0x0F); - } else { - aft_te1_write_cpld(card,0x00,0x07); - } + /* Changed for all Dallas chips + changed from 0x07 to 0x0F to support + external clocking */ + aft_te1_write_cpld(card,0x00,0x0F); }else{ if (IS_T1_CARD(card)){ @@ -1804,51 +1559,35 @@ static int aft_hwec_reset(void *pcard, int reset) ** 1 - channel out of channel map ** < 0 - failed ******************************************************************************/ -static int aft_hwec_enable(void *pcard, int enable, int channel) +static int aft_hwec_enable(void *pcard, int enable, int fe_chan) { sdla_t *card = (sdla_t*)pcard; + int hw_chan = fe_chan; unsigned int value; WAN_ASSERT(card == NULL); - if(!wan_test_bit(channel, &card->wandev.ec_enable_map)){ - return 1; + + if (IS_T1_CARD(card)){ + hw_chan = fe_chan-1; } - DEBUG_TEST("[HWEC]: %s: %s bypass mode for channel %d!\n", - card->devname, - (enable) ? "Enable" : "Disable", - channel); card->hw_iface.bus_read_4( card->hw, - AFT_PORT_REG(card,0x1000) + channel * 4, + AFT_PORT_REG(card,0x1000) + hw_chan * 4, &value); - if (enable){ - if (!wan_test_and_set_bit(channel,&card->wandev.ec_map)) { - value |= 0x20; - } else { - DEBUG_EVENT("[HWEC]: %s: %s bypass mode overrun detected for channel %d!\n", - card->devname, - (enable) ? "Enable" : "Disable", - channel); - return 0; - } + if (enable){ + value |= 0x20; } else { - if (wan_test_and_clear_bit(channel,&card->wandev.ec_map)) { - value &= ~0x20; - } else { - DEBUG_EVENT("[HWEC]: %s: %s bypass mode overrun detected for channel %d!\n", - card->devname, - (enable) ? "Enable" : "Disable", - channel); - return 0; - } + value &= ~0x20; } - + DEBUG_HWEC("[HWEC]: %s: %s bypass mode for fe_chan:%d (value=%X)...!\n", + card->devname, + (enable) ? "Enable" : "Disable", + fe_chan, value); card->hw_iface.bus_write_4( card->hw, - AFT_PORT_REG(card,0x1000) + channel * 4, + AFT_PORT_REG(card,0x1000) + hw_chan * 4, value); - return 0; } #endif diff --git a/patches/kdrivers/src/net/aft_analog.c b/patches/kdrivers/src/net/aft_analog.c index 158ef69..0dfa03b 100644 --- a/patches/kdrivers/src/net/aft_analog.c +++ b/patches/kdrivers/src/net/aft_analog.c @@ -26,20 +26,14 @@ # include #elif defined(__WINDOWS__) # include -# include # include -# include # include /* Socket Driver common area */ # include -//# include # include # include # include # include -//#define DEBUG_FE DbgPrint -#define DEBUG_FE - #else # include # include @@ -56,13 +50,14 @@ # include #endif + /*============================================== * PRIVATE FUNCITONS * */ #if defined(CONFIG_WANPIPE_HWEC) static int aft_analog_hwec_reset(void *pcard, int reset); -static int aft_analog_hwec_enable(void *pcard, int enable, int channel); +static int aft_analog_hwec_enable(void *pcard, int enable, int fe_chan); #endif static int aft_map_fifo_baddr_and_size(sdla_t *card, unsigned char fifo_size, unsigned char *addr); @@ -341,7 +336,7 @@ int aft_analog_global_chip_config(sdla_t *card) wan_set_bit(AFT_CHIPCFG_SFR_IN_BIT,®); if (card->fe.fe_cfg.cfg.remora.network_sync) { - DEBUG_EVENT("%s: Analog Clock set to External!\n", + DEBUG_EVENT("%s: Analog Clock set to Network Sync!\n", card->devname); wan_set_bit(AFT_CHIPCFG_ANALOG_CLOCK_SELECT_BIT,®); } @@ -350,6 +345,7 @@ int aft_analog_global_chip_config(sdla_t *card) card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + WP_DELAY(10); /* Disable the chip/hdlc reset condition */ @@ -383,10 +379,9 @@ int aft_analog_global_chip_config(sdla_t *card) DEBUG_EVENT("%s: Remora config done!\n",card->devname); - card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); - wan_set_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); - card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); - + /* Enable global front end interrupt */ + __aft_fe_intr_ctrl(card, 1); + return 0; } @@ -411,7 +406,7 @@ int aft_analog_global_chip_unconfig(sdla_t *card) return 0; } -int aft_analog_chip_config(sdla_t *card) +int aft_analog_chip_config(sdla_t *card, wandev_conf_t *conf) { u32 reg=0; int err=0; @@ -452,10 +447,12 @@ int aft_analog_chip_config(sdla_t *card) /* Enable Octasic Chip */ if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ - u16 max_ec_chans; - u32 cfg_reg; + u16 max_ec_chans, max_ports_no; + u32 cfg_reg, fe_port_map; card->hw_iface.getcfg(card->hw, SDLA_HWEC_NO, &max_ec_chans); + card->hw_iface.getcfg(card->hw, SDLA_PORTS_NO, &max_ports_no); + card->hw_iface.getcfg(card->hw, SDLA_PORT_MAP, &fe_port_map); card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG, &cfg_reg); if (max_ec_chans > aft_chipcfg_get_a200_ec_channels(cfg_reg)){ @@ -473,7 +470,12 @@ int aft_analog_chip_config(sdla_t *card) if (max_ec_chans){ #if defined(CONFIG_WANPIPE_HWEC) - card->wandev.ec_dev = wanpipe_ec_register(card, max_ec_chans); + card->wandev.ec_dev = wanpipe_ec_register( + card, + fe_port_map, + max_ports_no, + max_ec_chans, + (void*)&conf->oct_conf); card->wandev.hwec_reset = aft_analog_hwec_reset; card->wandev.hwec_enable = aft_analog_hwec_enable; #else @@ -681,404 +683,6 @@ int a200_check_ec_security(sdla_t *card) } return 0; } - -/*============================================================================ - * Read TE1/56K Front end registers - */ -int __aft_analog_write_fe (void* pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int mod_no, type, chain; - int reg, value; - u32 data = 0; - unsigned char cs = 0x00, ctrl_byte = 0x00; - int i; - - WAN_ASSERT(card == NULL); - WAN_ASSERT(card->hw_iface.bus_write_4 == NULL); - WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); - - va_start(args, pcard); - mod_no = va_arg(args, int); - type = va_arg(args, int); - chain = va_arg(args, int); - reg = va_arg(args, int); - value = va_arg(args, int); - va_end(args); -#if 0 - if (!wan_test_bit(mod_no, card->fe.fe_param.remora.module_map)){ - DEBUG_EVENT("%s: %s:%d: Internal Error: Module %d\n", - card->devname, __FUNCTION__,__LINE__,mod_no); - return -EINVAL; - } -#endif - DEBUG_FE( - "%s:%d: Module %d: Write RM FE code (%d:%02X)!\n", - __FUNCTION__,__LINE__, - mod_no, reg, (u8)value); - - /* bit 0-7: data byte */ - data = value & 0xFF; - if (type == MOD_TYPE_FXO){ - - /* bit 8-15: register number */ - data |= (reg & 0xFF) << 8; - - /* bit 16-23: chip select byte - ** bit 16 - ** - ** - ** */ - cs = 0x20; - cs |= MOD_SPI_CS_FXO_WRITE; - if (mod_no % 2 == 0){ - /* Select second chip in a chain */ - cs |= MOD_SPI_CS_FXO_CHIP_1; - } - data |= (cs & 0xFF) << 16; - - /* bit 24-31: ctrl byte - ** bit 24 - ** - ** - ** */ - ctrl_byte = mod_no / 2; -#if !defined(SPI2STEP) - if (card->u.aft.firm_ver > 3){ - ctrl_byte |= MOD_SPI_CTRL_START; - }else{ - ctrl_byte |= MOD_SPI_CTRL_V3_START; - } -#endif - ctrl_byte |= MOD_SPI_CTRL_CHAIN; /* always chain */ - data |= ctrl_byte << 24; - - }else if (type == MOD_TYPE_FXS){ - - /* bit 8-15: register byte */ - reg = reg & 0x7F; - reg |= MOD_SPI_ADDR_FXS_WRITE; - data |= (reg & 0xFF) << 8; - - /* bit 16-23: chip select byte - ** bit 16 - ** - ** - ** */ - if (mod_no % 2){ - /* Select first chip in a chain */ - cs = MOD_SPI_CS_FXS_CHIP_0; - }else{ - /* Select second chip in a chain */ - cs = MOD_SPI_CS_FXS_CHIP_1; - } - data |= cs << 16; - - /* bit 24-31: ctrl byte - ** bit 24 - ** - ** - ** */ - ctrl_byte = mod_no / 2; -#if !defined(SPI2STEP) - if (card->u.aft.firm_ver > 3){ - ctrl_byte |= MOD_SPI_CTRL_START; - }else{ - ctrl_byte |= MOD_SPI_CTRL_V3_START; - } -#endif - ctrl_byte |= MOD_SPI_CTRL_FXS; - if (chain){ - ctrl_byte |= MOD_SPI_CTRL_CHAIN; - } - data |= ctrl_byte << 24; - - }else{ - DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", - card->devname, mod_no, type); - return -EINVAL; - } - - card->hw_iface.bus_write_4( card->hw, - SPI_INTERFACE_REG, - data); -#if defined(SPI2STEP) - WP_DELAY(1); - if (card->u.aft.firm_ver > 3){ - data |= MOD_SPI_START; - }else{ - data |= MOD_SPI_V3_START; - } - card->hw_iface.bus_write_4( card->hw, - SPI_INTERFACE_REG, - data); -#endif -#if 0 - DEBUG_EVENT("%s: %s: Module %d - Execute SPI command %08X\n", - card->fe.name, - __FUNCTION__, - mod_no, - data); -#endif - - for (i=0;i<10;i++){ - WP_DELAY(10); - card->hw_iface.bus_read_4( card->hw, - SPI_INTERFACE_REG, - &data); - - if (data & MOD_SPI_BUSY){ - continue; - } - } - - if (data & MOD_SPI_BUSY) { - DEBUG_EVENT("%s: Module %d: Internal Error: SPI busy (%s:%d)!\n", - card->devname, mod_no, - __FUNCTION__,__LINE__); - return -EINVAL; - } - return 0; -} -int aft_analog_write_fe (void* pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int mod_no, type, chain, reg, value; -#if defined(WAN_DEBUG_FE) - char *fname; - int fline; -#endif - - WAN_ASSERT(card == NULL); - WAN_ASSERT(card->hw_iface.bus_write_4 == NULL); - WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); - - va_start(args, pcard); - mod_no = va_arg(args, int); - type = va_arg(args, int); - chain = va_arg(args, int); - reg = va_arg(args, int); - value = va_arg(args, int); -#if defined(WAN_DEBUG_FE) - fname = va_arg(args, char*); - fline = va_arg(args, int); -#endif - va_end(args); - - if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ -#if defined(WAN_DEBUG_FE) - DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", - card->devname, __FUNCTION__,__LINE__, fname, fline); -#else - DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", - card->devname, __FUNCTION__,__LINE__); -#endif - return -EINVAL; - } - - __aft_analog_write_fe(card, mod_no, type, chain, reg, value); - - card->hw_iface.fe_clear_bit(card->hw,0); - return 0; -} - -unsigned char __aft_analog_read_fe (void* pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int mod_no, type, chain, reg; - u32 data = 0; - unsigned char cs = 0x00, ctrl_byte = 0x00; - int i; - - WAN_ASSERT(card == NULL); - WAN_ASSERT(card->hw_iface.bus_write_4 == NULL); - WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); - - va_start(args, pcard); - mod_no = va_arg(args, int); - type = va_arg(args, int); - chain = va_arg(args, int); - reg = va_arg(args, int); - va_end(args); -#if 0 - if (!wan_test_bit(mod_no, card->fe.fe_param.remora.module_map)){ - DEBUG_EVENT("%s: %s:%d: Internal Error: Module %d\n", - card->devname, __FUNCTION__,__LINE__,mod_no); - return 0x00; - } -#endif - DEBUG_FE( - "%s:%d: Module %d: Read RM FE code (%d)!\n", - __FUNCTION__,__LINE__, - mod_no, reg); - - /* bit 0-7: data byte */ - data = 0x00; - if (type == MOD_TYPE_FXO){ - - /* bit 8-15: register byte */ - data |= (reg & 0xFF) << 8; - - /* bit 16-23: chip select byte - ** bit 16 - ** - ** - ** */ - cs = 0x20; - cs |= MOD_SPI_CS_FXO_READ; - if (mod_no % 2 == 0){ - /* Select second chip in a chain */ - cs |= MOD_SPI_CS_FXO_CHIP_1; - } - data |= (cs & 0xFF) << 16; - - /* bit 24-31: ctrl byte - ** bit 24 - ** - ** - ** */ - ctrl_byte = mod_no / 2; -#if !defined(SPI2STEP) - if (card->u.aft.firm_ver > 3){ - ctrl_byte |= MOD_SPI_CTRL_START; - }else{ - ctrl_byte |= MOD_SPI_CTRL_V3_START; - } -#endif - ctrl_byte |= MOD_SPI_CTRL_CHAIN; /* always chain */ - data |= ctrl_byte << 24; - - }else if (type == MOD_TYPE_FXS){ - - /* bit 8-15: register byte */ - reg = reg & 0x7F; - reg |= MOD_SPI_ADDR_FXS_READ; - data |= (reg & 0xFF) << 8; - - /* bit 16-23: chip select byte - ** bit 16 - ** - ** - ** */ - if (mod_no % 2){ - /* Select first chip in a chain */ - cs = MOD_SPI_CS_FXS_CHIP_0; - }else{ - /* Select second chip in a chain */ - cs = MOD_SPI_CS_FXS_CHIP_1; - } - data |= cs << 16; - - /* bit 24-31: ctrl byte - ** bit 24 - ** - ** - ** */ - ctrl_byte = mod_no / 2; -#if !defined(SPI2STEP) - if (card->u.aft.firm_ver > 3){ - ctrl_byte |= MOD_SPI_CTRL_START; - }else{ - ctrl_byte |= MOD_SPI_CTRL_V3_START; - } -#endif - ctrl_byte |= MOD_SPI_CTRL_FXS; - if (chain){ - ctrl_byte |= MOD_SPI_CTRL_CHAIN; - } - data |= ctrl_byte << 24; - - }else{ - DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", - card->devname, mod_no, type); - return -EINVAL; - } - - card->hw_iface.bus_write_4( card->hw, - SPI_INTERFACE_REG, - data); -#if defined(SPI2STEP) - WP_DELAY(1); - if (card->u.aft.firm_ver > 3){ - data |= MOD_SPI_START; - }else{ - data |= MOD_SPI_V3_START; - } - card->hw_iface.bus_write_4( card->hw, - SPI_INTERFACE_REG, - data); -#endif -#if 0 - DEBUG_EVENT("%s: %s: Module %d - Execute SPI command %08X\n", - card->fe.name, - __FUNCTION__, - mod_no, - data); -#endif - for (i=0;i<10;i++){ - WP_DELAY(10); - card->hw_iface.bus_read_4( card->hw, - SPI_INTERFACE_REG, - &data); - if (data & MOD_SPI_BUSY) { - continue; - } - } - - if (data & MOD_SPI_BUSY){ - DEBUG_EVENT("%s: Module %d: Internal Error: SPI busy (%s:%d)!\n", - card->devname, mod_no, - __FUNCTION__,__LINE__); - return 0xFF; - } - - return (u8)(data & 0xFF); -} - -unsigned char aft_analog_read_fe (void* pcard, ...) -{ - va_list args; - sdla_t *card = (sdla_t*)pcard; - int mod_no, type, chain, reg; - unsigned char data = 0; -#if defined(WAN_DEBUG_FE) - char *fname; - int fline; -#endif - - WAN_ASSERT(card == NULL); - WAN_ASSERT(card->hw_iface.bus_write_4 == NULL); - WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); - - va_start(args, pcard); - mod_no = va_arg(args, int); - type = va_arg(args, int); - chain = va_arg(args, int); - reg = va_arg(args, int); -#if defined(WAN_DEBUG_FE) - fname = va_arg(args, char*); - fline = va_arg(args, int); -#endif - va_end(args); - - if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ -#if defined(WAN_DEBUG_FE) - DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", - card->devname, __FUNCTION__,__LINE__,fname,fline); -#else - DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", - card->devname, __FUNCTION__,__LINE__); -#endif - return 0x00; - } - data = __aft_analog_read_fe (card, mod_no, type, chain, reg); - - card->hw_iface.fe_clear_bit(card->hw,0); - return data; -} unsigned char aft_analog_read_cpld(sdla_t *card, unsigned short cpld_off) { @@ -1112,9 +716,10 @@ unsigned char aft_analog_read_cpld(sdla_t *card, unsigned short cpld_off) return tmp; } -int aft_analog_write_cpld(sdla_t *card, unsigned short off,u_int16_t data) +int aft_analog_write_cpld(sdla_t *card, unsigned short off, u_int16_t data_in) { u16 org_off; + u8 data=(u8)data_in; if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", @@ -1196,51 +801,31 @@ static int aft_analog_hwec_reset(void *pcard, int reset) ** < 0 - failed ******************************************************************************/ #define AFT_REMORA_MUX_TS_EC_ENABLE 0x210 -static int aft_analog_hwec_enable(void *pcard, int enable, int channel) +static int aft_analog_hwec_enable(void *pcard, int enable, int fe_chan) { sdla_t *card = (sdla_t*)pcard; unsigned int value = 0x00; + int hw_chan = fe_chan-1; WAN_ASSERT(card == NULL); - if(!wan_test_bit(channel, &card->wandev.ec_enable_map)){ - return 1; - } card->hw_iface.bus_read_4( card->hw, AFT_REMORA_MUX_TS_EC_ENABLE, &value); if (enable){ - if (!wan_test_and_set_bit(channel,&card->wandev.ec_map)) { - value |= (1 << channel); - } else { - DEBUG_EVENT("[HWEC]: %s: %s bypass mode overrun detected for channel %d!\n", - card->devname, - (enable) ? "Enable" : "Disable", - channel); - return 0; - } + value |= (1 << hw_chan); } else { - if (wan_test_and_clear_bit(channel,&card->wandev.ec_map)) { - value &= ~(1 << channel); - } else { - DEBUG_EVENT("[HWEC]: %s: %s bypass mode overrun detected for channel %d!\n", - card->devname, - (enable) ? "Enable" : "Disable", - channel); - return 0; - } + value &= ~(1 << fe_chan); } + DEBUG_HWEC("[HWEC]: %s: %s bypass mode for fe_chan:%d (value=%X)...!\n", + card->devname, + (enable) ? "Enable" : "Disable", + fe_chan, value); card->hw_iface.bus_write_4( card->hw, AFT_REMORA_MUX_TS_EC_ENABLE, value); - DEBUG_HWEC("[HWEC]: %s: %s bypass mode for channel %d (value=%X)!\n", - card->devname, - (enable) ? "Enable" : "Disable", - channel, - value); - return 0; } #endif diff --git a/patches/kdrivers/src/net/aft_bri.c b/patches/kdrivers/src/net/aft_bri.c new file mode 100755 index 0000000..7200967 --- /dev/null +++ b/patches/kdrivers/src/net/aft_bri.c @@ -0,0 +1,1818 @@ +/***************************************************************************** +* aft_bri.c +* +* WANPIPE(tm) ISDN BRI Hardware Support +* +* Authors: David Rokhvarg +* +* Copyright: (c) 2003-2005 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +* Nov 9, 2006 David Rokhvarg Initial Version +*****************************************************************************/ + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + +# include +# include +# include +# include /* Socket Driver common area */ +# include +# include +# include + +#elif defined(__WINDOWS__) + +# include +# include +# include + +# include +# include /* Socket Driver common area */ +# include +# include + +# include + +extern +void +sdla_te_timer( + IN PKDPC, + void*, + void*, + void* + ); + +#else + +/* L I N U X */ + +# include +# include +# include +# include +# include +# include /* Socket Driver common area */ +# include +# include +# include +# include +# include + +#endif + +#undef BRI_DBG + +#if 0 +#warning "BRI_DBG - Debugging Enabled" +#define BRI_DBG if(1)DEBUG_EVENT +#else +#define BRI_DBG if(0)DEBUG_EVENT +#endif + +#if 0 +#warning "DEBUG_REG - Debugging Enabled" +#undef DEBUG_REG +#define DEBUG_REG if(0)DEBUG_EVENT +#endif + +#if 0 +#warning "DEBUG_BRI - Debugging Enabled" +#undef DEBUG_BRI +#define DEBUG_BRI if(0)DEBUG_EVENT +#endif + +#if 0 +#warning "BRI_FUNC - Debugging Enabled" +#undef BRI_FUNC() +#define BRI_FUNC() DEBUG_EVENT("%s(): Line: %d\n", __FUNCTION__, __LINE__) +#endif + + + +static inline void aft_set_bri_fifo_map(sdla_t *card, int port, unsigned int map) +{ + if (port >= MAX_BRI_MODULES) { + card->u.aft.fifo_addr_map_l2 |= map; + } else { + card->u.aft.fifo_addr_map |= map; + } +} + +static inline void aft_clear_bri_fifo_map(sdla_t *card, unsigned int map) +{ + if (WAN_FE_LINENO(&card->fe) >= MAX_BRI_MODULES) { + card->u.aft.fifo_addr_map_l2 &= map; + } else { + card->u.aft.fifo_addr_map &= map; + } +} + +static inline unsigned long aft_get_bri_fifo_map(sdla_t *card) +{ + if (WAN_FE_LINENO(&card->fe) >= MAX_BRI_MODULES) { + return card->u.aft.fifo_addr_map_l2; + } + return card->u.aft.fifo_addr_map; +} + + +/*============================================== + * PRIVATE FUNCITONS + * + */ +#if defined(CONFIG_WANPIPE_HWEC) +static int aft_bri_hwec_reset(void *pcard, int reset); +static int aft_bri_hwec_enable(void *pcard, int enable, int fe_chan); +#endif + +static int +read_bri_fe_byte(sdla_t *card, unsigned char mod_no, unsigned char reg, unsigned char *value, + unsigned char type, unsigned char optional_arg); +static int +write_bri_fe_byte(sdla_t *card, unsigned char mod_no, unsigned char addr, unsigned char value); + + +int bri_write_cpld(sdla_t *card, unsigned short off,unsigned char data); + +static int aft_map_fifo_baddr_and_size(sdla_t *card, unsigned char fifo_size, unsigned char *addr); + +static char fifo_size_vector[] = {1, 2, 4, 8, 16, 32}; +static char fifo_code_vector[] = {0, 1, 3, 7,0xF,0x1F}; + +static int request_fifo_baddr_and_size(sdla_t *card, private_area_t *chan) +{ + unsigned char req_fifo_size,fifo_size; + int i; + + BRI_FUNC(); + + /* Calculate the optimal fifo size based + * on the number of time slots requested */ + + if (chan->num_of_time_slots == 1) { + req_fifo_size=1; + } else if (chan->num_of_time_slots == 2 || chan->num_of_time_slots == 3) { + req_fifo_size=2; + } else { + DEBUG_EVENT("%s:%s: Invalid number of timeslots %d\n", + card->devname,chan->if_name,chan->num_of_time_slots); + return -EINVAL; + } + + + for (i=0;ife);i++){ + + /* This loop will not run when FE_LINE==0 */ + + /* Each bri line is separate, thus + we must account for the line number + and recognize that other cards + have requested fifo */ + DEBUG_TEST("%s: Presetting Fifo: Line=%i, Value=0x%08X\n", + card->devname,i,(0x03 << i%MAX_BRI_MODULES)*2); + aft_set_bri_fifo_map(card,i,(0x03 << (i%MAX_BRI_MODULES)*2)); + } + + DEBUG_BRI("%s:%s: Optimal Fifo Size =%d Timeslots=%d FifoMap=0x%08lX\n", + card->devname,chan->if_name,req_fifo_size,chan->num_of_time_slots, + aft_get_bri_fifo_map(card)); + + fifo_size=(u8)aft_map_fifo_baddr_and_size(card,req_fifo_size,&chan->fifo_base_addr); + if (fifo_size == 0 || chan->fifo_base_addr == 31){ + DEBUG_EVENT("%s:%s: Error: Failed to obtain fifo size %d or addr %d \n", + card->devname,chan->if_name,fifo_size,chan->fifo_base_addr); + return -EINVAL; + } + + DEBUG_TEST("%s:%s: Optimal Fifo Size =%d Timeslots=%d New Fifo Size=%d \n", + card->devname,chan->if_name,req_fifo_size,chan->num_of_time_slots,fifo_size); + + + for (i=0;ififo_size_code=fifo_code_vector[i]; + break; + } + } + + if (fifo_size != req_fifo_size){ + DEBUG_EVENT("%s:%s: Warning: Failed to obtain the req fifo %d got %d\n", + card->devname,chan->if_name,req_fifo_size,fifo_size); + } + + DEBUG_TEST("%s: %s:Fifo Size=%d Timeslots=%d Fifo Code=%d Addr=%d\n", + card->devname,chan->if_name,fifo_size, + chan->num_of_time_slots,chan->fifo_size_code, + chan->fifo_base_addr); + + chan->fifo_size = fifo_size; + + return 0; +} + + +static int aft_map_fifo_baddr_and_size(sdla_t *card, unsigned char fifo_size, unsigned char *addr) +{ + u32 reg=0; + u8 i; + + BRI_FUNC(); + + for (i=0;idevname,reg,aft_get_bri_fifo_map(card)); + + for (i=0;i<32;i+=fifo_size){ + if (aft_get_bri_fifo_map(card) & (reg<fe), (reg<devname,aft_get_bri_fifo_map(card)p,i); + + return fifo_size; + } + + if (fifo_size == 1){ + return 0; + } + + fifo_size = fifo_size >> 1; + + return aft_map_fifo_baddr_and_size(card,fifo_size,addr); +} + + +static int aft_free_fifo_baddr_and_size (sdla_t *card, private_area_t *chan) +{ + u32 reg=0; + int i; + + BRI_FUNC(); + + for (i=0;ififo_size;i++){ + wan_set_bit(i,®); + } + + DEBUG_TEST("%s: Unmapping 0x%X from 0x%lX\n", + card->devname,reg<fifo_base_addr, aft_get_bri_fifo_map(card)); + + aft_clear_bri_fifo_map(card, ~(reg<fifo_base_addr)) + + DEBUG_TEST("%s: New Map is 0x%lX\n", + card->devname, aft_get_bri_fifo_map(card)); + + + chan->fifo_size=0; + chan->fifo_base_addr=0; + + return 0; +} + + +static int aft_request_logical_channel_num (sdla_t *card, private_area_t *chan) +{ + signed char logic_ch=-1; + int err; + int if_cnt=wan_atomic_read(&card->wandev.if_cnt); + int if_offset=2; + long i; + + BRI_FUNC(); + + DEBUG_TEST("-- Request_Xilinx_logic_channel_num:-- (if_offset=%i)\n",if_offset); + + DEBUG_TEST("%s:%d Global Num Timeslots=%d Global Logic ch Map 0x%lX \n", + __FUNCTION__,__LINE__, + card->u.aft.num_of_time_slots, + card->u.aft.logic_ch_map); + + + /* Check that the time slot is not being used. If it is + * stop the interface setup. Notice, though we proceed + * to check for all timeslots before we start binding + * the channels in. This way, we don't have to go back + * and clean the time_slot_map */ + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&chan->time_slot_map)){ + + if (chan->first_time_slot == -1){ + DEBUG_EVENT("%s: First TSlot :%ld\n", + card->devname,i); + chan->first_time_slot=i; + } + + chan->last_time_slot=i; + + DEBUG_CFG("%s: Configuring %s for timeslot %ld\n", + card->devname, chan->if_name,i+1); + + if (wan_test_bit(i,&card->u.aft.time_slot_map)){ + DEBUG_EVENT("%s: Channel/Time Slot resource conflict!\n", + card->devname); + DEBUG_EVENT("%s: %s: Channel/Time Slot %ld, aready in use!\n", + card->devname,chan->if_name,(i+1)); + + return -EEXIST; + } + } + } + + + err=request_fifo_baddr_and_size(card,chan); + if (err){ + return -1; + } + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&chan->time_slot_map)){ + if (card->u.aft.security_id == 0){ + /* Unchannelized card must config + * its hdlc logic ch on FIRST logic + * ch number */ + + if (chan->channelized_cfg) { + if (card->u.aft.tdmv_dchan){ + /* In this case we KNOW that there is + * only a single hdlc channel */ + if (i==0 && !chan->hdlc_eng){ + continue; + } + } + }else{ + if (i==0 || i==1){ + if (!chan->hdlc_eng && + if_cnt < (card->u.aft.num_of_time_slots-if_offset)){ + continue; + } + } + } + } + + if (!wan_test_and_set_bit(i,&card->u.aft.logic_ch_map)){ + logic_ch=(char)i; + break; + } + } + } + + if (logic_ch == -1){ + return logic_ch; + } + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + break; + } + } + + if (card->u.aft.dev_to_ch_map[(unsigned char)logic_ch]){ + DEBUG_EVENT("%s: Error, request logical ch=%d map busy\n", + card->devname,logic_ch); + return -1; + } + + card->u.aft.dev_to_ch_map[(unsigned char)logic_ch]=(void*)chan; + + if (logic_ch >= card->u.aft.top_logic_ch){ + card->u.aft.top_logic_ch=logic_ch; + aft_dma_max_logic_ch(card); + } + + DEBUG_CFG("!!! %s: Binding logic ch %d Ptr=%p\n",chan->if_name,logic_ch,chan); + return logic_ch; +} + + + +static int aft_test_hdlc(sdla_t *card) +{ + int i; + int err; + u32 reg; + + BRI_FUNC(); + + for (i=0;i<10;i++){ + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); + + if (!wan_test_bit(AFT_CHIPCFG_HDLC_CTRL_RDY_BIT,®) || + !wan_test_bit(AFT_CHIPCFG_RAM_READY_BIT,®)){ + /* The HDLC Core is not ready! we have + * an error. */ + err = -EINVAL; + WP_DELAY(200); + }else{ + err=0; + break; + } + } + + return err; +} + + +/*============================================== + * PUBLIC FUNCITONS + * + */ + +int aft_bri_test_sync(sdla_t *card, int tx_only) +{ + volatile int i,err=1; + u32 reg; + + BRI_FUNC(); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + if (wan_test_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®)){ + DEBUG_EVENT("%s: Warning: BRI Reset Enabled %d! \n", + card->devname, card->wandev.comm_port+1); + } + + for (i=0;i<500;i++){ + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + if (tx_only){ + if (wan_test_bit(AFT_LCFG_TX_FE_SYNC_STAT_BIT,®)){ + err=-1; + WP_DELAY(200); + }else{ + err=0; + break; + } + }else{ + if (wan_test_bit(AFT_LCFG_TX_FE_SYNC_STAT_BIT,®) || + wan_test_bit(AFT_LCFG_RX_FE_SYNC_STAT_BIT,®)){ + err=-1; + WP_DELAY(200); + }else{ + err=0; + break; + } + } + } + + DEBUG_BRI("%s: DELAY INDEX = %i, AFT_LINE_CFG_REG: 0x%X\n", + card->devname,i, reg); + + return err; +} + +int aft_bri_led_ctrl(sdla_t *card, int color, int led_pos, int on) +{ + BRI_FUNC(); + /* no control over LEDs on BRI card */ + return 0; +} + + +int aft_bri_cpld0_set(sdla_t *card, int hwec_reset) +{ + u8 cpld_reg=0; + u32 reg=0; + + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); + + if (hwec_reset) { + /* Reset ECHO Canceler */ + wan_clear_bit(BRI_CPLD0_ECHO_RESET_BIT,&cpld_reg); + } else { + /* Clear Reset Echo Canceler */ + wan_set_bit(BRI_CPLD0_ECHO_RESET_BIT,&cpld_reg); + } + + /* If the jumper is used as a network sync we must + * configure the CPLD for INPUT, Otherwise send the clock + * out as OUTPUT */ + if (wan_test_bit(AFT_CHIPCFG_A500_NET_SYNC_CLOCK_SELECT_BIT,®)) { + wan_clear_bit(BRI_CPLD0_NETWORK_SYNC_OUT_BIT,&cpld_reg); + } else { + wan_set_bit(BRI_CPLD0_NETWORK_SYNC_OUT_BIT,&cpld_reg); + } + + DEBUG_TEST("%s: Writing to CPLD0 0x%02X (REG=0x%08X)\n", + card->devname,cpld_reg,reg); + + aft_bri_write_cpld(card,0x00,cpld_reg); + + return 0; +} + + +int aft_bri_global_chip_config(sdla_t *card) +{ + u32 reg; + int err=0; + wan_smp_flag_t smp_flags,flags; + + BRI_FUNC(); + + //FIME: hardcoded + card->u.aft.firm_id = AFT_DS_FE_CORE_ID; + + /*============ GLOBAL CHIP CONFIGURATION ===============*/ + + /* Enable the chip/hdlc reset condition */ + reg=0; + wan_set_bit(AFT_CHIPCFG_SFR_EX_BIT,®); + wan_set_bit(AFT_CHIPCFG_SFR_IN_BIT,®); + + DEBUG_CFG("--- AFT Chip Reset. -- \n"); + + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + WP_DELAY(10); + + /* Disable the chip/hdlc reset condition */ + wan_clear_bit(AFT_CHIPCFG_SFR_EX_BIT,®); + wan_clear_bit(AFT_CHIPCFG_SFR_IN_BIT,®); + + wan_clear_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); + + if (!IS_BRI_CARD(card)) { + DEBUG_EVENT("%s: Error: Xilinx doesn't support non BRI interface!\n", + card->devname); + return -EINVAL; + } + + DEBUG_CFG("--- Chip enable/config. -- \n"); + + if (card->fe.fe_cfg.cfg.remora.network_sync) { + DEBUG_EVENT("%s: ISDN BRI Clock set to (External) Network Sync!\n", + card->devname); + wan_set_bit(AFT_CHIPCFG_A500_NET_SYNC_CLOCK_SELECT_BIT,®); + } else { + wan_clear_bit(AFT_CHIPCFG_A500_NET_SYNC_CLOCK_SELECT_BIT,®); + + } + + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + card->hw_iface.hw_lock(card->hw,&smp_flags); + wan_spin_lock_irq(&card->wandev.lock,&flags); + + /* Reset HWEC and Set CPLD based on network sync */ + aft_bri_cpld0_set(card,1); + + wan_spin_unlock_irq(&card->wandev.lock,&flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + err=aft_test_hdlc(card); + if (err != 0){ + DEBUG_EVENT("%s: Error: HDLC Core Not Ready (0x%X)!\n", + card->devname,reg); + return -EINVAL; + } else{ + DEBUG_CFG("%s: HDLC Core Ready\n", + card->devname); + } + err = -EINVAL; + if (card->wandev.fe_iface.global_config){ + err=card->wandev.fe_iface.global_config(&card->fe); + } + if (err){ + return err; + } + + aft_fe_intr_ctrl(card, 1); + + return 0; + +} + +int aft_bri_global_chip_unconfig(sdla_t *card) +{ + u32 reg=0; + + BRI_FUNC(); + + /* Global BRI unconfig */ + if (card->wandev.fe_iface.global_unconfig){ + card->wandev.fe_iface.global_unconfig(&card->fe); + } + + /* Set Octasic to reset */ + aft_bri_cpld0_set(card,1); + + /* Disable the chip/hdlc reset condition */ + wan_set_bit(AFT_CHIPCFG_SFR_EX_BIT,®); + wan_set_bit(AFT_CHIPCFG_SFR_IN_BIT,®); + wan_clear_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); + + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + return 0; +} + + +int aft_bri_hwec_config(sdla_t *card, wandev_conf_t *conf) +{ + /* Enable Octasic Chip */ + u16 max_ec_chans, max_ports_no; + u32 cfg_reg, fe_port_map; + + + card->wandev.ec_dev = NULL; + card->wandev.hwec_reset = NULL; + card->wandev.hwec_enable = NULL; + + card->hw_iface.getcfg(card->hw, SDLA_HWEC_NO, &max_ec_chans); + card->hw_iface.getcfg(card->hw, SDLA_PORTS_NO, &max_ports_no); + card->hw_iface.getcfg(card->hw, SDLA_PORT_MAP, &fe_port_map); + + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG, &cfg_reg); + + if (max_ec_chans > A500_MAX_EC_CHANS){ + DEBUG_EVENT( + "%s: Critical Error: Exceeded Maximum Available Echo Channels!\n", + card->devname); + DEBUG_EVENT( + "%s: Critical Error: Max Allowed=%d Configured=%d (%X)\n", + card->devname, + A500_MAX_EC_CHANS, + max_ec_chans, + cfg_reg); + return -EINVAL; + } + + if (max_ec_chans){ +#if defined(CONFIG_WANPIPE_HWEC) + max_ports_no = 2;/* number of B-chans on BRI line is 2 */ + card->wandev.ec_dev = wanpipe_ec_register( + card, + fe_port_map, + max_ports_no, + max_ec_chans, + (void*)&conf->oct_conf); + + if (!card->wandev.ec_dev) { + DEBUG_EVENT( + "%s: Failed to register device in HW Echo Canceller module!\n", + card->devname); + return -EINVAL; + } + + card->wandev.hwec_reset = aft_bri_hwec_reset; + card->wandev.hwec_enable = aft_bri_hwec_enable; + + if (card->fe.fe_cfg.cfg.bri.clock_mode == WANOPT_FE_LINE_CLOCK) { + wan_event_ctrl_t *event = wan_malloc(sizeof(wan_event_ctrl_t)); + if (event) { + memset(event,0,sizeof(wan_event_ctrl_t)); + event->type=WAN_EVENT_EC_H100_REPORT; + event->mode=WAN_EVENT_DISABLE; + wanpipe_ec_event_ctrl(card->wandev.ec_dev,card,event); + DEBUG_EVENT("%s: Wanpipe HW Echo Canceller H100 Ignore!\n", + card->devname); + } + } +#else + DEBUG_EVENT("%s: Wanpipe HW Echo Canceller modele is not compiled!\n", + card->devname); +#endif + }else{ + DEBUG_EVENT( + "%s: WARNING: No Echo Canceller channels are available!\n", + card->devname); + } + + return 0; +} + +int aft_bri_chip_config(sdla_t *card, wandev_conf_t *conf) +{ + u32 reg=0, ctrl_ram_reg=0; + int i,err=0; + wan_smp_flag_t smp_flags; + int used_cnt; + u32 physical_card_config_counter; + + BRI_FUNC(); + + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &used_cnt); + + /* Check for NETWORK SYNC IN Clocking, if network sync in + * is enabled ignore all clock_modes */ + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); + if (wan_test_bit(AFT_CHIPCFG_A500_NET_SYNC_CLOCK_SELECT_BIT,®)) { + card->fe.fe_cfg.cfg.bri.clock_mode=0; + } + + reg=0; + + if (used_cnt > 1) { + card->hw_iface.hw_lock(card->hw,&smp_flags); + + aft_fe_intr_ctrl(card, 0); + + err = -EINVAL; + if (card->wandev.fe_iface.config){ + err=card->wandev.fe_iface.config(&card->fe); + } + + aft_fe_intr_ctrl(card, 1); + + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + if (err) { + DEBUG_EVENT("%s: Failed BRI configuration!\n", + card->devname); + return err; + } + + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } + + + err=aft_bri_hwec_config(card,conf); + + return err; + } + + + /*========================================================== + * This section of the code will run only ONCE + * On VERY FIRST BRI Module config + *=========================================================*/ + + card->hw_iface.hw_lock(card->hw,&smp_flags); + + aft_fe_intr_ctrl(card, 0); + + err = -EINVAL; + if (card->wandev.fe_iface.config){ + err=card->wandev.fe_iface.config(&card->fe); + } + + if (err == 0) { + aft_bri_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); + aft_bri_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_OFF); + aft_fe_intr_ctrl(card, 1); + } + + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + if (err){ + DEBUG_EVENT("%s: Failed BRI configuration!\n", + card->devname); + return -EINVAL; + } + /* Run rest of initialization not from lock */ + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } + + DEBUG_EVENT("%s: Front end successful\n", + card->devname); + + + /*============ LINE/PORT CONFIG REGISTER ===============*/ + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &physical_card_config_counter); + DEBUG_BRI("physical_card_config_counter: %d\n", physical_card_config_counter); + + if (physical_card_config_counter == 1){ + /* FE synch. For BRI reset done only ONCE for both lines */ + card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card,AFT_LINE_CFG_REG),®); + wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),reg); + } + + WP_DELAY(10); + + wan_clear_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),reg); + + WP_DELAY(10); + + err=aft_bri_test_sync(card,1); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),®); + if (err != 0){ + DEBUG_EVENT("%s: Error: Front End Interface Not Ready (0x%08X)!\n", + card->devname,reg); + return err; + } else{ + DEBUG_EVENT("%s: Front End Interface Ready 0x%08X\n", + card->devname,reg); + } + + + err=aft_bri_hwec_config(card,conf); + if (err) { + return err; + } + +#if defined(__WINDOWS__) + /*connect to interrupt line and only AFTER THAT enable device's interrupts.*/ + if(connect_to_interrupt_line(card)){ + return 1; + } + /*at this point we can handle front end interrupts*/ + card->init_flag = 0; +#endif + + /* Enable only Front End Interrupt + * Wait for front end to come up before enabling DMA */ + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + wan_clear_bit(AFT_LCFG_DMA_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_TDMV_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + card->u.aft.lcfg_reg=reg; + + + /*============ DMA CONTROL REGISTER ===============*/ + + /* Disable Global DMA because we will be + * waiting for the front end to come up */ + reg=0; + aft_dmactrl_set_max_logic_ch(®,0); + wan_clear_bit(AFT_DMACTRL_GLOBAL_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + + + /* Initialize all BRI timeslots ONLY on VERY FIRST BRI module */ + reg=0; + for (i=0;i<32;i++){ + ctrl_ram_reg=AFT_PORT_REG(card,AFT_CONTROL_RAM_ACCESS_BASE_REG); + ctrl_ram_reg+=(i*4); + + aft_ctrlram_set_logic_ch(®,0x1F); + aft_ctrlram_set_fifo_size(®,0); + aft_ctrlram_set_fifo_base(®,0x1F); + + wan_set_bit(AFT_CTRLRAM_HDLC_MODE_BIT,®); + wan_set_bit(AFT_CTRLRAM_HDLC_TXCH_RESET_BIT,®); + wan_set_bit(AFT_CTRLRAM_HDLC_RXCH_RESET_BIT,®); + + card->hw_iface.bus_write_4(card->hw, ctrl_ram_reg, reg); + } + + aft_wdt_reset(card); + + return 0; + +} + +int aft_bri_chip_unconfig(sdla_t *card) +{ + wan_smp_flag_t smp_flags,smp_flags1; + + BRI_FUNC(); + + /* chip unconfig is done in disable_comms() */ + + /* Disable Octasic for this BRI module */ + if (card->wandev.ec_dev){ +#if defined(CONFIG_WANPIPE_HWEC) + DEBUG_EVENT("%s: Unregisterd HWEC\n", + card->devname); + wanpipe_ec_unregister(card->wandev.ec_dev, card); +#else + DEBUG_EVENT("%s: Wanpipe HW Echo Canceller modele is not compiled!\n", + card->devname); +#endif + } + + card->wandev.hwec_enable = NULL; + card->wandev.ec_dev = NULL; + + /* Unconfiging, only on shutdown */ + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + __aft_fe_intr_ctrl(card,0); + if (card->wandev.fe_iface.unconfig){ + card->wandev.fe_iface.unconfig(&card->fe); + } + __aft_fe_intr_ctrl(card,0); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + + return 0; +} + +int aft_bri_chan_dev_config(sdla_t *card, void *chan_ptr) +{ + u32 reg; + long i; + int chan_num=-EBUSY; + private_area_t *chan = (private_area_t*)chan_ptr; + u32 ctrl_ram_reg,dma_ram_reg; + + BRI_FUNC(); + + if(chan->dchan_time_slot >= 0){ + BRI_FUNC(); + chan->logic_ch_num = 2; + card->u.aft.dev_to_ch_map[BRI_DCHAN_LOGIC_CHAN]=(void*)chan; + /* configure bri dchan here */ + return 0; + } + + chan_num=aft_request_logical_channel_num(card, chan); + if (chan_num < 0){ + return -EBUSY; + } + chan->logic_ch_num = chan_num; + + dma_ram_reg=AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + dma_ram_reg+=(chan->logic_ch_num*4); + + reg=0; + card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg); + + card->hw_iface.bus_read_4(card->hw, dma_ram_reg, ®); + + aft_dmachain_set_fifo_size(®, chan->fifo_size_code); + aft_dmachain_set_fifo_base(®, chan->fifo_base_addr); + + /* Initially always disable rx synchronization */ + wan_clear_bit(AFT_DMACHAIN_RX_SYNC_BIT,®); + + /* Enable SS7 if configured by user */ + if (chan->cfg.ss7_enable){ + wan_set_bit(AFT_DMACHAIN_SS7_ENABLE_BIT,®); + }else{ + wan_clear_bit(AFT_DMACHAIN_SS7_ENABLE_BIT,®); + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_dmachain_enable_tdmv_and_mtu_size(®,chan->mru); + } + + card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg); + + reg=0; + + + for (i=0;iu.aft.num_of_time_slots;i++){ + + + ctrl_ram_reg=AFT_PORT_REG(card,AFT_CONTROL_RAM_ACCESS_BASE_REG); + ctrl_ram_reg+=(i*4); + + if (wan_test_bit(i,&chan->time_slot_map)){ + + BRI_FUNC(); + + wan_set_bit(i,&card->u.aft.time_slot_map); + + card->hw_iface.bus_read_4(card->hw, ctrl_ram_reg, ®); + + aft_ctrlram_set_logic_ch(®,chan->logic_ch_num); + + if (i == chan->first_time_slot){ + wan_set_bit(AFT_CTRLRAM_SYNC_FST_TSLOT_BIT,®); + } + + aft_ctrlram_set_fifo_size(®,chan->fifo_size_code); + + aft_ctrlram_set_fifo_base(®,chan->fifo_base_addr); + + + if (chan->hdlc_eng){ + wan_set_bit(AFT_CTRLRAM_HDLC_MODE_BIT,®); + }else{ + wan_clear_bit(AFT_CTRLRAM_HDLC_MODE_BIT,®); + } + + if (chan->cfg.data_mux){ + wan_set_bit(AFT_CTRLRAM_DATA_MUX_ENABLE_BIT,®); + }else{ + wan_clear_bit(AFT_CTRLRAM_DATA_MUX_ENABLE_BIT,®); + } + + if (0){ /* FIXME card->fe.fe_cfg.cfg.te1cfg.fcs == 32){ */ + wan_set_bit(AFT_CTRLRAM_HDLC_CRC_SIZE_BIT,®); + }else{ + wan_clear_bit(AFT_CTRLRAM_HDLC_CRC_SIZE_BIT,®); + } + + /* Enable SS7 if configured by user */ + if (chan->cfg.ss7_enable){ + wan_set_bit(AFT_CTRLRAM_SS7_ENABLE_BIT,®); + }else{ + wan_clear_bit(AFT_CTRLRAM_SS7_ENABLE_BIT,®); + } + + wan_clear_bit(AFT_CTRLRAM_HDLC_TXCH_RESET_BIT,®); + wan_clear_bit(AFT_CTRLRAM_HDLC_RXCH_RESET_BIT,®); + + DEBUG_CFG("%s: Configuring %s LC=%i for timeslot %ld : Offset 0x%X Reg 0x%X\n", + card->devname, chan->if_name, chan->logic_ch_num, i, + ctrl_ram_reg,reg); + + card->hw_iface.bus_write_4(card->hw, ctrl_ram_reg, reg); + + } + } + + + if (chan->channelized_cfg && !chan->hdlc_eng){ + + BRI_FUNC(); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),®); + aft_lcfg_tdmv_cnt_inc(®); + + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),reg); + card->u.aft.lcfg_reg=reg; + + wan_set_bit(chan->logic_ch_num,&card->u.aft.tdm_logic_ch_map); + + DEBUG_TEST("%s: TDMV CNT = %i\n", + card->devname, + (reg>>AFT_LCFG_TDMV_CH_NUM_SHIFT)&AFT_LCFG_TDMV_CH_NUM_MASK); + } + + return 0; +} + +int aft_bri_chan_dev_unconfig(sdla_t *card, void *chan_ptr) +{ + private_area_t *chan = (private_area_t *)chan_ptr; + volatile int i; + u32 dma_ram_reg,ctrl_ram_reg,reg; + + DEBUG_BRI("%s: 1 BRI DEV UNCONFIG %i\n", + card->devname, chan->logic_ch_num); + + if( chan->dchan_time_slot >= 0) { + + DEBUG_BRI("%s: 2 BRI DEV DCHAN UNCONFIG %i\n", + card->devname, chan->logic_ch_num); + + chan->logic_ch_num = 2; + card->u.aft.dev_to_ch_map[BRI_DCHAN_LOGIC_CHAN]=NULL; + /* configure bri dchan here */ + return 0; + } + + /* Select an HDLC logic channel for configuration */ + if (chan->logic_ch_num != -1){ + + DEBUG_BRI("%s: 2 BRI DEV UNCONFIG %i\n", + card->devname, chan->logic_ch_num); + + dma_ram_reg=AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + dma_ram_reg+=(chan->logic_ch_num*4); + + card->hw_iface.bus_read_4(card->hw, dma_ram_reg, ®); + + aft_dmachain_set_fifo_base(®,0x1F); + aft_dmachain_set_fifo_size(®,0); + card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg); + + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&chan->time_slot_map)){ + BRI_FUNC(); + ctrl_ram_reg=AFT_PORT_REG(card,AFT_CONTROL_RAM_ACCESS_BASE_REG); + ctrl_ram_reg+=(i*4); + + reg=0; + aft_ctrlram_set_logic_ch(®,0x1F); + + aft_ctrlram_set_fifo_base(®,0x1F); + aft_ctrlram_set_fifo_size(®,0); + + wan_set_bit(AFT_CTRLRAM_HDLC_MODE_BIT,®); + wan_set_bit(AFT_CTRLRAM_HDLC_TXCH_RESET_BIT,®); + wan_set_bit(AFT_CTRLRAM_HDLC_RXCH_RESET_BIT,®); + + card->hw_iface.bus_write_4(card->hw, ctrl_ram_reg, reg); + } + } + + aft_free_logical_channel_num(card,chan->logic_ch_num); + aft_free_fifo_baddr_and_size(card,chan); + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&chan->time_slot_map)){ + wan_clear_bit(i,&card->u.aft.time_slot_map); + } + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + BRI_FUNC(); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG),®); + aft_lcfg_tdmv_cnt_dec(®); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG),reg); + wan_clear_bit(chan->logic_ch_num,&card->u.aft.tdm_logic_ch_map); + DEBUG_TEST("%s: TDMV CNT = %i\n", + card->devname, + (reg>>AFT_LCFG_TDMV_CH_NUM_SHIFT)&AFT_LCFG_TDMV_CH_NUM_MASK); + } + + /* Do not clear the logi_ch_num here. + We will do it at the end of del_if_private() funciton */ + } + + return 0; +} + +int bri_check_ec_security(sdla_t *card) +{ + u32 cfg_reg; + u32 security_bit=AFT_CHIPCFG_A500_EC_SECURITY_BIT; + + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG, &cfg_reg); + if (wan_test_bit(security_bit,&cfg_reg)){ + return 1; + } + return 0; +} + + +unsigned char aft_bri_read_cpld(sdla_t *card, unsigned short cpld_off) +{ + u8 tmp=0; + int err = -EINVAL; + + BRI_FUNC(); + + if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + + if (card->hw_iface.read_cpld){ + err = card->hw_iface.read_cpld(card->hw, (u16)cpld_off, &tmp); + } + + card->hw_iface.fe_clear_bit(card->hw,0); + + return tmp; +} + +int aft_bri_write_cpld(sdla_t *card, unsigned short off,unsigned short data) +{ + int err = -EINVAL; + + BRI_FUNC(); + + + if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + + if (card->hw_iface.write_cpld){ + err = card->hw_iface.write_cpld(card->hw, (u16)off, (u8)data); + } + + card->hw_iface.fe_clear_bit(card->hw,0); + + return 0; +} + + +int bri_write_cpld(sdla_t *card, unsigned short off,unsigned char data) +{ + u16 org_off; + + BRI_FUNC(); + + if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + + off &= ~AFT8_BIT_DEV_ADDR_CLEAR; + off |= AFT8_BIT_DEV_MAXIM_ADDR_CPLD; + + /*ALEX: Save the current original address */ + card->hw_iface.bus_read_2(card->hw, + AFT_MCPU_INTERFACE_ADDR, + &org_off); + + /* This delay is required to avoid bridge optimization + * (combining two writes together)*/ + WP_DELAY(5); + + card->hw_iface.bus_write_2(card->hw, + AFT_MCPU_INTERFACE_ADDR, + off); + + /* This delay is required to avoid bridge optimization + * (combining two writes together)*/ + WP_DELAY(5); + + card->hw_iface.bus_write_1(card->hw, + AFT_MCPU_INTERFACE, + data); + /*ALEX: Restore the original address */ + card->hw_iface.bus_write_2(card->hw, + AFT_MCPU_INTERFACE_ADDR, + org_off); + card->hw_iface.fe_clear_bit(card->hw,0); + + return 0; +} + + +void aft_bri_fifo_adjust(sdla_t *card, u32 level) +{ + u32 fifo_size,reg; + card->hw_iface.bus_read_4(card->hw, AFT_FIFO_MARK_REG, &fifo_size); + + BRI_FUNC(); + + aft_fifo_mark_gset(®,(u8)level); + + if (level == 1) { + /* FIXME: This is a kluge. Have fifo adjust for each + fifo size + For 32 bit fifo if level is 1 set it to zero */ + reg&=~(0x1); + } + + if (fifo_size == reg){ + return; + } + + card->hw_iface.bus_write_4(card->hw, AFT_FIFO_MARK_REG, reg); + DEBUG_EVENT("%s: Fifo Level Map:0x%08X\n",card->devname,reg); +} + + +#if defined(CONFIG_WANPIPE_HWEC) +static int aft_bri_hwec_reset(void *pcard, int reset) +{ + sdla_t *card = (sdla_t*)pcard; + wan_smp_flag_t smp_flags; + wan_smp_flag_t flags; + int err = -EINVAL; + + card->hw_iface.hw_lock(card->hw,&smp_flags); + wan_spin_lock_irq(&card->wandev.lock,&flags); + if (!reset){ + DEBUG_EVENT("%s: Clear Echo Canceller chip reset.\n", + card->devname); + + /* Clear RESET on HWEC */ + aft_bri_cpld0_set(card,0); + + WP_DELAY(1000); + err = 0; + + }else{ + DEBUG_EVENT("%s: Set Echo Canceller chip reset.\n", + card->devname); + + /* RESET HWEC */ + aft_bri_cpld0_set(card,1); + + err = 0; + } + wan_spin_unlock_irq(&card->wandev.lock,&flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + return err; +} +#endif + +#if defined(CONFIG_WANPIPE_HWEC) +/****************************************************************************** +** aft_bri_hwec_enable() +** +** Return: 0 - success +** 1 - channel out of channel map +** < 0 - failed +******************************************************************************/ +static int aft_bri_hwec_enable(void *pcard, int enable, int fe_chan) +{ + sdla_t *card = (sdla_t*)pcard; + unsigned int value, new_chan, bri_chan; + + DEBUG_HWEC("%s(): pcard: 0x%p\n", __FUNCTION__, pcard); + + WAN_ASSERT(card == NULL); + + DEBUG_HWEC("[HWEC BRI]: %s: %s bypass mode for channel %d, LineNo: %d!\n", + card->devname, + (enable) ? "Enable" : "Disable", + fe_chan, WAN_FE_LINENO(&card->fe)); + + /* make sure channel is 0 or 1, nothing else!! */ + if(fe_chan != 1 && fe_chan != 2){ + DEBUG_HWEC("[HWEC BRI]: %s: invalid channel %d. Must be 1 or 2!\n", + card->devname, fe_chan); + return -EINVAL; + } + + new_chan = 2 * WAN_FE_LINENO(&card->fe); /* 0, 2, 4...*/ + bri_chan = new_chan + (fe_chan-1); /* {0,1}, {2,3}, {4,5}... */ + + DEBUG_HWEC("bri_chan: %d\n", bri_chan); + + DEBUG_BRI("Offset: 0x%X!\n", AFT_PORT_REG(card,0x1000) + bri_chan * 4); + + card->hw_iface.bus_read_4( + card->hw, + AFT_PORT_REG(card,0x1000) + bri_chan * 4, + &value); + if (enable){ + value |= 0x20; + }else{ + value &= ~0x20; + } + + DEBUG_HWEC("[HWEC BRI]: %s: writing: 0x%08X!\n",card->devname, value); + + card->hw_iface.bus_write_4( + card->hw, + AFT_PORT_REG(card,0x1000) + bri_chan * 4, + value); + + return 0; +} +#endif + + +/*************************************************************************** + BRI card +***************************************************************************/ + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + +/*============================================================================ + * Write BRI register + */ + +int aft_bri_write_fe(void* pcard, ...) +{ + va_list args; + sdla_t *card = (sdla_t*)pcard; + int mod_no, type, chain, reg, value; +#if defined(WAN_DEBUG_FE) + char *fname; + int fline; +#endif + + WAN_ASSERT(card == NULL); + WAN_ASSERT(card->hw_iface.bus_write_4 == NULL); + WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); + + va_start(args, pcard); + mod_no = va_arg(args, int); + type = va_arg(args, int); + chain = va_arg(args, int); + reg = va_arg(args, int); + value = va_arg(args, int); +#if defined(WAN_DEBUG_FE) + fname = va_arg(args, char*); + fline = va_arg(args, int); +#endif + va_end(args); + + if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ +#if defined(WAN_DEBUG_FE) + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", + card->devname, __FUNCTION__,__LINE__, fname, fline); +#else + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + card->devname, __FUNCTION__,__LINE__); +#endif + return -EINVAL; + } + + write_bri_fe_byte(card, mod_no, reg, value); + + card->hw_iface.fe_clear_bit(card->hw,0); + return 0; +} + + +/*============================================================================ + * Read bri register + */ + +unsigned char aft_bri_read_fe (void* pcard, ...) +{ + va_list args; + sdla_t *card = (sdla_t*)pcard; + int mod_no, type, optional_arg, reg; + unsigned char data = 0; +#if defined(WAN_DEBUG_FE) + char *fname; + int fline; +#endif + + WAN_ASSERT(card == NULL); + WAN_ASSERT(card->hw_iface.bus_write_4 == NULL); + WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); + + va_start(args, pcard); + mod_no = va_arg(args, int); + type = va_arg(args, int); + optional_arg = va_arg(args, int); + reg = va_arg(args, int); +#if defined(WAN_DEBUG_FE) + fname = va_arg(args, char*); + fline = va_arg(args, int); +#endif + va_end(args); + + if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ +#if defined(WAN_DEBUG_FE) + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", + card->devname, __FUNCTION__,__LINE__,fname,fline); +#else + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + card->devname, __FUNCTION__,__LINE__); +#endif + return 0x00; + } + + read_bri_fe_byte(card, mod_no, reg, &data, type, optional_arg); + + card->hw_iface.fe_clear_bit(card->hw,0); + return data; +} + +/*============================================================================ + * Read bri register - debugging version + */ + +unsigned char __aft_bri_read_fe (void* pcard, ...) +{ + va_list args; + sdla_t *card = (sdla_t*)pcard; + int mod_no, type, optional_arg, reg; + unsigned char data = 0; +#if defined(WAN_DEBUG_FE) + char *fname; + int fline; +#endif + + WAN_ASSERT(card == NULL); + WAN_ASSERT(card->hw_iface.bus_write_4 == NULL); + WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); + + va_start(args, pcard); + mod_no = va_arg(args, int); + type = va_arg(args, int); + optional_arg = va_arg(args, int); + reg = va_arg(args, int); +#if defined(WAN_DEBUG_FE) + fname = va_arg(args, char*); + fline = va_arg(args, int); +#endif + va_end(args); + + read_bri_fe_byte(card, mod_no, reg, &data, type, optional_arg); + + return data; +} + + +#define SPI_DELAY if(0)WP_DELAY(10) + +#undef SPI_MAX_RETRY_COUNT +#define SPI_MAX_RETRY_COUNT 1000 + +#define MYBREAK if(1)break + +#define FAST_SPI 0 + +static int +read_bri_fe_byte(sdla_t *card, unsigned char mod_no, unsigned char reg, unsigned char *value, + unsigned char type, unsigned char optional_arg) +{ + bri_reg_t data, dummy; + u_int32_t *data_ptr = (u_int32_t*)&data; + u_int32_t *dummy_ptr = (u_int32_t*)&dummy; + u_int32_t retry_counter; + u_int8_t rm_no=0xFF; + + WAN_ASSERT(card == NULL); + +#if defined(WAN_DEBUG_REG) + BRI_DBG("%s():%s\n", __FUNCTION__, card->devname); +#endif + + if(type != MOD_TYPE_NT && type != MOD_TYPE_TE){ +#if 0 + BRI_DBG("%s(): Warning: unknown module type! (%d)\n", __FUNCTION__, type); +#endif + } + + /* setup address offset for fe */ + data.reset=0; + data.start=1; + data.reserv1=0; + + if(type == MOD_TYPE_NONE){ + /* the only case we get here is if running module detection code. */ + rm_no = optional_arg; + }else{ + /* Input mod_no is an even number between 0 and 22 (including). + Calculate rm_no - should be between 0 and 3 (including). + */ + if(mod_no % 2){ + DEBUG_BRI("%s(): Warning: module number (%d) is not even!!\n", + __FUNCTION__, mod_no); + } + rm_no = mod_no / (MAX_BRI_MODULES_PER_REMORA*2); +#if 0 + BRI_DBG("%s(input): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + /* Translate mod_no to be between 0 and 2 (including) */ + mod_no = (mod_no / 2) % MAX_BRI_MODULES_PER_REMORA; + } +#if 0 + BRI_DBG("%s(updated): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + if(rm_no > MAX_BRI_REMORAS - 1){ + DEBUG_EVENT("%s:%s(): Line:%d: invalid rm_no: %d!!(mod_no: %d)\n", + card->devname, __FUNCTION__, __LINE__, rm_no, mod_no); + return 0; + } + + data.remora_addr = rm_no; + data.mod_addr = mod_no; + + data.data = reg; + data.contrl = 0; + data.contrl |= ADDR_BIT; + + /* check spi not busy */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + card->hw_iface.bus_read_4(card->hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{MYBREAK;} + } + if(0)DEBUG_EVENT("%s(): Line:%d: retry_counter: %d, dummy.start: %d\n",__FUNCTION__, __LINE__, retry_counter, dummy.start); + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", card->devname, __FUNCTION__, __LINE__); + return 0; + } + +#if 0 + BRI_DBG("%s():Line:%d: bus_write_4(): data: 0x%08X\n", __FUNCTION__, __LINE__, data); +#endif + /* setup the address */ + card->hw_iface.bus_write_4(card->hw, SPI_INTERFACE_REG, *data_ptr); + + /* printf("2. data: 0x%08X\n", *data_ptr); */ + /* wait for end of spi operation */ +#if !FAST_SPI + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + card->hw_iface.bus_read_4(card->hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{MYBREAK;} + } + SPI_DELAY; + if(0)DEBUG_EVENT("%s(): Line:%d: retry_counter: %d, dummy.start: %d\n",__FUNCTION__, __LINE__, retry_counter, dummy.start); + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", card->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + + /* setup data for read spi operation */ + data.reset=0; + data.start=1; + data.reserv1=0; + + data.remora_addr = rm_no; + data.mod_addr = mod_no; + + data.data = 0; + data.contrl = 0; + data.contrl |= READ_BIT; + +#if FAST_SPI + SPI_DELAY; +#else + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + card->hw_iface.bus_read_4(card->hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{MYBREAK;} + } + SPI_DELAY; + if(0)DEBUG_EVENT("%s(): Line:%d: retry_counter: %d, dummy.start: %d\n",__FUNCTION__, __LINE__, retry_counter, dummy.start); + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", card->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + +#if 0 + BRI_DBG("%s():Line:%d: bus_write_4(): data: 0x%08X\n", __FUNCTION__, __LINE__, data); +#endif + /* start read spi operation */ + card->hw_iface.bus_write_4(card->hw, SPI_INTERFACE_REG, *data_ptr); + +#if FAST_SPI + SPI_DELAY; +#else + /* wait for end of spi operation */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + card->hw_iface.bus_read_4(card->hw, SPI_INTERFACE_REG, data_ptr); + if(data.start == 1){SPI_DELAY;}else{MYBREAK;} + } +#if 0 + BRI_DBG("%s():Line:%d: bus_read_4(): data: 0x%08X\n", __FUNCTION__, __LINE__, data); +#endif + SPI_DELAY; + if(0)DEBUG_EVENT("%s(): Line:%d: retry_counter: %d, dummy.start: %d\n",__FUNCTION__, __LINE__, retry_counter, dummy.start); + if(data.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", card->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + //printf("3. data: 0x%08X\n", *data_ptr); + + *value = data.data; + +#if defined(WAN_DEBUG_REG) + DEBUG_EVENT("%s():%s: mod_no:%d reg=0x%X (%d) value=0x%02X\n", + __FUNCTION__, + card->devname, + mod_no, + reg, + reg, + *value); +#endif + return 0; +} + +static int +write_bri_fe_byte(sdla_t *card, unsigned char mod_no, unsigned char addr, unsigned char value) +{ + bri_reg_t data, dummy; + u_int32_t *data_ptr = (u_int32_t*)&data; + u_int32_t *dummy_ptr = (u_int32_t*)&dummy; + u_int8_t rm_no=0xFF; + u_int32_t retry_counter; + + WAN_ASSERT(card == NULL); + +#if defined(WAN_DEBUG_REG) + DEBUG_EVENT("%s():%s: mod_no:%d addr=0x%X (%d) value=0x%02X\n", + __FUNCTION__, + card->devname, + mod_no, + addr, + addr, + value); +#endif + + /* Input mod_no is an even number between 0 and 22 (including). + Calculate rm_no - should be between 0 and 3 (including). + */ + rm_no = mod_no / (MAX_BRI_MODULES_PER_REMORA*2); +#if 0 + BRI_DBG("%s(input): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + /* Translate mod_no to be between 0 and 2 (including) */ + mod_no = (mod_no / 2) % MAX_BRI_MODULES_PER_REMORA; +#if 0 + BRI_DBG("%s(updated): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + if(rm_no > MAX_BRI_REMORAS - 1){ + DEBUG_EVENT("%s:%s(): Line:%d: invalid rm_no: %d!!(mod_no: %d)\n", + card->devname, __FUNCTION__, __LINE__, rm_no, mod_no); + return 0; + } + + /* setup address offset for fe */ + data.reset = 0; + data.start = 1; + data.reserv1 = 0; + + data.remora_addr = rm_no; + //data.mod_addr = 0; + data.mod_addr = mod_no; + + data.data = addr; + data.contrl = 0; + data.contrl |= ADDR_BIT; + + /* printf("1. data: 0x%08X\n", *data_ptr); */ + + /* check spi not busy */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + card->hw_iface.bus_read_4(card->hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{MYBREAK;} + } + SPI_DELAY; + if(0)DEBUG_EVENT("%s(): Line:%d: retry_counter: %d, dummy.start: %d\n",__FUNCTION__, __LINE__, retry_counter, dummy.start); + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", card->devname, __FUNCTION__, __LINE__); + return 0; + } + + card->hw_iface.bus_write_4( card->hw, SPI_INTERFACE_REG, *data_ptr); + + /* start write spi operation */ + data.reset=0; + data.start=1; + data.reserv1=0; + + //data.remora_addr =0; + //data.mod_addr =0; + data.remora_addr = rm_no; + data.mod_addr = mod_no; + + data.data = value; + data.contrl = 0; + + /* printf("2. data: 0x%08X\n", *data_ptr); */ +#if FAST_SPI + SPI_DELAY; +#else + /* wait for end of spi operation */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + card->hw_iface.bus_read_4(card->hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{MYBREAK;} + } + SPI_DELAY; + if(0)DEBUG_EVENT("%s(): Line:%d: retry_counter: %d, dummy.start: %d\n",__FUNCTION__, __LINE__, retry_counter, dummy.start); + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", card->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + /* write the actual data */ + card->hw_iface.bus_write_4( card->hw, SPI_INTERFACE_REG, *data_ptr); +/* + card->hw_iface.bus_read_4(card->hw, 0x40, dummy_ptr); + card->hw_iface.bus_read_4(card->hw, SPI_INTERFACE_REG, dummy_ptr); + if((*data_ptr & 0xFFFF) != (*dummy_ptr & 0xFFFF)){ + DEBUG_EVENT("%s:%s(): Line:%d: Error: *data_ptr: 0x%02X, *dummy_ptr: 0x%02X\n", + card->devname, __FUNCTION__, __LINE__, *data_ptr, *dummy_ptr); + } +*/ + return 0; +} + +/********************************************************************************/ +/* D channel Transmit */ +int aft_bri_dchan_transmit(sdla_t *card, void *chan_ptr, void *src_data_buffer, unsigned int buffer_len) +{ + int err = 0; + /*private_area_t *chan = (private_area_t*)chan_ptr;*/ + + BRI_FUNC(); + + if (card->wandev.fe_iface.isdn_bri_dchan_tx){ + err = card->wandev.fe_iface.isdn_bri_dchan_tx( + &card->fe, + src_data_buffer, + buffer_len); + }else{ + DEBUG_EVENT("%s():%s: Warning: uninitialized isdn_bri_dchan_tx() pointer.\n", + __FUNCTION__, card->devname); + } + + return err; +} + +/********************************************************************************/ +/* D channel Receive */ +/* +int aft_bri_dchan_receive( sdla_t *card, void *chan_ptr, void *dst_data_buffer, unsigned int buffer_len) +{ + u32 reg; + int err = 0; + private_area_t *chan = (private_area_t*)chan_ptr; + + BRI_FUNC(); + + if (card->wandev.fe_iface.isdn_bri_dchan_rx){ + err = card->wandev.fe_iface.isdn_bri_dchan_rx( + &card->fe, + dst_data_buffer, + buffer_len); + }else{ + DEBUG_EVENT("%s():%s: Warning: uninitialized isdn_bri_dchan_rx() pointer.\n", + __FUNCTION__, card->devname); + } + + return err; +} +*/ +#endif/* #if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) */ diff --git a/patches/kdrivers/src/net/diff b/patches/kdrivers/src/net/diff index 468eb2c..090c976 100644 --- a/patches/kdrivers/src/net/diff +++ b/patches/kdrivers/src/net/diff @@ -1,1162 +1,594 @@ ---- sdla_aft_te3.c 2008-02-19 18:54:10.000000000 -0500 -+++ /common/wanpipe/sdla_aft_te3.c 2008-02-02 12:33:18.000000000 -0500 -@@ -281,12 +281,11 @@ - #endif - static int if_open (netdevice_t* dev); - static int if_close (netdevice_t* dev); --static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); -- --static struct net_device_stats* if_stats (netdevice_t* dev); -+static int if_do_ioctl(netdevice_t*, struct ifreq*, wan_ioctl_cmd_t); - - #if defined(__LINUX__) - static int if_send (netskb_t* skb, netdevice_t* dev); -+static struct net_device_stats* if_stats (netdevice_t* dev); +--- sdla_aft_te1.c 2007-11-05 17:34:32.000000000 -0500 ++++ /common/wanpipe/sdla_aft_te1.c 2007-11-21 17:30:49.000000000 -0500 +@@ -26,6 +26,7 @@ + # include + # include + # include ++# include #else - static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct rtentry *rt); + # include + # include +@@ -38,10 +39,8 @@ + # include + # include + # include +-#if defined(CONFIG_PRODUCT_WANPIPE_AFT_SERIAL) + # include #endif -@@ -372,8 +371,8 @@ - static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num); - static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb); +-#endif --static int write_framer(void *pcard,unsigned short framer_off,unsigned short framer_data); --static unsigned int read_framer(void *pcard,unsigned short framer_off); -+//static int write_framer(void *pcard,unsigned short framer_off,unsigned short framer_data); -+//static unsigned int read_framer(void *pcard,unsigned short framer_off); - #if 0 - //FIXME to be taken out check with M.F. - static void framer_reset(sdla_t *card); -@@ -499,9 +498,6 @@ + #if defined(CONFIG_WANPIPE_HWEC) + # include +@@ -141,6 +140,14 @@ + # undef AFT_CLOCK_SYNC + #endif + ++#if 1 ++# warning "AFT_SERIAL_DEBUGGING is enabled" ++# define AFT_SINGLE_DMA_CHAIN 1 ++# define AFT_SERIAL_DEBUG ++#else ++# undef AFT_SERIAL_DEBUG ++#endif ++ + #if defined(__LINUX__) + #define AFT_TDM_API_SUPPORT 1 + #else +@@ -159,6 +166,7 @@ + # undef AFT_RTP_SUPPORT + #endif + ++ + #if defined(WANPIPE_64BIT_4G_DMA) + #warning "Wanpipe compiled for 64bit 4G DMA" + #endif +@@ -330,6 +338,7 @@ + static void wp_aft_tdmv_per_port_isr(sdla_t *card); + static void wp_aft_fifo_per_port_isr(sdla_t *card); + static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr); ++static void wp_aft_serial_status_isr(sdla_t *card, u32 status); + + /* Bottom half handlers */ + #if defined(__LINUX__) +@@ -816,17 +825,17 @@ + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + +- /* FIXME:hardcoded!! */ +- card->u.aft.firm_id = AFT_DS_FE_CORE_ID; +- + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); return -EINVAL; } --#if defined(WAN_DEBUG_MEM) -- DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); --#endif - - if (card->adptr_subtype == AFT_SUBTYPE_SHARK) { - DEBUG_EVENT("%s: Starting SHARK T3/E3 Adapter!\n", -@@ -512,7 +508,7 @@ - card->wandev.clocking = conf->clocking; - card->wandev.ignore_front_end_status = conf->ignore_front_end_status; - card->wandev.ttl = conf->ttl; -- card->wandev.interface = conf->interface; -+ card->wandev.electrical_interface = conf->electrical_interface; - card->wandev.comm_port = conf->comm_port; - card->wandev.udp_port = conf->udp_port; - card->wandev.new_if_cnt = 0; -@@ -534,14 +530,16 @@ - card->fe.write_fe_cpld = write_fe_cpld; - - // card->fe.read_cpld = read_cpld; -- card->fe.write_framer = write_framer; -- card->fe.read_framer = read_framer; -+ card->fe.write_fe_reg = card->hw_iface.fe_write; -+ card->fe.read_fe_reg = card->hw_iface.fe_read; -+ //card->fe.write_framer = write_framer; -+ //card->fe.read_framer = read_framer; - - // card->wandev.write_front_end_reg = write_front_end_reg; - // card->wandev.read_front_end_reg = read_front_end_reg; - card->wandev.fe_enable_timer = enable_timer; - card->wandev.te_link_state = handle_front_end_state; --//ALEX conf->interface = -+//ALEX conf->electrical_interface = - // IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; - - if (card->wandev.comm_port == WANOPT_PRI){ -@@ -667,12 +665,12 @@ - */ - static int update (wan_device_t* wandev) - { -- sdla_t* card = wandev->private; -+ sdla_t* card = wandev->priv; - netdevice_t* dev; - volatile private_area_t* chan; - - /* sanity checks */ -- if((wandev == NULL) || (wandev->private == NULL)) -+ if((wandev == NULL) || (wandev->priv == NULL)) - return -EFAULT; - - if(wandev->state == WAN_UNCONFIGURED) -@@ -744,7 +742,7 @@ - */ - static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) - { -- sdla_t* card = wandev->private; -+ sdla_t* card = wandev->priv; - private_area_t* chan; - int err = 0; - netskb_t *skb; -@@ -1015,7 +1013,6 @@ - chan->common.iface.close = &if_close; - chan->common.iface.output = &if_send; - chan->common.iface.ioctl = &if_do_ioctl; -- chan->common.iface.get_stats = &if_stats; - chan->common.iface.tx_timeout = &if_tx_timeout; - if (wan_iface.attach){ - if (!ifunit(wan_netif_name(dev))){ -@@ -1211,6 +1208,8 @@ - dev->type = ARPHRD_PPP; - dev->mtu = card->wandev.mtu; - dev->hard_header_len = 16; -+ dev->hard_header = NULL; -+ dev->rebuild_header = NULL; - dev->addr_len = 0; - } - -@@ -1286,6 +1285,7 @@ - WAN_NETIF_STOP_QUEUE(dev); - WAN_NETIF_CARRIER_OFF(dev); - +- /* Make special hardware initialization for ISDN BRI board */ ++ /* Make special hardware initialization for Serial board */ + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + - /* If FRONT End is down, it means that the DMA - * is disabled. In this case don't try to - * reset fifo. Let the enable_data_error_intr() -@@ -1504,7 +1504,9 @@ - xilinx_tx_fifo_under_recover(card,chan); - wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); ++ FE_MEDIA(&(card->fe.fe_cfg)) = WAN_MEDIA_SERIAL; ++ + wp_serial_iface_init(&card->wandev.fe_iface); + card->fe.name = card->devname; + card->fe.card = card; +@@ -850,9 +859,7 @@ -- aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); -+ if (!chan->single_dma_chain){ -+ aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); -+ } - } + card->u.aft.num_of_time_slots = 1; - -@@ -1662,6 +1664,7 @@ - } - - -+#if defined(__LINUX__) - /*============================================================================ - * if_stats - * -@@ -1714,9 +1717,7 @@ - - return &chan->if_stats; - } +- return -EINVAL; - -- -- -+#endif - - /*======================================================================== - * -@@ -1737,7 +1738,8 @@ - * wanpipemon debugger - * - */ --static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) -+static int -+if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t cmd) - { - private_area_t* chan= (private_area_t*)wan_netif_priv(dev); - sdla_t *card; -@@ -1857,8 +1859,8 @@ - - default: - #ifndef WANPIPE_GENERIC -- DEBUG_EVENT("%s: Command %x not supported!\n", -- card->devname,cmd); -+ DEBUG_IOCTL("%s: Command %x not supported!\n", -+ card->devname,cmd); - return -EOPNOTSUPP; - #else - if (card->wandev.ioctl){ -@@ -2444,10 +2446,10 @@ - static void wp_bh (void* data, int dummy) +- return wan_aft_init(card,conf); ++ return wan_aft_init(card,conf); + } #endif - { -- private_area_t* chan = (private_area_t *)data; -- netskb_t *new_skb,*skb; -- unsigned char pkt_error; -- unsigned long timeout=SYSTEM_TICKS; -+ private_area_t *chan = (private_area_t *)data; -+ netskb_t *new_skb,*skb; -+ unsigned char pkt_error; -+ wan_ticks_t timeout=SYSTEM_TICKS; - - DEBUG_TEST("%s: ------------ BEGIN --------------: %lu\n", - __FUNCTION__,SYSTEM_TICKS); -@@ -2621,6 +2623,9 @@ - card->devname); - return 0; - } -+ -+ DEBUG_TEST("%s: RX FIFO=0x%08X TX FIFO=0x%08X\n", -+ card->devname,rx_status,tx_status); - if (IS_TE3(&card->fe.fe_cfg)){ - num_of_logic_ch=1; -@@ -2879,7 +2884,6 @@ - XILINX_DMA_RX_INTR_PENDING_REG, - &dma_rx_reg); - -- - DEBUG_TEST("%s: DMA_RX_INTR_REG(0x%X) = 0x%X ActCH=0x%lX\n", - card->devname, - XILINX_DMA_RX_INTR_PENDING_REG,dma_rx_reg, -@@ -2998,7 +3002,9 @@ - chan->if_name,wan_test_bit(0,&chan->up)); - } - aft_reset_rx_watchdog(card); -- aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); -+ if (!chan->single_dma_chain){ -+ aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); -+ } - } +@@ -1472,12 +1479,11 @@ - DEBUG_TEST("%s: Rx WatchDog Expired %p!\n", -@@ -3218,34 +3224,6 @@ - wan_udp_pkt->wan_udp_return_code = 0; - break; - -- case WAN_GET_MEDIA_TYPE: -- case WAN_FE_GET_STAT: -- case WAN_FE_SET_LB_MODE: -- case WAN_FE_FLUSH_PMON: -- case WAN_FE_GET_CFG: -- -- if (IS_TE3(&card->fe.fe_cfg)){ -- WAN_FECALL(&card->wandev, process_udp, -- (&card->fe, -- &wan_udp_pkt->wan_udp_cmd, -- &wan_udp_pkt->wan_udp_data[0])); -- }else{ -- wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; -- } -- break; -- -- case WAN_GET_PROTOCOL: -- wan_udp_pkt->wan_udp_aft_num_frames = card->wandev.config_id; -- wan_udp_pkt->wan_udp_return_code = CMD_OK; -- wan_udp_pkt->wan_udp_data_len = 1; -- break; -- -- case WAN_GET_PLATFORM: -- wan_udp_pkt->wan_udp_data[0] = WAN_PLATFORM_ID; -- wan_udp_pkt->wan_udp_return_code = CMD_OK; -- wan_udp_pkt->wan_udp_data_len = 1; -- break; -- - case READ_OPERATIONAL_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memcpy(wan_udp_pkt->wan_udp_data,&chan->opstats,sizeof(aft_op_stats_t)); -@@ -3270,7 +3248,42 @@ - wan_udp_pkt->wan_udp_data_len=0; - break; - -+ case WAN_GET_PROTOCOL: -+ wan_udp_pkt->wan_udp_aft_num_frames = card->wandev.config_id; -+ wan_udp_pkt->wan_udp_return_code = CMD_OK; -+ wan_udp_pkt->wan_udp_data_len = 1; -+ break; -+ -+ case WAN_GET_PLATFORM: -+ wan_udp_pkt->wan_udp_data[0] = WAN_PLATFORM_ID; -+ wan_udp_pkt->wan_udp_return_code = CMD_OK; -+ wan_udp_pkt->wan_udp_data_len = 1; -+ break; -+ -+ case WAN_GET_MASTER_DEV_NAME: -+ wan_udp_pkt->wan_udp_data_len = 0; -+ wan_udp_pkt->wan_udp_return_code = 0xCD; -+ break; -+ -+ case WAN_GET_MEDIA_TYPE: -+ if (card->wandev.fe_iface.get_fe_media){ -+ wan_udp_pkt->wan_udp_data[0] = -+ card->wandev.fe_iface.get_fe_media(&card->fe); -+ wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; -+ wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); -+ }else{ -+ wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; -+ } -+ break; -+ - default: -+ if ((wan_udp_pkt->wan_udp_command & 0xF0) == WAN_FE_UDP_CMD_START){ -+ WAN_FECALL(&card->wandev, process_udp, -+ (&card->fe, -+ &wan_udp_pkt->wan_udp_cmd, -+ &wan_udp_pkt->wan_udp_data[0])); -+ break; -+ } - wan_udp_pkt->wan_udp_data_len = 0; - wan_udp_pkt->wan_udp_return_code = 0xCD; - -@@ -3927,7 +3940,7 @@ - - /* TE1 Update T1/E1 alarms */ - if (IS_TE3(&card->fe.fe_cfg)) { -- WAN_FECALL(&card->wandev, read_alarm, (&card->fe, 0)); -+ WAN_FECALL(&card->wandev, read_alarm, (&card->fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE)); - /* TE1 Update T1/E1 perfomance counters */ - WAN_FECALL(&card->wandev, read_pmon, (&card->fe, 0)); - } -@@ -3971,7 +3984,9 @@ - wanpipe_lip_kick(chan,0); } - #endif -- aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); -+ if (!chan->single_dma_chain){ -+ aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); -+ } - } - - static int xilinx_write_ctrl_hdlc(sdla_t *card, u32 timeslot, u8 reg_off, u32 data) -@@ -4213,7 +4228,7 @@ - - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - -- WP_DELAY(100); -+ WP_DELAY(10); - - /* Disable the chip/hdlc reset condition */ - wan_clear_bit(CHIP_RESET_BIT,®); -@@ -4280,8 +4295,6 @@ - DEBUG_CFG("--- T3 Exar Chip enable/config. -- \n"); - - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); -- -- WP_DELAY(100); - - xilinx_delay(1); - #if 0 -@@ -4453,6 +4466,15 @@ - card->u.xilinx.dev_to_ch_map[0]=(void*)chan; - } - -+ /* Setup global DMA parameters */ -+ if (chan->single_dma_chain){ -+ card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,®); -+ reg&=~DMA_CHAIN_TE3_MASK; -+ reg|=1&DMA_CHAIN_TE3_MASK; -+ card->hw_iface.bus_write_4(card->hw,XILINX_DMA_CONTROL_REG,reg); -+ } -+ -+ - reg=0; - if (chan->hdlc_eng){ -@@ -4571,6 +4593,9 @@ - } - - -+#if 0 -+/* Alex -+** This functions are moved to sdladrv_fe.c */ - #define BIT_DEV_ADDR_CLEAR 0x600 - - static int write_framer(void *pcard, unsigned short framer_off,unsigned short framer_data) -@@ -4585,12 +4610,10 @@ - card->hw_iface.bus_write_2(card->hw, - 0x46, - framer_off); -- WP_DELAY(5); - - card->hw_iface.bus_write_2(card->hw, - 0x44, - framer_data); -- WP_DELAY(5); - return 0; - } - -@@ -4605,18 +4628,17 @@ - card->hw_iface.bus_write_2(card->hw, - 0x46, - framer_off); -- WP_DELAY(5); - - card->hw_iface.bus_read_4(card->hw, - 0x44, - &framer_data); -- WP_DELAY(5); - - DEBUG_TEST("READ FRAMER OFFSET=0x%02X DATA=0x%02X\n", - framer_off,framer_data); - - return framer_data; - } -+#endif - - #if 0 - static void framer_reset(sdla_t *card) -@@ -4805,7 +4827,7 @@ - - wan_set_bit(TxDMA_HI_DMA_GO_READY_BIT,®); - -- DEBUG_TX("%s: TXDMA_HI=0x%X DmaDescr=0x%lX len=%i\n", -+ DEBUG_TEST("%s: TXDMA_HI=0x%X DmaDescr=0x%lX len=%i\n", - __FUNCTION__,reg,dma_chain->dma_addr,len); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); -@@ -4973,6 +4995,24 @@ - } - } - -+#if 0 -+ if (0){ -+ netskb_t *nskb=__dev_alloc_skb(wan_skb_len(skb),GFP_DMA|GFP_ATOMIC); -+ if (!nskb) { -+ wan_skb_free(skb); -+ wan_clear_bit(0,&dma_chain->init); -+ chan->if_stats.tx_errors++; -+ return -EINVAL; -+ } else { -+ unsigned char *buf = wan_skb_put(nskb,wan_skb_len(skb)); -+ memcpy(buf,wan_skb_data(skb),wan_skb_len(skb)); -+ wan_skb_free(skb); -+ skb=nskb; -+ } -+ } -+#endif -+ -+ - dma_chain->skb=skb; - - dma_chain->dma_addr = -@@ -5032,7 +5072,7 @@ - if (!wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status)){ - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); - } +- if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ +- /* Convert active_ch bit map to user */ +- chan->wp_tdm_api_dev.active_ch = conf->active_ch << 1; +- }else{ ++ if (IS_E1_CARD(card)){ + chan->wp_tdm_api_dev.active_ch = conf->active_ch; - } -+ } - - wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); ++ }else{ ++ chan->wp_tdm_api_dev.active_ch = conf->active_ch << 1; ++ } -@@ -5106,7 +5146,7 @@ + DEBUG_TEST("%s: TDM API ACTIVE CH 0x%08X CHAN=%i\n", + chan->if_name, chan->wp_tdm_api_dev.active_ch,chan->wp_tdm_api_dev.tdm_chan); +@@ -2221,9 +2227,12 @@ - wan_set_bit(RxDMA_HI_DMA_GO_READY_BIT,®); + for (i=0;idma_addr,dma_descr); +- err = card->hw_iface.busdma_alloc(card->hw,&chan->tx_dma_chain_table[i]); ++ err = card->hw_iface.busdma_alloc( ++ card->hw, ++ &chan->tx_dma_chain_table[i]); + if (err){ +- DEBUG_EVENT("%s:%s: Unable to load TX DMA buffer %d (%d)!\n", ++ DEBUG_EVENT( ++ "%s:%s: Unable to load TX DMA buffer %d (%d)!\n", + card->devname, chan->if_name, i, err); + err = -EINVAL; + break; +@@ -2233,9 +2242,12 @@ + chan->tx_dma_chain_table[i].dma_virt, + chan->dma_mru); + +- err = card->hw_iface.busdma_alloc(card->hw,&chan->rx_dma_chain_table[i]); ++ err = card->hw_iface.busdma_alloc( ++ card->hw, ++ &chan->rx_dma_chain_table[i]); + if (err){ +- DEBUG_EVENT("%s:%s: Unable to load RX DMA buffer %d (%d)!\n", ++ DEBUG_EVENT( ++ "%s:%s: Unable to load RX DMA buffer %d (%d)!\n", + card->devname, chan->if_name, i, err); + err = -EINVAL; + break; +@@ -2249,8 +2261,12 @@ - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); -@@ -5406,7 +5446,7 @@ - aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); - chan->rx_no_data_cnt=-1; + for (i=0;ihw_iface.busdma_free(card->hw,&chan->rx_dma_chain_table[i]); +- card->hw_iface.busdma_free(card->hw,&chan->tx_dma_chain_table[i]); ++ card->hw_iface.busdma_free( ++ card->hw, ++ &chan->rx_dma_chain_table[i]); ++ card->hw_iface.busdma_free( ++ card->hw, ++ &chan->tx_dma_chain_table[i]); + } + err = card->hw_iface.busdma_tag_destroy( + card->hw, +@@ -2530,7 +2546,8 @@ + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG || +- card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI) { ++ card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI || ++ card->wandev.config_id == WANCONFIG_AFT_SERIAL) { + wan_spin_lock_irq(&card->wandev.lock,&flags); + card->fe.fe_status = FE_CONNECTED; + handle_front_end_state(card); +@@ -2635,10 +2652,16 @@ + aft_free_tx_descriptors(chan); + aft_free_rx_descriptors(chan); + ++ wan_spin_unlock_irq(&card->wandev.lock,&flags); ++ + for (i=0;ihw_iface.busdma_free(card->hw,&chan->rx_dma_chain_table[i]); +- card->hw_iface.busdma_free(card->hw,&chan->tx_dma_chain_table[i]); ++ card->hw_iface.busdma_free( ++ card->hw, ++ &chan->rx_dma_chain_table[i]); ++ card->hw_iface.busdma_free( ++ card->hw, ++ &chan->tx_dma_chain_table[i]); + } + card->hw_iface.busdma_tag_destroy( + card->hw, +@@ -2649,6 +2672,8 @@ + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + ++ wan_spin_lock_irq(&card->wandev.lock,&flags); ++ + WAN_IFQ_DMA_PURGE(&chan->wp_rx_free_list); + WAN_IFQ_DESTROY(&chan->wp_rx_free_list); + +@@ -2759,7 +2784,7 @@ + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + if (card_use_cnt == 1) { +- DEBUG_BRI("%s: BRI Disabling TDMV INTR\n", ++ DEBUG_TEST("%s: BRI Disabling TDMV INTR\n", + card->devname); + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); +@@ -4529,8 +4554,9 @@ + * buffer and pass it up */ + *new_skb=wan_skb_alloc(len + 20); + if (!*new_skb){ +- DEBUG_EVENT("%s:%s: Failed to allocate rx skb pkt (len=%d)!\n", +- card->devname,chan->if_name,(len+20)); ++ DEBUG_EVENT( ++ "%s:%s: Failed to allocate rx skb pkt (len=%d)!\n", ++ card->devname,chan->if_name,(len+20)); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //chan->if_stats.rx_dropped++; + goto rx_comp_error; + } +@@ -5246,7 +5272,7 @@ + + card_list=__sdla_get_ptr_isr_array(card->hw); + +- DEBUG_BRI("%s(): card_list ptr: 0x%p\n", __FUNCTION__, card_list); ++ DEBUG_TEST("%s(): card_list ptr: 0x%p\n", __FUNCTION__, card_list); + + for (i=0; iwandev.fe_iface.isr) { + tmp_card->wandev.fe_iface.isr(&tmp_card->fe); +@@ -5315,11 +5341,12 @@ + static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) + { + u32 reg_sec=0,reg=0; +- u32 a108_reg=0, a56k_reg=0; ++ u32 a108_reg=0, a56k_reg=0, serial_reg=0; + u32 fifo_port_intr=0; + u32 dma_port_intr=0; + u32 wdt_port_intr=0; + u32 tdmv_port_intr=0; ++ u32 status_port_intr=0; + u32 fe_intr=0; + u32 max_ports=IS_BRI_CARD(card)?MAX_BRI_LINES:8; + +@@ -5358,16 +5385,17 @@ + __sdla_bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); + reg_sec=reg; + ++ DEBUG_TEST("%s:ISR = 0x%X\n",card->devname,reg); ++ + if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,®)){ + + #ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_dropped++; + #endif +- DEBUG_BRI("%s(): line: %d\n", __FUNCTION__, __LINE__); + + if (wan_test_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®)) { + +- DEBUG_BRI("%s: Got Front End Interrupt 0x%08X\n", ++ DEBUG_ISR("%s: Got Front End Interrupt 0x%08X\n", + card->devname,reg); + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); +@@ -5412,12 +5440,27 @@ + wdt_port_intr = aft_chipcfg_a108_get_wdt_intr_stats(a108_reg); + tdmv_port_intr = aft_chipcfg_a108_get_tdmv_intr_stats(a108_reg); + +- }else if(IS_56K_CARD(card)){ ++ } else if (IS_SERIAL_CARD(card)) { ++ __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &serial_reg); ++ ++#ifdef AFT_SERIAL_DEBUG ++if (serial_reg) { ++ DEBUG_EVENT("%s: SERIAL ISR = 0x%08X\n", ++ card->devname,serial_reg); ++} ++#endif ++ ++ fifo_port_intr = aft_chipcfg_a108_get_fifo_intr_stats(serial_reg); ++ dma_port_intr = aft_chipcfg_a108_get_dma_intr_stats(serial_reg); ++ wdt_port_intr = aft_chipcfg_serial_get_wdt_intr_stats(serial_reg); ++ status_port_intr = aft_chipcfg_serial_get_status_intr_stats(serial_reg, card->wandev.comm_port); ++ ++ } else if(IS_56K_CARD(card)) { + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a56k_reg); + fifo_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_FIFO_INTR_BIT,&a56k_reg); + dma_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_DMA_INTR_BIT,&a56k_reg); + wdt_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_WDT_INTR_BIT,&a56k_reg); +- }else{ ++ } else { + fifo_port_intr = aft_chipcfg_get_hdlc_intr_stats(reg); + dma_port_intr = aft_chipcfg_get_dma_intr_stats(reg); + wdt_port_intr = aft_chipcfg_get_wdt_intr_stats(reg); +@@ -5432,6 +5475,7 @@ + dma_port_intr || + fifo_port_intr || + dma_port_intr || ++ status_port_intr || + wdt_port_intr) { + /* Pass Through */ + } else { +@@ -5473,10 +5517,15 @@ #endif - { --#if defined(__LINUX__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) -+#if defined(__LINUX__) -+# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) - sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); -+# else -+ sdla_t *card = (sdla_t *)card_ptr; -+# endif + } + ++ ++ #else - sdla_t *card = (sdla_t *)card_ptr; --#endif -+#endif - wan_smp_flag_t smp_flags,isr_flags; + #warning "NCDEBUG DMA IGNORED" + #endif - if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ ---- sdla_te3.c 2008-01-11 14:07:46.000000000 -0500 -+++ /common/wanpipe/sdla_te3.c 2008-01-18 17:18:00.000000000 -0500 -@@ -52,27 +52,18 @@ - ** DEFINES AND MACROS - ******************************************************************************/ - --#if defined(DEBUG) --# define WRITE_CPLD(reg,val) \ -- DEBUG_EVENT("%s: Write to CPLD reg %d value %X\n", \ -- fe->name, reg, val); -- --# define WRITE_REG(reg,val) \ -- DEBUG_EVENT("%s: Write to Framer off %X value %X\n", \ -- fe->name, reg, val); --#else -- --# define WRITE_CPLD(reg,val) \ -- (fe->write_cpld) ? fe->write_cpld(fe->card, reg, val) : -EINVAL -+#define WRITE_CPLD(reg,val) \ -+ fe->write_cpld(fe->card, (reg), (val)) - --# define WRITE_EXAR_CPLD(reg,val) \ -- (fe->write_fe_cpld) ? fe->write_fe_cpld(fe->card, reg, val) : -EINVAL -+#define WRITE_EXAR_CPLD(reg,val) \ -+ fe->write_fe_cpld(fe->card, (reg), (val)) - --# define WRITE_REG(reg,val) \ -- (fe->write_framer) ? fe->write_framer(fe->card, reg, val) : -EINVAL --# define READ_REG(reg) \ -- (fe->read_framer) ? fe->read_framer(fe->card, reg) : 0 --#endif -+#define WRITE_REG(reg,val) \ -+ fe->write_fe_reg( \ -+ ((sdla_t*)fe->card)->hw,(int)(reg),(int)(val)); -+#define READ_REG(reg) \ -+ fe->read_fe_reg( \ -+ ((sdla_t*)fe->card)->hw,(int)(reg)); - - #define WAN_FE_SWAP_BIT(value, mask) \ - if ((value) & mask){ \ -@@ -105,8 +96,9 @@ - static int sdla_e3_isr(sdla_fe_t *fe); - static int sdla_te3_isr(sdla_fe_t *fe); - static int sdla_te3_udp(sdla_fe_t *fe, void*, unsigned char*); --static unsigned int sdla_te3_alarm(sdla_fe_t *fe, int); -+static unsigned int sdla_te3_read_alarms(sdla_fe_t *fe, int); - static int sdla_te3_read_pmon(sdla_fe_t *fe, int); -+static int sdla_te3_flush_pmon(sdla_fe_t *fe); - - static int sdla_te3_update_alarm_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt); - static int sdla_te3_update_pmon_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt); -@@ -221,6 +213,8 @@ - { - unsigned char value; - -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); - value = READ_REG(REG_TxDS3_LAPD_STATUS); - if (value & BIT_TxDS3_LAPD_STATUS_INT){ - DEBUG_EVENT("%s: LAPD Interrupt!\n", -@@ -240,43 +234,35 @@ - { - unsigned char value, status; - -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); - /* RxDS3 Interrupt status register (0x13) */ - value = READ_REG(REG_RxDS3_INT_STATUS); - status = READ_REG(REG_RxDS3_CFG_STATUS); - if (fe->fe_cfg.frame == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_CPBIT_ERR){ -- if (WAN_NET_RATELIMIT()){ -- DEBUG_TE3("%s: CP Bit Error interrupt detected!\n", -+ DEBUG_TE3("%s: CP Bit Error interrupt detected!\n", - fe->name); -- } - } - if (value & BIT_RxDS3_INT_STATUS_LOS){ - if (status & BIT_RxDS3_CFG_STATUS_RxLOS){ -- if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: LOS Status ON!\n", - fe->name); -- } - fe->fe_alarm |= WAN_TE3_BIT_LOS_ALARM; - }else{ -- if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: LOS Status OFF!\n", - fe->name); -- } - fe->fe_alarm &= ~WAN_TE3_BIT_LOS_ALARM; ++ ++ ++ + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + + if (tdmv_port_intr && +@@ -5596,9 +5645,13 @@ } } - if (value & BIT_RxDS3_INT_STATUS_AIS){ -- if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: AIS status %s!\n", - fe->name, - (status & BIT_RxDS3_CFG_STATUS_RxAIS) ? "ON" : "OFF"); -- } - } - if (value & BIT_RxDS3_INT_STATUS_IDLE){ -- if (WAN_NET_RATELIMIT()){ -- DEBUG_TE3("%s: IDLE condition status %s!\n", -+ DEBUG_EVENT("%s: IDLE condition status %s!\n", - fe->name, - (status & BIT_RxDS3_CFG_STATUS_RxIDLE) ? "ON" : "OFF"); -- } - } - if (value & BIT_RxDS3_INT_STATUS_OOF){ - if (status & BIT_RxDS3_CFG_STATUS_RxLOS){ -@@ -302,27 +288,23 @@ - } - } - if (fe->fe_cfg.frame == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_AIC){ -- if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: AIC bit-field status %s!\n", - fe->name, - (status & BIT_RxDS3_STATUS_RxAIC) ? "ON" : "OFF"); -- } - } - if (value & BIT_RxDS3_INT_STATUS_PBIT_ERR){ -- if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: P-Bit error interrupt!\n", - fe->name); -- } - } - /* RxDS3 FEAC Interrupt (0x17) */ - value = READ_REG(REG_RxDS3_FEAC_INT); - if (value & BIT_RxDS3_FEAC_REMOVE_INT_STATUS){ -- DEBUG_TE3("%s: RxFEAC Remove Interrupt!\n", -+ DEBUG_EVENT("%s: RxFEAC Remove Interrupt!\n", - fe->name); - } - if (value & BIT_RxDS3_FEAC_VALID_INT_STATUS){ -- DEBUG_TE3("%s: RxFEAC Valid Interrupt!\n", -+ DEBUG_EVENT("%s: RxFEAC Valid Interrupt!\n", - fe->name); - } - -@@ -340,6 +322,8 @@ - { - unsigned char value; - -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); - value = READ_REG(REG_BLOCK_INT_STATUS); - if (value & BIT_BLOCK_INT_STATUS_RxDS3_E3){ - sdla_ds3_rx_isr(fe); -@@ -379,6 +363,9 @@ - unsigned char int_status1, int_status2; - unsigned char status; - -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); ++ if (status_port_intr) { ++ wp_aft_serial_status_isr(card, status_port_intr); ++ } + - int_status1 = READ_REG(REG_RxE3_INT_STATUS_1); - int_status2 = READ_REG(REG_RxE3_INT_STATUS_2); - status = READ_REG(REG_RxE3_CFG_STATUS_2); -@@ -457,6 +444,9 @@ - { - unsigned char value; - -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); -+ - value = READ_REG(REG_BLOCK_INT_STATUS); - if (value & BIT_BLOCK_INT_STATUS_RxDS3_E3){ - sdla_e3_rx_isr(fe); -@@ -478,10 +468,8 @@ - static int sdla_te3_isr(sdla_fe_t *fe) - { - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; -- unsigned char value; - int err = 0; - -- value = READ_REG(REG_BLOCK_INT_STATUS); - switch(fe_cfg->media){ - case WAN_MEDIA_DS3: - err = sdla_ds3_isr(fe); -@@ -490,113 +478,135 @@ - err = sdla_e3_isr(fe); - break; - } -- fe->fe_alarm = sdla_te3_alarm(fe, 1); -+ sdla_te3_set_status(fe); - return err; + if (wan_test_bit(card->wandev.comm_port,&wdt_port_intr)){ + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); +- wp_aft_wdt_per_port_isr(card,1); ++ wp_aft_wdt_per_port_isr(card,1); + card->u.aft.wdt_tx_cnt=SYSTEM_TICKS; + #ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_fifo_errors++; +@@ -5684,6 +5737,32 @@ + WAN_IRQ_RETURN(irq_ret); } - /****************************************************************************** -- * sdla_te3_alarm() -+ * sdla_te3_read_alarms() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ --static unsigned int sdla_te3_alarm(sdla_fe_t *fe, int update) -+static unsigned int sdla_te3_read_framer_alarms(sdla_fe_t *fe) - { - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; -- unsigned int alarm = 0; -+ unsigned int alarms = 0; - unsigned char value; -- + -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); -+ - if (fe_cfg->media == WAN_MEDIA_DS3){ - value = READ_REG(REG_RxDS3_CFG_STATUS); - if (value & BIT_RxDS3_CFG_STATUS_RxAIS){ -- alarm |= WAN_TE3_BIT_AIS_ALARM; -- DEBUG_TE3("%s: (T3/E3) AIS Alarm is ON\n", fe->name); -+ alarms |= WAN_TE3_BIT_AIS_ALARM; - }else{ -- alarm &= ~WAN_TE3_BIT_AIS_ALARM; -- DEBUG_TE3("%s: (T3/E3) AIS Alarm is OFF\n", fe->name); -+ alarms &= ~WAN_TE3_BIT_AIS_ALARM; - } - if (value & BIT_RxDS3_CFG_STATUS_RxLOS){ -- alarm |= WAN_TE3_BIT_LOS_ALARM; -- DEBUG_TE3("%s: (T3/E3) LOS Alarm is ON\n", fe->name); -+ alarms |= WAN_TE3_BIT_LOS_ALARM; - }else{ -- alarm &= ~WAN_TE3_BIT_LOS_ALARM; -- DEBUG_TE3("%s: (T3/E3) LOS Alarm is OFF\n", fe->name); -+ alarms &= ~WAN_TE3_BIT_LOS_ALARM; - } - if (value & BIT_RxDS3_CFG_STATUS_RxOOF){ -- alarm |= WAN_TE3_BIT_OOF_ALARM; -- DEBUG_TE3("%s: (T3/E3) OOF Alarm is ON\n", fe->name); -+ alarms |= WAN_TE3_BIT_OOF_ALARM; - }else{ -- alarm &= ~WAN_TE3_BIT_OOF_ALARM; -- DEBUG_TE3("%s: (T3/E3) OOF Alarm is OFF\n", fe->name); -+ alarms &= ~WAN_TE3_BIT_OOF_ALARM; - } - value = READ_REG(REG_RxDS3_STATUS); - if (value & BIT_RxDS3_STATUS_RxFERF){ -- alarm |= WAN_TE3_BIT_YEL_ALARM; -- DEBUG_TE3("%s: (T3/E3) YEL Alarm is ON\n", fe->name); -+ alarms |= WAN_TE3_BIT_YEL_ALARM; - }else{ -- alarm &= ~WAN_TE3_BIT_YEL_ALARM; -- DEBUG_TE3("%s: (T3/E3) YEL Alarm is OFF\n", fe->name); -+ alarms &= ~WAN_TE3_BIT_YEL_ALARM; - } - }else{ - value = READ_REG(REG_RxE3_CFG_STATUS_2); - if (value & BIT_RxE3_CFG_STATUS_RxOOF){ -- DEBUG_TE3("%s: (T3/E3) OOF Alarm ON!\n", -- fe->name); -- alarm |= WAN_TE3_BIT_OOF_ALARM; -+ alarms |= WAN_TE3_BIT_OOF_ALARM; - }else{ -- DEBUG_TE3("%s: (T3/E3) OOF Alarm OFF!\n", -- fe->name); -- alarm &= ~WAN_TE3_BIT_OOF_ALARM; -+ alarms &= ~WAN_TE3_BIT_OOF_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxLOF){ -- DEBUG_TE3("%s: (T3/E3) LOF Alarm ON!\n", -- fe->name); -- alarm |= WAN_TE3_BIT_LOF_ALARM; -+ alarms |= WAN_TE3_BIT_LOF_ALARM; - }else{ -- DEBUG_TE3("%s: (T3/E3) LOF Alarm OFF!\n", -- fe->name); -- alarm &= ~WAN_TE3_BIT_LOF_ALARM; -+ alarms &= ~WAN_TE3_BIT_LOF_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxLOS){ -- DEBUG_TE3("%s: (T3/E3) LOS Alarm ON!\n", -- fe->name); -- alarm |= WAN_TE3_BIT_LOS_ALARM; -+ alarms |= WAN_TE3_BIT_LOS_ALARM; - }else{ -- DEBUG_TE3("%s: (T3/E3) LOS Alarm OFF!\n", -- fe->name); -- alarm &= ~WAN_TE3_BIT_LOS_ALARM; -+ alarms &= ~WAN_TE3_BIT_LOS_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxAIS){ -- DEBUG_TE3("%s: (T3/E3) AIS Alarm ON!\n", -- fe->name); -- alarm |= WAN_TE3_BIT_AIS_ALARM; -+ alarms |= WAN_TE3_BIT_AIS_ALARM; - }else{ -- DEBUG_TE3("%s: (T3/E3) AIS Alarm OFF!\n", -- fe->name); -- alarm &= ~WAN_TE3_BIT_AIS_ALARM; -+ alarms &= ~WAN_TE3_BIT_AIS_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxFERF){ -- DEBUG_TE3("%s: (T3/E3) Rx FERF status is ON (YELLOW)!\n", -- fe->name); -- alarm |= WAN_TE3_BIT_YEL_ALARM; -+ alarms |= WAN_TE3_BIT_YEL_ALARM; - }else{ -- DEBUG_TE3("%s: (T3/E3) Rx FERF status is OFF!\n", -- fe->name); -- alarm &= ~WAN_TE3_BIT_YEL_ALARM; -+ alarms &= ~WAN_TE3_BIT_YEL_ALARM; - } - } -+ return alarms; -+} - -- fe->fe_alarm = alarm; -- if (update){ -- sdla_te3_set_status(fe); -+static int sdla_te3_print_alarms(sdla_fe_t *fe, unsigned int alarms) ++static void wp_aft_serial_status_isr(sdla_t *card, u32 serial_intr_status) +{ -+ -+ DEBUG_EVENT("%s: %s Framer Alarms status (%X):\n", -+ fe->name, -+ FE_MEDIA_DECODE(fe), -+ alarms); ++ u32 reg; + -+ if (!alarms){ -+ DEBUG_EVENT("%s: %s Alarms status: No alarms detected!\n", -+ fe->name, -+ FE_MEDIA_DECODE(fe)); -+ return 0; - } -- return alarm; -+ if (alarms & WAN_TE3_BIT_AIS_ALARM){ -+ DEBUG_EVENT("%s: AIS Alarm is ON\n", fe->name); -+ } -+ if (alarms & WAN_TE3_BIT_LOS_ALARM){ -+ DEBUG_EVENT("%s: LOS Alarm is ON\n", fe->name); -+ } -+ if (alarms & WAN_TE3_BIT_OOF_ALARM){ -+ DEBUG_EVENT("%s: OOF Alarm is ON\n", fe->name); -+ } -+ if (alarms & WAN_TE3_BIT_YEL_ALARM){ -+ DEBUG_EVENT("%s: YEL Alarm is ON\n", fe->name); -+ } -+ if (alarms & WAN_TE3_BIT_LOF_ALARM){ -+ DEBUG_EVENT("%s: LOF Alarm OFF!\n", fe->name); -+ } -+ -+ return 0; -+} ++ __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG), ®); + -+static unsigned int sdla_te3_read_alarms(sdla_fe_t *fe, int action) -+{ -+ unsigned int alarms = 0; -+ -+ if (IS_FE_ALARM_READ(action)){ -+ alarms = sdla_te3_read_framer_alarms(fe); -+ } -+ -+ if (IS_FE_ALARM_PRINT(action)){ -+ sdla_te3_print_alarms(fe, alarms); -+ } -+ -+ if (IS_FE_ALARM_UPDATE(action)){ -+ fe->fe_alarm = alarms; -+ sdla_te3_set_status(fe); ++ if (wan_test_bit(AFT_CHIPCFG_SERIAL_CTS_STATUS_INTR_BIT,&serial_intr_status)) { ++ DEBUG_EVENT("%s: CTS ISR Status 0x%02X\n", ++ card->devname, ++ wan_test_bit(AFT_SERIAL_LCFG_CTS_BIT,®)); + } -+ return alarms; - } - - -@@ -616,18 +626,20 @@ - } - - /****************************************************************************** -- * sdla_te3_read_pmon() -- * -- * Description: -- * Arguments: -- * Returns: -- ****************************************************************************** -- */ -+* sdla_te3_read_pmon() -+* -+* Description: -+* Arguments: -+* Returns: -+******************************************************************************/ - static int sdla_te3_read_pmon(sdla_fe_t *fe, int action) ++ ++ if (wan_test_bit(AFT_CHIPCFG_SERIAL_DCD_STATUS_INTR_BIT,&serial_intr_status)) { ++ DEBUG_EVENT("%s: DCS ISR Status 0x%02X\n", ++ card->devname, ++ wan_test_bit(AFT_SERIAL_LCFG_DCD_BIT,®)); ++ } ++ ++ if (wan_test_bit(AFT_CHIPCFG_SERIAL_RTS_STATUS_INTR_BIT,&serial_intr_status)) { ++ DEBUG_EVENT("%s: RTS ISR Status 0x%02X\n", ++ card->devname, ++ wan_test_bit(AFT_SERIAL_LCFG_RTS_BIT,®)); ++ } ++} ++ + static void wp_aft_dma_per_port_isr(sdla_t *card) { - sdla_te3_pmon_t *pmon = (sdla_te3_pmon_t*)&fe->fe_stats.u.te3_pmon; - unsigned char value_msb, value_lsb; + int i; +@@ -5721,7 +5800,7 @@ + + /* Receive DMA Engine */ + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); +- DEBUG_BRI("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); ++ DEBUG_TEST("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); -+ - value_msb = READ_REG(REG_PMON_LCV_MSB); - value_lsb = READ_REG(REG_PMON_LCV_LSB); - pmon->pmon_lcv += ((value_msb << 8) | value_lsb); -@@ -651,6 +663,112 @@ - } + dma_rx_reg&=card->u.aft.active_ch_map; - /****************************************************************************** -+* sdla_te3_flush_pmon() -+* -+* Description: -+* Arguments: -+* Returns: -+******************************************************************************/ -+static int sdla_te3_flush_pmon(sdla_fe_t *fe) -+{ -+ sdla_te3_pmon_t *pmon = (sdla_te3_pmon_t*)&fe->fe_stats.u.te3_pmon; -+ -+ pmon->pmon_lcv = 0; -+ pmon->pmon_framing = 0; -+ pmon->pmon_parity = 0; -+ pmon->pmon_febe = 0; -+ pmon->pmon_cpbit = 0; -+ return 0; -+} -+ -+/****************************************************************************** -+* sdla_te3_old_set_lb_modes() -+* -+* Description: -+* Arguments: -+* Returns: -+******************************************************************************/ -+static int -+sdla_te3_old_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) -+{ -+ -+ WAN_ASSERT(fe->write_cpld == NULL); -+ DEBUG_EVENT("%s: %s %s mode...\n", -+ fe->name, -+ WAN_TE3_LB_MODE_DECODE(mode), -+ WAN_TE3_LB_TYPE_DECODE(type)); -+ -+ if (mode == WAN_TE3_DEACTIVATE_LB){ -+ fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_LLB; -+ fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_RLB; -+ }else{ -+ switch(type){ -+ case WAN_TE3_LIU_LB_ANALOG: -+ fe->te3_param.cpld_status |= BIT_CPLD_STATUS_LLB; -+ fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_RLB; -+ break; -+ case WAN_TE3_LIU_LB_REMOTE: -+ fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_LLB; -+ fe->te3_param.cpld_status |= BIT_CPLD_STATUS_RLB; -+ break; -+ case WAN_TE3_LIU_LB_DIGITAL: -+ fe->te3_param.cpld_status |= BIT_CPLD_STATUS_LLB; -+ fe->te3_param.cpld_status |= BIT_CPLD_STATUS_RLB; -+ break; -+ default : -+ DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", -+ fe->name); -+ break; -+ } -+ } -+ /* Write value to CPLD Status/Control register */ -+ WRITE_CPLD(REG_CPLD_STATUS, fe->te3_param.cpld_status); -+ return 0; -+} -+ -+static int -+sdla_te3_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) -+{ -+ unsigned char data = 0x00; -+ -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); -+ DEBUG_EVENT("%s: %s %s mode...\n", -+ fe->name, -+ WAN_TE3_LB_MODE_DECODE(mode), -+ WAN_TE3_LB_TYPE_DECODE(type)); -+ -+ data = READ_REG(REG_LINE_INTERFACE_DRIVE); -+ if (mode == WAN_TE3_DEACTIVATE_LB){ -+ data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; -+ data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; -+ }else{ -+ switch(type){ -+ case WAN_TE3_LIU_LB_NORMAL: -+ break; -+ case WAN_TE3_LIU_LB_ANALOG: -+ data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; -+ data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; -+ break; -+ case WAN_TE3_LIU_LB_REMOTE: -+ data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; -+ data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; -+ break; -+ case WAN_TE3_LIU_LB_DIGITAL: -+ data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; -+ data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; -+ break; -+ default : -+ DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", -+ fe->name); -+ break; -+ } -+ } -+ WRITE_REG(REG_LINE_INTERFACE_DRIVE, data); -+ return 0; -+} -+ -+/****************************************************************************** - * sdla_te3_udp() +@@ -5730,10 +5809,10 @@ + } + + dma_rx_reg &= card->u.aft.logic_ch_map; +- DEBUG_BRI("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); ++ DEBUG_TEST("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); + + dma_rx_reg &= ~(card->u.aft.tdm_logic_ch_map); +- DEBUG_BRI("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); ++ DEBUG_TEST("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); + + for (i=0; icommon); //chan->if_stats.rx_frame_errors++; + #endif + +- DEBUG_BRI("%s: RX Interrupt pend. \n", card->devname); ++ DEBUG_TEST("%s: RX Interrupt pend. \n", card->devname); + + aft_dma_rx_complete(card,chan,0); + +@@ -6295,8 +6374,7 @@ + + case AFT_HWEC_STATUS: + *(unsigned long *)&wan_udp_pkt->wan_udp_data[0] = +- IS_E1_CARD(card) ? card->wandev.ec_map: +- card->wandev.ec_map << 1; ++ card->wandev.fe_ec_map; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); + wan_udp_pkt->wan_udp_return_code = 0; + break; +@@ -8025,7 +8103,8 @@ + * aft_dma_chain_init * - * Description: -@@ -660,7 +778,9 @@ */ - static int sdla_te3_udp(sdla_fe_t *fe, void *pudp_cmd, unsigned char *data) +-static void aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain) ++static void ++aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain) { -+ sdla_t *card = (sdla_t*)fe->card; - wan_cmd_t *udp_cmd = (wan_cmd_t*)pudp_cmd; -+ int err = -EINVAL; + #define card chan->card - switch(udp_cmd->wan_cmd_command){ - case WAN_GET_MEDIA_TYPE: -@@ -671,19 +791,26 @@ +@@ -8512,16 +8591,18 @@ + wan_skb_trim(dma_chain->skb,0); + + /* A-DMA */ +- card->hw_iface.busdma_map( card->hw, +- dma_chain, +- wan_skb_tail(dma_chain->skb), +- chan->dma_mru, +- chan->dma_mru, +- SDLA_DMA_PREREAD); +- card->hw_iface.busdma_sync( card->hw, +- dma_chain, +- MAX_AFT_DMA_CHAINS, chan->single_dma_chain, +- SDLA_DMA_PREREAD); ++ card->hw_iface.busdma_map( ++ card->hw, ++ dma_chain, ++ wan_skb_tail(dma_chain->skb), ++ chan->dma_mru, ++ chan->dma_mru, ++ SDLA_DMA_PREREAD); ++ card->hw_iface.busdma_sync( ++ card->hw, ++ dma_chain, ++ MAX_AFT_DMA_CHAINS, chan->single_dma_chain, ++ SDLA_DMA_PREREAD); + DEBUG_DMA("%s: RXDMA PHY = 0x%08X VIRT = %p \n", + chan->if_name, + dma_chain->dma_addr,wan_skb_tail(dma_chain->skb)+dma_chain->dma_offset); +@@ -8636,16 +8717,18 @@ + + } - case WAN_FE_SET_LB_MODE: - /* Activate/Deactivate Line Loopback modes */ --// err = sdla_set_te1_lb_modes(card, data[0], data[1]); --// udp_cmd->wan_cmd_return_code = --// (!err) ? WAN_CMD_OK : WAN_UDP_FAILED_CMD; --// udp_cmd->wan_cmd_data_len = 0x00; -+ if (card->adptr_subtype == AFT_SUBTYPE_NORMAL){ -+ err = sdla_te3_old_set_lb_modes(fe, data[0], data[1]); -+ }else if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ -+ err = sdla_te3_set_lb_modes(fe, data[0], data[1]); -+ } -+ udp_cmd->wan_cmd_return_code = -+ (!err) ? WAN_CMD_OK : WAN_UDP_FAILED_CMD; -+ udp_cmd->wan_cmd_data_len = 0x00; - break; +- card->hw_iface.busdma_map( card->hw, +- dma_chain, +- wan_skb_tail(dma_chain->skb), +- chan->dma_mru, +- chan->dma_mru, +- SDLA_DMA_PREREAD); +- card->hw_iface.busdma_sync( card->hw, +- dma_chain, +- 1, chan->single_dma_chain, +- SDLA_DMA_PREREAD); ++ card->hw_iface.busdma_map( ++ card->hw, ++ dma_chain, ++ wan_skb_tail(dma_chain->skb), ++ chan->dma_mru, ++ chan->dma_mru, ++ SDLA_DMA_PREREAD); ++ card->hw_iface.busdma_sync( ++ card->hw, ++ dma_chain, ++ 1, chan->single_dma_chain, ++ SDLA_DMA_PREREAD); + intr=0; + if (!wan_test_bit(RX_INTR_PENDING,&chan->dma_chain_status)){ + +@@ -8861,13 +8944,16 @@ + dma_chain, + SDLA_DMA_POSTREAD); - case WAN_FE_GET_STAT: - /* TE1_56K Read T1/E1/56K alarms */ --#if 0 -- *(unsigned long *)&data[0] = sdla_te3_alarm(fe, 0); --#endif -- /* TE1 Update T1/E1 perfomance counters */ - sdla_te3_read_pmon(fe, 0); -+ if (udp_cmd->wan_cmd_fe_force){ -+ /* force to read FE alarms */ -+ DEBUG_EVENT("%s: Force to read Front-End alarms\n", -+ fe->name); -+ fe->fe_stats.alarms = -+ sdla_te3_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); -+ } - memcpy(&data[0], &fe->fe_stats, sizeof(sdla_fe_stats_t)); - udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(sdla_fe_stats_t); -@@ -691,7 +818,7 @@ ++#if defined(__FreeBSD__) ++ wan_skb_put(dma_chain->skb, rx_el->len); ++#endif + wan_skb_queue_tail(&chan->wp_rx_complete_list,dma_chain->skb); + rx_data_available=1; - case WAN_FE_FLUSH_PMON: - /* TE1 Flush T1/E1 pmon counters */ --// memset(&fe->fe_stats.u.te3_pmon, 0, sizeof(sdla_te3_pmon_t)); -+ sdla_te3_flush_pmon(fe); - udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - break; - -@@ -716,6 +843,9 @@ +- DEBUG_BRI("%s: RxInt Pending chain %d Rxlist=%d LO:0x%X HI:0x%X!\n", ++ DEBUG_TEST("%s: RxInt Pending chain %d Rxlist=%d LO:0x%X HI:0x%X Len=%i!\n", + chan->if_name,dma_chain->index, + wan_skb_queue_len(&chan->wp_rx_complete_list), +- rx_el->align,rx_el->reg); ++ rx_el->align,rx_el->reg, rx_el->len); + + rx_hndlr_skip_rx: + dma_chain->skb=NULL; +@@ -10314,24 +10400,27 @@ + #else + + #if 1 +- card->hw_iface.busdma_sync( card->hw, +- &chan->tx_dma_chain_table[0], +- MAX_AFT_DMA_CHAINS, +- chan->single_dma_chain, +- SDLA_DMA_POSTREAD); ++ card->hw_iface.busdma_sync( ++ card->hw, ++ &chan->tx_dma_chain_table[0], ++ MAX_AFT_DMA_CHAINS, ++ chan->single_dma_chain, ++ SDLA_DMA_POSTREAD); + + WAN_TDMV_CALL(rx_tx_span, (card), err); + +- card->hw_iface.busdma_sync( card->hw, +- &chan->tx_dma_chain_table[0], +- MAX_AFT_DMA_CHAINS, +- chan->single_dma_chain, +- SDLA_DMA_PREWRITE); +- card->hw_iface.busdma_sync( card->hw, +- &chan->rx_dma_chain_table[0], +- MAX_AFT_DMA_CHAINS, +- chan->single_dma_chain, +- SDLA_DMA_PREREAD); ++ card->hw_iface.busdma_sync( ++ card->hw, ++ &chan->tx_dma_chain_table[0], ++ MAX_AFT_DMA_CHAINS, ++ chan->single_dma_chain, ++ SDLA_DMA_PREWRITE); ++ card->hw_iface.busdma_sync( ++ card->hw, ++ &chan->rx_dma_chain_table[0], ++ MAX_AFT_DMA_CHAINS, ++ chan->single_dma_chain, ++ SDLA_DMA_PREREAD); + + #else + #warning "NCDEBUG: rx_tx_span disabled irq" +@@ -11281,7 +11370,7 @@ + static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int ctrl) { - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; + int err = 0; +- unsigned int channel=0; ++ int fe_chan = 0; + unsigned int tdmv_hwec_option=0; + + if (conf) { +@@ -11291,38 +11380,41 @@ + if (chan->common.usedby == TDM_VOICE_API || + chan->common.usedby == TDM_VOICE){ -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); -+ - DEBUG_EVENT("%s: Enabling interrupts for %s (%d)!\n", - fe->name, FE_MEDIA_DECODE(fe), IS_DS3(fe_cfg)); - /* Enable Framer Interrupts */ -@@ -778,6 +908,7 @@ - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned char data = 0x00; ++ /* Nov 6, 2007 Calling EC function with FE channel number. */ + if (IS_TE1_CARD(card)) { + if (IS_T1_CARD(card)){ +- channel = chan->first_time_slot; ++ fe_chan = chan->first_time_slot+1; + }else{ +- channel = chan->first_time_slot; ++ fe_chan = chan->first_time_slot; + } ++ } else if (IS_FXOFXS_CARD(card)) { ++ fe_chan = chan->first_time_slot+1; + } else { +- channel = chan->first_time_slot; ++ fe_chan = chan->first_time_slot+1; + } + + #if defined(CONFIG_WANPIPE_HWEC) + if (ctrl == 0 && card->wandev.ec_enable){ +- card->wandev.ec_enable(card, 0, channel); ++ card->wandev.ec_enable(card, 0, fe_chan); + + } else if (tdmv_hwec_option && card->wandev.ec_enable){ -+ WAN_ASSERT(fe->write_cpld == NULL); - if (fe_cfg->media == WAN_MEDIA_E3){ - data |= BIT_CPLD_CNTRL_E3; - } -@@ -812,33 +943,7 @@ - name); - data &= ~BIT_CPLD_STATUS_TAOS; - } -- switch(liu->lb_mode){ -- case WAN_TE3_LIU_LB_NORMAL: -- break; -- case WAN_TE3_LIU_LB_ANALOG: -- DEBUG_TE3("%s: (T3/E3) Enable Analog Loopback mode!\n", -- name); -- data |= BIT_CPLD_STATUS_LLB; -- data &= ~BIT_CPLD_STATUS_RLB; -- break; -- case WAN_TE3_LIU_LB_REMOTE: -- DEBUG_TE3("%s: (T3/E3) Enable Remote Loopback mode!\n", -- name); -- data &= ~BIT_CPLD_STATUS_LLB; -- data |= BIT_CPLD_STATUS_RLB; -- break; -- case WAN_TE3_LIU_LB_DIGITAL: -- DEBUG_TE3("%s: (T3/E3) Enable Digital Loopback mode!\n", -- name); -- data |= BIT_CPLD_STATUS_LLB; -- data |= BIT_CPLD_STATUS_RLB; -- break; -- default : -- DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", -- name); -- break; -- } -- /* Write value to CPLD Status/Control register */ -+ /* Write value to CPLD Status register */ - WRITE_CPLD(REG_CPLD_STATUS, data); - return 0; - } -@@ -857,11 +962,13 @@ - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned char data = 0x00; + if(IS_BRI_CARD(card)){ +- DEBUG_HWEC("%s(): original channel: %d\n", __FUNCTION__, channel); ++ DEBUG_HWEC("%s(): original fe_chan: %d\n", __FUNCTION__, fe_chan); -+ WAN_ASSERT(fe->write_fe_cpld == NULL); -+ fe->te3_param.cpld_cntrl = 0x00; - if (fe_cfg->media == WAN_MEDIA_E3){ -- data |= BIT_EXAR_CPLD_CNTRL_E3; -+ fe->te3_param.cpld_cntrl |= BIT_EXAR_CPLD_CNTRL_E3; - } - /* Write value to CPLD Control register */ -- WRITE_EXAR_CPLD(REG_EXAR_CPLD_CNTRL, data); -+ WRITE_EXAR_CPLD(REG_EXAR_CPLD_CNTRL, fe->te3_param.cpld_cntrl); - - data = 0x00; - if (liu->rx_equal == WAN_TRUE){ -@@ -892,33 +999,6 @@ - data &= ~BIT_LINE_INTERFACE_DRIVE_TAOS; - } - -- switch(liu->lb_mode){ -- case WAN_TE3_LIU_LB_NORMAL: -- break; -- case WAN_TE3_LIU_LB_ANALOG: -- DEBUG_TE3("%s: (T3/E3) Enable Analog Loopback mode!\n", -- name); -- data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; -- data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; -- break; -- case WAN_TE3_LIU_LB_REMOTE: -- DEBUG_TE3("%s: (T3/E3) Enable Remote Loopback mode!\n", -- name); -- data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; -- data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; -- break; -- case WAN_TE3_LIU_LB_DIGITAL: -- DEBUG_TE3("%s: (T3/E3) Enable Digital Loopback mode!\n", -- name); -- data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; -- data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; -- break; -- default : -- DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", -- name); -- break; -- } -- WRITE_REG(REG_LINE_INTERFACE_DRIVE, data); - - return 0; - } -@@ -934,8 +1014,9 @@ - fe_iface->polling = &sdla_te3_polling; - fe_iface->isr = &sdla_te3_isr; - fe_iface->process_udp = &sdla_te3_udp; -- fe_iface->read_alarm = &sdla_te3_alarm; -+ fe_iface->read_alarm = &sdla_te3_read_alarms; - fe_iface->read_pmon = &sdla_te3_read_pmon; -+ fe_iface->flush_pmon = &sdla_te3_flush_pmon; - fe_iface->set_fe_alarm = &sdla_te3_set_alarm; - fe_iface->get_fe_status = &sdla_te3_get_fe_status; - fe_iface->get_fe_media = &sdla_te3_get_fe_media; -@@ -954,6 +1035,9 @@ - u16 adptr_subtype; - unsigned char data = 0x00; - -+ WAN_ASSERT(fe->write_fe_reg == NULL); -+ WAN_ASSERT(fe->read_fe_reg == NULL); -+ - card->hw_iface.getcfg(card->hw, SDLA_ADAPTERSUBTYPE, &adptr_subtype); - - data = READ_REG(0x02); -@@ -1067,7 +1151,7 @@ - fe->fe_status = FE_DISCONNECTED; - DEBUG_EVENT("%s: %s disconnected!\n", - fe->name, FE_MEDIA_DECODE(fe)); -- sdla_te3_alarm(fe, 1); -+ sdla_te3_read_alarms(fe, 1); + /* translate channel to be 0 or 1, nothing else!! */ +- channel = (channel % 2); +- DEBUG_HWEC("%s(): new channel: %d\n", __FUNCTION__, channel); ++ fe_chan = (fe_chan % 2); ++ DEBUG_HWEC("%s(): new fe_chan: %d\n", __FUNCTION__, fe_chan); + } - sdla_te3_set_intr(fe); - return 0; +- DEBUG_HWEC("%s: HW echo canceller Enabled on channel %d\n", ++ DEBUG_HWEC("[HWEC] %s: Enable Echo Canceller on fe_chan %d\n", + chan->if_name, +- channel); ++ fe_chan); + +- err = card->wandev.ec_enable(card, 1, channel); ++ err = card->wandev.ec_enable(card, 1, fe_chan); + if (err) { +- DEBUG_EVENT("%s: Failed to enable HWEC on channel %d\n", +- chan->if_name,channel); ++ DEBUG_EVENT("%s: Failed to enable HWEC on fe chan %d\n", ++ chan->if_name,fe_chan); + return err; + } + } diff --git a/patches/kdrivers/src/net/modules.order b/patches/kdrivers/src/net/modules.order deleted file mode 100644 index eb0e518..0000000 --- a/patches/kdrivers/src/net/modules.order +++ /dev/null @@ -1,7 +0,0 @@ -kernel//root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/sdladrv.ko -kernel//root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanrouter.ko -kernel//root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe.ko -kernel//root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanpipe_syncppp.ko -kernel//root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/af_wanpipe.ko -kernel//root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wanec.ko -kernel//root/development/3.2/wanpipe-3.2.5.3/patches/kdrivers/src/net/wan_aften.ko diff --git a/patches/kdrivers/src/net/output b/patches/kdrivers/src/net/output deleted file mode 100644 index 875f33e..0000000 --- a/patches/kdrivers/src/net/output +++ /dev/null @@ -1,1385 +0,0 @@ -47a48,54 -> #if !defined(__WINDOWS__) -> #if 1 -> #define AFT_FUNC_DEBUG() -> #else -> #define AFT_FUNC_DEBUG() DEBUG_EVENT("%s:%d\n",__FUNCTION__,__LINE__) -> #endif -> #endif -58a66,71 -> #if 1 -> # define AFT_API_SUPPORT -> #else -> # undef AFT_API_SUPPORT -> #endif -> -65c78 -< #define AUDIO_RINGCHECK ---- -> #undef AUDIO_RINGCHECK -82c95 -< #define WP_RM_POLL_TIMER 1000 ---- -> #define WP_RM_POLL_TIMER 100 -92,93d104 -< //WP_RM_POLL_RING, -< //WP_RM_POLL_RING_STOP, -109c120,122 -< WP_RM_POLL_RING_DETECT ---- -> WP_RM_POLL_RING_DETECT, -> WP_RM_POLL_READ, -> WP_RM_POLL_WRITE -111a125,150 -> #define WP_RM_POLL_DECODE(type) \ -> ((type) == WP_RM_POLL_TONE_DIAL) ? "Tone (dial)": \ -> ((type) == WP_RM_POLL_TONE_BUSY) ? "Tone (busy)": \ -> ((type) == WP_RM_POLL_TONE_RING) ? "Tone (ring)": \ -> ((type) == WP_RM_POLL_TONE_CONGESTION) ? "Tone (congestion)": \ -> ((type) == WP_RM_POLL_TONE_DONE) ? "Tone (done)":\ -> ((type) == WP_RM_POLL_TDMV) ? "TDMV":\ -> ((type) == WP_RM_POLL_EVENT) ? "RM-Event":\ -> ((type) == WP_RM_POLL_INIT) ? "Init":\ -> ((type) == WP_RM_POLL_POWER) ? "Power":\ -> ((type) == WP_RM_POLL_LC) ? "Loop closure":\ -> ((type) == WP_RM_POLL_RING_TRIP) ? "Ring Trip":\ -> ((type) == WP_RM_POLL_DTMF) ? "DTMF":\ -> ((type) == WP_RM_POLL_RING) ? "Ring":\ -> ((type) == WP_RM_POLL_TONE) ? "Tone":\ -> ((type) == WP_RM_POLL_TXSIG_KEWL) ? "TX Sig KEWL":\ -> ((type) == WP_RM_POLL_TXSIG_START) ? "TX Sig Start":\ -> ((type) == WP_RM_POLL_TXSIG_OFFHOOK) ? "TX Sig Off-hook":\ -> ((type) == WP_RM_POLL_TXSIG_ONHOOK) ? "TX Sig On-hook":\ -> ((type) == WP_RM_POLL_ONHOOKTRANSFER) ? "On-hook transfer":\ -> ((type) == WP_RM_POLL_SETPOLARITY) ? "Set polarity":\ -> ((type) == WP_RM_POLL_RING_DETECT) ? "Ring Detect":\ -> ((type) == WP_RM_POLL_READ) ? "FE Read":\ -> ((type) == WP_RM_POLL_WRITE) ? "FE Write":"Unknown RM poll event" -> -> -334a374 -> static int acim2tiss[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3 }; -346c386 -< static int battdebounce = DEFAULT_BATT_DEBOUNCE; ---- -> static int battdebounce = 64; //DEFAULT_BATT_DEBOUNCE; -357a398 -> static int wp_remora_pre_release(void* pfe); -427a469,479 -> -> #if 0 -> { -> unsigned int value; -> -> /* Enable Slow speed SPI */ -> card->hw_iface.bus_read_4(card->hw, 0x40, &data); -> data |= 0x00000020; -> card->hw_iface.bus_write_4(card->hw, 0x40, data); -> } -> #endif -481c533 -< fe->name, mod_no, ---- -> fe->name, mod_no+1, -490c542 -< fe->name, mod_no, ---- -> fe->name, mod_no+1, -501c553 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -519c571 -< fe->name, mod_no,mod_no+1); ---- -> fe->name, mod_no+1,mod_no+2); -526c578 -< fe->name, mod_no,mod_no+1); ---- -> fe->name, mod_no+1,mod_no+2); -541c593 -< fe->name, mod_no,mod_no+1); ---- -> fe->name, mod_no+1,mod_no+2); -561c613 -< fe->name, mod_no, byte); ---- -> fe->name, mod_no+1, byte); -578c630 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -583c635 -< fe->name, mod_no,mod_no+1, ---- -> fe->name, mod_no+1,mod_no+2, -599c651 -< mod_no, ---- -> mod_no+1, -619c671 -< fe->name, mod_no, value); ---- -> fe->name, mod_no+1, value); -627c679 -< fe->name, mod_no, value); ---- -> fe->name, mod_no+1, value); -635c687 -< fe->name, mod_no, value); ---- -> fe->name, mod_no+1, value); -642d693 -< -654,656d704 -< start_ticks = SYSTEM_TICKS; -< WRITE_RM_REG(mod_no, 14, 0x0); /* DIFF DEMO 0x10 */ -< -660c708,711 -< WRITE_RM_REG(mod_no, 93, 0x1F); ---- -> //WRITE_RM_REG(mod_no, 93, 0x1F); -> WRITE_RM_REG(mod_no, 14, 0x0); /* DIFF DEMO 0x10 */ -> -> start_ticks = SYSTEM_TICKS; -672c723 -< "%s: Module %d: Failed to powerup within %d ms (%d mV only)!\n", ---- -> "%s: Module %d: Failed to powerup within %d ms (%dV : %dV)!\n", -674c725 -< mod_no, ---- -> mod_no+1, -676c727 -< vbat * 375); ---- -> (vbat * 375)/1000, (0xc0 * 375)/1000); -680c731 -< mod_no); ---- -> mod_no+1); -688c739 -< fe->name, mod_no, ---- -> fe->name, mod_no+1, -697c748 -< DEBUG_RM( ---- -> DEBUG_EVENT( -699c750 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -708d758 -< #if 1 -714,716c764,766 -< "%s: Module %d: Timeout waiting for DC-DC calibration\n", -< fe->name, -< mod_no); ---- -> "%s: Module %d: Timeout waiting for DC-DC calibration (%02X)\n", -> fe->name, mod_no+1, -> READ_RM_REG(mod_no, 93)); -721d770 -< #endif -725c774 -< static int wp_proslic_powerleak_test(sdla_fe_t *fe, int mod_no) ---- -> static int wp_proslic_powerleak_test(sdla_fe_t *fe, int mod_no, int fast) -735,740c784,785 -< while((vbat = READ_RM_REG(mod_no, 82)) >= 0x6){ -< if ((SYSTEM_TICKS - start_ticks) > (HZ/2)){ -< break; -< } -< wait_just_a_bit(HZ/10, 0); -< } ---- -> wait_just_a_bit(HZ, fast); -> vbat = READ_RM_REG(mod_no, 82); -744c789 -< fe->name, mod_no, ---- -> fe->name, mod_no+1, -752c797 -< mod_no, ---- -> mod_no+1, -757a803,907 -> static int wp_proslic_calibrate(sdla_fe_t *fe, int mod_no, int fast) -> { -> volatile unsigned long start_ticks; -> -> /* perform all calibration */ -> WRITE_RM_REG(mod_no, 97, 0x1f); -> /* start */ -> WRITE_RM_REG(mod_no, 96, 0x5f); -> -> start_ticks = SYSTEM_TICKS; -> while(READ_RM_REG(mod_no, 96)){ -> if ((SYSTEM_TICKS - start_ticks) > 2*HZ){ -> DEBUG_EVENT( -> "%s: Module %d: Timeout on module calibration!\n", -> fe->name, mod_no+1); -> return -1; -> } -> wait_just_a_bit(HZ/10, fast); -> } -> return 0; -> } -> -> static int wp_proslic_manual_calibrate(sdla_fe_t *fe, int mod_no, int fast) -> { -> volatile unsigned long start_ticks; -> int i=0; -> -> WRITE_RM_REG(mod_no, 21, 0x00); -> WRITE_RM_REG(mod_no, 22, 0x00); -> WRITE_RM_REG(mod_no, 23, 0x00); -> WRITE_RM_REG(mod_no, 64, 0x00); -> -> /* Step 14 */ -> WRITE_RM_REG(mod_no, 97, 0x18); -> WRITE_RM_REG(mod_no, 96, 0x47); -> -> /* Step 15 */ -> start_ticks = SYSTEM_TICKS; -> while(READ_RM_REG(mod_no, 96) != 0){ -> if ((SYSTEM_TICKS - start_ticks) > 800){ -> DEBUG_EVENT( -> "%s: Module %d: Timeout on SLIC calibration (15)!\n", -> fe->name, mod_no+1); -> return -1; -> } -> wait_just_a_bit(HZ/10, fast); -> } -> -> wait_just_a_bit(HZ/10, fast); -> WRITE_RM_REG(mod_no, 88, 0x00); -> WRITE_RM_REG(mod_no, 89, 0x00); -> WRITE_RM_REG(mod_no, 90, 0x00); -> WRITE_RM_REG(mod_no, 91, 0x00); -> WRITE_RM_REG(mod_no, 92, 0x00); -> WRITE_RM_REG(mod_no, 93, 0x00); -> -> /* Step 16 */ -> /* Insert manual calibration for sangoma Si3210 */ -> WRITE_RM_REG(mod_no, 98, 0x10); -> WRITE_RM_REG(mod_no, 99, 0x10); -> -> for (i = 0x1f; i > 0; i--){ -> WRITE_RM_REG(mod_no, 98, i); -> wait_just_a_bit(4, fast); -> if ((READ_RM_REG(mod_no, 88)) == 0){ -> break; -> } -> } -> for (i = 0x1f; i > 0; i--){ -> WRITE_RM_REG(mod_no, 99, i); -> wait_just_a_bit(4, fast); -> if ((READ_RM_REG(mod_no, 89)) == 0){ -> break; -> } -> } -> WRITE_RM_REG(mod_no, 64, 0x01); -> wait_just_a_bit(HZ, fast); -> WRITE_RM_REG(mod_no, 64, 0x00); -> /* Step 17 */ -> WRITE_RM_REG(mod_no, 23, 0x04); -> -> /* Step 18 */ -> /* DAC offset and without common mode calibration. */ -> WRITE_RM_REG(mod_no, 97, 0x01); /* Manual after */ -> /* Calibrate common mode and differential DAC mode DAC + ILIM */ -> WRITE_RM_REG(mod_no, 96, 0x40); -> -> /* Step 19 */ -> wait_just_a_bit(HZ*2, fast); -> start_ticks = SYSTEM_TICKS; -> while(READ_RM_REG(mod_no, 96) != 0){ -> if ((SYSTEM_TICKS - start_ticks) > 400){ -> DEBUG_EVENT( -> "%s: Module %d: Timeout on SLIC calibration (%ld:%ld!\n", -> fe->name, mod_no+1,start_ticks,SYSTEM_TICKS); -> return -1; -> } -> wait_just_a_bit(HZ/10, fast); -> } -> DEBUG_RM("%s: Module %d: Calibration is done\n", -> fe->name, mod_no+1); -> /*READ_RM_REG(mod_no, 96);*/ -> -> return 0; -> } -762,765c912,914 -< volatile unsigned long start_ticks; -< unsigned short tmp[5]; -< unsigned char value; -< volatile int i, x; ---- -> unsigned short tmp[5]; -> unsigned char value; -> volatile int x; -782a932,935 -> if (!fast){ -> fe->rm_param.mod[mod_no].u.fxs.proslic_power = PROSLIC_POWER_UNKNOWN; -> } -> -788c941 -< mod_no); ---- -> mod_no+1); -811c964 -< mod_no); ---- -> mod_no+1); -817c970 -< if (wp_proslic_powerleak_test(fe, mod_no)){ ---- -> if (wp_proslic_powerleak_test(fe, mod_no, fast)){ -821c974 -< mod_no); ---- -> mod_no+1); -829c982 -< mod_no); ---- -> mod_no+1); -836,873c989,993 -< /* Step 14 */ -< WRITE_RM_REG(mod_no, 97, 0x1E); -< WRITE_RM_REG(mod_no, 96, 0x47); -< -< /* Step 15 */ -< start_ticks = SYSTEM_TICKS; -< while(READ_RM_REG(mod_no, 96) != 0){ -< if ((SYSTEM_TICKS - start_ticks) > 400){ -< DEBUG_EVENT( -< "%s: Module %d: Timeout on SLIC calibration (15)!\n", -< fe->name, mod_no); -< return -1; -< } -< wait_just_a_bit(HZ/10, fast); -< } -< -< /* Step 16 */ -< /* Insert manual calibration for sangoma Si3210 */ -< WRITE_RM_REG(mod_no, 98, 0x10); -< //WRITE_RM_REG(mod_no, 98, 0x1F/*0x10*/); -< for (i = 0x1f; i > 0; i--){ -< -< WRITE_RM_REG(mod_no, 98, i); -< wait_just_a_bit(4, fast); -< if ((READ_RM_REG(mod_no, 88)) == 0){ -< break; -< } -< } -< -< WRITE_RM_REG(mod_no, 99, 0x10); -< //WRITE_RM_REG(mod_no, 99, 0x1F/*0x10*/); -< for (i = 0x1f; i > 0; i--){ -< -< WRITE_RM_REG(mod_no, 99, i); -< wait_just_a_bit(4, fast); -< if ((READ_RM_REG(mod_no, 89)) == 0){ -< break; -< } ---- -> //if (wp_proslic_calibrate(fe, mod_no, fast)){ -> // return -1; -> //} -> if (wp_proslic_manual_calibrate(fe, mod_no, fast)){ -> return -1; -876,891c996,1002 -< /* Step 17 */ -< value = READ_RM_REG(mod_no, 23); -< WRITE_RM_REG(mod_no, 23, value | 0x04); -< -< /* Step 18 */ -< /* DAC offset and without common mode calibration. */ -< WRITE_RM_REG(mod_no, 97, 0x01/*0x18*/); /* Manual after */ -< /* Calibrate common mode and differential DAC mode DAC + ILIM */ -< WRITE_RM_REG(mod_no, 96, 0x40/*0x47*/); -< -< /* Step 19 */ -< start_ticks = SYSTEM_TICKS; -< while(READ_RM_REG(mod_no, 96) != 0){ -< if ((SYSTEM_TICKS - start_ticks) > 2000/*400*/){ -< DEBUG_EVENT( -< "%s: Module %d: Timeout on SLIC calibration (19:%02X)!\n", ---- -> /* Perform DC-DC calibration */ -> WRITE_RM_REG(mod_no, 93, 0x99); -> wait_just_a_bit(10, fast); -> value = READ_RM_REG(mod_no, 107); -> if ((value < 0x2) || (value > 0xd)) { -> DEBUG_EVENT( -> "%s: Module %d: DC-DC calibration has a surprising direct 107 of 0x%02x!\n", -893,897c1004,1006 -< mod_no, -< READ_RM_REG(mod_no, 96)); -< return -1; -< } -< wait_just_a_bit(HZ/10, fast); ---- -> mod_no+1, -> value); -> WRITE_RM_REG(mod_no, 107, 0x8); -899,900c1008 -< DEBUG_RM("%s: SLIC calibration complete (%ld)\n", -< fe->name, SYSTEM_TICKS-start_ticks); ---- -> -915,982d1022 -< /* Step 20 */ -< wp_proslic_setreg_indirect(fe, mod_no, 88, 0); -< wp_proslic_setreg_indirect(fe, mod_no, 89, 0); -< wp_proslic_setreg_indirect(fe, mod_no, 90, 0); -< wp_proslic_setreg_indirect(fe, mod_no, 91, 0); -< wp_proslic_setreg_indirect(fe, mod_no, 92, 0); -< wp_proslic_setreg_indirect(fe, mod_no, 93, 0); -< wp_proslic_setreg_indirect(fe, mod_no, 94, 0); -< wp_proslic_setreg_indirect(fe, mod_no, 95, 0); -< -< if (!fast){ -< /* Disable interrupt while full initialization */ -< WRITE_RM_REG(mod_no, 21, 0); -< WRITE_RM_REG(mod_no, 22, 0); -< WRITE_RM_REG(mod_no, 23, 0); -< -< #if defined(AFT_RM_INTR_SUPPORT) -< fe->rm_param.mod[mod_no].u.fxs.imask1 = 0x00; -< fe->rm_param.mod[mod_no].u.fxs.imask2 = 0x03; -< fe->rm_param.mod[mod_no].u.fxs.imask3 = 0x01; -< #else -< fe->rm_param.mod[mod_no].u.fxs.imask1 = 0x00; -< fe->rm_param.mod[mod_no].u.fxs.imask2 = 0x00; -< fe->rm_param.mod[mod_no].u.fxs.imask3 = 0x00; -< #endif -< } -< -< WRITE_RM_REG(mod_no, 64, 0);/* (0) */ -< -< //Alex Apr 3 - WRITE_RM_REG(mod_no, 64, 0x1); -< -< value = READ_RM_REG(mod_no, 68); -< /* -< ** FIXME ???value = value & 0x03; -< ** if (value & 4){ -< ** printf("Module %d Timeout!\n", mod_no); -< ** return -1; -< ** } */ -< -< #if 1 -< WRITE_RM_REG(mod_no, 64, 0x00); -< -< /* this is a singular calibration bit for longitudinal calibration */ -< WRITE_RM_REG(mod_no, 97, 0x01); -< WRITE_RM_REG(mod_no, 96, 0x40); -< -< value = READ_RM_REG(mod_no, 96); -< -< WRITE_RM_REG(mod_no, 18,0xff); -< WRITE_RM_REG(mod_no, 19,0xff); -< WRITE_RM_REG(mod_no, 20,0xff); -< -< /* WRITE_RM_REG(mod_no, 64,0x1); */ -< #endif -< -< /* Perform DC-DC calibration */ -< WRITE_RM_REG(mod_no, 93, 0x99); -< /*wait_just_a_bit(10, fast);*/ -< value = READ_RM_REG(mod_no, 107); -< if ((value < 0x2) || (value > 0xd)) { -< DEBUG_EVENT( -< "%s: Module %d: DC-DC calibration has a surprising direct 107 of 0x%02x!\n", -< fe->name, -< mod_no, -< value); -< WRITE_RM_REG(mod_no, 107, 0x8); -< } -< -991c1031 -< mod_no); ---- -> mod_no+1); -1015,1021c1055,1068 -< #if 0 -< /* Enable loopback */ -< WRITE_RM_REG(mod_no, 8, 0x2); -< WRITE_RM_REG(mod_no, 14, 0x0); -< WRITE_RM_REG(mod_no, 64, 0x0); -< WRITE_RM_REG(mod_no, 1, 0x08); -< #endif ---- -> if (!strcmp(fxo_modes[fe->fe_cfg.cfg.remora.opermode].name, "AUSTRALIA")) { -> value = acim2tiss[fxo_modes[fe->fe_cfg.cfg.remora.opermode].acim]; -> WRITE_RM_REG(mod_no, 10, 0x8 | value); -> if (fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_osc){ -> wp_proslic_setreg_indirect( -> fe, mod_no, 20, -> fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_osc); -> } -> if (fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_x){ -> wp_proslic_setreg_indirect( -> fe, mod_no, 21, -> fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_x); -> } -> } -1023c1070,1073 -< WRITE_RM_REG(mod_no, 64, 0x1); ---- -> /* lowpower */ -> if (fe->fe_cfg.cfg.remora.fxs_lowpower == WANOPT_YES){ -> WRITE_RM_REG(mod_no, 72, 0x10); -> } -1024a1075,1166 -> if (fe->fe_cfg.cfg.remora.fxs_fastringer == WANOPT_YES){ -> /* Speed up Ringer */ -> wp_proslic_setreg_indirect(fe, mod_no, 20, 0x7e6d); -> wp_proslic_setreg_indirect(fe, mod_no, 21, 0x01b9); -> /* Beef up Ringing voltage to 89V */ -> if (!strcmp(fxo_modes[fe->fe_cfg.cfg.remora.opermode].name, "AUSTRALIA")) { -> WRITE_RM_REG(mod_no, 74, 0x3f); -> if (wp_proslic_setreg_indirect(fe, mod_no, 21, 0x247)){ -> return -1; -> } -> DEBUG_EVENT("%s: Module %d: Boosting fast ringer (89V peak)\n", -> fe->name, mod_no + 1); -> } else if (fe->fe_cfg.cfg.remora.fxs_lowpower == WANOPT_YES){ -> if (wp_proslic_setreg_indirect(fe, mod_no, 21, 0x14b)){ -> return -1; -> } -> DEBUG_EVENT("%s: Module %d: Reducing fast ring power (50V peak)\n", -> fe->name, mod_no + 1); -> } else { -> DEBUG_EVENT("%s: Module %d: Speeding up ringer (25Hz)\n", -> fe->name, mod_no + 1); -> } -> }else{ -> if (!strcmp(fxo_modes[fe->fe_cfg.cfg.remora.opermode].name, "AUSTRALIA")) { -> WRITE_RM_REG(mod_no, 74, 0x3f); -> if (wp_proslic_setreg_indirect(fe, mod_no, 21, 0x1d1)){ -> return -1; -> } -> DEBUG_EVENT("%s: Module %d: Boosting ringer (89V peak)\n", -> fe->name, mod_no+1); -> } else if (fe->fe_cfg.cfg.remora.fxs_lowpower == WANOPT_YES){ -> if (wp_proslic_setreg_indirect(fe, mod_no, 21, 0x108)){ -> return -1; -> } -> DEBUG_EVENT("%s: Module %d: Reducing ring power (50V peak)\n", -> fe->name, mod_no+1); -> } -> } -> -> /* Adjust RX/TX gains */ -> if (fe->fe_cfg.cfg.remora.fxs_txgain || fe->fe_cfg.cfg.remora.fxs_rxgain) { -> DEBUG_EVENT("%s: Module %d: Adjust TX Gain to %s\n", -> fe->name, mod_no+1, -> (fe->fe_cfg.cfg.remora.fxs_txgain == 35) ? "3.5dB": -> (fe->fe_cfg.cfg.remora.fxs_txgain == -35) ? "-3.5dB":"0dB"); -> value = READ_RM_REG(mod_no, 9); -> switch (fe->fe_cfg.cfg.remora.fxs_txgain) { -> case 35: -> value |= 0x8; -> break; -> case -35: -> value |= 0x4; -> break; -> case 0: -> break; -> } -> -> DEBUG_EVENT("%s: Module %d: Adjust RX Gain to %s\n", -> fe->name, mod_no+1, -> (fe->fe_cfg.cfg.remora.fxs_rxgain == 35) ? "3.5dB": -> (fe->fe_cfg.cfg.remora.fxs_rxgain == -35) ? "-3.5dB":"0dB"); -> switch (fe->fe_cfg.cfg.remora.fxs_rxgain) { -> case 35: -> value |= 0x2; -> break; -> case -35: -> value |= 0x01; -> break; -> case 0: -> break; -> } -> WRITE_RM_REG(mod_no, 9, value); -> } -> -> if (!fast){ -> /* Disable interrupt while full initialization */ -> WRITE_RM_REG(mod_no, 21, 0); -> WRITE_RM_REG(mod_no, 22, 0xFC); -> WRITE_RM_REG(mod_no, 23, 0); -> -> #if defined(AFT_RM_INTR_SUPPORT) -> fe->rm_param.mod[mod_no].u.fxs.imask1 = 0x00; -> fe->rm_param.mod[mod_no].u.fxs.imask2 = 0x03; -> fe->rm_param.mod[mod_no].u.fxs.imask3 = 0x01; -> #else -> fe->rm_param.mod[mod_no].u.fxs.imask1 = 0x00; -> fe->rm_param.mod[mod_no].u.fxs.imask2 = 0xFC; -> fe->rm_param.mod[mod_no].u.fxs.imask3 = 0x00; -> #endif -> } -> -> #if 0 -1026c1168 -< fe->name, mod_no, ---- -> fe->name, mod_no+1, -1031d1172 -< #if 0 -1057a1199 -> WRITE_RM_REG(mod_no, 64, 0x1); -1059,1063c1201,1209 -< DEBUG_RM("%s: Module %d: Current Battery1 %dV, Battery2 %dV (%d)\n", -< fe->name, mod_no, -< READ_RM_REG(mod_no, 82)*375/1000, -< READ_RM_REG(mod_no, 83)*375/1000, -< __LINE__); ---- -> wait_just_a_bit(HZ, fast); -> if (READ_RM_REG(mod_no, 81) < 0x0A){ -> DEBUG_EVENT( -> "%s: Module %d: TIP/RING is too low on FXS %d!\n", -> fe->name, -> mod_no, -> READ_RM_REG(mod_no, 81) * 375 / 1000); -> return -1; -> } -1065,1067c1211,1214 -< /* lowpower */ -< //WRITE_RM_REG(mod_no, 72, 0x14); -< //todayWRITE_RM_REG(mod_no, 64, 0x1); ---- -> DEBUG_RM("%s: Module %d: Current Battery1 %dV, Battery2 %dV\n", -> fe->name, mod_no+1, -> READ_RM_REG(mod_no, 82)*375/1000, -> READ_RM_REG(mod_no, 83)*375/1000); -1081c1228 -< mod_no, ---- -> mod_no+1, -1160c1307 -< mod_no); ---- -> mod_no+1); -1165c1312 -< mod_no, ---- -> mod_no+1, -1178a1326 -> WRITE_RM_REG(mod_no, 2, 0x04 | 0x03); /* Ring detect mode (begin/end) */ -1181a1330,1374 -> /* Take values for fxotxgain and fxorxgain and apply them to module */ -> if (fe->fe_cfg.cfg.remora.fxo_txgain) { -> if (fe->fe_cfg.cfg.remora.fxo_txgain >= -150 && fe->fe_cfg.cfg.remora.fxo_txgain < 0) { -> DEBUG_EVENT("%s: Module %d: Adjust TX Gain to %2d.%d dB\n", -> fe->name, mod_no+1, -> fe->fe_cfg.cfg.remora.fxo_txgain / 10, -> fe->fe_cfg.cfg.remora.fxo_txgain % -10); -> WRITE_RM_REG(mod_no, 38, 16 + (fe->fe_cfg.cfg.remora.fxo_txgain/-10)); -> if(fe->fe_cfg.cfg.remora.fxo_txgain % 10) { -> WRITE_RM_REG(mod_no, 40, 16 + (-fe->fe_cfg.cfg.remora.fxo_txgain%10)); -> } -> } -> else if (fe->fe_cfg.cfg.remora.fxo_txgain <= 120 && fe->fe_cfg.cfg.remora.fxo_txgain > 0) { -> DEBUG_EVENT("%s: Module %d: Adjust TX Gain to %2d.%d dB\n", -> fe->name, mod_no+1, -> fe->fe_cfg.cfg.remora.fxo_txgain / 10, -> fe->fe_cfg.cfg.remora.fxo_txgain % 10); -> WRITE_RM_REG(mod_no, 38, fe->fe_cfg.cfg.remora.fxo_txgain/10); -> if (fe->fe_cfg.cfg.remora.fxo_txgain % 10){ -> WRITE_RM_REG(mod_no, 40, (fe->fe_cfg.cfg.remora.fxo_txgain % 10)); -> } -> } -> } -> if (fe->fe_cfg.cfg.remora.fxo_rxgain) { -> if (fe->fe_cfg.cfg.remora.fxo_rxgain >= -150 && fe->fe_cfg.cfg.remora.fxo_rxgain < 0) { -> DEBUG_EVENT("%s: Module %d: Adjust RX Gain to %2d.%d dB\n", -> fe->name, mod_no+1, -> fe->fe_cfg.cfg.remora.fxo_rxgain / 10, -> (-1) * (fe->fe_cfg.cfg.remora.fxo_rxgain % 10)); -> WRITE_RM_REG(mod_no, 39, 16 + (fe->fe_cfg.cfg.remora.fxo_rxgain/-10)); -> if(fe->fe_cfg.cfg.remora.fxo_rxgain%10) { -> WRITE_RM_REG(mod_no, 41, 16 + (-fe->fe_cfg.cfg.remora.fxo_rxgain%10)); -> } -> }else if (fe->fe_cfg.cfg.remora.fxo_rxgain <= 120 && fe->fe_cfg.cfg.remora.fxo_rxgain > 0) { -> DEBUG_EVENT("%s: Module %d: Adjust RX Gain to %2d.%d dB\n", -> fe->name, mod_no+1, -> fe->fe_cfg.cfg.remora.fxo_rxgain / 10, -> fe->fe_cfg.cfg.remora.fxo_rxgain % 10); -> WRITE_RM_REG(mod_no, 39, fe->fe_cfg.cfg.remora.fxo_rxgain/10); -> if(fe->fe_cfg.cfg.remora.fxo_rxgain % 10) { -> WRITE_RM_REG(mod_no, 41, (fe->fe_cfg.cfg.remora.fxo_rxgain%10)); -> } -> } -> } -> -1186c1379 -< mod_no); ---- -> mod_no+1); -1199c1392 -< int wp_remora_iface_init(void *pfe_iface) ---- -> int wp_remora_iface_init(void *p_fe, void *pfe_iface) -1200a1394 -> sdla_fe_t *fe = (sdla_fe_t*)p_fe; -1207a1402 -> fe_iface->pre_release = &wp_remora_pre_release; -1218c1413 -< #if defined(AFT_TDM_API_SUPPORT) ---- -> #if defined(AFT_TDM_API_SUPPORT) || defined(AFT_API_SUPPORT) -1221a1417,1418 -> WAN_LIST_INIT(&fe->event); -> wan_spin_lock_irq_init(&fe->lockirq); -1279a1477 -> #if 0 -1282,1283c1480,1481 -< wan_spin_lock_init(&fe->lock); -< ---- -> wan_spin_lock_init(&fe->lockirq); -> #endif -1308,1309c1506 -< fe->name, -< mod_no); ---- -> fe->name, mod_no+1); -1318c1515 -< mod_no); ---- -> mod_no+1); -1329,1330c1526 -< fe->name, -< mod_no, ---- -> fe->name, mod_no+1, -1339c1535 -< mod_no); ---- -> mod_no+1); -1348,1349c1544 -< fe->name, -< mod_no); ---- -> fe->name, mod_no+1); -1350a1546 -> ((sdla_t*)fe->card)->fe_no_intr = 0x1; -1355,1356c1551 -< fe->name, -< mod_no); ---- -> fe->name, mod_no+1); -1360,1361c1555,1560 -< sane = 1; -< if (retry++ < 10) goto retry_cfg; ---- -> if (!sane/*retry++ < 10*/){ -> sane = 1; -> DEBUG_EVENT("%s: Module %d: Retry configuration...\n", -> fe->name, mod_no+1); -> goto retry_cfg; -> } -1363,1364c1562 -< fe->name, -< mod_no, ---- -> fe->name, mod_no+1, -1376c1574 -< ---- -> -1435,1436d1632 -< sdla_fe_timer_event_t *fe_event; -< wan_smp_flag_t smp_flags; -1446a1643,1668 -> -> for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no++){ -> if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { -> wan_clear_bit(mod_no, &fe->rm_param.module_map); -> } -> } -> return 0; -> } -> -> /* -> ****************************************************************************** -> * sdla_te_pre_release() -> * -> * Description: T1/E1 pre release routines (not locked). -> * Arguments: -> * Returns: -> ****************************************************************************** -> */ -> static int wp_remora_pre_release(void* pfe) -> { -> sdla_fe_t *fe = (sdla_fe_t*)pfe; -> sdla_fe_timer_event_t *fe_event = NULL; -> wan_smp_flag_t smp_flags; -> int empty = 0; -> -> /* Kill TE timer poll command */ -1454,1457c1676,1685 -< wan_spin_lock_irq(&fe->lock,&smp_flags); -< while(!WAN_LIST_EMPTY(&fe->event)){ -< fe_event = WAN_LIST_FIRST(&fe->event); -< WAN_LIST_REMOVE(fe_event, next); ---- -> do{ -> wan_spin_lock_irq(&fe->lockirq,&smp_flags); -> if (!WAN_LIST_EMPTY(&fe->event)){ -> fe_event = WAN_LIST_FIRST(&fe->event); -> WAN_LIST_REMOVE(fe_event, next); -> }else{ -> empty = 1; -> } -> wan_spin_unlock_irq(&fe->lockirq,&smp_flags); -> /* Free should be called not from spin_lock_irq (windows) !!!! */ -1459,1460c1687,1688 -< } -< wan_spin_unlock_irq(&fe->lock,&smp_flags); ---- -> fe_event = NULL; -> }while(!empty); -1462,1466d1689 -< for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no++){ -< if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { -< wan_clear_bit(mod_no, &fe->rm_param.module_map); -< } -< } -1610c1833 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -1615c1838 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -1645c1868 -< DEBUG_RM("%s: RM timer!\n", fe->name); ---- -> DEBUG_TEST("%s: RM timer!\n", fe->name); -1660c1883 -< wan_spin_lock_irq(&fe->lock,&smp_flags); ---- -> wan_spin_lock_irq(&fe->lockirq,&smp_flags); -1662c1885 -< wan_spin_unlock_irq(&fe->lock,&smp_flags); ---- -> wan_spin_unlock_irq(&fe->lockirq,&smp_flags); -1675c1898 -< sdla_rm_add_timer(fe, 1000); ---- -> sdla_rm_add_timer(fe, WP_RM_POLL_TIMER); -1693c1916 -< DEBUG_RM("%s: Add new RM timer!\n", fe->name); ---- -> DEBUG_TEST("%s: Add new RM timer!\n", fe->name); -1725c1948 -< wan_spin_lock_irq(&fe->lock,&smp_flags); ---- -> wan_spin_lock_irq(&fe->lockirq,&smp_flags); -1728c1951 -< wan_spin_unlock_irq(&fe->lock,&smp_flags); ---- -> wan_spin_unlock_irq(&fe->lockirq,&smp_flags); -1736c1959,1965 -< wan_spin_unlock_irq(&fe->lock,&smp_flags); ---- -> wan_spin_unlock_irq(&fe->lockirq,&smp_flags); -> -> #if defined(__WINDOWS__) -> /* FIXME: Try to make common code for all OS */ -> /* poll is NOT locked outside! */ -> wan_spin_lock_irq(&card->wandev.lock,&smp_flags); -> #endif -1739,1740c1968,1969 -< DEBUG_RM("%s: Module %d: RM Polling State=%s Cmd=0x%X!\n", -< fe->name, mod_no, ---- -> DEBUG_EVENT("[RM] %s: Module %d: RM Polling State=%s Cmd=%s(%X) Mode=%s!\n", -> fe->name, mod_no+1, -1742c1971,1973 -< fe_event->type); ---- -> WP_RM_POLL_DECODE(fe_event->type), fe_event->type, -> WAN_EVENT_MODE_DECODE(fe_event->mode)); -> -1810,1811c2041,2042 -< DEBUG_EVENT("%s: Module %d: %s %s events (%d)!\n", -< fe->name, mod_no, ---- -> DEBUG_RM("%s: Module %d: %s %s events (%d)!\n", -> fe->name, mod_no+1, -1813c2044 -< WAN_EVENT_TYPE_DECODE(fe_event->type), ---- -> WP_RM_POLL_DECODE(fe_event->type), -1844c2075 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -1925c2156 -< #if defined(__WINDOWS__) ---- -> #if 0 /*defined(__WINDOWS__)*/ -1946,1954c2177,2188 -< imask = READ_RM_REG(mod_no, 3); -< if (fe_event->mode == WAN_EVENT_ENABLE){ -< imask |= 0x80; -< wan_set_bit(WAN_RM_EVENT_RING_DETECT, -< &fe->rm_param.mod[mod_no].events); -< }else{ -< imask &= ~0x80; -< wan_clear_bit(WAN_RM_EVENT_RING_DETECT, -< &fe->rm_param.mod[mod_no].events); ---- -> if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ -> imask = READ_RM_REG(mod_no, 3); -> if (fe_event->mode == WAN_EVENT_ENABLE){ -> imask |= 0x80; -> wan_set_bit(WAN_RM_EVENT_RING_DETECT, -> &fe->rm_param.mod[mod_no].events); -> }else{ -> imask &= ~0x80; -> wan_clear_bit(WAN_RM_EVENT_RING_DETECT, -> &fe->rm_param.mod[mod_no].events); -> } -> WRITE_RM_REG(mod_no, 3, imask); -1956d2189 -< WRITE_RM_REG(mod_no, 3, imask); -1971a2205,2219 -> case WP_RM_POLL_READ: -> DEBUG_EVENT("%s: Module %d: Reading %s register: Reg[%d]=%02X\n", -> fe->name, mod_no, -> WP_REMORA_DECODE_TYPE(fe->rm_param.mod[mod_no].type), -> fe_event->rm_event.reg, -> READ_RM_REG(mod_no,fe_event->rm_event.reg)); -> break; -> case WP_RM_POLL_WRITE: -> DEBUG_EVENT("%s: Module %d: Writting %s register: Reg[%d]=%02X\n", -> fe->name, mod_no, -> WP_REMORA_DECODE_TYPE(fe->rm_param.mod[mod_no].type), -> fe_event->rm_event.reg, -> fe_event->rm_event.value); -> WRITE_RM_REG(mod_no, fe_event->rm_event.reg, fe_event->rm_event.value); -> break; -1978a2227,2231 -> /* poll is NOT locked outside! */ -> wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); -> #endif -> -> #if 0/*defined(__WINDOWS__)*/ -1999c2252 -< sdla_rm_add_timer(fe, HZ); ---- -> sdla_rm_add_timer(fe, WP_RM_POLL_TIMER); -2043c2296 -< wan_spin_lock_irq(&fe->lock,&smp_flags); ---- -> wan_spin_lock_irq(&fe->lockirq,&smp_flags); -2046a2300,2306 -> #if defined(__WINDOWS__) -> /* only one event allowed at a time */ -> DEBUG_RM("%s: returning EBUSY\n", -> fe->name); -> wan_spin_unlock_irq(&fe->lockirq, &smp_flags); -> return EBUSY; -> #else -2053c2313 -< wan_spin_unlock_irq(&fe->lock, &smp_flags); ---- -> wan_spin_unlock_irq(&fe->lockirq, &smp_flags); -2056a2317 -> #endif -2058c2319 -< wan_spin_unlock_irq(&fe->lock, &smp_flags); ---- -> wan_spin_unlock_irq(&fe->lockirq, &smp_flags); -2061a2323,2378 -> /****************************************************************************** -> * wp_remora_event_verification() -> * -> * Description: -> * Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) -> * Returns: -> ******************************************************************************/ -> static int -> wp_remora_event_verification(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) -> { -> int mod_no = ectrl->mod_no-1; -> -> /* Event verification */ -> if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ -> switch(ectrl->type){ -> case WAN_EVENT_RM_POWER: -> case WAN_EVENT_RM_LC: -> case WAN_EVENT_RM_DTMF: -> case WAN_EVENT_RM_RING_TRIP: -> case WAN_EVENT_RM_RING: -> case WAN_EVENT_RM_TONE: -> case WAN_EVENT_RM_TXSIG_KEWL: -> case WAN_EVENT_RM_TXSIG_START: -> case WAN_EVENT_RM_TXSIG_OFFHOOK: -> case WAN_EVENT_RM_TXSIG_ONHOOK: -> case WAN_EVENT_RM_ONHOOKTRANSFER: -> case WAN_EVENT_RM_SETPOLARITY: -> break; -> default: -> DEBUG_EVENT( -> "%s: Module %d: Remora RING Event is only valid for FXS module (%X)\n", -> fe->name,mod_no+1, -> ectrl->type); -> return -EINVAL; -> } -> }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ -> switch(ectrl->type){ -> case WAN_EVENT_RM_RING_DETECT: -> case WAN_EVENT_RM_TXSIG_START: -> case WAN_EVENT_RM_TXSIG_OFFHOOK: -> case WAN_EVENT_RM_TXSIG_ONHOOK: -> break; -> default: -> DEBUG_EVENT( -> "%s: Module %d: Remora RING Event is only valid for FXO module(%X)\n", -> fe->name,mod_no+1, -> ectrl->type); -> return -EINVAL; -> } -> }else{ -> DEBUG_EVENT( -> "%s: Module %d: Unknown Module type %X\n", -> fe->name,mod_no+1, -> fe->rm_param.mod[mod_no].type); -> return -EINVAL; -> } -2062a2380,2381 -> return 0; -> } -2074c2393 -< int mod_no, err = 0; ---- -> int mod_no = ectrl->mod_no-1, err = 0; -2077,2079c2396,2397 -< mod_no = ectrl->mod_no; -< -< if (mod_no >= MAX_REMORA_MODULES){ ---- -> -> if (mod_no+1 > MAX_REMORA_MODULES){ -2081c2399 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -2090,2092c2408,2415 -< DEBUG_RM("%s: Module %d: Scheduling %s event type!\n", -< fe->name, mod_no, -< WAN_EVENT_TYPE_DECODE(ectrl->type)); ---- -> if (wp_remora_event_verification(fe, ectrl)){ -> return -EINVAL; -> } -> -> DEBUG_RM("%s: Module %d: Scheduling %s event (%s:%X)!\n", -> fe->name, mod_no+1, -> WAN_EVENT_TYPE_DECODE(ectrl->type), -> WAN_EVENT_MODE_DECODE(ectrl->mode), ectrl->mode); -2095c2418,2419 -< fe_event.rm_event.mod_no= ectrl->mod_no; ---- -> fe_event.rm_event.mod_no= mod_no; -> fe_event.delay = WP_RM_POLL_TIMER; -2103,2105d2426 -< case WAN_EVENT_RM_RING_TRIP: -< fe_event.type = WP_RM_POLL_RING_TRIP; -< break; -2108a2430,2432 -> case WAN_EVENT_RM_RING_TRIP: -> fe_event.type = WP_RM_POLL_RING_TRIP; -> break; -2111a2436,2438 -> case WAN_EVENT_RM_RING_DETECT: -> fe_event.type = WP_RM_POLL_RING_DETECT; -> break; -2135,2144c2462 -< case WAN_EVENT_RM_RING_DETECT: -< fe_event.type = WP_RM_POLL_RING_DETECT; -< break; -< default: -< DEBUG_EVENT("%s: Module %d: Invalid wan event type %X\n", -< fe->name,mod_no, -< ectrl->type); -< return -EINVAL; -< } -< ---- -> } -2152,2153c2470,2471 -< DEBUG_EVENT("%s: Module %d: Enable Dial tone\n", -< fe->name, mod_no); ---- -> DEBUG_RM("%s: Module %d: Enable Dial tone\n", -> fe->name, mod_no+1); -2176,2177c2494,2495 -< DEBUG_EVENT("%s: Module %d: Enable Busy tone\n", -< fe->name, mod_no); ---- -> DEBUG_RM("%s: Module %d: Enable Busy tone\n", -> fe->name, mod_no+1); -2200,2201c2518,2519 -< DEBUG_EVENT("%s: Module %d: Enable Ring tone\n", -< fe->name, mod_no); ---- -> DEBUG_RM("%s: Module %d: Enable Ring tone\n", -> fe->name, mod_no+1); -2224,2225c2542,2543 -< DEBUG_EVENT("%s: Module %d: Enable Congestion tone\n", -< fe->name, mod_no); ---- -> DEBUG_RM("%s: Module %d: Enable Congestion tone\n", -> fe->name, mod_no+1); -2327,2329c2645,2648 -< wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; -< sdla_fe_debug_t *fe_debug; -< int err = -EINVAL; ---- -> wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; -> sdla_fe_debug_t *fe_debug; -> sdla_fe_timer_event_t event; -> int err = -EINVAL; -2358,2384d2676 -< #if 0 -< /* verify TIP/RING voltage */ -< if (!fast){ -< WRITE_RM_REG(mod_no, 8, 0x2); -< wait_just_a_bit(HZ, fast); -< start_ticks = SYSTEM_TICKS; -< while(READ_RM_REG(mod_no, 81) < 0x75){ -< if ((SYSTEM_TICKS - start_ticks) > HZ*10){ -< break; -< } -< wait_just_a_bit(HZ, fast); -< } -< wait_just_a_bit(HZ, fast); -< if (READ_RM_REG(mod_no, 81) < 0x75){ -< if (sane){ -< DEBUG_EVENT( -< "%s: Module %d: TIP/RING is too low on FXS %d!\n", -< fe->name, -< mod_no, -< READ_RM_REG(mod_no, 81) * 375 / 1000); -< } -< WRITE_RM_REG(mod_no, 8, 0x0); -< return -1; -< } -< WRITE_RM_REG(mod_no, 8, 0x0); -< } -< #endif -2393d2684 -< #if 0 -2395,2396c2686,2698 -< case WAN_FE_DEBUG_VOLTAGE: -< /* FIXME: Add code */ ---- -> case WAN_FE_DEBUG_REG: -> event.type = (fe_debug->fe_debug_reg.read) ? -> WP_RM_POLL_READ : WP_RM_POLL_WRITE; -> event.rm_event.mod_no = fe_debug->mod_no; -> event.rm_event.reg = (u_int16_t)fe_debug->fe_debug_reg.reg; -> event.rm_event.value = fe_debug->fe_debug_reg.value; -> event.delay = WP_RM_POLL_TIMER; -> sdla_rm_add_event(fe, &event); -> udp_cmd->wan_cmd_return_code = WAN_CMD_OK; -> break; -> default: -> udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; -> udp_cmd->wan_cmd_data_len = 0; -2399d2700 -< #endif -2422c2723 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -2450c2751 -< #if defined(AFT_TDM_API_SUPPORT) ---- -> #if defined(AFT_TDM_API_SUPPORT) || defined(AFT_API_SUPPORT) -2452a2754,2756 -> //#undef DEBUG_RM -> //#define DEBUG_RM DEBUG_EVENT -> -2483a2788 -> -2488c2793 -< fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 16); ---- -> fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 4); -2506c2811 -< fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 4; ---- -> fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 2; -2557a2863,2865 -> DEBUG_RM("%s: Module %d: On-Hook status!\n", -> fe->name, -> mod_no + 1); -2567a2876 -> -2568a2878 -> -2629,2632c2939,2940 -< "%s: Module %d: %lu Polarity reversed (%d -> %d)\n", -< fe->name, -< mod_no + 1, -< SYSTEM_TICKS, ---- -> "%s: Module %d: Polarity reversed (%d -> %d) (%ul)\n", -> fe->name, mod_no + 1, -2634c2942,2943 -< fe->rm_param.mod[mod_no].u.fxo.lastpol); ---- -> fe->rm_param.mod[mod_no].u.fxo.lastpol, -> (unsigned int)SYSTEM_TICKS); -2643a2953,2954 -> //#undef DEBUG_RM -> //#define DEBUG_RM DEBUG_TEST -2724c3035 -< #if defined(AFT_TDM_API_SUPPORT) ---- -> #if defined(AFT_TDM_API_SUPPORT) || defined(AFT_API_SUPPORT) -2735,2739c3046 -< -< if (SYSTEM_TICKS - fe->rm_param.last_watchdog < WP_RM_WATCHDOG_TIMEOUT) { -< return 0; -< } -< fe->rm_param.last_watchdog = SYSTEM_TICKS; ---- -> -2807a3115 -> -2809,2810c3117,3122 -< if (wp_remora_check_intr(fe)){ -< wp_remora_intr(fe); ---- -> if (SYSTEM_TICKS - fe->rm_param.last_watchdog > WP_RM_WATCHDOG_TIMEOUT) { -> fe->rm_param.last_watchdog = SYSTEM_TICKS; -> -> if (wp_remora_check_intr(fe)){ -> wp_remora_intr(fe); -> } -2833c3145 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -2838c3150 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -2858c3170 -< fe->name, mod_no, type); ---- -> fe->name, mod_no+1, type); -2875c3187 -< fe->name, mod_no, type); ---- -> fe->name, mod_no+1, type); -2898c3210 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -2923d3234 -< -2932,2933d3242 -< //mod_no = fe->rm_param.intcount % MAX_REMORA_MODULES; -< -3010,3011d3318 -< DEBUG_TDMAPI("mod_no: %d\n", mod_no); -< -3025c3332 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -3037c3344 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -3043c3350 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -3056c3363 -< fe->name, mod_no); ---- -> fe->name, mod_no+1); -3074,3075c3381,3382 -< fe->name, mod_no); -< event.rxhook = WAN_EVENT_RING_TRIP_PRESENT; ---- -> fe->name, mod_no+1); -> event.ring_mode = WAN_EVENT_RING_TRIP_PRESENT; -3079,3080c3386,3387 -< fe->name, mod_no); -< event.rxhook = WAN_EVENT_RING_TRIP_STOP; ---- -> fe->name, mod_no+1); -> event.ring_mode = WAN_EVENT_RING_TRIP_STOP; -3085a3393,3416 -> if (stat2 & 0x80) { -> DEBUG_EVENT("%s: Module %d: Power Alarm Q6!\n", -> fe->name, mod_no+1); -> } -> if (stat2 & 0x40) { -> DEBUG_EVENT("%s: Module %d: Power Alarm Q5!\n", -> fe->name, mod_no+1); -> } -> if (stat2 & 0x20) { -> DEBUG_EVENT("%s: Module %d: Power Alarm Q4!\n", -> fe->name, mod_no+1); -> } -> if (stat2 & 0x10) { -> DEBUG_EVENT("%s: Module %d: Power Alarm Q3!\n", -> fe->name, mod_no+1); -> } -> if (stat2 & 0x08) { -> DEBUG_EVENT("%s: Module %d: Power Alarm Q2!\n", -> fe->name, mod_no+1); -> } -> if (stat2 & 0x04) { -> DEBUG_EVENT("%s: Module %d: Power Alarm Q1!\n", -> fe->name, mod_no+1); -> } -3088c3419 -< fe->name, mod_no, ---- -> fe->name, mod_no+1, -3130c3461 -< }else{ ---- -> } else { -3137c3468 -< }else{ ---- -> } else { -3143a3475,3479 -> #ifdef AUDIO_RINGCHECK -> /* If audio ringcheck is enabled, we use this code -> * if disabled we use the check_hook code. -> * Right now we use the check_hook code because -> * this code does not have debounce */ -3146,3150c3482,3487 -< } -< }else if (status){ -< DEBUG_RM( -< "%s: Module %d: Receive interrupt %02X!\n", -< fe->name, mod_no+1, status); ---- -> } -> #endif -> } -> if (status & 0x01){ -> DEBUG_RM("%s: Module %d: Polarity reversed!\n", -> fe->name, mod_no+1); diff --git a/patches/kdrivers/src/net/sdla_56k.c b/patches/kdrivers/src/net/sdla_56k.c index 90454e3..e76dc3b 100644 --- a/patches/kdrivers/src/net/sdla_56k.c +++ b/patches/kdrivers/src/net/sdla_56k.c @@ -37,25 +37,46 @@ # include # include # include -# include /* for aft_56k_write_cpld() declaration */ #elif defined(__WINDOWS__) # include # include /* WANPIPE common user API definitions */ -# include /* for aft_56k_write_cpld() declaration */ #else # include # include # include # include # include /* WANPIPE common user API definitions */ -# include /* for aft_56k_write_cpld() declaration */ #endif /****************************************************************************** DEFINES AND MACROS ******************************************************************************/ -#define WRITE_REG(reg,val) fe->write_fe_reg(fe->card, 0, (int)(reg),(int)(val)) -#define READ_REG(reg) fe->read_fe_reg(fe->card, 0, (int)(reg)) +#if defined(__WINDOWS__) +#define WRITE_REG(reg,val) \ + fe->write_fe_reg( \ + ((sdla_t*)fe->card)->hw, \ + 0, \ + (int)(reg),(int)(val)) +#define READ_REG(reg) \ + fe->read_fe_reg( \ + ((sdla_t*)fe->card)->hw, \ + 0, \ + (int)(reg)) + +#else + +#define WRITE_REG(reg,val) \ + fe->write_fe_reg( \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED),\ + 0, \ + (int)(reg),(int)(val)) +#define READ_REG(reg) \ + fe->read_fe_reg( \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED),\ + 0, \ + (int)(reg)) #if 1 #define AFT_FUNC_DEBUG() @@ -63,6 +84,8 @@ #define AFT_FUNC_DEBUG() DEBUG_EVENT("%s:%d\n",__FUNCTION__,__LINE__) #endif +#endif + /****************************************************************************** STRUCTURES AND TYPEDEFS ******************************************************************************/ @@ -80,7 +103,7 @@ static int sdla_56k_global_config(void* pfe); static int sdla_56k_global_unconfig(void* pfe); static int sdla_56k_config(void* pfe); -static unsigned int sdla_56k_alarm(sdla_fe_t *fe, int manual_read); +static u_int32_t sdla_56k_alarm(sdla_fe_t *fe, int manual_read); static int sdla_56k_udp(sdla_fe_t*, void*, unsigned char*); static void display_Rx_code_condition(sdla_fe_t* fe); static int sdla_56k_print_alarm(sdla_fe_t* fe, unsigned int); @@ -90,11 +113,6 @@ static int sdla_56k_unconfig(void* pfe); static int sdla_56k_intr(sdla_fe_t *fe); static int sdla_56k_check_intr(sdla_fe_t *fe); -/* enable 56k chip reset state */ -static unsigned int reset_on_LXT441PE(sdla_t *card); -/* disable 56k chip reset state */ -static unsigned int reset_off_LXT441PE(sdla_t *card); - /****************************************************************************** FUNCTION DEFINITIONS ******************************************************************************/ @@ -143,7 +161,7 @@ static int sdla_56k_get_fe_status(sdla_fe_t *fe, unsigned char *status) return 0; } -unsigned int sdla_56k_alarm(sdla_fe_t *fe, int manual_read) +u_int32_t sdla_56k_alarm(sdla_fe_t *fe, int manual_read) { unsigned short status = 0x00; @@ -242,8 +260,9 @@ int sdla_56k_default_cfg(void* pcard, void* p56k_cfg) } -int sdla_56k_iface_init(void* pfe_iface) +int sdla_56k_iface_init(void *p_fe, void* pfe_iface) { + sdla_fe_t *fe = (sdla_fe_t*)p_fe; sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)pfe_iface; AFT_FUNC_DEBUG(); @@ -251,8 +270,8 @@ int sdla_56k_iface_init(void* pfe_iface) fe_iface->global_config = &sdla_56k_global_config; fe_iface->global_unconfig = &sdla_56k_global_unconfig; - fe_iface->config = &sdla_56k_config; - fe_iface->unconfig = &sdla_56k_unconfig; + fe_iface->config = &sdla_56k_config; + fe_iface->unconfig = &sdla_56k_unconfig; fe_iface->get_fe_status = &sdla_56k_get_fe_status; fe_iface->get_fe_media = &sdla_56k_get_fe_media; @@ -262,9 +281,12 @@ int sdla_56k_iface_init(void* pfe_iface) fe_iface->update_alarm_info = &sdla_56k_update_alarm_info; fe_iface->process_udp = &sdla_56k_udp; - fe_iface->isr = &sdla_56k_intr; - fe_iface->check_isr = &sdla_56k_check_intr; + fe_iface->isr = &sdla_56k_intr; + fe_iface->check_isr = &sdla_56k_check_intr; + /* The 56k CSU/DSU front end status has not been initialized */ + fe->fe_status = FE_UNITIALIZED; + return 0; } @@ -297,14 +319,18 @@ static int sdla_56k_check_intr(sdla_fe_t *fe) static int sdla_56k_global_config(void* pfe) { - DEBUG_56K("%s: %s Global Front End configuration\n", + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + DEBUG_EVENT("%s: %s Global Front End configuration\n", fe->name, FE_MEDIA_DECODE(fe)); return 0; } static int sdla_56k_global_unconfig(void* pfe) { - DEBUG_56K("%s: %s Global unconfiguration!\n", + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + DEBUG_EVENT("%s: %s Global unconfiguration!\n", fe->name, FE_MEDIA_DECODE(fe)); return 0; @@ -315,15 +341,12 @@ static int sdla_56k_config(void* pfe) { sdla_fe_t *fe = (sdla_fe_t*)pfe; sdla_t *card = (sdla_t *)fe->card; - u16 adapter_type; AFT_FUNC_DEBUG(); WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - card->hw_iface.getcfg(card->hw, SDLA_ADAPTERTYPE, &adapter_type); - /* The 56k CSU/DSU front end status has not been initialized */ fe->fe_status = FE_UNITIALIZED; @@ -333,11 +356,6 @@ static int sdla_56k_config(void* pfe) /* Zero the RRC register changes */ fe->fe_param.k56_param.delta_RRC_reg_56k = 0; - if(adapter_type == AFT_ADPTR_56K){ - reset_on_LXT441PE(card); - reset_off_LXT441PE(card); - } - if(WRITE_REG(REG_INT_EN_STAT, (BIT_INT_EN_STAT_IDEL | BIT_INT_EN_STAT_RX_CODE | BIT_INT_EN_STAT_ACTIVE))) { return 1; @@ -384,41 +402,19 @@ static int sdla_56k_config(void* pfe) return 1; } + fe->fe_status = FE_CONNECTED; return 0; } static int sdla_56k_unconfig(void* pfe) { sdla_fe_t *fe = (sdla_fe_t*)pfe; - sdla_t *card = (sdla_t *)fe->card; - u16 adapter_type; AFT_FUNC_DEBUG(); WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - - card->hw_iface.getcfg(card->hw, SDLA_ADAPTERTYPE, &adapter_type); - - if(adapter_type == AFT_ADPTR_56K){ - reset_on_LXT441PE(card); - } - return 0; -} - -static unsigned int reset_on_LXT441PE(sdla_t *card) -{ - AFT_FUNC_DEBUG(); - aft_56k_write_cpld(card, 0x00,0x00); - WP_DELAY(1000); - return 0; -} - -static unsigned int reset_off_LXT441PE(sdla_t *card) -{ - AFT_FUNC_DEBUG(); - aft_56k_write_cpld(card, 0x00, 0x03); - WP_DELAY(1000); + fe->fe_status = FE_UNITIALIZED; return 0; } @@ -517,8 +513,14 @@ sdla_56k_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) //unsigned char loop=BIT_RX_CTRL_DSU_LOOP|BIT_RX_CTRL_CSU_LOOP; //unsigned char loop=BIT_RX_CTRL_DSU_LOOP; //unsigned char loop=BIT_RX_CTRL_CSU_LOOP; - unsigned char loop=0x40; - + unsigned char loop=0x00; + + if(type==WAN_TE1_PAYLB_MODE){ + loop=BIT_RX_CTRL_DSU_LOOP; + }else{ + loop=BIT_RX_CTRL_CSU_LOOP; + } + WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); @@ -601,9 +603,9 @@ static int sdla_56k_udp(sdla_fe_t *fe, void* pudp_cmd, unsigned char* data) ** Arguments: ** Returns: */ -static int sdla_56k_print_alarm(sdla_fe_t* fe, unsigned int status) +static int sdla_56k_print_alarm(sdla_fe_t* fe, u_int32_t status) { - unsigned int alarms = (unsigned int)status; + u_int32_t alarms = status; AFT_FUNC_DEBUG(); diff --git a/patches/kdrivers/src/net/sdla_8te1.c b/patches/kdrivers/src/net/sdla_8te1.c index ae95a13..762c844 100644 --- a/patches/kdrivers/src/net/sdla_8te1.c +++ b/patches/kdrivers/src/net/sdla_8te1.c @@ -29,20 +29,25 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: sdla_8te1.c,v 1.66 2007/04/10 16:28:49 sangoma Exp $ + * $Id: sdla_8te1.c,v 1.117 2008/03/06 18:17:59 sangoma Exp $ */ -/* - ****************************************************************************** - * sdla_8te1.c WANPIPE(tm) Multiprotocol WAN Link Driver. - * 8 ports T1/E1 board configuration. - * - * Author: Alex Feldman - * - * ============================================================================ - * Feb 18, 2006 Alex Feldma Initial version. - ****************************************************************************** - */ +/****************************************************************************** +** sdla_8te1.c WANPIPE(tm) Multiprotocol WAN Link Driver. +** 8 ports T1/E1 board configuration. +** +** Author: Alex Feldman +** +** ============================================================================ +** Date Name Label Description +** ============================================================================ +** 02-18-06 Alex Feldman Initial version. +** 07-10-07 Alex Feldman EBIT Enable auto E-bit support. +** Nov 23, 2007 Alex Feldman UNFRM Add support E1 Unframe mode for E1 +** interface. +** Nov 23, 2007 Alex Feldman TXTRI Add support for TX Tri-state. +** Feb 06, 2008 Alex Feldman E1_120 Adjust waveform for E1, 120 ohm. +******************************************************************************/ /****************************************************************************** * INCLUDE FILES @@ -81,10 +86,8 @@ /****************************************************************************** * DEFINES AND MACROS ******************************************************************************/ -#undef WANPIPE_IGNORE_T1_YELLOW -/* Dec 14, 2007 -** Disable all FE interrupt if Short Circuit condition detected! */ -#undef WAN_FE_SC_DISABLE_INTR + +#define WAN_TE1_DEVICE_ID DEVICE_ID_DS(READ_REG_LINE(0, REG_IDR)) #define CLEAR_REG(sreg,ereg) { \ unsigned short reg; \ @@ -104,72 +107,46 @@ IS_LIUREG(reg) ? 0x020 : \ IS_BERTREG(reg) ? 0x010 : 0x001 -#if 1 /* Read/Write to front-end register */ #define WRITE_REG(reg,val) \ fe->write_fe_reg( \ - fe->card, \ - fe->fe_cfg.line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe->fe_cfg.line_no, \ (int)sdla_ds_te1_address(fe,fe->fe_cfg.line_no,(reg)), \ (int)(val)) #define WRITE_REG_LINE(fe_line_no, reg,val) \ fe->write_fe_reg( \ - fe->card, \ - fe_line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe_line_no, \ (int)sdla_ds_te1_address(fe,fe_line_no,(reg)), \ (int)(val)) #define READ_REG(reg) \ fe->read_fe_reg( \ - fe->card, \ - fe->fe_cfg.line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe->fe_cfg.line_no, \ (int)sdla_ds_te1_address(fe,fe->fe_cfg.line_no,(reg))) #define __READ_REG(reg) \ fe->__read_fe_reg( \ - fe->card, \ - fe->fe_cfg.line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe->fe_cfg.line_no, \ (int)sdla_ds_te1_address(fe,fe->fe_cfg.line_no,(reg))) #define READ_REG_LINE(fe_line_no, reg) \ fe->read_fe_reg( \ - fe->card, \ - fe_line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe_line_no, \ (int)sdla_ds_te1_address(fe,fe_line_no,(reg))) -#else -/* Read/Write to front-end register */ -#define WRITE_REG(reg,val) \ - fe->write_fe_reg( \ - fe->card, \ - (int)((reg) + ((fe->fe_cfg.line_no)*(DLS_PORT_DELTA(reg)))),\ - (int)(val)) - -#define WRITE_REG_LINE(fe_line_no, reg,val) \ - fe->write_fe_reg( \ - fe->card, \ - (int)((reg) + (fe_line_no)*(DLS_PORT_DELTA(reg))), \ - (int)(val)) - -#define READ_REG(reg) \ - fe->read_fe_reg( \ - fe->card, \ - (int)((reg) + ((fe->fe_cfg.line_no)*(DLS_PORT_DELTA(reg))))) - -#define __READ_REG(reg) \ - fe->__read_fe_reg( \ - fe->card, \ - (int)((reg) + ((fe->fe_cfg.line_no)*(DLS_PORT_DELTA(reg))))) - -#define READ_REG_LINE(fe_line_no, reg) \ - fe->read_fe_reg( \ - fe->card, \ - (int)((reg) + (fe_line_no)*(DLS_PORT_DELTA(reg)))) -#endif - - #define WAN_TE1_FRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_OOF_ALARM) +/*Nov 23, 2007 UNFRM */ #define WAN_TE1_UNFRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_LOS_ALARM) #define IS_T1_ALARM(alarm) \ @@ -249,6 +226,7 @@ static int sdla_ds_te1_reset(void* pfe, int port_no, int reset); static int sdla_ds_te1_global_config(void* pfe); /* Change to static */ static int sdla_ds_te1_global_unconfig(void* pfe); /* Change to static */ static int sdla_ds_te1_chip_config(void* pfe); +/*static int sdla_ds_te1_chip_config_verify(sdla_fe_t* pfe);*/ static int sdla_ds_te1_config(void* pfe); /* Change to static */ static int sdla_ds_te1_reconfig(sdla_fe_t* fe); static int sdla_ds_te1_post_init(void *pfe); @@ -266,11 +244,11 @@ static int sdla_ds_te1_pmon(sdla_fe_t *fe, int action); static int sdla_ds_te1_rxlevel(sdla_fe_t* fe); static int sdla_ds_te1_polling(sdla_fe_t* fe); static unsigned int sdla_ds_te1_read_alarms(sdla_fe_t *fe, int read); -static int sdla_ds_te1_set_alarms(sdla_fe_t* fe, unsigned long alarms); -static int sdla_ds_te1_clear_alarms(sdla_fe_t* fe, unsigned long alarms); -static void sdla_ds_te1_set_status(sdla_fe_t* fe, unsigned long alarms); +static int sdla_ds_te1_set_alarms(sdla_fe_t* fe, u_int32_t alarms); +static int sdla_ds_te1_clear_alarms(sdla_fe_t* fe, u_int32_t alarms); +static void sdla_ds_te1_set_status(sdla_fe_t* fe, u_int32_t alarms); static int sdla_ds_te1_print_alarms(sdla_fe_t*, unsigned int); -static int sdla_ds_te1_set_lbmode(sdla_fe_t*, unsigned char, unsigned char); +static int sdla_ds_te1_set_lb(sdla_fe_t*, unsigned char, unsigned char); static int sdla_ds_te1_rbs_update(sdla_fe_t* fe, int, unsigned char); static int sdla_ds_te1_set_rbsbits(sdla_fe_t *fe, int, unsigned char); static int sdla_ds_te1_rbs_report(sdla_fe_t* fe); @@ -405,8 +383,9 @@ static int sdla_ds_te1_RxChanCtrl(sdla_fe_t* fe, int channel, int enable) } -int sdla_ds_te1_iface_init(void *p_fe_iface) +int sdla_ds_te1_iface_init(void *p_fe, void *p_fe_iface) { + sdla_fe_t *fe = (sdla_fe_t*)p_fe; sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)p_fe_iface; fe_iface->reset = &sdla_ds_te1_reset; @@ -423,6 +402,7 @@ int sdla_ds_te1_iface_init(void *p_fe_iface) fe_iface->check_isr = &sdla_ds_te1_check_intr; fe_iface->intr_ctrl = &sdla_ds_te1_intr_ctrl; fe_iface->polling = &sdla_ds_te1_polling; + fe_iface->add_timer = &sdla_ds_te1_add_timer; fe_iface->process_udp = &sdla_ds_te1_udp; fe_iface->print_fe_alarm = &sdla_ds_te1_print_alarms; @@ -436,16 +416,20 @@ int sdla_ds_te1_iface_init(void *p_fe_iface) fe_iface->get_fe_media_string = &sdla_ds_te1_get_fe_media_string; fe_iface->update_alarm_info = &sdla_ds_te1_update_alarm_info; fe_iface->update_pmon_info = &sdla_ds_te1_update_pmon_info; - fe_iface->set_fe_lbmode = &sdla_ds_te1_set_lbmode; + fe_iface->set_fe_lbmode = &sdla_ds_te1_set_lb; fe_iface->read_rbsbits = &sdla_ds_te1_read_rbsbits; fe_iface->check_rbsbits = &sdla_ds_te1_check_rbsbits; fe_iface->report_rbsbits = &sdla_ds_te1_rbs_report; fe_iface->set_rbsbits = &sdla_ds_te1_set_rbsbits; fe_iface->set_fe_sigctrl = &sdla_ds_te1_sigctrl; - #if 0 fe_iface->led_ctrl = &sdla_te_led_ctrl; #endif + + /* Initial FE state */ + fe->fe_status = FE_UNITIALIZED; //FE_DISCONNECTED; + WAN_LIST_INIT(&fe->event); + wan_spin_lock_irq_init(&fe->lockirq, "wan_8te1_lock"); return 0; } @@ -458,11 +442,12 @@ int sdla_ds_te1_iface_init(void *p_fe_iface) ******************************************************************************/ static int sdla_ds_te1_device_id(sdla_fe_t* fe) { - u_int8_t value; +// u_int8_t value; /* Revision/Chip ID (Reg. 0x0D) */ - value = READ_REG_LINE(0, REG_IDR); - fe->fe_chip_id = DEVICE_ID_DS(value); +// value = READ_REG_LINE(0, REG_IDR); +// fe->fe_chip_id = DEVICE_ID_DS(value); + fe->fe_chip_id = WAN_TE1_DEVICE_ID; switch(fe->fe_chip_id){ case DEVICE_ID_DS26528: fe->fe_max_ports = 8; @@ -481,7 +466,7 @@ static int sdla_ds_te1_device_id(sdla_fe_t* fe) fe->name, FE_MEDIA_DECODE(fe), fe->fe_chip_id, - value); + READ_REG_LINE(0, REG_IDR)); return -EINVAL; } return 0; @@ -579,7 +564,7 @@ static int sdla_ds_e1_set_sig_mode(sdla_fe_t *fe, int verbose) /* CAS signalling mode */ if (verbose){ - DEBUG_EVENT("%s: Enabling CAS Signalling mode!\n", + DEBUG_EVENT("%s: Enable E1 CAS Signalling mode!\n", fe->name); } value = READ_REG(REG_RCR1); @@ -592,12 +577,16 @@ static int sdla_ds_e1_set_sig_mode(sdla_fe_t *fe, int verbose) /* CCS signalling mode */ if (verbose){ - DEBUG_TEST("%s: Enabling CCS Signalling mode!\n", + DEBUG_EVENT("%s: Enable E1 CCS Signalling mode!\n", fe->name); } WAN_TE1_SIG_MODE(fe) = WAN_TE1_SIG_CCS; value = READ_REG(REG_RCR1); WRITE_REG(REG_RCR1, value | BIT_RCR1_E1_RSIGM); + + value = READ_REG(REG_TCR1); + WRITE_REG(REG_TCR1, value & ~BIT_TCR1_E1_T16S); + } return 0; } @@ -655,6 +644,7 @@ static int sdla_ds_te1_global_unconfig(void* pfe) WRITE_REG_LINE(0, REG_GFIMR, 0x00); WRITE_REG_LINE(0, REG_GLIMR, 0x00); WRITE_REG_LINE(0, REG_GBIMR, 0x00); + WP_DELAY(1000); WRITE_REG_LINE(0, REG_GLSRR, 0xFF); WRITE_REG_LINE(0, REG_GFSRR, 0xFF); @@ -664,237 +654,233 @@ static int sdla_ds_te1_global_unconfig(void* pfe) } /****************************************************************************** -** sdla_ds_te1_cfg_verify() +** sdla_ds_t1_cfg_verify() ** -** Description: Verify T1/E1 Front-End configuration -** Arguments: -** Returns: 0 - successfully, otherwise -EINVAL. +** Description: Verify T1 Front-End configuration +** Arguments: +** Returns: 0 - successfully, otherwise -EINVAL. *******************************************************************************/ -static int sdla_ds_te1_cfg_verify(void* pfe) +static int sdla_ds_t1_cfg_verify(void* pfe) { - sdla_fe_t *fe = (sdla_fe_t*)pfe; + sdla_fe_t *fe = (sdla_fe_t*)pfe; - - if (IS_T1_FEMEDIA(fe) || IS_J1_FEMEDIA(fe)){ - - /* Verify FE framing type */ - switch(WAN_FE_FRAME(fe)){ - case WAN_FR_D4: case WAN_FR_ESF: case WAN_FR_UNFRAMED: - break; - case WAN_FR_NONE: - DEBUG_EVENT("%s: Defaulting T1 Frame = ESF\n", + /* Verify FE framing type */ + switch(WAN_FE_FRAME(fe)){ + case WAN_FR_D4: case WAN_FR_ESF: case WAN_FR_UNFRAMED: + break; + case WAN_FR_NONE: + DEBUG_EVENT("%s: Defaulting T1 Frame = ESF\n", fe->name); - WAN_FE_FRAME(fe) = WAN_FR_ESF; - break; - default: - DEBUG_EVENT("%s: Error: Invalid %s FE Framing type (%X)\n", + WAN_FE_FRAME(fe) = WAN_FR_ESF; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Framing type (%X)\n", fe->name, FE_MEDIA_DECODE(fe), WAN_FE_FRAME(fe)); - return -EINVAL; - break; - } - - /* Verify FE line code type */ - switch(WAN_FE_LCODE(fe)){ - case WAN_LCODE_B8ZS: case WAN_LCODE_AMI: - break; - case WAN_LCODE_NONE: - DEBUG_EVENT("%s: Defaulting T1 Line Code = B8ZS\n", - fe->name); - WAN_FE_LCODE(fe) = WAN_LCODE_B8ZS; - break; - default: - DEBUG_EVENT("%s: Error: Invalid %s FE Line code type (%X)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_FE_LCODE(fe)); - return -EINVAL; - break; - } - - /* Verify LBO */ - switch(WAN_TE1_LBO(fe)) { - case WAN_T1_LBO_0_DB: case WAN_T1_LBO_75_DB: - case WAN_T1_LBO_15_DB: case WAN_T1_LBO_225_DB: - case WAN_T1_0_133: case WAN_T1_0_110: - case WAN_T1_133_266: case WAN_T1_110_220: - case WAN_T1_266_399: case WAN_T1_220_330: - case WAN_T1_399_533: case WAN_T1_330_440: case WAN_T1_440_550: - case WAN_T1_533_655: case WAN_T1_550_660: - break; - case WAN_T1_LBO_NONE: - DEBUG_EVENT("%s: Defaulting T1 LBO = 0 db\n", - fe->name); - WAN_TE1_LBO(fe) = WAN_T1_LBO_0_DB; - break; - default: - DEBUG_EVENT("%s: Error: Invalid %s LBO value (%X)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_TE1_LBO(fe)); - return -EINVAL; - break; - } - - - if (WAN_TE1_HI_MODE(fe)){ - switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ - case WAN_TE1_RX_SLEVEL_30_DB: case WAN_TE1_RX_SLEVEL_225_DB: - case WAN_TE1_RX_SLEVEL_175_DB: case WAN_TE1_RX_SLEVEL_12_DB: - break; - case WAN_TE1_RX_SLEVEL_NONE: - DEBUG_EVENT("%s: Defaulting T1 Rx Sens. Gain= 30 db\n", - fe->name); - fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_30_DB; - break; - default: - DEBUG_EVENT( - "%s: Error: Invalid T1 Rx Sensitivity Gain (%d).\n", - fe->name, - fe->fe_cfg.cfg.te_cfg.rx_slevel); - return -EINVAL; - } - }else{ - switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ - case WAN_TE1_RX_SLEVEL_36_DB: case WAN_TE1_RX_SLEVEL_30_DB: - case WAN_TE1_RX_SLEVEL_18_DB: case WAN_TE1_RX_SLEVEL_12_DB: - break; - case WAN_TE1_RX_SLEVEL_NONE: - DEBUG_EVENT("%s: Defaulting T1 Rx Sens. Gain= 36 db\n", - fe->name); - fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_36_DB; - break; - default: - DEBUG_EVENT( - "%s: Error: Invalid T1 Rx Sensitivity Gain (%d).\n", - fe->name, - fe->fe_cfg.cfg.te_cfg.rx_slevel); - return -EINVAL; - } - } - - - }else if (IS_E1_FEMEDIA(fe)){ - - /* Verify FE framing type */ - switch(WAN_FE_FRAME(fe)){ - case WAN_FR_NCRC4: case WAN_FR_CRC4: case WAN_FR_UNFRAMED: - break; - case WAN_FR_NONE: - DEBUG_EVENT("%s: Defaulting E1 Frame = CRC4\n", - fe->name); - WAN_FE_FRAME(fe) = WAN_FR_CRC4; - break; - default: - DEBUG_EVENT("%s: Error: Invalid %s FE Framing type (%X)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_FE_FRAME(fe)); - return -EINVAL; - break; - } - - /* Verify FE line code type */ - switch(WAN_FE_LCODE(fe)){ - case WAN_LCODE_HDB3: case WAN_LCODE_AMI: - break; - case WAN_LCODE_NONE: - DEBUG_EVENT("%s: Defaulting E1 Line Code = HDB3\n", - fe->name); - WAN_FE_LCODE(fe) = WAN_LCODE_HDB3; - break; - default: - DEBUG_EVENT("%s: Error: Invalid %s FE Line code type (%X)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_FE_LCODE(fe)); - return -EINVAL; - break; - } - - /* Verify LBO */ - switch(WAN_TE1_LBO(fe)) { - case WAN_E1_120: case WAN_E1_75: - break; - case WAN_T1_LBO_NONE: - DEBUG_EVENT("%s: Defaulting E1 LBO = 120 OH\n", - fe->name); - WAN_TE1_LBO(fe) = WAN_E1_120; - break; - default: - DEBUG_EVENT("%s: Error: Invalid %s LBO value (%X)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_TE1_LBO(fe)); - return -EINVAL; - break; - } - - switch(WAN_TE1_SIG_MODE(fe)){ - case WAN_TE1_SIG_CAS: case WAN_TE1_SIG_CCS: - break; - case WAN_TE1_SIG_NONE: - DEBUG_EVENT("%s: Defaulting E1 Signalling = CCS\n", - fe->name); - WAN_TE1_SIG_MODE(fe) = WAN_TE1_SIG_CCS; - break; - default: - DEBUG_EVENT("%s: Error: Invalid E1 Signalling type (%X)\n", - fe->name, - WAN_TE1_SIG_MODE(fe)); - return -EINVAL; - break; - } - - - - if (WAN_TE1_HI_MODE(fe)){ - switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ - case WAN_TE1_RX_SLEVEL_30_DB: case WAN_TE1_RX_SLEVEL_225_DB: - case WAN_TE1_RX_SLEVEL_175_DB: case WAN_TE1_RX_SLEVEL_12_DB: - break; - case WAN_TE1_RX_SLEVEL_NONE: - DEBUG_EVENT("%s: Defaulting E1 Rx Sens. Gain= 30 db\n", - fe->name); - fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_30_DB; - break; - default: - DEBUG_EVENT( - "%s: Error: Invalid E1 Rx Sensitivity Gain (%d).\n", - fe->name, - fe->fe_cfg.cfg.te_cfg.rx_slevel); - return -EINVAL; - } - }else{ - switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ - case WAN_TE1_RX_SLEVEL_43_DB: case WAN_TE1_RX_SLEVEL_30_DB: - case WAN_TE1_RX_SLEVEL_18_DB: case WAN_TE1_RX_SLEVEL_12_DB: - break; - case WAN_TE1_RX_SLEVEL_NONE: - DEBUG_EVENT("%s: Defaulting E1 Rx Sens. Gain= 43 db\n", - fe->name); - fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_43_DB; - break; - default: - DEBUG_EVENT( - "%s: Error: Invalid E1 Rx Sensitivity Gain (%d).\n", - fe->name, - fe->fe_cfg.cfg.te_cfg.rx_slevel); - return -EINVAL; - } - - } - - }else{ - DEBUG_EVENT("%s: Error: Invalid FE Media type (%X)\n", - fe->name, - WAN_FE_MEDIA(fe)); return -EINVAL; + break; } + + /* Verify FE line code type */ + switch(WAN_FE_LCODE(fe)){ + case WAN_LCODE_B8ZS: case WAN_LCODE_AMI: + break; + case WAN_LCODE_NONE: + DEBUG_EVENT("%s: Defaulting T1 Line Code = B8ZS\n", + fe->name); + WAN_FE_LCODE(fe) = WAN_LCODE_B8ZS; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Line code type (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_FE_LCODE(fe)); + return -EINVAL; + break; + } + + /* Verify LBO */ + switch(WAN_TE1_LBO(fe)) { + case WAN_T1_LBO_0_DB: case WAN_T1_LBO_75_DB: + case WAN_T1_LBO_15_DB: case WAN_T1_LBO_225_DB: + case WAN_T1_0_133: case WAN_T1_133_266: case WAN_T1_110_220: + case WAN_T1_266_399: case WAN_T1_220_330: + case WAN_T1_399_533: case WAN_T1_330_440: case WAN_T1_440_550: + case WAN_T1_533_655: case WAN_T1_550_660: + break; + case WAN_T1_LBO_NONE: + DEBUG_EVENT("%s: Defaulting T1 LBO = 0 db\n", + fe->name); + WAN_TE1_LBO(fe) = WAN_T1_LBO_0_DB; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s LBO value (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_TE1_LBO(fe)); + return -EINVAL; + break; + } + + if (WAN_TE1_HI_MODE(fe)){ + switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ + case WAN_TE1_RX_SLEVEL_30_DB: case WAN_TE1_RX_SLEVEL_225_DB: + case WAN_TE1_RX_SLEVEL_175_DB: case WAN_TE1_RX_SLEVEL_12_DB: + break; + case WAN_TE1_RX_SLEVEL_NONE: + DEBUG_EVENT("%s: Defaulting T1 Rx Sens. Gain= 12 db\n", + fe->name); + fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_12_DB; + break; + default: + DEBUG_EVENT( + "%s: Error: Invalid T1 Rx Sensitivity Gain (%d).\n", + fe->name, + fe->fe_cfg.cfg.te_cfg.rx_slevel); + return -EINVAL; + } + }else{ + switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ + case WAN_TE1_RX_SLEVEL_36_DB: case WAN_TE1_RX_SLEVEL_30_DB: + case WAN_TE1_RX_SLEVEL_18_DB: case WAN_TE1_RX_SLEVEL_12_DB: + break; + case WAN_TE1_RX_SLEVEL_NONE: + DEBUG_EVENT("%s: Defaulting T1 Rx Sens. Gain= 36 db\n", + fe->name); + fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_36_DB; + break; + default: + DEBUG_EVENT( + "%s: Error: Invalid T1 Rx Sensitivity Gain (%d).\n", + fe->name, + fe->fe_cfg.cfg.te_cfg.rx_slevel); + return -EINVAL; + } + } + return 0; } +/****************************************************************************** +** sdla_ds_e1_cfg_verify() +** +** Description: Verify E1 Front-End configuration +** Arguments: +** Returns: 0 - successfully, otherwise -EINVAL. +*******************************************************************************/ +static int sdla_ds_e1_cfg_verify(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + /* Verify FE framing type */ + switch(WAN_FE_FRAME(fe)){ + case WAN_FR_NCRC4: case WAN_FR_CRC4: case WAN_FR_UNFRAMED: + break; + case WAN_FR_NONE: + DEBUG_EVENT("%s: Defaulting E1 Frame = CRC4\n", + fe->name); + WAN_FE_FRAME(fe) = WAN_FR_CRC4; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Framing type (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_FE_FRAME(fe)); + return -EINVAL; + break; + } + /* Verify FE line code type */ + switch(WAN_FE_LCODE(fe)){ + case WAN_LCODE_HDB3: case WAN_LCODE_AMI: + break; + case WAN_LCODE_NONE: + DEBUG_EVENT("%s: Defaulting E1 Line Code = HDB3\n", + fe->name); + WAN_FE_LCODE(fe) = WAN_LCODE_HDB3; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Line code type (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_FE_LCODE(fe)); + return -EINVAL; + break; + } + + /* Verify LBO */ + switch(WAN_TE1_LBO(fe)) { + case WAN_E1_120: case WAN_E1_75: + break; + case WAN_T1_LBO_NONE: + DEBUG_EVENT("%s: Defaulting E1 LBO = 120 OH\n", + fe->name); + WAN_TE1_LBO(fe) = WAN_E1_120; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s LBO value (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_TE1_LBO(fe)); + return -EINVAL; + break; + } + + switch(WAN_TE1_SIG_MODE(fe)){ + case WAN_TE1_SIG_CAS: case WAN_TE1_SIG_CCS: + break; + case WAN_TE1_SIG_NONE: + DEBUG_EVENT("%s: Defaulting E1 Signalling = CCS\n", + fe->name); + WAN_TE1_SIG_MODE(fe) = WAN_TE1_SIG_CCS; + break; + default: + DEBUG_EVENT("%s: Error: Invalid E1 Signalling type (%X)\n", + fe->name, + WAN_TE1_SIG_MODE(fe)); + return -EINVAL; + break; + } + + if (WAN_TE1_HI_MODE(fe)){ + switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ + case WAN_TE1_RX_SLEVEL_30_DB: case WAN_TE1_RX_SLEVEL_225_DB: + case WAN_TE1_RX_SLEVEL_175_DB: case WAN_TE1_RX_SLEVEL_12_DB: + break; + case WAN_TE1_RX_SLEVEL_NONE: + DEBUG_EVENT("%s: Defaulting E1 Rx Sens. Gain= 12 db\n", + fe->name); + fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_12_DB; + break; + default: + DEBUG_EVENT( + "%s: Error: Invalid T1 Rx Sensitivity Gain (%d).\n", + fe->name, + fe->fe_cfg.cfg.te_cfg.rx_slevel); + return -EINVAL; + } + }else{ + switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ + case WAN_TE1_RX_SLEVEL_43_DB: case WAN_TE1_RX_SLEVEL_30_DB: + case WAN_TE1_RX_SLEVEL_18_DB: case WAN_TE1_RX_SLEVEL_12_DB: + break; + case WAN_TE1_RX_SLEVEL_NONE: + DEBUG_EVENT("%s: Defaulting E1 Rx Sens. Gain= 43 db\n", + fe->name); + fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_43_DB; + break; + default: + DEBUG_EVENT( + "%s: Error: Invalid T1 Rx Sensitivity Gain (%d).\n", + fe->name, + fe->fe_cfg.cfg.te_cfg.rx_slevel); + return -EINVAL; + } + + } + + return 0; +} /****************************************************************************** ** sdla_ds_te1_chip_config() @@ -932,7 +918,7 @@ static int sdla_ds_te1_chip_config(void* pfe) /* Enable Rx Framer */ WRITE_REG(REG_RMMR, BIT_RMMR_FRM_EN); if (IS_FE_TXTRISTATE(fe)){ - DEBUG_EVENT("%s: Tx Disabled (tri-state mode)\n", + DEBUG_EVENT("%s: Disable TX (tri-state mode)\n", fe->name); }else{ /* Enable Tx Framer */ @@ -946,7 +932,7 @@ static int sdla_ds_te1_chip_config(void* pfe) /* Enable Rx Framer */ WRITE_REG(REG_RMMR, (BIT_RMMR_FRM_EN | BIT_RMMR_T1E1)); if (IS_FE_TXTRISTATE(fe)){ - DEBUG_EVENT("%s: Tx Disabled (tri-state mode)\n", + DEBUG_EVENT("%s: Disable TX (tri-state mode)\n", fe->name); }else{ /* Enable Tx Framer */ @@ -964,10 +950,10 @@ static int sdla_ds_te1_chip_config(void* pfe) value = READ_REG(REG_TCR2); WRITE_REG(REG_TCR2, value & ~BIT_TCR2_T1_TFDLS); - + value = READ_REG(REG_TCR3); WRITE_REG(REG_TCR3, value | BIT_TCR3_TFM); - + WRITE_REG(REG_T1TFDL, 0x1c); break; @@ -976,11 +962,33 @@ static int sdla_ds_te1_chip_config(void* pfe) value |= BIT_RCR1_T1_SYNCC; value &= ~BIT_RCR1_T1_RFM; WRITE_REG(REG_RCR1, value); - + value = READ_REG(REG_TCR3); value &= ~BIT_TCR3_TFM; WRITE_REG(REG_TCR3, value); break; + + case WAN_FR_SLC96: + value = READ_REG(REG_RCR1); + value |= (BIT_RCR1_T1_RFM|BIT_RCR1_T1_SYNCC); + value &= ~BIT_RCR1_T1_SYNCT; + WRITE_REG(REG_RCR1, value); + + value = READ_REG(REG_T1RCR2); + WRITE_REG(REG_T1RCR2, value | BIT_T1RCR2_RSLC96); + + value = READ_REG(REG_TCR1); + value &= ~BIT_TCR1_T1_TFPT; + WRITE_REG(REG_TCR1, value); + + value = READ_REG(REG_TCR2); + value |= BIT_TCR2_T1_TSLC96; + value &= ~BIT_TCR2_T1_TFDLS; + WRITE_REG(REG_TCR2, value); + + value = READ_REG(REG_TCR3); + WRITE_REG(REG_TCR3, value | BIT_TCR3_TFM); + break; case WAN_FR_NCRC4: break; case WAN_FR_CRC4: @@ -988,6 +996,7 @@ static int sdla_ds_te1_chip_config(void* pfe) WRITE_REG(REG_RCR1, value | BIT_RCR1_E1_RCRC4); value = READ_REG(REG_TCR1); WRITE_REG(REG_TCR1, value | BIT_TCR1_E1_TCRC4); + /* EBIT: Enable auto E-bit support */ value = READ_REG(REG_TCR2); WRITE_REG(REG_TCR2, value | BIT_TCR2_E1_AEBE); break; @@ -999,10 +1008,8 @@ static int sdla_ds_te1_chip_config(void* pfe) WRITE_REG(REG_RCR1, value | BIT_RCR1_E1_SYNCE); break; default: - DEBUG_EVENT("%s: Error: Invalid %s Frame mode (%X:%s)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_FE_FRAME(fe), FE_FRAME_DECODE(fe)); + DEBUG_EVENT("%s: Unsupported DS Frame mode (%X)\n", + fe->name, WAN_FE_FRAME(fe)); return -EINVAL; } @@ -1040,10 +1047,8 @@ static int sdla_ds_te1_chip_config(void* pfe) break; default: - DEBUG_EVENT("%s: Error: Invalid %s Line code value (%X:%s)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_FE_LCODE(fe), FE_LCODE_DECODE(fe)); + DEBUG_EVENT("%s: Unsupported DS Line code mode (%X)\n", + fe->name, WAN_FE_LCODE(fe)); return -EINVAL; } @@ -1072,9 +1077,11 @@ static int sdla_ds_te1_chip_config(void* pfe) WRITE_REG(REG_TIOCR, value); } #endif + if (IS_E1_FEMEDIA(fe)){ //WRITE_REG(REG_E1TAF, 0x1B); //WRITE_REG(REG_E1TNAF, 0x40); + WRITE_REG(REG_E1TAF, 0x1B); WRITE_REG(REG_E1TNAF, 0x5F); WRITE_REG(REG_E1TSa4, 0x00); @@ -1093,8 +1100,9 @@ static int sdla_ds_te1_chip_config(void* pfe) } } + if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ - /* Set INIT_DONE (not unframed mode) */ + /* Set INIT_DONE (for not unframed mode) */ value = READ_REG(REG_RMMR); WRITE_REG(REG_RMMR, value | BIT_RMMR_INIT_DONE); value = READ_REG(REG_TMMR); @@ -1110,7 +1118,6 @@ static int sdla_ds_te1_chip_config(void* pfe) } value = 0x00; - switch(WAN_TE1_LBO(fe)) { case WAN_T1_LBO_0_DB: value = 0x00; @@ -1124,25 +1131,19 @@ static int sdla_ds_te1_chip_config(void* pfe) case WAN_T1_LBO_225_DB: value = BIT_LTITSR_L2 | BIT_LTITSR_L1 | BIT_LTITSR_L0; break; - case WAN_T1_0_133: - case WAN_T1_0_110: + case WAN_T1_0_133: case WAN_T1_0_110: value = 0x00; break; - case WAN_T1_133_266: - case WAN_T1_110_220: + case WAN_T1_133_266: case WAN_T1_110_220: value = BIT_LTITSR_L0; break; - case WAN_T1_266_399: - case WAN_T1_220_330: + case WAN_T1_266_399: case WAN_T1_220_330: value = BIT_LTITSR_L1; break; - case WAN_T1_399_533: - case WAN_T1_330_440: - case WAN_T1_440_550: + case WAN_T1_399_533: case WAN_T1_330_440: value = BIT_LTITSR_L1 | BIT_LTITSR_L0; break; - case WAN_T1_533_655: - case WAN_T1_550_660: + case WAN_T1_533_655: case WAN_T1_440_550: case WAN_T1_550_660: value = BIT_LTITSR_L2; break; case WAN_E1_120: @@ -1152,11 +1153,10 @@ static int sdla_ds_te1_chip_config(void* pfe) value = 0x00; break; default: - DEBUG_EVENT("%s: Error: Invalid %s LBO value (%X)\n", - fe->name, - FE_MEDIA_DECODE(fe), - WAN_TE1_LBO(fe)); - return -EINVAL; + if (IS_E1_FEMEDIA(fe)){ + value = BIT_LTITSR_L0; + } + break; } if (IS_T1_FEMEDIA(fe)){ WRITE_REG(REG_LTITSR, value | BIT_LTITSR_TIMPL0); @@ -1189,9 +1189,12 @@ static int sdla_ds_te1_chip_config(void* pfe) fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_30_DB; break; } - DEBUG_EVENT("%s: Rx Sensitivity Gain %s (High Impedence mode).\n", - fe->name, - WAN_TE1_RX_SLEVEL_DECODE(fe->fe_cfg.cfg.te_cfg.rx_slevel)); + DEBUG_EVENT( + "%s: Rx Sensitivity Gain %s%s (High Impedence mode).\n", + fe->name, + WAN_TE1_RX_SLEVEL_DECODE(fe->fe_cfg.cfg.te_cfg.rx_slevel), + (fe->fe_cfg.cfg.te_cfg.rx_slevel==WAN_TE1_RX_SLEVEL_30_DB)? + " (default)":""); }else{ switch(fe->fe_cfg.cfg.te_cfg.rx_slevel){ case WAN_TE1_RX_SLEVEL_12_DB: @@ -1204,20 +1207,18 @@ static int sdla_ds_te1_chip_config(void* pfe) break; case WAN_TE1_RX_SLEVEL_36_DB: case WAN_TE1_RX_SLEVEL_43_DB: + value |= (BIT_LRISMR_RSMS1 | BIT_LRISMR_RSMS0); + break; default: /* set default value */ - value |= (BIT_LRISMR_RSMS1 | BIT_LRISMR_RSMS0); + fe->fe_cfg.cfg.te_cfg.rx_slevel = WAN_TE1_RX_SLEVEL_12_DB; break; } - DEBUG_EVENT("%s: Rx Sensitivity Gain %s%s.\n", fe->name, WAN_TE1_RX_SLEVEL_DECODE(fe->fe_cfg.cfg.te_cfg.rx_slevel), - ((IS_T1_FEMEDIA(fe) && (fe->fe_cfg.cfg.te_cfg.rx_slevel==WAN_TE1_RX_SLEVEL_36_DB)) || - (IS_E1_FEMEDIA(fe) && (fe->fe_cfg.cfg.te_cfg.rx_slevel==WAN_TE1_RX_SLEVEL_43_DB))) ? - " (default)": ""); + (fe->fe_cfg.cfg.te_cfg.rx_slevel==WAN_TE1_RX_SLEVEL_12_DB)? + " (default)":""); } - - if (IS_T1_FEMEDIA(fe)){ value |= BIT_LRISMR_RIMPM0; }else{ @@ -1226,7 +1227,6 @@ static int sdla_ds_te1_chip_config(void* pfe) value |= BIT_LRISMR_RIMPM1 | BIT_LRISMR_RIMPM0; } } - WRITE_REG(REG_LRISMR, value); if (IS_E1_FEMEDIA(fe) && WAN_TE1_LBO(fe) == WAN_E1_120){ @@ -1234,7 +1234,7 @@ static int sdla_ds_te1_chip_config(void* pfe) ** Adjust DAC gain (-4.88%) */ WRITE_REG(REG_LTXLAE, 0x09); } - + /* Additional front-end settings */ value = READ_REG(REG_ERCNT); if (WAN_FE_LCODE(fe) == WAN_LCODE_AMI){ @@ -1279,6 +1279,74 @@ static int sdla_ds_te1_chip_config(void* pfe) return 0; } +#if 0 +/* + ****************************************************************************** + * sdla_ds_te1_chip_config_verify() + * + * Description: Configure Sangoma 8 ports T1/E1 board + * Arguments: + * Returns: WANTRUE - TE1 configred successfully, otherwise WAN_FALSE. + ****************************************************************************** + */ +static int sdla_ds_te1_chip_config_verify(sdla_fe_t *fe) +{ + int e1_mode = 0; + u_int8_t rmmr, tmmr, value = 0x00; + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + rmmr = READ_REG(REG_RMMR); + DEBUG_EVENT("%s: RX: %s mode\n", + fe->name, (rmmr & BIT_RMMR_T1E1) ? "E1" : "T1"); + e1_mode = (value & BIT_RMMR_T1E1) ? 1 : 0; + + tmmr = READ_REG(REG_TMMR); + DEBUG_EVENT("%s: TX: %s mode\n", + fe->name, (tmmr & BIT_TMMR_T1E1) ? "E1" : "T1"); + if ((rmmr & BIT_RMMR_T1E1) && (tmmr & BIT_RMMR_T1E1)){ + e1_mode = 1; + } else if ((rmmr & BIT_RMMR_T1E1) || (tmmr & BIT_RMMR_T1E1)){ + DEBUG_EVENT( + "%s: ERROR: RX/TX has different mode configuration (%02X:%02X)!\n", + fe->name, rmmr, tmmr); + return -EINVAL; + } + + if (e1_mode){ + value = READ_REG(REG_RCR1); + DEBUG_EVENT("%s: RX Ctrl Reg: %s %s %s\n", + fe->name, + (value & BIT_RCR1_E1_RCRC4) ? "CRC4" : "NCRC4", + (value & BIT_RCR1_E1_RHDB3) ? "HDB3": "AMI", + (value & BIT_RCR1_E1_RSIGM) ? "CCS" : "CAS"); + value = READ_REG(REG_TCR1); + DEBUG_EVENT("%s: TX Ctrl Reg: %s %s %s\n", + fe->name, + (value & BIT_TCR1_E1_TCRC4) ? "CRC4" : "NCRC4", + (value & BIT_TCR1_E1_THDB3) ? "HDB3": "AMI", + (value & BIT_TCR1_E1_T16S) ? "CAS" : "CCS"); + }else{ + value = READ_REG(REG_RCR1); + DEBUG_EVENT("%s: RX Ctrl Reg: %s %s\n", + fe->name, + (value & BIT_RCR1_T1_RFM) ? "D4" : "ESF", + (value & BIT_RCR1_T1_RB8ZS) ? "B8ZS": "AMI"); + value = READ_REG(REG_TCR1); + DEBUG_EVENT("%s: TX Ctrl Reg: %s\n", + fe->name, + (value & BIT_TCR1_T1_TB8ZS) ? "B8ZS": "AMI"); + value = READ_REG(REG_TCR3); + DEBUG_EVENT("%s: TX Ctrl Reg: %s\n", + fe->name, + (value & BIT_TCR3_TFM) ? "D4" : "ESF"); + } + + return 0; +} +#endif + /* ****************************************************************************** * sdla_ds_te1_config() @@ -1290,17 +1358,12 @@ static int sdla_ds_te1_chip_config(void* pfe) */ static int sdla_ds_te1_config(void* pfe) { - sdla_fe_t *fe = (sdla_fe_t*)pfe; + int err = 0; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - /* Initial FE state */ - fe->fe_status = FE_UNITIALIZED; //FE_DISCONNECTED; - WAN_LIST_INIT(&fe->event); - wan_spin_lock_init(&fe->lock); - /* Revision/Chip ID (Reg. 0x0D) */ if (sdla_ds_te1_device_id(fe)) return -EINVAL; switch(fe->fe_chip_id){ @@ -1334,7 +1397,17 @@ static int sdla_ds_te1_config(void* pfe) break; } - if (sdla_ds_te1_cfg_verify(fe)) return -EINVAL; + if (IS_T1_FEMEDIA(fe) || IS_J1_FEMEDIA(fe)){ + err = sdla_ds_t1_cfg_verify(fe); + }else if (IS_E1_FEMEDIA(fe)){ + err = sdla_ds_e1_cfg_verify(fe); + }else{ + DEBUG_EVENT("%s: Error: Invalid FE Media type (%X)\n", + fe->name, + WAN_FE_MEDIA(fe)); + err =-EINVAL; + } + if (err) return -EINVAL; DEBUG_EVENT("%s: Configuring DS %s %s FE\n", fe->name, @@ -1346,7 +1419,7 @@ static int sdla_ds_te1_config(void* pfe) FE_LCODE_DECODE(fe), FE_FRAME_DECODE(fe), TE_LBO_DECODE(fe)); - DEBUG_EVENT("%s: Clk %s:%d, Ch %X\n", + DEBUG_EVENT("%s: Clk %s:%d, Channels: %X\n", fe->name, TE_CLK_DECODE(fe), WAN_TE1_REFCLK(fe), @@ -1360,8 +1433,12 @@ static int sdla_ds_te1_config(void* pfe) if (fe->fe_cfg.poll_mode == WANOPT_YES){ sdla_t *card = (sdla_t*)fe->card; DEBUG_EVENT("%s: FE Poll driven\n", - fe->name); - card->fe_no_intr = 1; + fe->name); + card->fe_no_intr = 1; /* disable global front interrupt */ + } + if (fe->fe_cfg.cfg.te_cfg.ignore_yel_alarm == WANOPT_YES){ + DEBUG_EVENT("%s: YEL alarm ignored\n", + fe->name); } if (sdla_ds_te1_chip_config(fe)){ return -EINVAL; @@ -1372,18 +1449,15 @@ static int sdla_ds_te1_config(void* pfe) sdla_ds_te1_flush_pmon(fe); - /* LIU alarms are available in A108 */ - fe->fe_stats.liu_alarms = WAN_TE_BIT_LIU_ALARM; + fe->fe_alarm = WAN_TE_BIT_LIU_ALARM; wan_set_bit(TE_CONFIGURED,(void*)&fe->te_param.critical); #if 0 -/* Do not enable it here */ +/* FIXME: Enable all interrupt only when link is connected (event global) */ /* Enable interrupts */ - sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_GLOBAL, WAN_FE_INTR_ENABLE, 0x00); - /* Enable manual update pmon counter */ - sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_PMON, WAN_FE_INTR_MASK, 0x00); -#endif + sdla_ds_te1_intr_ctrl(fe, 0, WAN_TE_INTR_GLOBAL, WAN_FE_INTR_ENABLE, 0x00); +#endif return 0; } @@ -1433,8 +1507,9 @@ static int sdla_ds_te1_post_init(void* pfe) static int sdla_ds_te1_pre_release(void* pfe) { sdla_fe_t *fe = (sdla_fe_t*)pfe; - sdla_fe_timer_event_t *fe_event; + sdla_fe_timer_event_t *fe_event = NULL; wan_smp_flag_t smp_flags; + int empty = 0; /* Kill TE timer poll command */ wan_set_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical); @@ -1442,14 +1517,19 @@ static int sdla_ds_te1_pre_release(void* pfe) wan_del_timer(&fe->timer); } wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); - wan_spin_lock_irq(&fe->lock,&smp_flags); - while(!WAN_LIST_EMPTY(&fe->event)){ - fe_event = WAN_LIST_FIRST(&fe->event); - WAN_LIST_REMOVE(fe_event, next); + do{ + wan_spin_lock_irq(&fe->lockirq,&smp_flags); + if (!WAN_LIST_EMPTY(&fe->event)){ + fe_event = WAN_LIST_FIRST(&fe->event); + WAN_LIST_REMOVE(fe_event, next); + }else{ + empty = 1; + } + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); + /* Free should be called not from spin_lock_irq (windows) !!!! */ if (fe_event) wan_free(fe_event); - } - fe->event_map = 0; - wan_spin_unlock_irq(&fe->lock,&smp_flags); + fe_event = NULL; + }while(!empty); return 0; } @@ -1468,8 +1548,8 @@ static int sdla_ds_te1_unconfig(void* pfe) /* Verify if FE timer is stopped */ if (!wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ - DEBUG_EVENT("%s: Front-End timer is not stopped!\n", - fe->name); + DEBUG_EVENT("%s: %s(): Front-End timer is not stopped!\n", + fe->name, __FUNCTION__); return -EINVAL; } @@ -1479,7 +1559,7 @@ static int sdla_ds_te1_unconfig(void* pfe) /* FIXME: Alex to disable interrupts here */ sdla_ds_te1_disable_irq(fe); - + /* Set Rx Framer soft reset */ WRITE_REG(REG_RMMR, BIT_RMMR_SFTRST); /* Set Tx Framer soft reset */ @@ -1511,10 +1591,10 @@ static int sdla_ds_te1_disable_irq(void* pfe) sdla_fe_t *fe = (sdla_fe_t*)pfe; if (fe->fe_cfg.poll_mode == WANOPT_NO){ - /* Disable interrupts here */ + /* Disable all interrupts */ sdla_ds_te1_intr_ctrl( fe, 0, - (WAN_TE_INTR_GLOBAL|WAN_TE_INTR_BASIC|WAN_TE_INTR_PMON), + (WAN_TE_INTR_GLOBAL|WAN_TE_INTR_BASIC|WAN_TE_INTR_PMON), WAN_FE_INTR_MASK, 0x00); } return 0; @@ -1568,14 +1648,19 @@ sdla_ds_te1_sigctrl(sdla_fe_t *fe, int sig_mode, unsigned long ch_map, int mode) ** Returns: 1 - the port is connected ** 0 - the port is disconnected ******************************************************************************/ -static int sdla_ds_t1_is_alarm(sdla_fe_t *fe, unsigned long alarms) +static u_int32_t sdla_ds_t1_is_alarm(sdla_fe_t *fe, u_int32_t alarms) { - /* NC: Bring the link down if we re in SC mode */ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ - return 1; + u_int32_t alarm_mask = WAN_TE1_FRAMED_ALARMS; + + /* Alex Feb 27, 2008 + ** Special case for customer that uses + ** YEL alarm for protocol control */ + if (fe->fe_cfg.cfg.te_cfg.ignore_yel_alarm == WANOPT_NO){ + alarm_mask |= WAN_TE_BIT_RAI_ALARM; } - return (alarms & WAN_TE1_FRAMED_ALARMS); + return (alarms & alarm_mask); } + /****************************************************************************** ** sdla_ds_e1_is_alarm() ** @@ -1584,89 +1669,78 @@ static int sdla_ds_t1_is_alarm(sdla_fe_t *fe, unsigned long alarms) ** Returns: 1 - the port is connected ** 0 - the port is disconnected ******************************************************************************/ -static int sdla_ds_e1_is_alarm(sdla_fe_t *fe, unsigned long alarms) +static u_int32_t sdla_ds_e1_is_alarm(sdla_fe_t *fe, u_int32_t alarms) { - if (WAN_FE_FRAME(fe) == WAN_FR_UNFRAMED){ - if (!fe->te_param.lb_mode && - (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_OC || - fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC || - fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_LOS)){ - return 1; - } - return (alarms & WAN_TE1_UNFRAMED_ALARMS); - } + u_int32_t alarm_mask = 0x00; - /* NC: Bring the link down if we re in SC mode */ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ - return 1; + if (WAN_FE_FRAME(fe) == WAN_FR_UNFRAMED){ + alarm_mask = WAN_TE1_UNFRAMED_ALARMS; + if (!fe->te_param.lb_mode){ + alarm_mask |= ( WAN_TE_BIT_LIU_ALARM_OC | + WAN_TE_BIT_LIU_ALARM_SC | + WAN_TE_BIT_LIU_ALARM_LOS); + } + }else{ + alarm_mask = WAN_TE1_FRAMED_ALARMS; } - return (alarms & WAN_TE1_FRAMED_ALARMS); + return (alarms & alarm_mask); } -/* - ****************************************************************************** - * sdla_ds_te1_set_status() - * - * Description: Set T1/E1 status. Enable OOF and LCV interrupt (if status - * changed to disconnected. - * Arguments: - * Returns: - ****************************************************************************** - */ -static void sdla_ds_te1_set_status(sdla_fe_t* fe, unsigned long alarms) +/****************************************************************************** +** sdla_ds_te1_set_status() +** +** Description: Set T1/E1 status. Enable OOF and LCV interrupt (if status +** changed to disconnected. +** Arguments: +** Returns: +******************************************************************************/ +static void sdla_ds_te1_set_status(sdla_fe_t* fe, u_int32_t alarms) { sdla_t *card = (sdla_t*)fe->card; unsigned char curr_fe_status = fe->fe_status; + u_int32_t valid_rx_alarms = 0x00; if (IS_T1_FEMEDIA(fe)){ + valid_rx_alarms = sdla_ds_t1_is_alarm(fe, alarms); + }else if (IS_E1_FEMEDIA(fe)){ + valid_rx_alarms = sdla_ds_e1_is_alarm(fe, alarms); + } - if (sdla_ds_t1_is_alarm(fe, alarms)){ - if (fe->fe_status != FE_DISCONNECTED){ - fe->fe_status = FE_DISCONNECTED; + if (valid_rx_alarms){ + if (fe->fe_status != FE_DISCONNECTED){ + if (!(valid_rx_alarms & WAN_TE_BIT_RAI_ALARM)){ + sdla_ds_te1_set_alarms(fe, WAN_TE_BIT_YEL_ALARM); } - }else{ - -#ifdef WANPIPE_IGNORE_T1_YELLOW -#warning "AFT IGNORING YELLOW ALARM!" -/* If we ignore yellow alarm, we will pass it up - to zaptel. We will be in connected state where - zaptel will be in alarm. Its a deadlock - condition - - This option can be compiled using Setup - script in case of some users that - have yellow alarm issues. - - Should never be used in ZAPTEL mode! -*/ - if (fe->fe_status != FE_CONNECTED){ + fe->fe_status = FE_DISCONNECTED; + }else if (fe->te_param.tx_yel_alarm && valid_rx_alarms & WAN_TE_BIT_RAI_ALARM){ + /* Special case for loopback */ + sdla_ds_te1_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); + } + }else{ + if (fe->fe_status != FE_CONNECTED){ + if (fe->te_param.tx_yel_alarm){ sdla_ds_te1_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); - fe->fe_status = FE_CONNECTED; } -#else - //sdla_ds_te1_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); - if (!(fe->fe_alarm & WAN_TE_BIT_YEL_ALARM)){ - if (fe->fe_status != FE_CONNECTED){ - fe->fe_status = FE_CONNECTED; - } - }else{ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: T1 Waiting for Yellow Alarm to clear...\n", - fe->name); - } - fe->fe_status = FE_DISCONNECTED; - } -#endif + fe->fe_status = FE_CONNECTED; } - } else { - if (sdla_ds_e1_is_alarm(fe, alarms)){ - if (fe->fe_status != FE_DISCONNECTED){ - fe->fe_status = FE_DISCONNECTED; + } + + if ((IS_T1_FEMEDIA(fe) && sdla_ds_t1_is_alarm(fe, alarms)) || + (IS_E1_FEMEDIA(fe) && sdla_ds_e1_is_alarm(fe, alarms))){ + if (fe->fe_status != FE_DISCONNECTED){ + if (!(alarms & WAN_TE_BIT_RAI_ALARM)){ + /* Send YEL alarm only if our state is not + ** connected*/ + sdla_ds_te1_set_alarms(fe, WAN_TE_BIT_YEL_ALARM); } - }else{ - if (fe->fe_status != FE_CONNECTED){ - fe->fe_status = FE_CONNECTED; + fe->fe_status = FE_DISCONNECTED; + } + }else{ + if (fe->fe_status != FE_CONNECTED){ + if (fe->te_param.tx_yel_alarm){ + sdla_ds_te1_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); } + fe->fe_status = FE_CONNECTED; } } @@ -1714,14 +1788,6 @@ static void sdla_ds_te1_set_status(sdla_fe_t* fe, unsigned long alarms) fe->te_param.status_cnt); } -#if defined(WAN_FE_SC_DISABLE_INTR) - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ - if (card->wandev.critical_event){ - card->wandev.critical_event(card, 0); - } - } -#endif - return; } @@ -1751,30 +1817,30 @@ static int sdla_ds_te1_print_alarms(sdla_fe_t* fe, unsigned int alarms) FE_MEDIA_DECODE(fe), alarms); if (alarms & WAN_TE_BIT_RAI_ALARM){ - DEBUG_EVENT("%s: RAI is ON\n", fe->name); + DEBUG_EVENT("%s: RAI : ON\n", fe->name); } if (alarms & WAN_TE_BIT_LOS_ALARM){ - DEBUG_EVENT("%s: LOS is ON\n", fe->name); + DEBUG_EVENT("%s: LOS : ON\n", fe->name); } if (alarms & WAN_TE_BIT_OOF_ALARM){ - DEBUG_EVENT("%s: OOF is ON\n", fe->name); + DEBUG_EVENT("%s: OOF : ON\n", fe->name); } if (alarms & WAN_TE_BIT_RED_ALARM){ - DEBUG_EVENT("%s: RED is ON\n", fe->name); + DEBUG_EVENT("%s: RED : ON\n", fe->name); } DEBUG_EVENT("%s: %s LIU Alarms status (%X):\n", fe->name, FE_MEDIA_DECODE(fe), - fe->liu_alarm); - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_OC){ + alarms); + if (alarms & WAN_TE_BIT_LIU_ALARM_OC){ DEBUG_EVENT("%s: Open Circuit is detected!\n", fe->name); } - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ - DEBUG_EVENT("%s: Short Circuit is detected!\n", - fe->name); + if (alarms & WAN_TE_BIT_LIU_ALARM_SC){ + DEBUG_EVENT("%s: Short Circuit is detected!(%i)\n", + fe->name, __LINE__); } - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_LOS){ + if (alarms & WAN_TE_BIT_LIU_ALARM_LOS){ DEBUG_EVENT("%s: Lost of Signal is detected!\n", fe->name); } @@ -1790,96 +1856,98 @@ static int sdla_ds_te1_print_alarms(sdla_fe_t* fe, unsigned int alarms) ** Arguments: ** Returns: */ -static unsigned int sdla_ds_te1_read_frame_alarms(sdla_fe_t *fe) +static u_int32_t sdla_ds_te1_read_frame_alarms(sdla_fe_t *fe) { - unsigned int fr_alarm = fe->fe_alarm; + u_int32_t alarm = fe->fe_alarm; unsigned char rrts1 = READ_REG(REG_RRTS1); + alarm &= WAN_TE_BIT_FRAMER_ALARM_MASK; DEBUG_TE1("%s: Framer Alarm status = %02X (%X)\n", - fe->name, rrts1, fr_alarm); + fe->name, rrts1, alarm); /* Framer alarms */ //if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ if (rrts1 & BIT_RRTS1_RRAI){ - if (!(fr_alarm & WAN_TE_BIT_RAI_ALARM)){ - DEBUG_EVENT("%s: RAI alarm is ON\n", + if (!(alarm & WAN_TE_BIT_RAI_ALARM)){ + DEBUG_EVENT("%s: RAI : ON\n", fe->name); } - fr_alarm |= WAN_TE_BIT_RAI_ALARM; + alarm |= WAN_TE_BIT_RAI_ALARM; }else{ - if (fr_alarm & WAN_TE_BIT_RAI_ALARM){ - DEBUG_EVENT("%s: RAI alarm is OFF\n", + if (alarm & WAN_TE_BIT_RAI_ALARM){ + DEBUG_EVENT("%s: RAI : OFF\n", fe->name); } - fr_alarm &= ~WAN_TE_BIT_RAI_ALARM; + alarm &= ~WAN_TE_BIT_RAI_ALARM; } //} if (rrts1 & BIT_RRTS1_RAIS){ - if (!(fr_alarm & WAN_TE_BIT_AIS_ALARM)){ - DEBUG_EVENT("%s: AIS alarm is ON\n", + if (!(alarm & WAN_TE_BIT_AIS_ALARM)){ + DEBUG_EVENT("%s: AIS : ON\n", fe->name); } - fr_alarm |= WAN_TE_BIT_AIS_ALARM; + alarm |= WAN_TE_BIT_AIS_ALARM; }else{ - if (fr_alarm & WAN_TE_BIT_AIS_ALARM){ - DEBUG_EVENT("%s: AIS alarm is OFF\n", + if (alarm & WAN_TE_BIT_AIS_ALARM){ + DEBUG_EVENT("%s: AIS : OFF\n", fe->name); } - fr_alarm &= ~WAN_TE_BIT_AIS_ALARM; + alarm &= ~WAN_TE_BIT_AIS_ALARM; } if (rrts1 & BIT_RRTS1_RLOS){ - if (!(fr_alarm & WAN_TE_BIT_LOS_ALARM)){ - DEBUG_EVENT("%s: LOS alarm is ON\n", + if (!(alarm & WAN_TE_BIT_LOS_ALARM)){ + DEBUG_EVENT("%s: LOS : ON\n", fe->name); } - fr_alarm |= WAN_TE_BIT_LOS_ALARM; + alarm |= WAN_TE_BIT_LOS_ALARM; }else{ - if (fr_alarm & WAN_TE_BIT_LOS_ALARM){ - DEBUG_EVENT("%s: LOS alarm is OFF\n", + if (alarm & WAN_TE_BIT_LOS_ALARM){ + DEBUG_EVENT("%s: LOS : OFF\n", fe->name); } - fr_alarm &= ~WAN_TE_BIT_LOS_ALARM; + alarm &= ~WAN_TE_BIT_LOS_ALARM; } if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ if (rrts1 & BIT_RRTS1_RLOF){ - if (!(fr_alarm & WAN_TE_BIT_OOF_ALARM)){ - DEBUG_EVENT("%s: OOF alarm is ON\n", + if (!(alarm & WAN_TE_BIT_OOF_ALARM)){ + DEBUG_EVENT("%s: OOF : ON\n", fe->name); } - fr_alarm |= WAN_TE_BIT_OOF_ALARM; + alarm |= WAN_TE_BIT_OOF_ALARM; }else{ - if (fr_alarm & WAN_TE_BIT_OOF_ALARM){ - DEBUG_EVENT("%s: OOF alarm is OFF\n", + if (alarm & WAN_TE_BIT_OOF_ALARM){ + DEBUG_EVENT("%s: OOF : OFF\n", fe->name); } - fr_alarm &= ~WAN_TE_BIT_OOF_ALARM; + alarm &= ~WAN_TE_BIT_OOF_ALARM; } } /* Aug 30, 2006 ** Red alarm is either LOS or OOF alarms */ - if (IS_TE_OOF_ALARM(fr_alarm) || - IS_TE_LOS_ALARM(fr_alarm)){ - if (!(fr_alarm & WAN_TE_BIT_RED_ALARM)){ - DEBUG_EVENT("%s: RED alarm is ON\n", + if (IS_TE_OOF_ALARM(alarm) || + IS_TE_LOS_ALARM(alarm)){ + if (!(alarm & WAN_TE_BIT_RED_ALARM)){ + DEBUG_EVENT("%s: RED : ON\n", fe->name); } - fr_alarm |= WAN_TE_BIT_RED_ALARM; + alarm |= WAN_TE_BIT_RED_ALARM; }else{ - if (fr_alarm & WAN_TE_BIT_RED_ALARM){ - DEBUG_EVENT("%s: RED alarm is OFF\n", + if (alarm & WAN_TE_BIT_RED_ALARM){ + DEBUG_EVENT("%s: RED : OFF\n", fe->name); } - fr_alarm &= ~WAN_TE_BIT_RED_ALARM; + alarm &= ~WAN_TE_BIT_RED_ALARM; } - return fr_alarm; + return alarm; } static unsigned int sdla_ds_te1_read_liu_alarms(sdla_fe_t *fe) { - unsigned int alarm = fe->liu_alarm; + unsigned int alarm = fe->fe_alarm; unsigned char lrsr = READ_REG(REG_LRSR); + alarm &= WAN_TE_BIT_LIU_ALARM_MASK; DEBUG_TE1("%s: LIU Alarm status = %02X (%X)\n", - fe->name, lrsr1, alarm); + fe->name, lrsr, alarm); /* LIU alarms */ if (lrsr & BIT_LRSR_OCS){ @@ -1897,14 +1965,14 @@ static unsigned int sdla_ds_te1_read_liu_alarms(sdla_fe_t *fe) } if (lrsr & BIT_LRSR_SCS){ if (!(alarm & WAN_TE_BIT_LIU_ALARM_SC)){ - DEBUG_EVENT("%s: Short Circuit is detected!\n", - fe->name); + DEBUG_EVENT("%s: Short Circuit is detected!(%i)\n", + fe->name, __LINE__); } alarm |= WAN_TE_BIT_LIU_ALARM_SC; }else{ if (alarm & WAN_TE_BIT_LIU_ALARM_SC){ - DEBUG_EVENT("%s: Short Circuit is cleared!\n", - fe->name); + DEBUG_EVENT("%s: Short Circuit is cleared!(%i)\n", + fe->name, __LINE__); } alarm &= ~WAN_TE_BIT_LIU_ALARM_SC; } @@ -1925,35 +1993,35 @@ static unsigned int sdla_ds_te1_read_liu_alarms(sdla_fe_t *fe) return alarm; } -static unsigned int sdla_ds_te1_read_alarms(sdla_fe_t *fe, int action) +static u_int32_t sdla_ds_te1_read_alarms(sdla_fe_t *fe, int action) { - unsigned int fr_alarm = fe->fe_alarm; - unsigned int alarm = fe->liu_alarm; + u_int32_t alarm = fe->fe_alarm; if (IS_FE_ALARM_READ(action)){ - fr_alarm = sdla_ds_te1_read_frame_alarms(fe); - alarm = sdla_ds_te1_read_liu_alarms(fe); + alarm = sdla_ds_te1_read_frame_alarms(fe); + alarm |= sdla_ds_te1_read_liu_alarms(fe); } if (IS_FE_ALARM_PRINT(action)){ - sdla_ds_te1_print_alarms(fe, fr_alarm); + sdla_ds_te1_print_alarms(fe, alarm); } if (IS_FE_ALARM_UPDATE(action)){ - fe->fe_alarm = fr_alarm; - fe->liu_alarm = alarm; + fe->fe_alarm = alarm; } return fe->fe_alarm; } -#define WAN_TE_CRIT_ALARM_TIMEOUT 30000 /* 30 sec */ + +#define WAN_TE_CRIT_ALARM_TIMEOUT 30 /* 30 sec */ static int sdla_ds_te1_read_crit_alarms(sdla_fe_t *fe) { + u_int32_t liu_alarms = 0x00; - fe->liu_alarm = sdla_ds_te1_read_liu_alarms(fe); - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + liu_alarms = sdla_ds_te1_read_liu_alarms(fe); + if (liu_alarms & WAN_TE_BIT_LIU_ALARM_SC){ fe->te_param.crit_alarm_start = SYSTEM_TICKS; }else{ - if((SYSTEM_TICKS - fe->te_param.crit_alarm_start) > ((WAN_TE_CRIT_ALARM_TIMEOUT * HZ)/1000)) { + if (WAN_STIMEOUT(fe->te_param.crit_alarm_start, WAN_TE_CRIT_ALARM_TIMEOUT)){ /* The link was stable for 30 sec, let try to go back */ return 0; } @@ -1962,36 +2030,54 @@ static int sdla_ds_te1_read_crit_alarms(sdla_fe_t *fe) return 1; } -/* -******************************************************************************* +/****************************************************************************** ** sdla_ds_te1_set_alarms() ** -** Description: +** Description: ** Arguments: ** Returns: */ -static int sdla_ds_te1_set_alarms(sdla_fe_t* fe, unsigned long alarms) +static int sdla_ds_te1_set_alarms(sdla_fe_t* fe, u_int32_t alarms) { + u8 value; + if (alarms & WAN_TE_BIT_YEL_ALARM){ - DEBUG_TEST("%s: Setting YELLOW alarm (not supported)!\n", - fe->name); + if (IS_T1_FEMEDIA(fe) && + fe->fe_cfg.cfg.te_cfg.ignore_yel_alarm == WANOPT_NO){ + value = READ_REG(REG_TCR1); + if (!(value & BIT_TCR1_T1_TRAI)){ + DEBUG_TE1("%s: Set YEL alarm!\n", + fe->name); + WRITE_REG(REG_TCR1, value | BIT_TCR1_T1_TRAI); + fe->te_param.tx_yel_alarm = 1; + } + } } return 0; } -/* -******************************************************************************* +/****************************************************************************** ** sdla_ds_te1_clear_alarms() ** -** Description: +** Description: ** Arguments: ** Returns: */ -static int sdla_ds_te1_clear_alarms(sdla_fe_t* fe, unsigned long alarms) +static int sdla_ds_te1_clear_alarms(sdla_fe_t* fe, u_int32_t alarms) { + u8 value; + if (alarms & WAN_TE_BIT_YEL_ALARM){ - DEBUG_TEST("%s: Clearing YELLOW alarm (not supported)!\n", - fe->name); + if (IS_T1_FEMEDIA(fe) && + fe->fe_cfg.cfg.te_cfg.ignore_yel_alarm == WANOPT_NO){ + value = READ_REG(REG_TCR1); + if (value & BIT_TCR1_T1_TRAI){ + DEBUG_TE1("%s: Clear YEL alarm!\n", + fe->name); + WRITE_REG(REG_TCR1, value & ~BIT_TCR1_T1_TRAI); + fe->te_param.tx_yel_alarm = 0; + } + } } return 0; } @@ -2460,10 +2546,8 @@ sdla_ds_te1_intr_ctrl(sdla_fe_t *fe, int dummy, u_int8_t type, u_int8_t mode, un if (type & WAN_TE_INTR_GLOBAL){ mask = READ_REG(REG_GFIMR); if (mode == WAN_FE_INTR_ENABLE){ - //mask |= (1<name, rls1); //if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ if (rls1 & (BIT_RLS1_RRAIC|BIT_RLS1_RRAID)){ if (rrts1 & BIT_RRTS1_RRAI){ fe->fe_alarm |= WAN_TE_BIT_RAI_ALARM; - DEBUG_EVENT("%s: RAI alarm is ON\n", + if (!silent) DEBUG_EVENT("%s: RAI alarm is ON\n", fe->name); }else{ fe->fe_alarm &= ~WAN_TE_BIT_RAI_ALARM; - DEBUG_EVENT("%s: RAI alarm is OFF\n", + if (!silent) DEBUG_EVENT("%s: RAI alarm is OFF\n", fe->name); } } @@ -2597,22 +2676,22 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) if (rls1 & (BIT_RLS1_RAISC|BIT_RLS1_RAISD)){ if (rrts1 & BIT_RRTS1_RAIS){ fe->fe_alarm |= WAN_TE_BIT_AIS_ALARM; - DEBUG_EVENT("%s: AIS alarm is ON\n", + if (!silent) DEBUG_EVENT("%s: AIS alarm is ON\n", fe->name); }else{ fe->fe_alarm &= ~WAN_TE_BIT_AIS_ALARM; - DEBUG_EVENT("%s: AIS alarm is OFF\n", + if (!silent) DEBUG_EVENT("%s: AIS alarm is OFF\n", fe->name); } } if (rls1 & (BIT_RLS1_RLOSC|BIT_RLS1_RLOSD)){ if (rrts1 & BIT_RRTS1_RLOS){ fe->fe_alarm |= WAN_TE_BIT_LOS_ALARM; - DEBUG_EVENT("%s: LOS alarm is ON\n", + if (!silent) DEBUG_EVENT("%s: LOS alarm is ON\n", fe->name); }else{ fe->fe_alarm &= ~WAN_TE_BIT_LOS_ALARM; - DEBUG_EVENT("%s: LOS alarm is OFF\n", + if (!silent) DEBUG_EVENT("%s: LOS alarm is OFF\n", fe->name); } } @@ -2620,11 +2699,11 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) if (rls1 & (BIT_RLS1_RLOFC|BIT_RLS1_RLOFD)){ if (rrts1 & BIT_RRTS1_RLOF){ fe->fe_alarm |= WAN_TE_BIT_OOF_ALARM; - DEBUG_EVENT("%s: OOF alarm is ON\n", + if (!silent) DEBUG_EVENT("%s: OOF alarm is ON\n", fe->name); }else{ fe->fe_alarm &= ~WAN_TE_BIT_OOF_ALARM; - DEBUG_EVENT("%s: OOF alarm is OFF\n", + if (!silent) DEBUG_EVENT("%s: OOF alarm is OFF\n", fe->name); } } @@ -2633,38 +2712,42 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) if (IS_T1_FEMEDIA(fe)){ if (IS_TE_OOF_ALARM(fe->fe_alarm) && IS_TE_LOS_ALARM(fe->fe_alarm)){ - DEBUG_EVENT("%s: RED alarm is ON\n", + if (!(fe->fe_alarm & WAN_TE_BIT_RED_ALARM)){ + if (!silent) DEBUG_EVENT("%s: RED alarm is ON\n", fe->name); - fe->fe_alarm |= WAN_TE_BIT_RED_ALARM; + fe->fe_alarm |= WAN_TE_BIT_RED_ALARM; + } }else{ - DEBUG_EVENT("%s: RED alarm is OFF\n", - fe->name); - fe->fe_alarm &= ~WAN_TE_BIT_RED_ALARM; + if (fe->fe_alarm & WAN_TE_BIT_RED_ALARM){ + if (!silent) DEBUG_EVENT("%s: RED alarm is OFF\n", + fe->name); + fe->fe_alarm &= ~WAN_TE_BIT_RED_ALARM; + } } } } if (istatus & BIT_RIIR_RLS2){ unsigned char rls2 = READ_REG(REG_RLS2); if (IS_E1_FEMEDIA(fe)){ - DEBUG_TE1("%s: E1 RX Latched Status Register 2 %02X\n", + if (!silent) DEBUG_TE1("%s: E1 RX Latched Status Register 2 %02X\n", fe->name, rls2); if (rls2 & BIT_RLS2_E1_RSA1){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Receive Signalling All Ones Event!\n", fe->name); } if (rls2 & BIT_RLS2_E1_RSA0){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Receive Signalling All Ones Event!\n", fe->name); } if (rls2 & BIT_RLS2_E1_RCMF){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Receive CRC4 Multiframe Event!\n", fe->name); } if (rls2 & BIT_RLS2_E1_RAF){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Receive Align Frame Event!\n", fe->name); } @@ -2673,27 +2756,27 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) } if (istatus & BIT_RIIR_RLS3){ unsigned char rls3 = READ_REG(REG_RLS3); - DEBUG_TE1("%s: RX Latched Status Register 3 %02X\n", + if (!silent) DEBUG_TE1("%s: RX Latched Status Register 3 %02X\n", fe->name, rls3); if (IS_T1_FEMEDIA(fe)){ if (rls3 & BIT_RLS3_T1_LORCC){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Loss of Receive Clock Condition Clear!\n", fe->name); } if (rls3 & BIT_RLS3_T1_LORCD){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Loss of Receive Clock Condition Detect!\n", fe->name); } }else{ if (rls3 & BIT_RLS3_E1_LORCC){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Loss of Receive Clock Condition Clear!\n", fe->name); } if (rls3 & BIT_RLS3_E1_LORCD){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Loss of Receive Clock Condition Detect!\n", fe->name); } @@ -2702,10 +2785,10 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) } if (istatus & BIT_RIIR_RLS4){ unsigned char rls4 = READ_REG(REG_RLS4); - DEBUG_TE1("%s: RX Latched Status Register 4 %02X\n", + if (!silent) DEBUG_TE1("%s: RX Latched Status Register 4 %02X\n", fe->name, rls4); if (rls4 & BIT_RLS4_RSCOS){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Receive Signalling status changed!\n", fe->name); sdla_ds_te1_check_rbsbits(fe, 1, ENABLE_ALL_CHANNELS, 1); @@ -2716,7 +2799,7 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) } } if (rls4 & BIT_RLS4_TIMER){ - DEBUG_ISR( + if (!silent) DEBUG_ISR( "%s: Performance monitor counters have been updated!\n", fe->name); sdla_ds_te1_pmon(fe, WAN_FE_PMON_READ); @@ -2725,30 +2808,30 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) } if (istatus & BIT_RIIR_RLS5){ unsigned char rls5 = READ_REG(REG_RLS5); - DEBUG_TE1("%s: RX Latched Status Register 5 %02X\n", + if (!silent) DEBUG_TE1("%s: RX Latched Status Register 5 %02X\n", fe->name, rls5); if (rls5 & BIT_RLS5_ROVR){ - DEBUG_EVENT("%s: Receive FIFO overrun (HDLC)!\n", + if (!silent) DEBUG_EVENT("%s: Receive FIFO overrun (HDLC)!\n", fe->name); } if (rls5 & BIT_RLS5_RHOBT){ - DEBUG_EVENT("%s: Receive HDLC Opening Byte Event (HDLC)!\n", + if (!silent) DEBUG_EVENT("%s: Receive HDLC Opening Byte Event (HDLC)!\n", fe->name); } if (rls5 & BIT_RLS5_RPE){ - DEBUG_EVENT("%s: Receive Packet End Event (HDLC)!\n", + if (!silent) DEBUG_EVENT("%s: Receive Packet End Event (HDLC)!\n", fe->name); } if (rls5 & BIT_RLS5_RPS){ - DEBUG_EVENT("%s: Receive Packet Start Event (HDLC)!\n", + if (!silent) DEBUG_EVENT("%s: Receive Packet Start Event (HDLC)!\n", fe->name); } if (rls5 & BIT_RLS5_RHWMS){ - DEBUG_EVENT("%s: Receive FIFO Above High Watermark Set Event (HDLC)!\n", + if (!silent) DEBUG_EVENT("%s: Receive FIFO Above High Watermark Set Event (HDLC)!\n", fe->name); } if (rls5 & BIT_RLS5_RNES){ - DEBUG_EVENT("%s: Receive FIFO Not Empty Set Event (HDLC)!\n", + if (!silent) DEBUG_EVENT("%s: Receive FIFO Not Empty Set Event (HDLC)!\n", fe->name); } WRITE_REG(REG_RLS5, rls5); @@ -2759,30 +2842,30 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) #endif if (istatus & BIT_RIIR_RLS7){ unsigned char rls7 = READ_REG(REG_RLS7); - DEBUG_TE1("%s: RX Latched Status Register 7 %02X\n", + if (!silent) DEBUG_TE1("%s: RX Latched Status Register 7 %02X\n", fe->name, rls7); if (rls7 & BIT_RLS7_RRAI_CI){ - DEBUG_EVENT("%s: Receive RAI-CI Detect!\n", + if (!silent) DEBUG_EVENT("%s: Receive RAI-CI Detect!\n", fe->name); } if (rls7 & BIT_RLS7_RAIS_CI){ - DEBUG_EVENT("%s: Receive RAI-CI Detect!\n", + if (!silent) DEBUG_EVENT("%s: Receive RAI-CI Detect!\n", fe->name); } if (rls7 & BIT_RLS7_RSLC96){ - DEBUG_EVENT("%s: Receive SLC-96 Alignment Event!\n", + if (!silent) DEBUG_EVENT("%s: Receive SLC-96 Alignment Event!\n", fe->name); } if (rls7 & BIT_RLS7_RFDLF){ - DEBUG_EVENT("%s: Receive FDL Register Full Event!\n", + if (!silent) DEBUG_EVENT("%s: Receive FDL Register Full Event!\n", fe->name); } if (rls7 & BIT_RLS7_BC){ - DEBUG_EVENT("%s: BOC Clear Event!\n", + if (!silent) DEBUG_EVENT("%s: BOC Clear Event!\n", fe->name); } if (rls7 & BIT_RLS7_BD){ - DEBUG_EVENT("%s: BOC Detect Event!\n", + if (!silent) DEBUG_EVENT("%s: BOC Detect Event!\n", fe->name); } WRITE_REG(REG_RLS7, rls7); @@ -2791,7 +2874,7 @@ static int sdla_ds_te1_framer_rx_intr(sdla_fe_t *fe) return 0; } -static int sdla_ds_te1_framer_tx_intr(sdla_fe_t *fe) +static int sdla_ds_te1_framer_tx_intr(sdla_fe_t *fe, int silent) { unsigned char istatus; unsigned char status; @@ -2800,12 +2883,12 @@ static int sdla_ds_te1_framer_tx_intr(sdla_fe_t *fe) if (istatus & BIT_TIIR_TLS1){ status = READ_REG(REG_TLS1); if (status & BIT_TLS1_TPDV){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Transmit Pulse Density Violation Event!\n", fe->name); } if (status & BIT_TLS1_LOTCC){ - DEBUG_EVENT( + if (!silent) DEBUG_EVENT( "%s: Loss of Transmit Clock condition Clear!\n", fe->name); } @@ -2822,36 +2905,36 @@ static int sdla_ds_te1_framer_tx_intr(sdla_fe_t *fe) return 0; } -static int sdla_ds_te1_bert_intr(sdla_fe_t *fe) +static int sdla_ds_te1_bert_intr(sdla_fe_t *fe, int silent) { unsigned char blsr = READ_REG(REG_BLSR); if (blsr & BIT_BLSR_BBED){ - DEBUG_EVENT("%s: BERT bit error detected!\n", + if (!silent) DEBUG_EVENT("%s: BERT bit error detected!\n", fe->name); } if (blsr & BIT_BLSR_BBCO){ - DEBUG_EVENT("%s: BERT Bit Counter overflows!\n", + if (!silent) DEBUG_EVENT("%s: BERT Bit Counter overflows!\n", fe->name); } if (blsr & BIT_BLSR_BECO){ - DEBUG_EVENT("%s: BERT Error Counter overflows!\n", + if (!silent) DEBUG_EVENT("%s: BERT Error Counter overflows!\n", fe->name); } if (blsr & BIT_BLSR_BRA1){ - DEBUG_EVENT("%s: BERT Receive All-Ones Condition!\n", + if (!silent) DEBUG_EVENT("%s: BERT Receive All-Ones Condition!\n", fe->name); } if (blsr & BIT_BLSR_BRA0){ - DEBUG_EVENT("%s: BERT Receive All-Zeros Condition!\n", + if (!silent) DEBUG_EVENT("%s: BERT Receive All-Zeros Condition!\n", fe->name); } if (blsr & BIT_BLSR_BRLOS){ - DEBUG_EVENT("%s: BERT Receive Loss of Synchronization Condition!\n", + if (!silent) DEBUG_EVENT("%s: BERT Receive Loss of Synchronization Condition!\n", fe->name); } if (blsr & BIT_BLSR_BSYNC){ - DEBUG_EVENT("%s: BERT in synchronization Condition!\n", + if (!silent) DEBUG_EVENT("%s: BERT in synchronization Condition!\n", fe->name); } @@ -2859,17 +2942,17 @@ static int sdla_ds_te1_bert_intr(sdla_fe_t *fe) return 0; } -static int sdla_ds_te1_liu_intr(sdla_fe_t *fe) +static int sdla_ds_te1_liu_intr(sdla_fe_t *fe, int silent) { unsigned char llsr = READ_REG(REG_LLSR); unsigned char lrsr = READ_REG(REG_LRSR); if (llsr & BIT_LLSR_JALTC){ - DEBUG_TE1("%s: Jitter Attenuator Limit Trip Clear!\n", + if (!silent) DEBUG_TE1("%s: Jitter Attenuator Limit Trip Clear!\n", fe->name); } if (llsr & BIT_LLSR_JALTS){ - DEBUG_TE1("%s: Jitter Attenuator Limit Trip Set!\n", + if (!silent) DEBUG_TE1("%s: Jitter Attenuator Limit Trip Set!\n", fe->name); } if (llsr & (BIT_LLSR_OCC | BIT_LLSR_OCD)){ @@ -2880,46 +2963,46 @@ static int sdla_ds_te1_liu_intr(sdla_fe_t *fe) } #endif if (lrsr & BIT_LRSR_OCS){ - if (!(fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_OC)){ - DEBUG_TE1("%s: Open Circuit is detected!\n", + if (!(fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_OC)){ + if (!silent) DEBUG_TE1("%s: Open Circuit is detected!\n", fe->name); - fe->liu_alarm |= WAN_TE_BIT_LIU_ALARM_OC; + fe->fe_alarm |= WAN_TE_BIT_LIU_ALARM_OC; } }else{ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_OC){ - DEBUG_TE1("%s: Open Circuit is cleared!\n", + if (fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_OC){ + if (!silent) DEBUG_TE1("%s: Open Circuit is cleared!\n", fe->name); - fe->liu_alarm &= ~WAN_TE_BIT_LIU_ALARM_OC; + fe->fe_alarm &= ~WAN_TE_BIT_LIU_ALARM_OC; } } } if (llsr & (BIT_LLSR_SCC | BIT_LLSR_SCD)){ if (lrsr & BIT_LRSR_SCS){ - if (!(fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC)){ - DEBUG_EVENT("%s: Short Circuit is detected!\n", - fe->name); - fe->liu_alarm |= WAN_TE_BIT_LIU_ALARM_SC; + if (!(fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_SC)){ + if (!silent) DEBUG_EVENT("%s: Short Circuit is detected!(%i)\n", + fe->name, __LINE__); + fe->fe_alarm |= WAN_TE_BIT_LIU_ALARM_SC; } }else{ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ - DEBUG_EVENT("%s: Short Circuit is cleared!\n", - fe->name); - fe->liu_alarm &= ~WAN_TE_BIT_LIU_ALARM_SC; + if (fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + if (!silent) DEBUG_EVENT("%s: Short Circuit is cleared!(%i)\n", + fe->name, __LINE__); + fe->fe_alarm &= ~WAN_TE_BIT_LIU_ALARM_SC; } } } if (llsr & (BIT_LLSR_LOSC | BIT_LLSR_LOSD)){ if (lrsr & BIT_LRSR_LOSS){ - if (!(fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_LOS)){ - DEBUG_EVENT("%s: Lost of Signal is detected!\n", + if (!(fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_LOS)){ + if (!silent) DEBUG_EVENT("%s: Lost of Signal is detected!\n", fe->name); - fe->liu_alarm |= WAN_TE_BIT_LIU_ALARM_LOS; + fe->fe_alarm |= WAN_TE_BIT_LIU_ALARM_LOS; } }else{ - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_LOS){ - DEBUG_EVENT("%s: Lost of Signal is cleared!\n", + if (fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_LOS){ + if (!silent) DEBUG_EVENT("%s: Lost of Signal is cleared!\n", fe->name); - fe->liu_alarm &= ~WAN_TE_BIT_LIU_ALARM_LOS; + fe->fe_alarm &= ~WAN_TE_BIT_LIU_ALARM_LOS; } } } @@ -2946,12 +3029,6 @@ static int sdla_ds_te1_check_intr(sdla_fe_t *fe) bert_imask = __READ_REG(REG_GBIMR); //if (framer_istatus & (1 << WAN_FE_LINENO(fe))){ - if (framer_istatus & (1 << WAN_DS_REGBITMAP(fe))){ - DEBUG_ISR("%s: Interrupt for line %d (framer)\n", - fe->name, WAN_FE_LINENO(fe)); - return 1; - } - //if (liu_istatus & (1 << WAN_FE_LINENO(fe))){ if ((framer_istatus & (1 << WAN_DS_REGBITMAP(fe))) && (framer_imask & (1 << WAN_DS_REGBITMAP(fe)))) { DEBUG_ISR("%s: Interrupt for line %d (FRAMER)\n", @@ -2972,7 +3049,6 @@ static int sdla_ds_te1_check_intr(sdla_fe_t *fe) fe->name, WAN_FE_LINENO(fe)); return 1; } - DEBUG_ISR("%s: This interrupt not for this port %d\n", fe->name, WAN_FE_LINENO(fe)+1); @@ -2981,34 +3057,41 @@ static int sdla_ds_te1_check_intr(sdla_fe_t *fe) static int sdla_ds_te1_intr(sdla_fe_t *fe) { - unsigned char status = fe->fe_status; - unsigned char framer_istatus; - unsigned char liu_istatus; - unsigned char bert_istatus; + u_int8_t status = fe->fe_status; + u_int8_t framer_istatus, liu_istatus, bert_istatus; + u_int8_t device_id; + int silent = 0; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); + device_id = WAN_TE1_DEVICE_ID; + if (device_id == DEVICE_ID_BAD){ + DEBUG_EVENT( + "%s: ERROR: Failed to verify Device id (silent mode)!\n", + fe->name); + silent = 1; + } framer_istatus = READ_REG(REG_GFISR); liu_istatus = READ_REG(REG_GLISR); bert_istatus = READ_REG(REG_GBISR); //if (framer_istatus & (1 << WAN_FE_LINENO(fe))){ if (framer_istatus & (1 << WAN_DS_REGBITMAP(fe))){ - sdla_ds_te1_framer_rx_intr(fe); - sdla_ds_te1_framer_tx_intr(fe); + sdla_ds_te1_framer_rx_intr(fe, silent); + sdla_ds_te1_framer_tx_intr(fe, silent); //WRITE_REG(REG_GFISR, (1<name,fe->fe_alarm); #if 1 - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + if (fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_SC){ sdla_fe_timer_event_t event; /* AL: March 1, 2006 - ** Mask global FE intr - ** Disable automatic update */ + ** 1. Mask global FE intr + ** 2. Disable automatic update */ sdla_ds_te1_intr_ctrl( - fe, 0, + fe, 0, (WAN_TE_INTR_GLOBAL|WAN_TE_INTR_BASIC|WAN_TE_INTR_PMON), - WAN_FE_INTR_MASK, 0x00); + WAN_FE_INTR_MASK, + 0x00); /* Start LINKDOWN poll */ event.type = TE_LINKCRIT_TIMER; event.delay = POLLING_TE1_TIMER*5; sdla_ds_te1_add_event(fe, &event); - //if (card->wandev.critical_event){ - // card->wandev.critical_event(card, 0); - //} return 0; } #endif @@ -3043,12 +3124,13 @@ static int sdla_ds_te1_intr(sdla_fe_t *fe) if (fe->fe_status != FE_CONNECTED){ sdla_fe_timer_event_t event; /* AL: March 1, 2006 - ** Mask global FE intr - ** Disable automatic update */ + ** 1. Mask global FE intr + ** 2. Disable automatic update */ sdla_ds_te1_intr_ctrl( - fe, 0, + fe, 0, (WAN_TE_INTR_GLOBAL|WAN_TE_INTR_BASIC|WAN_TE_INTR_PMON), - WAN_FE_INTR_MASK, 0x00); + WAN_FE_INTR_MASK, + 0x00); /* Start LINKDOWN poll */ event.type = TE_LINKDOWN_TIMER; event.delay = POLLING_TE1_TIMER*5; @@ -3095,9 +3177,9 @@ static void sdla_ds_te1_timer(unsigned long pfe) wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); /* Enable hardware interrupt for TE1 */ - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); empty = WAN_LIST_EMPTY(&fe->event); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); if (!empty){ if (wan_test_and_set_bit(TE_TIMER_EVENT_PENDING,(void*)&fe->te_param.critical)){ @@ -3128,21 +3210,23 @@ static int sdla_ds_te1_add_timer(sdla_fe_t* fe, unsigned long delay) { int err=0; - if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ + if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical) || + wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)) { return 0; } - if (wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)) { - return 0; - } - - wan_set_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); - +#if defined(__WINDOWS__) + /* delay is in MS, so it can be used directly by wan_add_timer() */ + err = wan_add_timer(&fe->timer, delay); +#else err = wan_add_timer(&fe->timer, delay * HZ / 1000); +#endif + if (err){ /* Failed to add timer */ return -EINVAL; } + wan_set_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); return 0; } @@ -3185,12 +3269,12 @@ sdla_ds_te1_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *event) DEBUG_EVENT("%s: %s:%d: ---------------STOP ----------------------\n", fe->name, __FUNCTION__,__LINE__); #endif - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); /* Set event from pending event map */ if (wan_test_and_set_bit(event->type,(void*)&fe->event_map)){ DEBUG_EVENT("%s: WARNING: Event type %d is already pending!\n", fe->name, event->type); - wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_spin_unlock_irq(&fe->lockirq, &smp_flags); wan_free(tevent); return -EINVAL; } @@ -3204,9 +3288,9 @@ sdla_ds_te1_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *event) cnt ++; } if (tmp == NULL){ - DEBUG_EVENT("%s: Internal Error!!!\n", fe->name); + DEBUG_EVENT("%s: ERROR: Internal Error!!!\n", fe->name); wan_clear_bit(event->type,(void*)&fe->event_map); - wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_spin_unlock_irq(&fe->lockirq, &smp_flags); return -EINVAL; } if (cnt > WAN_FE_MAX_QEVENT_LEN){ @@ -3215,26 +3299,25 @@ sdla_ds_te1_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *event) DEBUG_EVENT("%s: ERROR: Dropping new event type %d!\n", fe->name, event->type); wan_clear_bit(event->type,(void*)&fe->event_map); - wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_spin_unlock_irq(&fe->lockirq, &smp_flags); wan_free(tevent); return -EINVAL; } WAN_LIST_INSERT_AFTER(tmp, tevent, next); } - wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_spin_unlock_irq(&fe->lockirq, &smp_flags); return 0; } -/* - ****************************************************************************** - * sdla_ds_te1_polling() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ +/****************************************************************************** +** sdla_ds_te1_polling() +** +** Description: +** Arguments: +** Returns: 0 - There are no more event. Do not need to schedule sw timer +** number - delay to schedule next event. +******************************************************************************/ static int sdla_ds_te1_polling(sdla_fe_t* fe) { sdla_t *card = (sdla_t*)fe->card; @@ -3243,9 +3326,12 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) u_int8_t pending = 0; unsigned char value; unsigned int ch, bit, off; +#if 0 + unsigned int reg; +#endif - WAN_ASSERT(fe->write_fe_reg == NULL); - WAN_ASSERT(fe->read_fe_reg == NULL); + WAN_ASSERT_RC(fe->write_fe_reg == NULL, 0); + WAN_ASSERT_RC(fe->read_fe_reg == NULL, 0); #if 0 DEBUG_EVENT("%s: %s:%d: ---------------START ----------------------\n", @@ -3254,20 +3340,19 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) DEBUG_EVENT("%s: %s:%d: ---------------STOP ----------------------\n", fe->name, __FUNCTION__,__LINE__); #endif - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); if (WAN_LIST_EMPTY(&fe->event)){ wan_clear_bit(TE_TIMER_EVENT_PENDING,(void*)&fe->te_param.critical); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); DEBUG_EVENT("%s: WARNING: No FE events in a queue!\n", fe->name); - sdla_ds_te1_add_timer(fe, HZ); - return 0; + return HZ; } event = WAN_LIST_FIRST(&fe->event); WAN_LIST_REMOVE(event, next); /* Clear event from pending event map */ wan_clear_bit(event->type,(void*)&fe->event_map); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); DEBUG_TE1("%s: TE1 Polling State=%s Event=%X!\n", fe->name, WAN_FE_STATUS_DECODE(fe), event->type); @@ -3284,7 +3369,7 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) case TE_LINKDOWN_TIMER: sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + if (fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_SC){ /* Short circuit detected, go to LINKCRIT state */ event->type = TE_LINKCRIT_TIMER; event->delay = POLLING_TE1_TIMER; @@ -3310,22 +3395,22 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) ** because it cause to stay longer in interrupt handler ** (critical for XILINX code) */ if (fe->fe_status == FE_CONNECTED){ + if (card->wandev.te_link_state){ + card->wandev.te_link_state(card); + } if (fe->fe_cfg.poll_mode == WANOPT_YES){ event->type = WAN_TE_POLL_LINKREADY; event->delay = POLLING_TE1_TIMER; pending = 1; }else{ - /* Enable Basic Interrupt */ - /* Enable automatic update pmon counters */ + /* Enable Basic Interrupt + ** Enable automatic update pmon counters */ sdla_ds_te1_intr_ctrl( fe, 0, (WAN_TE_INTR_GLOBAL|WAN_TE_INTR_BASIC|WAN_TE_INTR_PMON), WAN_FE_INTR_ENABLE, 0x00); } - if (card->wandev.te_link_state){ - card->wandev.te_link_state(card); - } }else{ event->type = TE_LINKDOWN_TIMER; event->delay = POLLING_TE1_TIMER; @@ -3333,11 +3418,10 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) } break; - case WAN_TE_POLL_LINKREADY: /* Only used in no interrupt driven front-end mode */ sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); - if (fe->liu_alarm & WAN_TE_BIT_LIU_ALARM_SC){ + if (fe->fe_alarm & WAN_TE_BIT_LIU_ALARM_SC){ /* Short circuit detected, go to LINKCRIT state */ event->type = TE_LINKCRIT_TIMER; event->delay = POLLING_TE1_TIMER; @@ -3414,7 +3498,7 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) break; case TE_SET_LB_MODE: - sdla_ds_te1_set_lbmode(fe, event->te_event.lb_type, event->mode); + sdla_ds_te1_set_lb(fe, event->te_event.lb_type, event->mode); break; case TE_POLL_CONFIG: @@ -3423,20 +3507,50 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) if (sdla_ds_te1_chip_config(fe)){ DEBUG_EVENT("%s: Failed to re-configuring Front-End chip!\n", fe->name); - return -EINVAL; + break; } + /* Do not enable interrupts here */ event->type = TE_LINKDOWN_TIMER; event->delay = POLLING_TE1_TIMER; pending = 1; break; - +#if 0 + case TE_POLL_CONFIG_VERIFY: + DEBUG_EVENT("%s: Verifing %s Front-End chip configuration...\n", + fe->name, FE_MEDIA_DECODE(fe)); + if (sdla_ds_te1_chip_config_verify(fe)){ + DEBUG_EVENT("%s: Failed to verify Front-End chip configuration!\n", + fe->name); + } + break; +#endif case TE_POLL_READ: fe->te_param.reg_dbg_value = READ_REG(event->te_event.reg); DEBUG_TE1("%s: Read %s Front-End Reg:%04X=%02X\n", fe->name, FE_MEDIA_DECODE(fe), event->te_event.reg, fe->te_param.reg_dbg_value); - fe->te_param.reg_dbg_ready = 1; + fe->te_param.reg_dbg_ready = 1; +#if 0 + DEBUG_EVENT("%s: Reading %s Front-End Registers:\n", + fe->name, FE_MEDIA_DECODE(fe)); + for(reg=0x0;reg<=0x1ff;reg++){ + DEBUG_EVENT("%s: REG[%04X]=%02X\n", + fe->name, reg, READ_REG(reg)); + } + DEBUG_EVENT("%s: Reading %s Front-End LIU Registers:\n", + fe->name, FE_MEDIA_DECODE(fe)); + for(reg=0x1000;reg<=0x1007;reg++){ + DEBUG_EVENT("%s: REG[%04X]=%02X\n", + fe->name, reg, READ_REG(reg)); + } + DEBUG_EVENT("%s: Reading %s Front-End BERT Registers:\n", + fe->name, FE_MEDIA_DECODE(fe)); + for(reg=0x1100;reg<=0x110F;reg++){ + DEBUG_EVENT("%s: REG[%04X]=%02X\n", + fe->name, reg, READ_REG(reg)); + } +#endif break; case TE_POLL_WRITE: @@ -3462,11 +3576,9 @@ static int sdla_ds_te1_polling(sdla_fe_t* fe) /* Add fe timer */ event = WAN_LIST_FIRST(&fe->event); if (event){ - sdla_ds_te1_add_timer(fe, event->delay); - }else{ - sdla_ds_te1_add_timer(fe, HZ); + return event->delay; } - return 0; + return HZ; } /* @@ -3526,7 +3638,7 @@ static int sdla_ds_te1_pmon(sdla_fe_t *fe, int action) /* OOF Error for T1/E1 */ pmon3 = READ_REG(REG_FOSCR1) << 8 | READ_REG(REG_FOSCR2); if (IS_E1_FEMEDIA(fe) && WAN_FE_FRAME(fe) == WAN_FR_CRC4){ - /* E-bit counter (Far End Block Errors) */ + /* E-bit counter (Far End Block Errors) for CRC4 */ pmon4 = READ_REG(REG_E1EBCR1) << 8 | READ_REG(REG_E1EBCR2); } @@ -3706,7 +3818,7 @@ static int sdla_ds_te1_fr_flb(sdla_fe_t* fe, unsigned char mode) }else{ value &= ~BIT_RCR3_FLB; } - WRITE_REG(REG_LMCR, value); + WRITE_REG(REG_RCR3, value); return 0; } @@ -3732,13 +3844,13 @@ static int sdla_ds_te1_fr_plb(sdla_fe_t* fe, unsigned char mode) }else{ value &= ~BIT_RCR3_PLB; } - WRITE_REG(REG_LMCR, value); + WRITE_REG(REG_RCR3, value); return 0; } /* ****************************************************************************** - * sdla_ds_te1_set_lbmode() + * sdla_ds_te1_set_lb() * * Description: * Arguments: @@ -3746,7 +3858,7 @@ static int sdla_ds_te1_fr_plb(sdla_fe_t* fe, unsigned char mode) ****************************************************************************** */ static int -sdla_ds_te1_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) +sdla_ds_te1_set_lb(sdla_fe_t *fe, unsigned char mode, unsigned char action) { int err = 0; @@ -3754,33 +3866,33 @@ sdla_ds_te1_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) WAN_ASSERT(fe->read_fe_reg == NULL); DEBUG_EVENT("%s: %s %s mode...\n", fe->name, - WAN_TE1_LB_MODE_DECODE(mode), - WAN_TE1_LB_TYPE_DECODE(type)); - switch(type){ - case WAN_TE1_DDLB_MODE: + WAN_TE1_LB_ACTION_DECODE(action), + WAN_TE1_LB_MODE_DECODE(mode)); + switch(mode){ case WAN_TE1_LIU_ALB_MODE: - err = sdla_ds_te1_liu_alb(fe, mode); + err = sdla_ds_te1_liu_alb(fe, action); break; case WAN_TE1_LIU_LLB_MODE: - err = sdla_ds_te1_liu_llb(fe, mode); + err = sdla_ds_te1_liu_llb(fe, action); break; - case WAN_TE1_LINELB_MODE: case WAN_TE1_LIU_RLB_MODE: - err = sdla_ds_te1_liu_rlb(fe, mode); + err = sdla_ds_te1_liu_rlb(fe, action); break; case WAN_TE1_LIU_DLB_MODE: - if (!sdla_ds_te1_liu_llb(fe, mode)){ - err = sdla_ds_te1_liu_rlb(fe, mode); + if (!sdla_ds_te1_liu_llb(fe, action)){ + err = sdla_ds_te1_liu_rlb(fe, action); } break; + case WAN_TE1_DDLB_MODE: case WAN_TE1_FR_FLB_MODE: - err = sdla_ds_te1_fr_flb(fe, mode); + err = sdla_ds_te1_fr_flb(fe, action); break; case WAN_TE1_PAYLB_MODE: case WAN_TE1_FR_PLB_MODE: - err = sdla_ds_te1_fr_plb(fe, mode); + err = sdla_ds_te1_fr_plb(fe, action); break; case WAN_TE1_FR_RLB_MODE: + case WAN_TE1_LINELB_MODE: default: DEBUG_EVENT("%s: Unsupport loopback mode (%s)!\n", fe->name, @@ -3788,13 +3900,13 @@ sdla_ds_te1_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) return -EINVAL; } if (!err){ - if (mode == WAN_TE1_ACTIVATE_LB){ - wan_set_bit(type, &fe->te_param.lb_mode); + if (action == WAN_TE1_ACTIVATE_LB){ + wan_set_bit(mode, &fe->te_param.lb_mode); }else{ - wan_clear_bit(type, &fe->te_param.lb_mode); + wan_clear_bit(mode, &fe->te_param.lb_mode); } } - return 0; + return err; } /* @@ -3827,11 +3939,11 @@ static int sdla_ds_te1_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) #if 1 event.type = TE_SET_LB_MODE; event.te_event.lb_type = data[0]; /* LB type */ - event.mode = data[1]; /* LB mode (activate/deactivate) */ + event.mode = data[1]; /* LB action (activate/deactivate) */ event.delay = POLLING_TE1_TIMER; err = sdla_ds_te1_add_event(fe, &event); #else - err = sdla_ds_te1_set_lbmode(fe, data[0], data[1]); + err = sdla_ds_te1_set_lb(fe, data[0], data[1]); #endif udp_cmd->wan_cmd_return_code = (!err) ? WAN_CMD_OK : WAN_UDP_FAILED_CMD; @@ -3841,15 +3953,16 @@ static int sdla_ds_te1_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) case WAN_FE_GET_STAT: /* TE1 Update T1/E1 perfomance counters */ sdla_ds_te1_pmon(fe, WAN_FE_PMON_UPDATE|WAN_FE_PMON_READ); + sdla_ds_te1_rxlevel(fe); + memcpy(&data[0], &fe->fe_stats, sizeof(sdla_fe_stats_t)); if (udp_cmd->wan_cmd_fe_force){ + sdla_fe_stats_t *fe_stats = (sdla_fe_stats_t*)&data[0]; /* force to read FE alarms */ DEBUG_EVENT("%s: Force to read Front-End alarms\n", fe->name); - fe->fe_stats.alarms = - sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); + fe_stats->alarms = + sdla_ds_te1_read_alarms(fe, WAN_FE_ALARM_READ); } - sdla_ds_te1_rxlevel(fe); - memcpy(&data[0], &fe->fe_stats, sizeof(sdla_fe_stats_t)); udp_cmd->wan_cmd_return_code = WAN_CMD_OK; udp_cmd->wan_cmd_data_len = sizeof(sdla_fe_stats_t); break; @@ -3948,6 +4061,16 @@ static int sdla_ds_te1_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) sdla_ds_te1_add_event(fe, &event); udp_cmd->wan_cmd_return_code = WAN_CMD_OK; break; + +#if 0 + case WAN_FE_DEBUG_CONFIG_VERIFY: + event.type = TE_POLL_CONFIG_VERIFY; + event.delay = POLLING_TE1_TIMER; + sdla_ds_te1_add_event(fe, &event); + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + break; +#endif + case WAN_FE_DEBUG_REG: if (fe->te_param.reg_dbg_busy){ if (fe_debug->fe_debug_reg.read == 2 && fe->te_param.reg_dbg_ready){ @@ -4023,14 +4146,14 @@ sdla_ds_te1_update_alarm_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt) "AIS", WAN_TE_AIS_ALARM(fe->fe_alarm)); if (IS_T1_FEMEDIA(fe)){ PROC_ADD_LINE(m, - PROC_STATS_ALARM_FORMAT, - "YEL", WAN_TE_YEL_ALARM(fe->fe_alarm), - "OOF", WAN_TE_OOF_ALARM(fe->fe_alarm)); + PROC_STATS_ALARM_FORMAT, + "RAI", WAN_TE_RAI_ALARM(fe->fe_alarm), + "OOF", WAN_TE_OOF_ALARM(fe->fe_alarm)); }else{ PROC_ADD_LINE(m, PROC_STATS_ALARM_FORMAT, "OOF", WAN_TE_OOF_ALARM(fe->fe_alarm), - "", ""); + "RAI", WAN_TE_RAI_ALARM(fe->fe_alarm)); } return m->count; #endif diff --git a/patches/kdrivers/src/net/sdla_adccp.c b/patches/kdrivers/src/net/sdla_adccp.c index 3752670..68bd213 100644 --- a/patches/kdrivers/src/net/sdla_adccp.c +++ b/patches/kdrivers/src/net/sdla_adccp.c @@ -238,6 +238,8 @@ typedef struct x25_channel } x25_channel_t; /* FIXME Take this out */ + + #pragma pack(1) #ifdef NEX_OLD_CALL_INFO typedef struct x25_call_info @@ -320,11 +322,7 @@ static void timer_intr (sdla_t *); /*================================================= * Background polling routines */ -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -static void wpx_poll (void * card_ptr); -# else -static void wpx_poll (struct work_struct *work); -#endif +static void wpx_poll (void*); #if 0 static void poll_disconnected (sdla_t* card); #endif @@ -530,7 +528,7 @@ int wp_adccp_init (sdla_t* card, wandev_conf_t* conf) u.cfg.station = 0; /* DCE mode */ } - if (conf->interface != WANOPT_RS232 ){ + if (conf->electrical_interface != WANOPT_RS232 ){ u.cfg.hdlcOptions |= 0x80; /* V35 mode */ } @@ -596,7 +594,7 @@ int wp_adccp_init (sdla_t* card, wandev_conf_t* conf) /* Initialize protocol-specific fields of adapter data space */ card->wandev.bps = conf->bps; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; card->wandev.station = conf->u.x25.station; card->isr = &wpx_isr; @@ -661,6 +659,7 @@ int wp_adccp_init (sdla_t* card, wandev_conf_t* conf) WAN_TASKQ_INIT((&card->u.x.x25_poll_task),0,wpx_poll,card); + init_timer(&card->u.x.x25_timer); card->u.x.x25_timer.data = (unsigned long)card; card->u.x.x25_timer.function = x25_timer_routine; @@ -713,7 +712,7 @@ static int update (wan_device_t* wandev) unsigned long smp_flags; /* sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL)) + if ((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if (wandev->state == WAN_UNCONFIGURED) @@ -726,7 +725,7 @@ static int update (wan_device_t* wandev) if (!dev) return -ENODEV; - card = wandev->private; + card = wandev->priv; DEBUG_EVENT("%s: UPDATE\n",card->devname); @@ -775,7 +774,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; x25_channel_t* chan; int err = 0; @@ -882,7 +881,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) static int del_if (wan_device_t* wandev, netdevice_t* dev) { - sdla_t *card=wandev->private; + sdla_t *card=wandev->priv; x25_channel_t* chan = dev->priv; set_chan_state(dev, WAN_DISCONNECTED); @@ -949,6 +948,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; dev->do_ioctl = &if_ioctl; @@ -2064,18 +2065,10 @@ static void spur_intr (sdla_t* card) * enabled. Beware! *====================================================================*/ -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -static void wpx_poll (void * card_ptr) -# else -static void wpx_poll (struct work_struct *work) -#endif +static void wpx_poll (void *card_ptr) { -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) - sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); -#else - sdla_t *card = (sdla_t *)card_ptr; -#endif netdevice_t *dev; + sdla_t *card=card_ptr; ++card->statistics.poll_processed; dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); @@ -4239,11 +4232,11 @@ static int x25_get_dev_config_info(char* buf, char** start, off_t offs, int len, int size = 0; PROC_ADD_DECL(stop_cnt); - if (wandev == NULL || wandev->private == NULL) + if (wandev == NULL || wandev->priv == NULL) return cnt; PROC_ADD_INIT(offs, stop_cnt); - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; x25_conf = &card->u.x.x25_conf; PROC_ADD_LINE(cnt, @@ -4337,7 +4330,7 @@ static int x25_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_adsl.c b/patches/kdrivers/src/net/sdla_adsl.c index efa9d84..f0e02c9 100644 --- a/patches/kdrivers/src/net/sdla_adsl.c +++ b/patches/kdrivers/src/net/sdla_adsl.c @@ -10,8 +10,11 @@ * Feb 25, 2002 Nenad Corbic Initial version * Based on GlobeSpan ADSL device driver. * http://www.globespan.net +* * July 1, 2002 Alex Feldman Porting ADSL driver to FreeBSD/OpenBSD * +* March 9, 2006 David Rokhvarg Ported ADSL driver to MS Windows XP/2003 +* * ============================================================================ * History: * 2/5/01 PG: Modified to add the support for EOC handling @@ -75,6 +78,15 @@ # include # include # include +#elif defined(__WINDOWS__) + +# include +# include +# include +# include +# include +# include + #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) # include # include @@ -94,11 +106,11 @@ */ #define MAX_TRACE_QUEUE 100 #define MAX_TRACE_BUFFER (MAX_LGTH_UDP_MGNT_PKT - \ - sizeof(iphdr_t) - \ - sizeof(udphdr_t) - \ - sizeof(wan_mgmt_t) - \ - sizeof(wan_trace_info_t) - \ - sizeof(wan_cmd_t)) + sizeof(iphdr_t) - \ + sizeof(udphdr_t) - \ + sizeof(wan_mgmt_t) - \ + sizeof(wan_trace_info_t) - \ + sizeof(wan_cmd_t)) /* ************************************************************************** @@ -115,6 +127,9 @@ #if defined(__LINUX__) # define LIST_FIRST_MCLIST(dev) dev->mc_list # define LIST_NEXT_MCLIST(mclist) mclist->next +#elif defined(__WINDOWS__) +# define LIST_FIRST_MCLIST(dev) dev->mc_list +# define LIST_NEXT_MCLIST(mclist) mclist->next #elif defined(__FreeBSD__) # define LIST_FIRST_MCLIST(dev) LIST_FIRST(&dev->if_multiaddrs) # define LIST_NEXT_MCLIST(mclist) mclist->ifma_link.le_next @@ -156,6 +171,26 @@ static void adsl_tx_timeout (netdevice_t *dev); static void adsl_multicast(netdevice_t* dev); static struct net_device_stats* adsl_stats(netdevice_t* dev); static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *conf); +#elif defined(__WINDOWS__) +static int adsl_open(netdevice_t*); +static int adsl_close(netdevice_t*); +static int adsl_output(struct sk_buff *skb, netdevice_t *dev); +static int adsl_ioctl(netdevice_t* ifp, struct ifreq *ifr, int command); +static void adsl_tx_timeout (netdevice_t *dev); +static void adsl_multicast(netdevice_t* dev); +static struct net_device_stats* adsl_stats(netdevice_t* dev); +static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *conf); + +static int netif_rx(netdevice_t *sdla_net_dev, netskb_t *rx_skb); +static int adsl_if_send(void *not_used, netdevice_t *sdla_net_dev); + +static int +adsl_insert_packet_in_to_rx_queue( + netdevice_t *sdla_net_dev, + RX_DATA_STRUCT *rx_data_struct + ); + +extern DRIVER_VERSION drv_version; #else static void adsl_watchdog (netdevice_t*); static void adsl_tx (netdevice_t *); @@ -171,17 +206,43 @@ static int adsl_init(netdevice_t* dev); static WAN_IRQ_RETVAL wpa_isr (sdla_t*); static void disable_comm(sdla_t* card); -static int process_udp_mgmt_pkt(sdla_t*, netdevice_t*, adsl_private_area_t*, int); static int new_if (wan_device_t*, netdevice_t*, wanif_conf_t*); static int del_if (wan_device_t*, netdevice_t*); static int process_udp_cmd(netdevice_t*,wan_udp_hdr_t*); + +#if defined(__WINDOWS__) +static void process_bh( + IN PKDPC Dpc, + IN PVOID arg, + IN PVOID not_used1, + IN PVOID not_used2 + ); + +static void adsl_if_send_task_func( + IN PKDPC Dpc, + IN PVOID arg, + IN PVOID not_used1, + IN PVOID not_used2 + ); + +static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* netdev, adsl_private_area_t* chan); +static int adsl_init(void* priv); + +#else + +#if defined(__LINUX__) # if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) static void process_bh (void *); -#else +# else static void process_bh (struct work_struct *work); -#endif -int adsl_trace_queue_len(void *trace_ptr); +# endif +#endif +static int process_udp_mgmt_pkt(sdla_t*, netdevice_t*, adsl_private_area_t*, int); + +#endif + +unsigned int adsl_trace_queue_len(void *trace_ptr); /* @@ -191,32 +252,32 @@ int adsl_trace_queue_len(void *trace_ptr); */ /*============================================================================ - * DSL Hardware initialization routine. - * - * This routine is called by the main WANPIPE module during setup. At this - * point adapter is completely initialized and firmware is running. - * - * Return: 0 o.k. - * < 0 failure. - */ +* DSL Hardware initialization routine. +* +* This routine is called by the main WANPIPE module during setup. At this +* point adapter is completely initialized and firmware is running. +* +* Return: 0 o.k. +* < 0 failure. +*/ int wp_adsl_init (sdla_t* card, wandev_conf_t* conf) { DEBUG_EVENT("%s: Initializing S518 ADSL card...\n", - card->devname); - + card->devname); + card->isr = &wpa_isr; card->poll = NULL; card->exec = NULL; card->wandev.update = NULL; /*&update; */ - card->wandev.new_if = &new_if; + card->wandev.new_if = &new_if; card->wandev.del_if = &del_if; card->wandev.udp_port = conf->udp_port; card->wandev.new_if_cnt = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; - conf->u.adsl.tty_minor = conf->tty_minor; + conf->u.adsl.tty_minor = (unsigned char)conf->tty_minor; switch (conf->u.adsl.EncapMode){ case RFC_MODE_ROUTED_IP_LLC: @@ -232,16 +293,16 @@ int wp_adsl_init (sdla_t* card, wandev_conf_t* conf) } break; } - conf->u.adsl.mtu = conf->mtu; + conf->u.adsl.mtu = (unsigned short)conf->mtu; card->wandev.mtu = conf->mtu; - + card->u.adsl.adapter = adsl_create(&conf->u.adsl, - card, - card->devname); + card, + card->devname); if (card->u.adsl.adapter == NULL){ return -EINVAL; } - + card->u.adsl.EncapMode = conf->u.adsl.EncapMode; card->wandev.station = conf->u.adsl.EncapMode; @@ -257,34 +318,34 @@ int wp_adsl_init (sdla_t* card, wandev_conf_t* conf) #endif } #endif - + #if defined(__LINUX__) - card->disable_comm = &disable_comm; + card->disable_comm = &disable_comm; #else - if (adsl_wan_interface_type(card->u.adsl.adapter)){ - card->disable_comm = &disable_comm; - } + if (adsl_wan_interface_type(card->u.adsl.adapter)){ + card->disable_comm = &disable_comm; + } #endif card->wandev.state = WAN_CONNECTING; - return 0; + return 0; } /*============================================================================ - * Handle transmit timeout event from netif watchdog - */ +* Handle transmit timeout event from netif watchdog +*/ #if defined(__NetBSD__) || defined (__FreeBSD__) || defined (__OpenBSD__) static void adsl_watchdog(netdevice_t* dev) { adsl_private_area_t* dsl = NULL; - sdla_t* card = NULL; + sdla_t* card = NULL; WAN_ASSERT1(dev == NULL); dsl = wan_netif_priv(dev); WAN_ASSERT1(dsl == NULL); - card = dsl->common.card; + card = dsl->common.card; DEBUG_TIMER("%s: Watchdog function called\n", - wan_netif_name(dev)); + wan_netif_name(dev)); process_udp_mgmt_pkt(card, dev, dsl,0); @@ -293,23 +354,27 @@ static void adsl_watchdog(netdevice_t* dev) /*============================================================================ - * Create new logical channel. - * This routine is called by the router when ROUTER_IFNEW IOCTL is being - * handled. - * o parse media- and hardware-specific configuration - * o make sure that a new channel can be created - * o allocate resources, if necessary - * o prepare network device structure for registaration. - * - * Return: 0 o.k. - * < 0 Failure (channel will not be created) - */ +* Create new logical channel. +* This routine is called by the router when ROUTER_IFNEW IOCTL is being +* handled. +* o parse media- and hardware-specific configuration +* o make sure that a new channel can be created +* o allocate resources, if necessary +* o prepare network device structure for registaration. +* +* Return: 0 o.k. +* < 0 Failure (channel will not be created) +*/ static int new_if (wan_device_t* wandev, netdevice_t* ifp, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; adsl_private_area_t* adsl = NULL; - + +#if defined(__WINDOWS__) + if ((ifp->name[0] == '\0') || (strlen(ifp->name) > WAN_IFNAME_SZ)) { +#else if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { +#endif DEBUG_EVENT("%s: Invalid interface name!\n", card->devname); return -EINVAL; @@ -320,113 +385,155 @@ static int new_if (wan_device_t* wandev, netdevice_t* ifp, wanif_conf_t* conf) } /* (FreeBSD/OpenBSD only) - * Verify that SPPP is enabled in the kernel. - */ + * Verify that SPPP is enabled in the kernel. + */ +#if !defined(__WINDOWS__) if (!WAN_SPPP_ENABLED){ if (card->u.adsl.EncapMode == RFC_MODE_PPP_VC || - card->u.adsl.EncapMode == RFC_MODE_PPP_LLC){ - DEBUG_EVENT("%s: Please verify that SPPP is enabled in your kernel!\n", - card->devname); - return -EINVAL; + card->u.adsl.EncapMode == RFC_MODE_PPP_LLC){ + DEBUG_EVENT("%s: Please verify that SPPP is enabled in your kernel!\n", + card->devname); + return -EINVAL; } } +#endif /* allocate and initialize private data */ adsl = wan_malloc(sizeof(adsl_private_area_t)); if (adsl == NULL){ DEBUG_EVENT("%s: Failed allocating private data...\n", - card->devname); + card->devname); return -ENOMEM; } memset(adsl,0,sizeof(adsl_private_area_t)); DEBUG_EVENT("%s: Configuring Interface: %s\n", - card->devname, conf->name); + card->devname, conf->name); /* prepare network device data space for registration */ - memcpy(adsl->if_name, conf->name, strlen(conf->name)); + memcpy(adsl->if_name, conf->name, strlen(conf->name)); if (wan_netif_init(ifp, adsl->if_name)){ DEBUG_EVENT("%s: Failed to initialize network interface!\n", - conf->name); + conf->name); wan_free(adsl); return -ENOMEM; } #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) ifp->if_softc = adsl; - ifp->if_output = adsl_output; - ifp->if_start = adsl_tx; - ifp->if_watchdog = adsl_watchdog; - ifp->if_ioctl = adsl_ioctl; + ifp->if_output = adsl_output; + ifp->if_start = adsl_tx; + ifp->if_watchdog = adsl_watchdog; + ifp->if_ioctl = adsl_ioctl; # if defined(__NetBSD__) || defined (__FreeBSD__) - ifp->if_init = adsl_init; + ifp->if_init = adsl_init; # endif - ifp->if_snd.ifq_len = 0; -#elif defined(__LINUX__) + ifp->if_snd.ifq_len = 0; +#elif defined(__LINUX__) || defined(__WINDOWS__) + +#if defined(__LINUX__) + WAN_TASKQ_INIT((&adsl->common.wanpipe_task), 0, process_bh, ifp); +#elif defined(__WINDOWS__) + /* # define WAN_TASKQ_INIT(task, priority, func, arg) */ + WAN_TASKQ_INIT((&adsl->common.wanpipe_task), 0, process_bh, ifp); + WAN_TASKQ_INIT((&adsl->adsl_if_send_task), 0, adsl_if_send_task_func, ifp); +#endif - WAN_TASKQ_INIT((&adsl->common.wanpipe_task),0,process_bh,ifp); - ifp->priv = adsl; ifp->irq = card->wandev.irq; - card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &ifp->mem_start); - card->hw_iface.getcfg(card->hw, SDLA_MEMEND, &ifp->mem_end); - - ifp->open = &adsl_open; - ifp->stop = &adsl_close; - ifp->hard_start_xmit = &adsl_output; - ifp->get_stats = &adsl_stats; - ifp->set_multicast_list = &adsl_multicast; + card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &ifp->mem_start); + card->hw_iface.getcfg(card->hw, SDLA_MEMEND, &ifp->mem_end); + + ifp->open = &adsl_open; + ifp->stop = &adsl_close; + +#if defined(__WINDOWS__) + ifp->hard_start_xmit = &adsl_if_send;/* will call adsl_output() */ + ifp->udp_mgmt = &process_udp_mgmt_pkt; + ifp->init = &adsl_init; + + adsl->common.card = card; + adsl->card = card; + + wpabs_trace_info_init(&adsl->trace_info, MAX_TRACE_QUEUE); + ifp->trace_info = &adsl->trace_info; + adsl->sdla_net_dev = ifp; + +#else + ifp->hard_start_xmit = &adsl_output; +#endif + + ifp->get_stats = &adsl_stats; + +#if !defined(__WINDOWS__) + ifp->set_multicast_list = &adsl_multicast; +#endif ifp->tx_timeout = &adsl_tx_timeout; ifp->watchdog_timeo = (1*HZ); - + ifp->do_ioctl = adsl_ioctl; -#endif +#endif/*#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)*/ adsl->common.card = card; adsl->pAdapter = adsl_new_if(card->u.adsl.adapter, adsl->macAddr, ifp); if (adsl->pAdapter == NULL){ DEBUG_EVENT("%s: Failed ADSL interface initialization\n", - card->devname); + card->devname); del_if(wandev, ifp); return -EINVAL; } +#if defined(__WINDOWS__) + //connect to the Interrupt Line + if(connect_to_interrupt_line(card)){ + return 1; + }else{ + //at this point we can handle front end interrupts + card->init_flag = 0; + } +#endif - +#if !defined(__WINDOWS__) if(strcmp(conf->usedby, "STACK") == 0) { adsl->common.usedby = STACK; DEBUG_EVENT( "%s:%s: Running in Stack mode.\n", - card->devname,adsl->if_name); + card->devname,adsl->if_name); card->u.adsl.EncapMode=RFC_MODE_STACK_VC; }else{ +#endif + adsl->common.usedby = WANPIPE; DEBUG_EVENT( "%s:%s: Running in Wanpipe mode.\n", - card->devname,adsl->if_name); + card->devname,adsl->if_name); +#if !defined(__WINDOWS__) } +#endif - /*TASK_INIT(&adsl->tq_atm_task, 0, &adsl_atm_tasklet, adsl->pAdapter); - */ - switch (card->u.adsl.EncapMode){ - + /*TASK_INIT(&adsl->tq_atm_task, 0, &adsl_atm_tasklet, adsl->pAdapter);*/ + switch (card->u.adsl.EncapMode) + { case RFC_MODE_BRIDGED_ETH_LLC: case RFC_MODE_BRIDGED_ETH_VC: DEBUG_EVENT("%s: Configuring %s as Ethernet\n", - card->devname, wan_netif_name(ifp)); + card->devname, wan_netif_name(ifp)); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - ifp->if_flags |= (IFF_DRV_RUNNING|IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); + ifp->if_flags |= (IFF_DRV_RUNNING|IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST); /* if_type,if_addrlen, if_hdrlen, if_mtu inialize - * in ether_ifattach - */ + * in ether_ifattach + */ # if !defined(__NetBSD__) bcopy(adsl->macAddr, - WAN_IFP2ENADDR(ifp)/*(WAN_IFP2AC(ifp))->ac_enaddr*/, - 6); + WAN_IFP2ENADDR(ifp)/*(WAN_IFP2AC(ifp))->ac_enaddr*/, + 6); # endif bcopy(adsl->macAddr, wandev->macAddr, ETHER_ADDR_LEN); #else + +#if !defined(__WINDOWS__) ether_setup(ifp); +#endif memcpy(ifp->dev_addr, adsl->macAddr, 6); #endif break; @@ -434,19 +541,19 @@ static int new_if (wan_device_t* wandev, netdevice_t* ifp, wanif_conf_t* conf) case RFC_MODE_ROUTED_IP_LLC: case RFC_MODE_ROUTED_IP_VC: DEBUG_EVENT("%s: Configuring %s as Raw IP\n", - card->devname, wan_netif_name(ifp)); - + card->devname, wan_netif_name(ifp)); +#if !defined(__WINDOWS__) /* Drop down to STACK_VC: Standard if config */ - case RFC_MODE_STACK_VC: - +#endif + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - ifp->if_mtu = card->wandev.mtu; /* ETHERMTU */ - ifp->if_type = IFT_OTHER; - ifp->if_flags |= (IFF_POINTOPOINT|IFF_DRV_RUNNING); - /*ifp->if_flags |= IFF_NOARP;*/ - ifp->if_hdrlen = 0; -#else + ifp->if_mtu = card->wandev.mtu; /* ETHERMTU */ + ifp->if_type = IFT_OTHER; + ifp->if_flags |= (IFF_POINTOPOINT|IFF_DRV_RUNNING); + /*ifp->if_flags |= IFF_NOARP;*/ + ifp->if_hdrlen = 0; +#elif defined(__LINUX__) ifp->type = ARPHRD_PPP; ifp->flags |= IFF_POINTOPOINT; ifp->flags |= IFF_NOARP; @@ -457,12 +564,13 @@ static int new_if (wan_device_t* wandev, netdevice_t* ifp, wanif_conf_t* conf) #endif break; +#if !defined(__WINDOWS__) case RFC_MODE_PPP_VC: case RFC_MODE_PPP_LLC: DEBUG_EVENT("%s: Attaching SPPP protocol \n", card->devname); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) WAN_SPPP_ATTACH(ifp); - ifp->if_start = adsl_sppp_tx; + ifp->if_start = adsl_sppp_tx; #else ifp->type = ARPHRD_PPP; ifp->flags |= IFF_POINTOPOINT; @@ -489,28 +597,29 @@ static int new_if (wan_device_t* wandev, netdevice_t* ifp, wanif_conf_t* conf) ifp->do_ioctl = adsl_ioctl; #endif break; +#endif /* #if !defined(__WINDOWS__) */ default: DEBUG_EVENT("%s: Error invalid EncapMode %i\n", - card->devname,card->u.adsl.EncapMode); + card->devname,card->u.adsl.EncapMode); del_if(wandev,ifp); return -EINVAL; } - + wan_getcurrenttime(&adsl->router_start_time, NULL); - return 0; + return 0; } static int del_if (wan_device_t* wandev, netdevice_t* ifp) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; adsl_private_area_t* adsl = wan_netif_priv(ifp); WAN_ASSERT(adsl == NULL); - + DEBUG_EVENT("%s: Deleting Interface %s\n", - card->devname, wan_netif_name(ifp)); + card->devname, wan_netif_name(ifp)); if (adsl->pAdapter != NULL){ adsl_del_if(adsl->pAdapter); @@ -522,50 +631,55 @@ static int del_if (wan_device_t* wandev, netdevice_t* ifp) } card->u.adsl.adapter = NULL; adsl->pAdapter = NULL; - - /* Initialize interrupt handler pointer */ - card->isr = NULL; + /* Initialize interrupt handler pointer */ + card->isr = NULL; +#if defined(__WINDOWS__) + disconnect_from_interrupt_line(card); +#else /* Initialize network interface */ if (card->u.adsl.EncapMode == RFC_MODE_PPP_VC || - card->u.adsl.EncapMode == RFC_MODE_PPP_LLC){ + card->u.adsl.EncapMode == RFC_MODE_PPP_LLC){ - DEBUG_EVENT("%s: Detaching SPPP protocol \n", card->devname); + DEBUG_EVENT("%s: Detaching SPPP protocol \n", card->devname); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - WAN_SPPP_FLUSH(ifp); - WAN_SPPP_DETACH(ifp); + WAN_SPPP_FLUSH(ifp); + WAN_SPPP_DETACH(ifp); #else - if (adsl->common.prot_ptr){ - wp_sppp_detach(ifp); + if (adsl->common.prot_ptr){ + wp_sppp_detach(ifp); - ifp->do_ioctl = NULL; + ifp->do_ioctl = NULL; + ifp->hard_header = NULL; + ifp->rebuild_header = NULL; - kfree(adsl->common.prot_ptr); - adsl->common.prot_ptr= NULL; - } + wan_free(adsl->common.prot_ptr); + adsl->common.prot_ptr= NULL; + } #endif } +#endif/* #if !defined(__WINDOWS__)*/ #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) #if 0 - ifp->if_output = NULL; - ifp->if_start = NULL; - ifp->if_ioctl = NULL; - ifp->if_watchdog= NULL; + ifp->if_output = NULL; + ifp->if_start = NULL; + ifp->if_ioctl = NULL; + ifp->if_watchdog= NULL; # if defined(__NetBSD__) || defined(__FreeBSD__) - ifp->if_init = NULL; + ifp->if_init = NULL; # endif - ifp->if_flags &= ~(IFF_UP | IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - if (ifp->if_softc){ - wan_free(ifp->if_softc); - ifp->if_softc = NULL; - } + ifp->if_flags &= ~(IFF_UP | IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + if (ifp->if_softc){ + wan_free(ifp->if_softc); + ifp->if_softc = NULL; + } #endif #else ifp->irq = 0; - ifp->mem_start = 0; - ifp->mem_end = 0; + ifp->mem_start = 0; + ifp->mem_end = 0; /* Private structure will be free later */ wan_netif_del(ifp); #endif @@ -574,23 +688,25 @@ static int del_if (wan_device_t* wandev, netdevice_t* ifp) } /*+F************************************************************************* - * Function: - * adsl_init - * - * Description: - *-F*************************************************************************/ +* Function: +* adsl_init +* +* Description: +*-F*************************************************************************/ #if defined(__FreeBSD__) static void adsl_init(void* priv){ return; } #elif defined(__NetBSD__) static int adsl_init(netdevice_t* dev){return 0; } +#elif defined(__WINDOWS__) +static int adsl_init(netdevice_t* dev){return 0; } #endif /*+F************************************************************************* - * Function: - * adsl_vcivpi_update - * - * Description: - *-F*************************************************************************/ +* Function: +* adsl_vcivpi_update +* +* Description: +*-F*************************************************************************/ void adsl_vcivpi_update(sdla_t* card, wandev_conf_t* conf) { wan_adsl_conf_t* adsl_conf = &conf->u.adsl; @@ -601,54 +717,56 @@ void adsl_vcivpi_update(sdla_t* card, wandev_conf_t* conf) adsl_conf->vcivpi_list[x].vpi = adsl_vcivpi_list[x].vpi; } - adsl_conf->vcivpi_num = adsl_vcivpi_num; + adsl_conf->vcivpi_num = (unsigned short)adsl_vcivpi_num; } /*+F************************************************************************* - * Function: - * disable_comm - * - * Description: - * Called by the LAN subsystem when the ethernet interface is - * configured make ready to accept data (ifconfig up). - *-F*************************************************************************/ +* Function: +* disable_comm +* +* Description: +* Called by the LAN subsystem when the ethernet interface is +* configured make ready to accept data (ifconfig up). +*-F*************************************************************************/ static void disable_comm(sdla_t* card) { char wan; if (!card->u.adsl.adapter) return; - - wan = adsl_wan_interface_type(card->u.adsl.adapter); - + + wan = (char)adsl_wan_interface_type(card->u.adsl.adapter); + adsl_disable_comm(card->u.adsl.adapter); card->u.adsl.adapter = NULL; if (wan){ +#if !defined(__WINDOWS__) #if !defined(LINUX_2_6) MOD_DEC_USE_COUNT; +#endif #endif } } #if defined(__LINUX__) /*+F************************************************************************* - * Function: - * adsl_tx_timeout - * - * Description: - * Handle transmit timeout event from netif watchdog - *-F*************************************************************************/ +* Function: +* adsl_tx_timeout +* +* Description: +* Handle transmit timeout event from netif watchdog +*-F*************************************************************************/ static void adsl_tx_timeout (netdevice_t *dev) { - adsl_private_area_t* adsl = wan_netif_priv(dev); + adsl_private_area_t* adsl = wan_netif_priv(dev); sdla_t* card = adsl->common.card; /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ #if defined(__LINUX__) dev->trans_start = SYSTEM_TICKS; #endif @@ -660,19 +778,18 @@ static void adsl_tx_timeout (netdevice_t *dev) } /*+F************************************************************************* - * Function: - * adsl_open - * - * Description: - * Called by the LAN subsystem when the ethernet interface is configured - * make ready to accept data (ifconfig up). - *-F*************************************************************************/ +* Function: +* adsl_open +* +* Description: +* Called by the LAN subsystem when the ethernet interface is configured +* make ready to accept data (ifconfig up). +*-F*************************************************************************/ static int adsl_open(netdevice_t* ifp) { int status = 0; -#if defined (__LINUX__) adsl_private_area_t* adsl = wan_netif_priv(ifp); -#endif + sdla_t* card = adsl->common.card; #if defined (__LINUX__) if (adsl->common.prot_ptr){ @@ -681,19 +798,25 @@ static int adsl_open(netdevice_t* ifp) } } #endif - + /* Start Tx queuing */ WAN_NETDEVICE_START(ifp); - WAN_NETIF_START_QUEUE(ifp); + if (card->wandev.state == WAN_CONNECTED) { + WAN_NETIF_CARRIER_ON(ifp); + WAN_NETIF_START_QUEUE(ifp); + } else { + WAN_NETIF_CARRIER_OFF(ifp); + WAN_NETIF_STOP_QUEUE(ifp); + } if (adsl->common.usedby == STACK){ /* Force the lip to connect state - * since there is no state change - * mechanism for an interface - * FIXME: This is temporary */ + * since there is no state change + * mechanism for an interface + * FIXME: This is temporary */ wanpipe_lip_connect(adsl,0); } - + #if !defined(LINUX_2_6) MOD_INC_USE_COUNT; #endif @@ -701,13 +824,13 @@ static int adsl_open(netdevice_t* ifp) } /*+F************************************************************************* - * Function: - * adsl_close - * - * Description: - * Called by the LAN subsystem when the ethernet interface is disabled - * (ifconfig down). - *-F*************************************************************************/ +* Function: +* adsl_close +* +* Description: +* Called by the LAN subsystem when the ethernet interface is disabled +* (ifconfig down). +*-F*************************************************************************/ int adsl_close(netdevice_t* ifp) { int status = 0; @@ -731,47 +854,117 @@ int adsl_close(netdevice_t* ifp) #endif return status; } +#elif defined(__WINDOWS__) +/*+F************************************************************************* +* Function: +* adsl_tx_timeout +* +* Description: +* Handle transmit timeout event from netif watchdog +*-F*************************************************************************/ +static void adsl_tx_timeout (netdevice_t *dev) +{ + adsl_private_area_t* adsl = wan_netif_priv(dev); + sdla_t* card = adsl->common.card; + + DBG_DSL_NOT_IMPLD + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + /* + dev->trans_start = SYSTEM_TICKS; + card->wandev.stats.collisions++; + + adsl_timeout(card->u.adsl.adapter); + WAN_NETIF_WAKE_QUEUE(dev); + */ +} + +/*+F************************************************************************* +* Function: +* adsl_open +* +* Description: +* Called by the LAN subsystem when the ethernet interface is configured +* make ready to accept data (ifconfig up). +*-F*************************************************************************/ +static int adsl_open(netdevice_t* ifp) +{ + int status = 0; + + DBG_DSL_NOT_IMPLD +#if defined (__LINUX__) + adsl_private_area_t* adsl = wan_netif_priv(ifp); +#endif + return status; +} + +/*+F************************************************************************* +* Function: +* adsl_close +* +* Description: +* Called by the LAN subsystem when the ethernet interface is disabled +* (ifconfig down). +*-F*************************************************************************/ +int adsl_close(netdevice_t* ifp) +{ + int status = 0; +#if defined (__LINUX__) + adsl_private_area_t* adsl = wan_netif_priv(ifp); +#endif + DBG_DSL_NOT_IMPLD + + return status; +} #endif /*+F************************************************************************* - * Function: - * wpa_isr - * - * Description: - *-F*************************************************************************/ +* Function: +* wpa_isr +* +* Description: +*-F*************************************************************************/ static WAN_IRQ_RETVAL wpa_isr (sdla_t* card) { int ret; + + DEBUG_ISR("%s()\n", __FUNCTION__); + if (!card->u.adsl.adapter){ DEBUG_CFG("wpa_isr: No adapter ptr!\n"); WAN_IRQ_RETURN(WAN_IRQ_NONE); } /*WAN_ASSERT1(card->u.adsl.adapter == NULL);*/ ret=adsl_isr((void*)card->u.adsl.adapter); + DEBUG_ISR("%s(): ret: %d\n", __FUNCTION__, ret); if (ret) { - WAN_IRQ_RETURN(WAN_IRQ_HANDLED); + WAN_IRQ_RETURN(WAN_IRQ_HANDLED); } - + WAN_IRQ_RETURN(WAN_IRQ_NONE); } /*+F************************************************************************* - * Function: - * adsl_lan_rx - * - * Description: - * A new LAN receive packet is available. Create a SKB for the data, and - * give it to the operating system. - *-F*************************************************************************/ +* Function: +* adsl_lan_rx +* +* Description: +* A new LAN receive packet is available. Create a SKB for the data, and +* give it to the operating system. +*-F*************************************************************************/ void adsl_lan_rx( - void* dev_id, - void* pHeader, - unsigned long headerSize, - unsigned char* rx_data, - int rx_len - ) + void* dev_id, + void* pHeader, + unsigned long headerSize, + unsigned char* rx_data, + int rx_len + ) { netdevice_t* dev = (netdevice_t*)dev_id; sdla_t* card = NULL; @@ -791,44 +984,76 @@ adsl_lan_rx( WAN_ASSERT1(dev == NULL); WAN_ASSERT1(adsl == NULL); card = (sdla_t*)adsl->common.card; - DEBUG_RX("(RX INTR) pHeader, (%p)\n", pHeader); - DEBUG_RX("(RX INTR) headerSize, %ld\n", headerSize); - DEBUG_RX("(RX INTR) rx_len, %d\n", rx_len); + DEBUG_RX("(RX INTR) pHeader, (%p)\n", pHeader); + DEBUG_RX("(RX INTR) headerSize, %ld\n", headerSize); + DEBUG_RX("(RX INTR) rx_len, %d\n", rx_len); - len = headerSize + rx_len; +#if defined(__WINDOWS__) + //DBG_ADSL_RX("(RX INTR) pHeader, (%p)\n", pHeader); //for rfc 1483 always zero + //DBG_ADSL_RX("(RX INTR) headerSize, %ld\n", headerSize); //for rfc 1483 always zero + DBG_ADSL_RX("(RX INTR) rx_len, %d\n", rx_len); + + len = rx_len; +#else + len = headerSize + rx_len; +#endif if (len == 0) return; +#if defined(__WINDOWS__) + rx_skb = wan_skb_alloc(len); +#else rx_skb = wan_skb_alloc(len+4); +#endif if (rx_skb == NULL){ DEBUG_EVENT("%s: Failed allocate memory for RX packet!\n", - wan_netif_name(dev)); + wan_netif_name(dev)); return; } - wan_skb_reserve(rx_skb, 2); - wan_skb_set_dev(rx_skb, dev); + +#if !defined(__WINDOWS__) + wpabs_skb_reserve(rx_skb, 2); + wpabs_skb_set_dev(rx_skb, dev); +#endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) eh = (struct ether_header*)wan_skb_data(rx_skb); #endif - if (card->u.adsl.EncapMode == RFC_MODE_PPP_VC || - card->u.adsl.EncapMode == RFC_MODE_PPP_LLC || - card->u.adsl.EncapMode == RFC_MODE_STACK_VC){ - if (rx_data[0] != hdr[0] || rx_data[1] != hdr[1]){ - wan_skb_copyback(rx_skb, - wan_skb_len(rx_skb), - 2, - (caddr_t)hdr); - } - } - - if (pHeader && headerSize){ - wan_skb_copyback(rx_skb, - wan_skb_len(rx_skb), - headerSize, - (caddr_t)pHeader); - } - wan_skb_copyback(rx_skb, wan_skb_len(rx_skb), len, (caddr_t)rx_data); +#if !defined(__WINDOWS__) + if (card->u.adsl.EncapMode == RFC_MODE_PPP_VC || + card->u.adsl.EncapMode == RFC_MODE_PPP_LLC || + card->u.adsl.EncapMode == RFC_MODE_STACK_VC ){ + + if (rx_data[0] != hdr[0] || rx_data[1] != hdr[1]){ + wpabs_skb_copyback(rx_skb, + wan_skb_len(rx_skb), + 2, +# if defined(__LINUX__) + (unsigned long)hdr); +# else + (caddr_t)hdr); +# endif + } + } +#endif + + if (pHeader && headerSize){ + wpabs_skb_copyback(rx_skb, + wan_skb_len(rx_skb), + headerSize, +#if defined(__LINUX__) + (unsigned long)pHeader); +#else + (caddr_t)pHeader); +#endif + } + +#if defined(__LINUX__) + wpabs_skb_copyback(rx_skb, wan_skb_len(rx_skb), len, (unsigned long)rx_data); +#else + wpabs_skb_copyback(rx_skb, wan_skb_len(rx_skb), len, (caddr_t)rx_data); +#endif + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) # if defined(__FreeBSD__) && (__FreeBSD_version < 500000) @@ -841,7 +1066,6 @@ adsl_lan_rx( card->wandev.stats.rx_bytes += wan_skb_len(rx_skb); switch(card->u.adsl.EncapMode){ - case RFC_MODE_STACK_VC: if (wanpipe_lip_rx(adsl,rx_skb) != 0){ card->wandev.stats.rx_packets--; @@ -849,7 +1073,7 @@ adsl_lan_rx( wan_skb_free(rx_skb); } break; - + case RFC_MODE_PPP_VC: case RFC_MODE_PPP_LLC: wan_skb_clear_mark(rx_skb); @@ -866,13 +1090,13 @@ adsl_lan_rx( schednetisr(NETISR_IP); if (IF_QFULL(&ipintrq)){ DEBUG_RX("%s: IP queue is full, drop packet!\n", - card->devname); + card->devname); /* oh, no - IP queue is full - well - we'll ** try again later */ card->wandev.stats.rx_packets--; card->wandev.stats.rx_bytes -= wan_skb_len(rx_skb); - + IF_DROP(&ipintrq); wan_skb_free(rx_skb); wan_spin_unlock_irq(NULL, &s); @@ -895,14 +1119,15 @@ adsl_lan_rx( # endif break; } - -#else /* LINUX */ + +#else /* LINUX, WINDOWS */ card->wandev.stats.rx_packets ++; card->wandev.stats.rx_bytes += wan_skb_len(rx_skb); switch (card->u.adsl.EncapMode){ +#if !defined(__WINDOWS__) case RFC_MODE_STACK_VC: if (wanpipe_lip_rx(adsl,rx_skb) != 0){ card->wandev.stats.rx_packets--; @@ -910,29 +1135,41 @@ adsl_lan_rx( wan_skb_free(rx_skb); } break; - +#endif + case RFC_MODE_BRIDGED_ETH_LLC: case RFC_MODE_BRIDGED_ETH_VC: +#if defined(__WINDOWS__) + netif_rx(dev, rx_skb); +#else rx_skb->protocol = eth_type_trans(rx_skb, rx_skb->dev); netif_rx(rx_skb); +#endif break; + case RFC_MODE_ROUTED_IP_LLC: case RFC_MODE_ROUTED_IP_VC: +#if defined(__WINDOWS__) + netif_rx(dev, rx_skb); +#else rx_skb->protocol = htons(ETH_P_IP); - wan_skb_reset_mac_header(rx_skb); + __wan_skb_reset_mac_header(rx_skb); netif_rx(rx_skb); +#endif break; - + +#if !defined(__WINDOWS__) case RFC_MODE_PPP_VC: case RFC_MODE_PPP_LLC: rx_skb->protocol = htons(ETH_P_WAN_PPP); - rx_skb->dev = dev; - wan_skb_reset_mac_header(rx_skb); + rx_skb->dev = dev; + __wan_skb_reset_mac_header(rx_skb); wp_sppp_input(rx_skb->dev,rx_skb); break; +#endif } - + #endif @@ -940,14 +1177,14 @@ adsl_lan_rx( } /*+F************************************************************************* - * Function: - * adsl_output - * - * Description: - * Handle a LAN interface buffer (SKB) transmit request. Allocate an NDIS - * buffer, copy the data into the NDIS packet, and give it to the RFC layer. - *-F*************************************************************************/ -#if defined(__LINUX__) +* Function: +* adsl_output +* +* Description: +* Handle a LAN interface buffer (SKB) transmit request. Allocate an NDIS +* buffer, copy the data into the NDIS packet, and give it to the RFC layer. +*-F*************************************************************************/ +#if defined(__LINUX__) || defined(__WINDOWS__) int adsl_output(netskb_t* skb, netdevice_t* dev) #else static int @@ -955,41 +1192,42 @@ adsl_output(netdevice_t* dev, netskb_t* skb, struct sockaddr* dst, struct rtentr #endif { sdla_t* card = NULL; - adsl_private_area_t* adsl = wan_netif_priv(dev); - int status = 0; -#if defined(__LINUX__) + adsl_private_area_t* adsl = wan_netif_priv(dev); + int status = 0; +#if defined(__LINUX__) || defined(__WINDOWS__) unsigned long smp_flags; #endif #if defined(ALTQ) WAN_PKTATTR_DECL(pktattr); #endif - - if (!skb){ + + if (!skb){ WAN_NETIF_START_QUEUE(dev); return 0; - } + } - if (!adsl){ + if (!adsl){ DEBUG_EVENT("%s: Error: TxLan: No private adapter !\n", wan_netif_name(dev)); -#if defined(__LINUX__) +#if defined(__LINUX__) || defined(__WINDOWS__) wan_skb_free(skb); #endif WAN_NETIF_START_QUEUE(dev); return 0; - } + } card = (sdla_t*)adsl->common.card; - switch (card->u.adsl.EncapMode){ - +#if !defined(__WINDOWS__) + switch (card->u.adsl.EncapMode) + { case RFC_MODE_PPP_VC: case RFC_MODE_PPP_LLC: case RFC_MODE_STACK_VC: - if (wan_skb_len(skb) <= 2){ DEBUG_EVENT("%s: Error: TxLan: PPP pkt len <= 2! (len=%i)\n", wan_netif_name(dev),wan_skb_len(skb)); + wan_skb_print(skb); wan_skb_free(skb); WAN_NETIF_START_QUEUE(dev); @@ -998,24 +1236,25 @@ adsl_output(netdevice_t* dev, netskb_t* skb, struct sockaddr* dst, struct rtentr } wan_skb_pull(skb,2); break; - } - - if (adsl_can_tx(adsl->pAdapter)){ - wan_skb_free(skb); + }/* switch() */ +#endif + + if (adsl_can_tx(adsl->pAdapter)){ + wpabs_skb_free(skb); WAN_NETIF_START_QUEUE(dev); card->wandev.stats.tx_carrier_errors++; -#if defined(__LINUX__) +#if defined(__LINUX__) || defined(__WINDOWS__) dev->trans_start = SYSTEM_TICKS; return 0; #else return -EINVAL; #endif } - + DEBUG_TX("%s: TxLan %d bytes...\n", - card->devname, wan_skb_len(skb)); - - + card->devname, wan_skb_len(skb)); + + #if 0 DBG_ASSERT(skb->len < GSI_LAN_NDIS_BUFFER_SIZE); @@ -1029,12 +1268,12 @@ adsl_output(netdevice_t* dev, netskb_t* skb, struct sockaddr* dst, struct rtentr printk("\n"); } #endif - + #if defined(__LINUX__) dev->trans_start = SYSTEM_TICKS; status = adsl_send(adsl->pAdapter, skb, 0); wan_spin_lock_irq(&card->wandev.lock,&smp_flags); - if (status == 1){ + if (status == 1){ WAN_NETIF_STOP_QUEUE(dev); wan_set_bit(TX_BUSY_SET,&card->wandev.critical); status = 1; @@ -1047,10 +1286,31 @@ adsl_output(netdevice_t* dev, netskb_t* skb, struct sockaddr* dst, struct rtentr status = 0; } wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); +#elif defined(__WINDOWS__) + dev->trans_start = SYSTEM_TICKS; + status = adsl_send(adsl->pAdapter, skb, 0); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + if (status == 1){ + WAN_NETIF_STOP_QUEUE(dev); + wan_set_bit(TX_BUSY_SET,&card->wandev.critical); + status = 1; + }else{ + if (status == 2){ + card->wandev.stats.rx_dropped++; + } +// wpabs_skb_free(skb);//can NOT deallocate memory inside IRQ Lock!!! + WAN_NETIF_START_QUEUE(dev); + status = 0; + } + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + if(status == 0){ + wpabs_skb_free(skb); + } #else if (dst->sa_family != AF_INET){ DEBUG_EVENT("%s: Protocol family is not supported!\n", - card->devname); + card->devname); wan_skb_free(skb); return -EAFNOSUPPORT; } @@ -1069,7 +1329,7 @@ adsl_output(netdevice_t* dev, netskb_t* skb, struct sockaddr* dst, struct rtentr WAN_IFQ_ENQUEUE(&dev->if_snd, skb, &pktattr, status); if (status){ DEBUG_TX("%s: Send queue is full!\n", - card->devname); + card->devname); wan_skb_free(skb); break; } @@ -1088,30 +1348,30 @@ adsl_output(netdevice_t* dev, netskb_t* skb, struct sockaddr* dst, struct rtentr break; } #endif - return status; + return status; } - + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) /*+F************************************************************************* - * Function: - * adsl_sppp_tx - * - * Description: - * Handle a LAN interface buffer (SKB) transmit request. Allocate an NDIS - * buffer, copy the data into the NDIS packet, and give it to the RFC layer. - *-F*************************************************************************/ +* Function: +* adsl_sppp_tx +* +* Description: +* Handle a LAN interface buffer (SKB) transmit request. Allocate an NDIS +* buffer, copy the data into the NDIS packet, and give it to the RFC layer. +*-F*************************************************************************/ void adsl_sppp_tx (netdevice_t *ifp) { netskb_t* tx_mbuf = NULL; - adsl_private_area_t* adsl = wan_netif_priv(ifp); - + adsl_private_area_t* adsl = wan_netif_priv(ifp); + WAN_ASSERT1(ifp == NULL); WAN_ASSERT1(adsl == NULL); - if (adsl_can_tx(adsl->pAdapter)){ + if (adsl_can_tx(adsl->pAdapter)){ return; } - - while((tx_mbuf = WAN_SPPP_DEQUEUE(ifp)) != NULL){ + + while((tx_mbuf = WAN_SPPP_DEQUEUE(ifp)) != NULL){ #if 0 if (wan_skb_check(tx_mbuf)){ #endif @@ -1125,14 +1385,14 @@ void adsl_sppp_tx (netdevice_t *ifp) } #endif DEBUG_TX("%s: TxLan %d bytes...\n", - wan_netif_name(ifp), - wan_skb_len(tx_mbuf)); + wan_netif_name(ifp), + wan_skb_len(tx_mbuf)); wan_bpf_report(ifp, tx_mbuf, 0, WAN_BPF_DIR_OUT); wan_skb_pull(tx_mbuf, 2); if (adsl_send(adsl->pAdapter, tx_mbuf, 0)){ DEBUG_TX("%s: TX failed to send %d bytes!\n", - wan_netif_name(ifp), - wan_skb_len(tx_mbuf)); + wan_netif_name(ifp), + wan_skb_len(tx_mbuf)); ifp->if_iqdrops++; } @@ -1141,25 +1401,25 @@ void adsl_sppp_tx (netdevice_t *ifp) } } - return; + return; } /*+F************************************************************************* - * Function: - * adsl_tx - * - * Description: - * Handle a LAN interface buffer (SKB) transmit request. Allocate an NDIS - * buffer, copy the data into the NDIS packet, and give it to the RFC layer. - *-F*************************************************************************/ +* Function: +* adsl_tx +* +* Description: +* Handle a LAN interface buffer (SKB) transmit request. Allocate an NDIS +* buffer, copy the data into the NDIS packet, and give it to the RFC layer. +*-F*************************************************************************/ void adsl_tx (netdevice_t *ifp) { netskb_t* tx_mbuf = NULL; - adsl_private_area_t* adsl = wan_netif_priv(ifp); + adsl_private_area_t* adsl = wan_netif_priv(ifp); #if 0 sdla_t* card = NULL; #endif - + WAN_ASSERT1(ifp == NULL); WAN_ASSERT1(adsl == NULL); WAN_ASSERT1(adsl->common.card == NULL); @@ -1167,15 +1427,15 @@ void adsl_tx (netdevice_t *ifp) #if defined(NETGRAPH) #if 0 card = adsl->card; - while(!WAN_IFQ_IS_EMPTY(&card->xmitq_hipri)){ + while(!WAN_IFQ_IS_EMPTY(&card->xmitq_hipri)){ WAN_IFQ_POLL(&card->xmitq_hipri, tx_mbuf); if (tx_mbuf == NULL) break; DEBUG_TX("%s: TxLan %d bytes...\n", - wan_netif_name(ifp), wan_skb_len(tx_mbuf)); + wan_netif_name(ifp), wan_skb_len(tx_mbuf)); if (adsl_send(adsl->pAdapter, tx_mbuf, 0)){ DEBUG_TX("%s: TX failed to send %d bytes!\n", wan_netif_name(ifp), wan_skb_len(tx_mbuf)); - } + } WAN_IFQ_DEQUEUE(&card->xmitq_hipri, tx_mbuf); if (tx_mbuf){ @@ -1184,7 +1444,7 @@ void adsl_tx (netdevice_t *ifp) } #endif #endif - while(!WAN_IFQ_IS_EMPTY(&ifp->if_snd)){ + while(!WAN_IFQ_IS_EMPTY(&ifp->if_snd)){ WAN_IFQ_DEQUEUE(&ifp->if_snd, tx_mbuf); if (tx_mbuf == NULL) break; @@ -1203,31 +1463,31 @@ void adsl_tx (netdevice_t *ifp) #endif DEBUG_TX("%s: TxLan %d bytes...\n", - wan_netif_name(ifp), - wan_skb_len(tx_mbuf)); - if (adsl_send(adsl->pAdapter, tx_mbuf, 0)){ + wan_netif_name(ifp), + wan_skb_len(tx_mbuf)); + if (adsl_send(adsl->pAdapter, tx_mbuf, 0)){ DEBUG_TX("%s: TX failed to send %d bytes!\n", - wan_netif_name(ifp), - wan_skb_len(tx_mbuf)); + wan_netif_name(ifp), + wan_skb_len(tx_mbuf)); ifp->if_iqdrops++; } - + wan_bpf_report(ifp, tx_mbuf, 0, WAN_BPF_DIR_OUT); if (tx_mbuf){ wan_skb_free(tx_mbuf); } } - return; + return; } #endif /*+F************************************************************************* - * Function: - * aadsl_tx_complete - * - * Description: - *-F*************************************************************************/ +* Function: +* aadsl_tx_complete +* +* Description: +*-F*************************************************************************/ void adsl_tx_complete(void* dev_id, int length, int txStatus) { netdevice_t* ifp = (netdevice_t*)dev_id; @@ -1238,119 +1498,123 @@ void adsl_tx_complete(void* dev_id, int length, int txStatus) adsl = wan_netif_priv(ifp); WAN_ASSERT1(adsl == NULL); - + card = (sdla_t*)adsl->common.card; WAN_ASSERT1(card == NULL); - - if (txStatus == 0){ + + if (txStatus == 0){ DEBUG_TX("%s: TxLan tx successful.\n", - wan_netif_name(ifp)); + wan_netif_name(ifp)); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - ifp->if_opackets++; - ifp->if_obytes += length; + ifp->if_opackets++; + ifp->if_obytes += length; #endif card->wandev.stats.tx_packets ++; card->wandev.stats.tx_bytes += length; - }else{ + }else{ DEBUG_TX("%s: TxLan tx failure.\n", - wan_netif_name(ifp)); + wan_netif_name(ifp)); #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - ifp->if_oerrors++; + ifp->if_oerrors++; #endif - } + } -#if defined(__LINUX__) +#if defined(__LINUX__) || defined(__WINDOWS__) ifp->trans_start = SYSTEM_TICKS; #endif +#if defined(__WINDOWS__) + wan_clear_bit(TX_BUSY_SET,&card->wandev.critical); + WAN_NETIF_WAKE_QUEUE(ifp); +#else if (WAN_NETIF_QUEUE_STOPPED(ifp) || - wan_test_bit(TX_BUSY_SET,&card->wandev.critical)){ - - wan_clear_bit(TX_BUSY_SET,&card->wandev.critical); - DEBUG_TX("%s: adsl_tx_complete, waking dev %s\n", - card->devname, wan_netif_name(ifp)); - WAN_NETIF_WAKE_QUEUE(ifp); + wan_test_bit(TX_BUSY_SET,&card->wandev.critical)){ - if (adsl->common.usedby == STACK){ - wanpipe_lip_kick(adsl,0); - } + wan_clear_bit(TX_BUSY_SET,&card->wandev.critical); + DEBUG_TX("%s: adsl_tx_complete, waking dev %s\n", + card->devname, wan_netif_name(ifp)); + WAN_NETIF_WAKE_QUEUE(ifp); + if (adsl->common.usedby == STACK){ + wanpipe_lip_kick(adsl,0); + } } - return ; +#endif + return ; } #if defined(__LINUX__) /*+F************************************************************************* - * Function: - * adsl_multicast - * - * Description: - * Handle the LAN subsystem multicast, broadcast, and promiscous updates. - * These values can be modified by using the ifconfig command or other - * applications like network sniffers. - *-F*************************************************************************/ +* Function: +* adsl_multicast +* +* Description: +* Handle the LAN subsystem multicast, broadcast, and promiscous updates. +* These values can be modified by using the ifconfig command or other +* applications like network sniffers. +*-F*************************************************************************/ static void adsl_multicast(netdevice_t* dev) { - adsl_private_area_t* adsl = wan_netif_priv(dev); + adsl_private_area_t* adsl = wan_netif_priv(dev); short flags = wan_netif_flags(dev); int mcount = wan_netif_mcount(dev); char* mcaddrs = NULL; WAN_ASSERT1(adsl == NULL); - - DEBUG_TX("%s: IF Flags: %s%s%s%s!\n", + + DEBUG_TX("%s: IF Flags: %s%s%s%s!\n", adsl->if_name, (flags & IFF_BROADCAST) ? "Broadcast " : "", - (flags & IFF_PROMISC) ? "Promiscous " : "", - (flags & IFF_MULTICAST) ? "Multicast " : "", - (flags & IFF_ALLMULTI) ? "All-Multicast" : ""); - - DEBUG_TX("%s: HwAddr: %02x:%02x:%02x:%02x:%02x:%02x\n", - adsl->if_name, + (flags & IFF_PROMISC) ? "Promiscous " : "", + (flags & IFF_MULTICAST) ? "Multicast " : "", + (flags & IFF_ALLMULTI) ? "All-Multicast" : ""); + + DEBUG_TX("%s: HwAddr: %02x:%02x:%02x:%02x:%02x:%02x\n", + adsl->if_name, adsl->macAddr[0], adsl->macAddr[1], adsl->macAddr[2], adsl->macAddr[3], adsl->macAddr[4], adsl->macAddr[5]); - - if ((flags & IFF_MULTICAST) && mcount != 0){ + + if ((flags & IFF_MULTICAST) && mcount != 0){ #if !defined(__OpenBSD__) # if defined(__FreeBSD__) struct ifmultiaddr* mclist = NULL; # else struct dev_mc_list* mclist = NULL; # endif - int x = 0; + int x = 0; mcaddrs = wan_malloc(mcount * 6); - for (mclist = LIST_FIRST_MCLIST(dev); + for (mclist = LIST_FIRST_MCLIST(dev); mclist != NULL; - x++, mclist = LIST_NEXT_MCLIST(mclist)){ + x++, mclist = LIST_NEXT_MCLIST(mclist)){ # if defined(__FreeBSD__) - memcpy(&(mcaddrs[x * 6]), (void*)mclist->ifma_addr, 6); + memcpy(&(mcaddrs[x * 6]), (void*)mclist->ifma_addr, 6); # else - memcpy(&(mcaddrs[x * 6]), mclist->dmi_addr, 6); + memcpy(&(mcaddrs[x * 6]), mclist->dmi_addr, 6); # endif - } + } #endif - } + } /*adsl_lan_multicast(adsl->pAdapter, flags, mcaddrs, mcount); */ - + if (mcaddrs){ wan_free(mcaddrs); } - return; + return; } /*+F************************************************************************* - * Function: - * GpLanStats - * - * Description: - * Return the current LAN device statistics. - * - * Note: For 2.6 kernels we are not allowed to return NULL - *-F*************************************************************************/ +* Function: +* GpLanStats +* +* Description: +* Return the current LAN device statistics. +* +* Note: For 2.6 kernels we are not allowed to return NULL +*-F*************************************************************************/ static struct net_device_stats gstats; static struct net_device_stats* adsl_stats(netdevice_t* dev) { @@ -1360,32 +1624,52 @@ static struct net_device_stats* adsl_stats(netdevice_t* dev) if (adsl == NULL){ return &gstats; } - + card = (sdla_t*)adsl->common.card; - + if (card == NULL){ return &gstats; } return &card->wandev.stats; } +#elif defined(__WINDOWS__) +static struct net_device_stats gstats; +static struct net_device_stats* adsl_stats(netdevice_t* dev) +{ + sdla_t* card = NULL; + adsl_private_area_t* adsl = wan_netif_priv(dev); + + if (adsl == NULL){ + return &gstats; + } + + card = (sdla_t*)adsl->common.card; + + if (card == NULL){ + return &gstats; + } + + return &card->wandev.stats; +} + #endif /*+F************************************************************************* - * Function: - * adsl_tracing_enabled - * - * Description: - * - * - *-F*************************************************************************/ +* Function: +* adsl_tracing_enabled +* +* Description: +* +* +*-F*************************************************************************/ int adsl_tracing_enabled(void *trace_ptr) { adsl_trace_info_t *trace_info = (adsl_trace_info_t*)trace_ptr; WAN_ASSERT(trace_info == NULL); if (wan_test_bit(0,&trace_info->tracing_enabled)){ - + if ((SYSTEM_TICKS - trace_info->trace_timeout) > MAX_TRACE_TIMEOUT){ DEBUG_EVENT("wanpipe: Disabling trace, timeout!\n"); wan_clear_bit(0,&trace_info->tracing_enabled); @@ -1404,8 +1688,8 @@ int adsl_tracing_enabled(void *trace_ptr) } DEBUG_UDP("wanpipe: Too many packet in trace queue %d (max=%d)!\n", - adsl_trace_queue_len(trace_info), - trace_info->max_trace_queue); + adsl_trace_queue_len(trace_info), + trace_info->max_trace_queue); return -ENOBUFS; } return -EINVAL; @@ -1452,7 +1736,7 @@ int adsl_trace_enqueue(void *trace_ptr, void *skb_ptr) return err; } -int adsl_trace_queue_len(void *trace_ptr) +unsigned int adsl_trace_queue_len(void *trace_ptr) { adsl_trace_info_t* trace = (adsl_trace_info_t *)trace_ptr; wan_skb_queue_t* trace_queue = NULL; @@ -1463,13 +1747,13 @@ int adsl_trace_queue_len(void *trace_ptr) } /*+F************************************************************************* - * Function: - * adsl_ioctl - * - * Description: - * - * - *-F*************************************************************************/ +* Function: +* adsl_ioctl +* +* Description: +* +* +*-F*************************************************************************/ #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) static int adsl_ioctl(netdevice_t* ifp, u_long command, caddr_t data) #else @@ -1480,76 +1764,77 @@ static int adsl_ioctl(netdevice_t* ifp, struct ifreq *ifr, int command) struct ifreq* ifr = (struct ifreq*)data; struct ifmediareq* ifmr = (struct ifmediareq*)data; struct ifaddr* ifa = (struct ifaddr *)data; - # if defined(__FreeBSD__) +# if defined(__FreeBSD__) struct ifstat* ifs = (struct ifstat *)data; # endif #endif adsl_private_area_t* adsl = wan_netif_priv(ifp); sdla_t* card = (sdla_t*)adsl->common.card; wan_udp_pkt_t* wan_udp_pkt = NULL; - int error = 0; + int error = 0; #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) wan_smp_flag_t s; - wan_spin_lock_irq(NULL, &s); + wan_spin_lock_irq(NULL, &s); #endif - switch (command){ + switch (command){ +#if !defined(__WINDOWS__) + case SIOC_WANPIPE_PIPEMON: + DEBUG_IOCTL("%s - ioctl(WANPIPE_PIPEMON) called.\n", card->devname); + if (wan_atomic_read(&adsl->udp_pkt_len) != 0){ + error = -EBUSY; + goto adsl_ioctl_done; + } - case SIOC_WANPIPE_PIPEMON: - DEBUG_IOCTL("%s - ioctl(WANPIPE_PIPEMON) called.\n", card->devname); - if (wan_atomic_read(&adsl->udp_pkt_len) != 0){ - error = -EBUSY; - goto adsl_ioctl_done; - } - - wan_atomic_set(&adsl->udp_pkt_len,sizeof(wan_udp_hdr_t)); - - /* For performance reasons test the critical - * here before spin lock */ - if (wan_test_bit(0,&card->in_isr)){ - wan_atomic_set(&adsl->udp_pkt_len,0); - error = -EBUSY; - goto adsl_ioctl_done; - } - - wan_udp_pkt=(wan_udp_pkt_t*)&adsl->udp_pkt_data[0]; - if (WAN_COPY_FROM_USER(&wan_udp_pkt->wan_udp_hdr,ifr->ifr_data,sizeof(wan_udp_hdr_t))){ - DEBUG_EVENT("%s: Error: Failed to copy memory from USER space!\n", - card->devname); - wan_atomic_set(&adsl->udp_pkt_len,0); - error = -EFAULT; - goto adsl_ioctl_done; - } + wan_atomic_set(&adsl->udp_pkt_len,sizeof(wan_udp_hdr_t)); - error = process_udp_cmd(ifp, &wan_udp_pkt->wan_udp_hdr); + /* For performance reasons test the critical + * here before spin lock */ + if (wan_test_bit(0,&card->in_isr)){ + wan_atomic_set(&adsl->udp_pkt_len,0); + error = -EBUSY; + goto adsl_ioctl_done; + } - /* This area will still be critical to other - * PIPEMON commands due to udp_pkt_len - * thus we can release the irq */ - - if (wan_atomic_read(&adsl->udp_pkt_len) > sizeof(wan_udp_pkt_t)){ - DEBUG_EVENT("%s: Error: Pipemon buf too big on the way up! %i\n", + wan_udp_pkt=(wan_udp_pkt_t*)&adsl->udp_pkt_data[0]; + if (WAN_COPY_FROM_USER(&wan_udp_pkt->wan_udp_hdr,ifr->ifr_data,sizeof(wan_udp_hdr_t))){ + DEBUG_EVENT("%s: Error: Failed to copy memory from USER space!\n", + card->devname); + wan_atomic_set(&adsl->udp_pkt_len,0); + error = -EFAULT; + goto adsl_ioctl_done; + } + + error = process_udp_cmd(ifp, &wan_udp_pkt->wan_udp_hdr); + + /* This area will still be critical to other + * PIPEMON commands due to udp_pkt_len + * thus we can release the irq */ + + if (wan_atomic_read(&adsl->udp_pkt_len) > sizeof(wan_udp_pkt_t)){ + DEBUG_EVENT("%s: Error: Pipemon buf too big on the way up! %i\n", card->devname,wan_atomic_read(&adsl->udp_pkt_len)); - wan_atomic_set(&adsl->udp_pkt_len,0); - error = -EINVAL; - goto adsl_ioctl_done; - } + wan_atomic_set(&adsl->udp_pkt_len,0); + error = -EINVAL; + goto adsl_ioctl_done; + } + + if (WAN_COPY_TO_USER(ifr->ifr_data,&wan_udp_pkt->wan_udp_hdr,sizeof(wan_udp_hdr_t))){ + DEBUG_EVENT("%s: Error: Failed to copy memory to USER space!\n", + card->devname); + wan_atomic_set(&adsl->udp_pkt_len,0); + error = -EFAULT; + goto adsl_ioctl_done; + } - if (WAN_COPY_TO_USER(ifr->ifr_data,&wan_udp_pkt->wan_udp_hdr,sizeof(wan_udp_hdr_t))){ - DEBUG_EVENT("%s: Error: Failed to copy memory to USER space!\n", - card->devname); wan_atomic_set(&adsl->udp_pkt_len,0); - error = -EFAULT; - goto adsl_ioctl_done; - } - - wan_atomic_set(&adsl->udp_pkt_len,0); - break; + break; +#endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - case SIOCGIFMEDIA: - switch (card->u.adsl.EncapMode){ + case SIOCGIFMEDIA: + switch (card->u.adsl.EncapMode){ case RFC_MODE_BRIDGED_ETH_LLC: case RFC_MODE_BRIDGED_ETH_VC: ifmr->ifm_current = IFM_ETHER; @@ -1557,73 +1842,79 @@ static int adsl_ioctl(netdevice_t* ifp, struct ifreq *ifr, int command) default: error = -EOPNOTSUPP; goto adsl_ioctl_done; - } - ifmr->ifm_active = ifmr->ifm_current; - ifmr->ifm_mask = 0; - ifmr->ifm_status = 0; - ifmr->ifm_count = 1; - break; + } + ifmr->ifm_active = ifmr->ifm_current; + ifmr->ifm_mask = 0; + ifmr->ifm_status = 0; + ifmr->ifm_count = 1; + break; # if defined(__FreeBSD__) - case SIOCGIFSTATUS: - sprintf(ifs->ascii + strlen(ifs->ascii), - "\tstatus: %s\n", wanpipe_get_state_string(card)); - break; -# endif - case SIOCSIFMTU: - ifp->if_mtu = ifr->ifr_mtu; - break; - - case SIOCSIFADDR: - case SIOCGIFADDR: - if (card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_LLC || - card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ - error = ETHER_IOCTL(ifp, command, data); + case SIOCGIFSTATUS: + sprintf(ifs->ascii + strlen(ifs->ascii), + "\tstatus: %s\n", wanpipe_get_state_string(card)); break; - } else if (card->u.adsl.EncapMode == RFC_MODE_ROUTED_IP_LLC || - card->u.adsl.EncapMode == RFC_MODE_ROUTED_IP_VC){ - if (ifa->ifa_addr->sa_family == AF_INET){ +# endif + case SIOCSIFMTU: + ifp->if_mtu = ifr->ifr_mtu; + break; + + case SIOCSIFADDR: + case SIOCGIFADDR: + if (card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_LLC || + card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ + error = ETHER_IOCTL(ifp, command, data); break; - } - } - /* For all other modes fall through */ + } else if (card->u.adsl.EncapMode == RFC_MODE_ROUTED_IP_LLC || + card->u.adsl.EncapMode == RFC_MODE_ROUTED_IP_VC){ + if (ifa->ifa_addr->sa_family == AF_INET){ + break; + } + } + /* For all other modes fall through */ #endif - default: - if (card->u.adsl.EncapMode == RFC_MODE_PPP_VC || - card->u.adsl.EncapMode == RFC_MODE_PPP_LLC){ + default: + if (card->u.adsl.EncapMode == RFC_MODE_PPP_VC || + card->u.adsl.EncapMode == RFC_MODE_PPP_LLC){ #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - error = WAN_SPPP_IOCTL(ifp, command, data); -#else - error = wp_sppp_do_ioctl(ifp,ifr,command); + error = WAN_SPPP_IOCTL(ifp, command, data); +#elif defined(__LINUX__) + error = wp_sppp_do_ioctl(ifp,ifr,command); +#elif defined(__WINDOWS__) + error = -EOPNOTSUPP; #endif - }else if (card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_LLC || - card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ + }else if (card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_LLC || + card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ #if defined(__LINUX__) - error = ETHER_IOCTL(ifp, command, data); + error = ETHER_IOCTL(ifp, command, data); #else - error = -EOPNOTSUPP; + error = -EOPNOTSUPP; #endif - }else{ - error = EINVAL; - } - break; /* NEW */ - } + }else{ + error = EINVAL; + } + break; /* NEW */ + } + +#if !defined(__WINDOWS__) adsl_ioctl_done: -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) - wan_spin_unlock_irq(NULL, &s); #endif - /* done */ - return error; + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) + wan_spin_unlock_irq(NULL, &s); +#endif + /* done */ + return error; } #if defined(__LINUX__) /* FIXME update for BSD */ -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -static void process_bh (void *dev_ptr) -#else +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) static void process_bh (struct work_struct *work) +#else +static void process_bh (void *dev_ptr) #endif { netdevice_t *dev; @@ -1646,10 +1937,145 @@ static void process_bh (struct work_struct *work) process_udp_mgmt_pkt(card, dev, adsl,0); } +#elif defined(__WINDOWS__) +VOID process_bh( + IN PKDPC Dpc, + IN PVOID arg, + IN PVOID not_used1, + IN PVOID not_used2 + ) +{ + DBG_DSL_NOT_IMPLD +} #endif +#if defined(__WINDOWS__) +static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* netdev, adsl_private_area_t* chan) +{ + unsigned short buffer_length; + wan_udp_pkt_t *wan_udp_pkt; +// struct timeval tv; + unsigned long tv; + wan_trace_t *trace_info=NULL; + unsigned long smp_flags; + struct sk_buff* skb; + DATA_QUEUE_ELEMENT* tmp_trace_q_el; + int rc = SANG_STATUS_SUCCESS; + wanif_conf_t *wanif_conf; + + wan_udp_pkt = (wan_udp_pkt_t*)chan->udp_pkt_data; + //trace_info = &chan->trace_info; + wanif_conf = netdev->wanif_conf; + + //copy from the user buffer + wpabs_memcpy(&wan_udp_pkt->wan_udp_hdr, netdev->mgmt_userbfr, + netdev->mgmt_userbfr_len); + + wan_udp_pkt->wan_udp_opp_flag = 0; + + switch(wan_udp_pkt->wan_udp_command) { + + case READ_CONFIGURATION: + DEBUG_UDP("READ_CONFIGURATION\n"); + { + if_cfg_t *if_cfg = (if_cfg_t*)wan_udp_pkt->wan_udp_data; + + DEBUG_UDP("usedby: %s\n", wanif_conf->usedby); + DEBUG_UDP("active_ch: 0x%08X\n", wanif_conf->active_ch); + + DEBUG_UDP("sizeof(wan_udp_hdr_t): %d, sizeof(wanif_conf_t): %d\n", + sizeof(wan_udp_hdr_t), sizeof(wanif_conf_t)); + + //DO NOT do this!! because "sizeof(wan_udp_hdr_t) < sizeof(wanif_conf_t)" + //so it will crash the system. Use "if_cfg_t" instead!! + //wpabs_memcpy(wan_udp_pkt->wan_udp_data, wanif_conf, sizeof(wanif_conf_t));//WRONG!!! + + _snprintf(if_cfg->usedby, USED_BY_FIELD, "%s", wanif_conf->usedby); + if_cfg->active_ch = wanif_conf->active_ch; + if_cfg->media = WAN_FE_MEDIA(&card->fe); + if_cfg->interface_number = netdev->interface_number; + } + + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(wanif_conf_t); + break; + + case READ_CODE_VERSION: + wpabs_memcpy(wan_udp_pkt->wan_udp_data, &drv_version, sizeof(DRIVER_VERSION)); + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(DRIVER_VERSION); + break; + + case GET_OPEN_HANDLES_COUNTER: + *(int*)&wan_udp_pkt->wan_udp_data[0] = netdev->open_handle_counter; + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(int); + break; + + case ROUTER_UP_TIME: + wan_getcurrenttime( &tv, NULL ); + + chan->router_up_time = tv - chan->router_start_time; + *(unsigned long *)&wan_udp_pkt->wan_udp_data = + chan->router_up_time; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); + wan_udp_pkt->wan_udp_return_code = 0; + break; + + case READ_OPERATIONAL_STATS: + DEBUG_UDP("%s: READ_OPERATIONAL_STATS\n", netdev->name); + + wpabs_memcpy(wan_udp_pkt->wan_udp_data, &chan->if_stats, sizeof(net_device_stats_t)); + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(net_device_stats_t); + break; + + case FLUSH_OPERATIONAL_STATS: + DEBUG_UDP("%s: FLUSH_OPERATIONAL_STATS\n", netdev->name); + + memset(&chan->if_stats, 0x00, sizeof(net_device_stats_t)); + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(net_device_stats_t); + break; + + case WAN_GET_MEDIA_TYPE: + wan_udp_pkt->wan_udp_data[0] = WAN_MEDIA_NONE; + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + break; + + case WAN_GET_PROTOCOL: + DEBUG_UDP("%s: WAN_GET_PROTOCOL\n", netdev->name); + + wan_udp_pkt->wan_udp_data[0] = (unsigned char)card->wandev.config_id; + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = 1; + break; + + case WAN_GET_PLATFORM: + wan_udp_pkt->wan_udp_data[0] = WAN_WIN2K_PLATFORM; + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = 1; + break; + + default: + wan_udp_pkt->wan_udp_data_len = 0; + wan_udp_pkt->wan_udp_return_code = 0xCD; + DEBUG_EVENT( + "%s: Warning: Unknowd Management command: 0x%X\n", + netdev->name, wan_udp_pkt->wan_udp_command); + break; + }//end of switch + + //copy back to the user buffer + wpabs_memcpy(netdev->mgmt_userbfr, &wan_udp_pkt->wan_udp_hdr, + netdev->mgmt_userbfr_len); + return rc; +} + +#else static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, - adsl_private_area_t* adsl, int local_dev) + adsl_private_area_t* adsl, int local_dev) { wan_udp_pkt_t* wan_udp_pkt = NULL; netskb_t* new_skb = NULL; @@ -1665,61 +2091,61 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, if (local_dev){ return 0; } - + len = wan_reply_udp(card, adsl->udp_pkt_data, wan_udp_pkt->wan_udp_data_len); if (card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_LLC || - card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ - len += sizeof(ethhdr_t); + card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ + len += sizeof(ethhdr_t); } - + new_skb = wan_skb_alloc(len); if (new_skb != NULL){ wan_skb_set_dev(new_skb, dev); if (card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_LLC || - card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ - unsigned short ether_type = 0x0008; + card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ + unsigned short ether_type = 0x0008; - if (adsl->udp_pkt_src == UDP_PKT_FRM_NETWORK){ + if (adsl->udp_pkt_src == UDP_PKT_FRM_NETWORK){ + wan_skb_copyback(new_skb, + wan_skb_len(new_skb), + ETHER_ADDR_LEN, + &adsl->macAddr[0]); + wan_skb_copyback(new_skb, + wan_skb_len(new_skb), + ETHER_ADDR_LEN, + &adsl->remote_eth_addr[0]); + }else{ + wan_skb_copyback(new_skb, + wan_skb_len(new_skb), + ETHER_ADDR_LEN, + &adsl->remote_eth_addr[0]); + wan_skb_copyback(new_skb, + wan_skb_len(new_skb), + ETHER_ADDR_LEN, + &adsl->macAddr[0]); + } wan_skb_copyback(new_skb, - wan_skb_len(new_skb), - ETHER_ADDR_LEN, - &adsl->macAddr[0]); - wan_skb_copyback(new_skb, - wan_skb_len(new_skb), - ETHER_ADDR_LEN, - &adsl->remote_eth_addr[0]); - }else{ - wan_skb_copyback(new_skb, - wan_skb_len(new_skb), - ETHER_ADDR_LEN, - &adsl->remote_eth_addr[0]); - wan_skb_copyback(new_skb, - wan_skb_len(new_skb), - ETHER_ADDR_LEN, - &adsl->macAddr[0]); - } - wan_skb_copyback(new_skb, - wan_skb_len(new_skb), - sizeof(ether_type), - (caddr_t)ðer_type); - len -= sizeof(ethhdr_t); + wan_skb_len(new_skb), + sizeof(ether_type), + (caddr_t)ðer_type); + len -= sizeof(ethhdr_t); } - + /* copy data into new_skb */ wan_skb_copyback(new_skb, - wan_skb_len(new_skb), - len, - adsl->udp_pkt_data); + wan_skb_len(new_skb), + len, + adsl->udp_pkt_data); #if defined(__LINUX__) if (card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_LLC || - card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ - new_skb->protocol = eth_type_trans(new_skb, new_skb->dev); + card->u.adsl.EncapMode == RFC_MODE_BRIDGED_ETH_VC){ + new_skb->protocol = eth_type_trans(new_skb, new_skb->dev); }else{ /* Decapsulate pkt and pass it up the protocol stack */ new_skb->protocol = htons(ETH_P_IP); - wan_skb_reset_mac_header(new_skb); + __wan_skb_reset_mac_header(new_skb); } if (adsl->udp_pkt_src == UDP_PKT_FRM_NETWORK){ dev_queue_xmit(new_skb); @@ -1731,8 +2157,8 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, #if defined(__FreeBSD__) ether_output_frame(dev, new_skb); #else - wan_spinlock_t s; - wan_spin_lock_irq(NULL, &s); + wan_smp_flag_t s; + wan_spin_lock_irq(&card->wandev.lock, &s); WAN_IFQ_ENQUEUE(&dev->if_snd, new_skb, NULL, error); if (!error){ dev->if_obytes += wan_skb_len(new_skb) + sizeof(ethhdr_t); @@ -1740,7 +2166,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, (*dev->if_start)(dev); } } - wan_spin_unlock_irq(NULL, &s); + wan_spin_unlock_irq(&card->wandev.lock, &s); #endif }else{ # if defined(__OpenBSD__) || defined(__FreeBSD__) && (__FreeBSD_version <= 500000) @@ -1760,11 +2186,11 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, # endif } #endif - + }else{ - + DEBUG_EVENT("%s: no socket buffers available!\n", - card->devname); + card->devname); } wan_atomic_set(&adsl->udp_pkt_len,0); @@ -1772,34 +2198,33 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, } /* - * - * - */ - +* +* +*/ static int process_udp_cmd(netdevice_t* ifp, wan_udp_hdr_t* udp_hdr) { netskb_t* skb = NULL; - adsl_private_area_t* adsl = wan_netif_priv(ifp); - sdla_t* card = adsl->common.card; + adsl_private_area_t* adsl = wan_netif_priv(ifp); + sdla_t* card = adsl->common.card; int buffer_length=0; adsl_trace_info_t *trace_info = adsl_get_trace_ptr(adsl->pAdapter); - + udp_hdr->wan_udphdr_return_code=0; if (card->u.adsl.adapter == NULL){ return 0; } switch(udp_hdr->wan_udphdr_command){ - case WAN_GET_PROTOCOL: - udp_hdr->wan_udphdr_adsl_num_frames = WANCONFIG_ADSL; - udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; - udp_hdr->wan_udphdr_data_len = 2; - break; + case WAN_GET_PROTOCOL: + udp_hdr->wan_udphdr_adsl_num_frames = WANCONFIG_ADSL; + udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; + udp_hdr->wan_udphdr_data_len = 2; + break; - case WAN_GET_PLATFORM: - udp_hdr->wan_udphdr_data[0] = WAN_FREEBSD_PLATFORM; - udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; - udp_hdr->wan_udphdr_data_len = 1; - break; + case WAN_GET_PLATFORM: + udp_hdr->wan_udphdr_data[0] = WAN_FREEBSD_PLATFORM; + udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; + udp_hdr->wan_udphdr_data_len = 1; + break; case ADSL_TEST_DRIVER_RESPONSE: udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; @@ -1808,29 +2233,29 @@ static int process_udp_cmd(netdevice_t* ifp, wan_udp_hdr_t* udp_hdr) case ADSL_READ_DRIVER_VERSION: udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; sprintf(udp_hdr->wan_udphdr_data, "%s", WANPIPE_VERSION); - udp_hdr->wan_udphdr_data_len = strlen(udp_hdr->wan_udphdr_data); + udp_hdr->wan_udphdr_data_len = (unsigned short)strlen(udp_hdr->wan_udphdr_data); break; - + case ADSL_ROUTER_UP_TIME: wan_getcurrenttime(&adsl->router_up_time, NULL); adsl->router_up_time -= adsl->router_start_time; *(unsigned long *)&udp_hdr->wan_udphdr_data = - adsl->router_up_time; + adsl->router_up_time; udp_hdr->wan_udphdr_data_len = sizeof(unsigned long); udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; break; - + case ADSL_ENABLE_TRACING: - + udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; udp_hdr->wan_udphdr_data_len = 0; - + if (!wan_test_bit(0,&trace_info->tracing_enabled)){ - + trace_info->trace_timeout = SYSTEM_TICKS; - - adsl_trace_purge(trace_info); - + + adsl_trace_purge(trace_info); + if (udp_hdr->wan_udphdr_data[0] == 0){ wan_clear_bit(1,&trace_info->tracing_enabled); DEBUG_UDP("%s: ADSL L3 trace enabled!\n", @@ -1839,119 +2264,119 @@ static int process_udp_cmd(netdevice_t* ifp, wan_udp_hdr_t* udp_hdr) wan_clear_bit(2,&trace_info->tracing_enabled); wan_set_bit(1,&trace_info->tracing_enabled); DEBUG_UDP("%s: ADSL L2 trace enabled!\n", - card->devname); + card->devname); }else{ wan_clear_bit(1,&trace_info->tracing_enabled); wan_set_bit(2,&trace_info->tracing_enabled); DEBUG_UDP("%s: ADSL L1 trace enabled!\n", - card->devname); + card->devname); } wan_set_bit (0,&trace_info->tracing_enabled); }else{ DEBUG_EVENT("%s: Error: ADSL trace running!\n", - card->devname); + card->devname); udp_hdr->wan_udphdr_return_code = 2; } - + break; case ADSL_DISABLE_TRACING: - + udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; - + if(wan_test_bit(0,&trace_info->tracing_enabled)) { - + wan_clear_bit(0,&trace_info->tracing_enabled); wan_clear_bit(1,&trace_info->tracing_enabled); wan_clear_bit(2,&trace_info->tracing_enabled); - adsl_trace_purge(trace_info); + adsl_trace_purge(trace_info); DEBUG_UDP("%s: Disabling ADSL trace\n", - card->devname); - + card->devname); + }else{ /* set return code to line trace already - disabled */ + disabled */ udp_hdr->wan_udphdr_return_code = 1; } break; - case ADSL_GET_TRACE_INFO: + case ADSL_GET_TRACE_INFO: - if(wan_test_bit(0,&trace_info->tracing_enabled)){ + if(wan_test_bit(0,&trace_info->tracing_enabled)){ trace_info->trace_timeout = SYSTEM_TICKS; }else{ DEBUG_EVENT("%s: Error ADSL trace not enabled\n", - card->devname); - /* set return code */ - udp_hdr->wan_udphdr_return_code = 1; - break; - } + card->devname); + /* set return code */ + udp_hdr->wan_udphdr_return_code = 1; + break; + } - buffer_length = 0; + buffer_length = 0; udp_hdr->wan_udphdr_adsl_num_frames = 0; udp_hdr->wan_udphdr_adsl_ismoredata = 0; - + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) while (adsl_trace_queue_len(trace_info)){ WAN_IFQ_POLL(&trace_info->trace_queue, skb); if (skb == NULL){ DEBUG_EVENT("%s: No more trace packets in trace queue!\n", - card->devname); + card->devname); break; } if ((WAN_MAX_DATA_SIZE - buffer_length) < skb->m_pkthdr.len){ - /* indicate there are more frames on board & exit */ + /* indicate there are more frames on board & exit */ udp_hdr->wan_udphdr_adsl_ismoredata = 0x01; - break; - } + break; + } m_copydata(skb, - 0, - skb->m_pkthdr.len, - &udp_hdr->wan_udphdr_data[buffer_length]); + 0, + skb->m_pkthdr.len, + &udp_hdr->wan_udphdr_data[buffer_length]); buffer_length += skb->m_pkthdr.len; WAN_IFQ_DEQUEUE(&trace_info->trace_queue, skb); if (skb){ wan_skb_free(skb); } udp_hdr->wan_udphdr_adsl_num_frames++; - } + } #elif defined(__LINUX__) while ((skb=skb_dequeue(&trace_info->trace_queue)) != NULL){ - if((MAX_TRACE_BUFFER - buffer_length) < wan_skb_len(skb)){ - /* indicate there are more frames on board & exit */ - udp_hdr->wan_udphdr_adsl_ismoredata = 0x01; - if (buffer_length != 0){ - skb_queue_head(&trace_info->trace_queue, skb); - }else{ - memcpy(&udp_hdr->wan_udphdr_adsl_data[buffer_length], - wan_skb_data(skb), - sizeof(wan_trace_pkt_t)); + if((MAX_TRACE_BUFFER - buffer_length) < wan_skb_len(skb)){ + /* indicate there are more frames on board & exit */ + udp_hdr->wan_udphdr_adsl_ismoredata = 0x01; + if (buffer_length != 0){ + skb_queue_head(&trace_info->trace_queue, skb); + }else{ + memcpy(&udp_hdr->wan_udphdr_adsl_data[buffer_length], + wan_skb_data(skb), + sizeof(wan_trace_pkt_t)); - buffer_length = sizeof(wan_trace_pkt_t); - udp_hdr->wan_udphdr_adsl_num_frames++; - wan_skb_free(skb); - } - break; - } + buffer_length = sizeof(wan_trace_pkt_t); + udp_hdr->wan_udphdr_adsl_num_frames++; + wan_skb_free(skb); + } + break; + } - memcpy(&udp_hdr->wan_udphdr_adsl_data[buffer_length], - wan_skb_data(skb), - wan_skb_len(skb)); + memcpy(&udp_hdr->wan_udphdr_adsl_data[buffer_length], + wan_skb_data(skb), + wan_skb_len(skb)); - buffer_length += wan_skb_len(skb); - wan_skb_free(skb); - udp_hdr->wan_udphdr_adsl_num_frames++; - } + buffer_length += wan_skb_len(skb); + wan_skb_free(skb); + udp_hdr->wan_udphdr_adsl_num_frames++; + } #endif - /* set the data length and return code */ - udp_hdr->wan_udphdr_data_len = buffer_length; - udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; - break; - + /* set the data length and return code */ + udp_hdr->wan_udphdr_data_len = (unsigned short)buffer_length; + udp_hdr->wan_udphdr_return_code = WAN_CMD_OK; + break; + default: adsl_udp_cmd( card->u.adsl.adapter, @@ -1963,12 +2388,13 @@ static int process_udp_cmd(netdevice_t* ifp, wan_udp_hdr_t* udp_hdr) } wan_atomic_set(&adsl->udp_pkt_len, - sizeof(wan_mgmt_t) + sizeof(wan_trace_info_t) + - sizeof(wan_cmd_t) + udp_hdr->wan_udphdr_data_len); + sizeof(wan_mgmt_t) + sizeof(wan_trace_info_t) + + sizeof(wan_cmd_t) + udp_hdr->wan_udphdr_data_len); udp_hdr->wan_udphdr_request_reply = UDPMGMT_REPLY; return 0; } +#endif #if defined (__LINUX__) static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *conf) @@ -1976,7 +2402,7 @@ static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *con adsl_private_area_t *adsl=dev->priv; struct ppp_device *pppdev=NULL; struct sppp *sp=NULL; - + pppdev=kmalloc(sizeof(struct ppp_device),GFP_KERNEL); if (!pppdev){ return -ENOMEM; @@ -1986,11 +2412,11 @@ static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *con adsl->common.prot_ptr=(void*)pppdev; /* Attach PPP protocol layer to pppdev - * The wp_sppp_attach() will initilize the dev structure - * and setup ppp layer protocols. - * All we have to do is to bind in: - * if_open(), if_close(), if_send() and get_stats() functions. - */ + * The wp_sppp_attach() will initilize the dev structure + * and setup ppp layer protocols. + * All we have to do is to bind in: + * if_open(), if_close(), if_send() and get_stats() functions. + */ pppdev->dev=dev; @@ -1998,15 +2424,15 @@ static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *con if(conf->pap == WANOPT_YES){ pppdev->sppp.myauth.proto = PPP_PAP; DEBUG_EVENT("%s: Enableing PAP Protocol\n", - card->devname); + card->devname); }else if(conf->chap == WANOPT_YES){ pppdev->sppp.myauth.proto = PPP_CHAP; DEBUG_EVENT("%s: Enableing CHAP Protocol\n", - card->devname); + card->devname); }else{ pppdev->sppp.myauth.proto = 0; DEBUG_EVENT("%s: Authentication protocols disabled\n", - card->devname); + card->devname); } if(pppdev->sppp.myauth.proto){ @@ -2014,9 +2440,9 @@ static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *con memcpy(pppdev->sppp.myauth.secret, conf->passwd, AUTHNAMELEN); DEBUG_TX("%s: %s Username=%s Passwd=*****\n", - card->devname, - (pppdev->sppp.myauth.proto==PPP_PAP)?"PAP":"CHAP", - conf->userid); + card->devname, + (pppdev->sppp.myauth.proto==PPP_PAP)?"PAP":"CHAP", + conf->userid); } pppdev->sppp.gateway = conf->gateway; @@ -2029,17 +2455,17 @@ static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *con wp_sppp_attach(pppdev); sp = &pppdev->sppp; - + /* Enable PPP Debugging */ if (conf->protocol == WANCONFIG_CHDLC){ printk(KERN_INFO "%s: Starting Kernel CISCO HDLC protocol\n", - card->devname); + card->devname); sp->pp_flags |= PP_CISCO; conf->ignore_dcd = WANOPT_YES; conf->ignore_cts = WANOPT_YES; }else{ printk(KERN_INFO "%s: Starting Kernel Sync PPP protocol\n", - card->devname); + card->devname); sp->pp_flags &= ~PP_CISCO; dev->type = ARPHRD_PPP; } @@ -2048,3 +2474,227 @@ static int wanpipe_attach_sppp(sdla_t *card, netdevice_t *dev, wanif_conf_t *con } #endif + +#if defined(__WINDOWS__) +////////////////////////////////////////////////////////////////////////// +//////////// RX +static int netif_rx(netdevice_t *sdla_net_dev, netskb_t *rx_skb) +{ + TX_RX_DATA_STRUCT *tx_rx_struct; + int rc; + unsigned long smp_flags; + adsl_private_area_t *chan = (adsl_private_area_t*)wan_netif_priv(sdla_net_dev); + sdla_t *card = (sdla_t*)chan->common.card; + + DBG_ADSL_RX("%s()\n", __FUNCTION__); + + if((tx_rx_struct = convert_skb_to_TX_RX_DATA_STRUCT(rx_skb)) == NULL){ + return 1; + } + + wan_skb_print(rx_skb); + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + rc = adsl_insert_packet_in_to_rx_queue(sdla_net_dev, tx_rx_struct); + if(rc == SANG_STATUS_SUCCESS){ + //At this point all the data in per-Logic Channel RX queue. + //Queue the DPC, where data will be passed up to the user. + if(KeInsertQueueDpc(&card->rx_dpc_obj, NULL, NULL) == FALSE){ + //may happen when there is a lot of data. Not critical. + DBG_ADSL_RX("ADSL:Failed to 'queue rx_dpc_obj' - Not critical.\n"); + } + } + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + //deallocate temporary buffer + wpabs_free(tx_rx_struct); + //deallocate the original rx skb buffer + wpabs_skb_free(rx_skb); + return rc; +} + +////////////////////////////////////////////////////////////////////////// +//must be called with IRQ Lock or from ISR. +static int +adsl_insert_packet_in_to_rx_queue( + netdevice_t *sdla_net_dev, + RX_DATA_STRUCT *rx_data_struct + ) +{ + DATA_QUEUE_ELEMENT tmp_rx_q_el; + int rc = 0, i; + adsl_private_area_t *chan = (adsl_private_area_t*)wan_netif_priv(sdla_net_dev); + sdla_t *card = (sdla_t*)chan->common.card; + api_header_t *api_header = &rx_data_struct->api_header; + unsigned char *rx_data = rx_data_struct->data; + + DBG_ADSL_RX("%s: api_header->data_length: %d\n", + chan->if_name, api_header->data_length); +/* + //this will print the RX data into debugger: + for(i = 0; i < api_header->data_length; i++){ + DBG_ADSL_RX("rx_data[%d]: 0x%02X\n", i, rx_data[i]); + if(i > 30){ + DBG_ADSL_RX("...\n"); + break; + } + } +*/ + if(sdla_net_dev->open_handle_counter == 0){ + DBG_ADSL_RX("%s: open_handle_counter == 0. discarding data\n", + chan->if_name); + return 1; + } + + //check data length + if(api_header->data_length > ((DATA_QUEUE*)sdla_net_dev->rx_user_info.queue)->max_data_length){ + + //won't fit into rx queue buffer + DBG_ADSL_RX("api_header->data_length > DATA_BUFFER_LEN!!\n"); + chan->if_stats.rx_packets_discarded_excessive_length++; + return 2; + } + + if(api_header->data_length < 1){ + DBG_ADSL_RX("api_header->data_length < 1!!\n"); + chan->if_stats.rx_packets_discarded_too_short++; + return 3; + } + + //now copy header in to the element + RtlCopyMemory(&tmp_rx_q_el.api_header, api_header, sizeof(api_header_t)); + //initialize data pointer + tmp_rx_q_el.data = rx_data; + + tmp_rx_q_el.api_header.operation_status = SANG_STATUS_RX_DATA_AVAILABLE; + + // + //Code inside enqueue() will copy from 'tmp_rx_q_el' to a real queue element. + //Insert element at the tail of the rx queue. + // + rc = enqueue(sdla_net_dev->rx_user_info.queue, &tmp_rx_q_el); + if(rc){ + if(((DATA_QUEUE*)sdla_net_dev->rx_user_info.queue)->q_full_message_printed == 0){ + ((DATA_QUEUE*)sdla_net_dev->rx_user_info.queue)->q_full_message_printed = 1; + switch(rc) + { + default: + DEBUG_EVENT("%s: Warning: Discarding Rx data - rx queue is full!!\n", + sdla_net_dev->name); + break; + case 2: + DEBUG_EVENT("%s: Warning: Discarding Rx data - data too long!!\n", + sdla_net_dev->name); + break; + } + } + + //DbgPrint("rx q full!!\n"); + //DbgBreakPoint(); + chan->if_stats.rx_packets_discarded_rx_q_full++; + }else{ + ((DATA_QUEUE*)sdla_net_dev->rx_user_info.queue)->q_full_message_printed = 0; + } + + //even if data was discarded because rx q was full, increment + //statistics to indicate that rx is happening + chan->if_stats.rx_packets++; + chan->if_stats.rx_bytes += tmp_rx_q_el.api_header.data_length; + + //arr_q_size(sdla_net_dev->rx_queue); + + return rc; +} + +////////////////////////////////////////////////////////////////////////// +//////////// TX +//must be called with IRQ Lock or from ISR. +static int adsl_if_send(void *not_used, netdevice_t *sdla_net_dev) +{ + DATA_QUEUE_ELEMENT *tmp_tx_q_el; + int len; + adsl_private_area_t *chan = (adsl_private_area_t*)wan_netif_priv(sdla_net_dev); + sdla_t *card = (sdla_t*)chan->common.card; + api_header_t *tx_header; + + DBG_ADSL_TX("%s()\n", __FUNCTION__); + + if(wan_test_bit(TX_BUSY_SET,&card->wandev.critical)){ + DBG_ADSL_FAST_TX("%s: return 'SANG_STATUS_DEVICE_BUSY'\n", sdla_net_dev->name); + return SANG_STATUS_DEVICE_BUSY; + } + + if(sdla_net_dev->open_handle_counter == 0){ + //nobody is using this device, drop the data?? + DBG_ADSL_TX("%s: open_handle_counter == 0. return 'SANG_STATUS_INVALID_PARAMETER'\n", + sdla_net_dev->name); + return SANG_STATUS_INVALID_PARAMETER; + } + + DBG_ADSL_TX("%s():line:%d: current_num_of_elements_in_q: %d\n", __FUNCTION__, __LINE__, + ((DATA_QUEUE*)sdla_net_dev->tx_queue)->current_num_of_elements_in_q); + + //Reasons to queue DPC: + //1. can NOT allocate memory while holding irq spinlock, do it in adsl_if_send_task_func() + // + //2. IMPORTANT: first queue DPC, AFTER that return, becase otherwise there can be an infinite busy loop, + // since there will be always something in transmit queue. The problem is easyly reproduced by + // printing lots of messages to WinDebug over the Serial port, because it slows down the code. + wpabs_tasklet_schedule(&chan->adsl_if_send_task); + return SANG_STATUS_SUCCESS; +} + +static void adsl_if_send_task_func( + IN PKDPC Dpc, + IN PVOID arg, + IN PVOID not_used1, + IN PVOID not_used2 + ) +{ + netdevice_t *sdla_net_dev = (netdevice_t *)arg; + adsl_private_area_t *chan = (adsl_private_area_t*)wan_netif_priv(sdla_net_dev); + sdla_t *card = (sdla_t*)chan->common.card; + unsigned long smp_flags; + netskb_t *skb; + DATA_QUEUE_ELEMENT *tmp_tx_q_el; + unsigned int tx_retry_counter; + + DBG_ADSL_TX("%s()\n", __FUNCTION__); + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + //check there is something in tx queue + tmp_tx_q_el = dequeue(sdla_net_dev->tx_queue); + if(tmp_tx_q_el == NULL){ + DBG_ADSL_TX("%s():%s: tx queue is empty!\n", __FUNCTION__, sdla_net_dev->name); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + return; + } + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + skb = convert_DATA_QUEUE_ELEMENT_to_skb(tmp_tx_q_el); + if(skb == NULL){ + DEBUG_EVENT("%s():Warning: %s: skb is NULL!\n", __FUNCTION__, sdla_net_dev->name); + return; + } + tx_retry_counter = 0; +retry: + if(adsl_output(skb, sdla_net_dev)){ + tx_retry_counter++; + if(tx_retry_counter < 100){ + DBG_ADSL_FAST_TX("retry tx\n"); + KeStallExecutionProcessor(50UL); + goto retry; + }else{ + wpabs_skb_free(skb); + DEBUG_EVENT("%s():%s:Warning: adsl_output() failed. Dropping TX data!\n", + __FUNCTION__, sdla_net_dev->name); + + WAN_NETIF_START_QUEUE(sdla_net_dev); + } + }else{ + chan->if_stats.tx_packets++; + chan->if_stats.tx_bytes += tmp_tx_q_el->api_header.data_length; + } +} + +#endif /* #if defined(__WINDOWS__) */ diff --git a/patches/kdrivers/src/net/sdla_aft_te1.c b/patches/kdrivers/src/net/sdla_aft_te1.c index 0087b8b..c1d4979 100644 --- a/patches/kdrivers/src/net/sdla_aft_te1.c +++ b/patches/kdrivers/src/net/sdla_aft_te1.c @@ -5,15 +5,17 @@ * * Authors: Nenad Corbic * -* Copyright: (c) 2003-2006 Sangoma Technologies Inc. +* Copyright: (c) 2003-2008 Sangoma Technologies Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ -* Jan 07, 2003 Nenad Corbic Initial version. -* Oct 25, 2004 Nenad Corbic Support for QuadPort TE1 +* Feb 04,2008 Nenad Corbic Support for RTP TAP, Fixed 56K +* Mar 16,2007 David Rokhvarg Support for ISDN BRI card. +* Oct 25,2004 Nenad Corbic Support for QuadPort TE1 +* Jan 07,2003 Nenad Corbic Initial version. *****************************************************************************/ #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) @@ -39,13 +41,13 @@ # include #endif + #if defined(CONFIG_WANPIPE_HWEC) # include #endif #define INIT_FE_ONLY 0 -#undef DEBUG_REG #if 1 #define AFT_FUNC_DEBUG() @@ -54,7 +56,6 @@ #endif - #if 0 # define AFT_XTEST_UPDATE 1 #else @@ -114,8 +115,6 @@ #if 0 # warning "IRQ STAT DEBUGGIN ON" # define AFT_IRQ_STAT_DEBUG 1 -# define AFT_IRQ_STAT_TIMEOUT 5 -static unsigned long stat_timeout; #else # undef AFT_IRQ_STAT_DEBUG #endif @@ -140,12 +139,18 @@ static unsigned long stat_timeout; # undef AFT_CLOCK_SYNC #endif +#if 0 +# warning "AFT_SERIAL_DEBUGGING is enabled" +# define AFT_SINGLE_DMA_CHAIN 1 +# define AFT_SERIAL_DEBUG +#else +# undef AFT_SERIAL_DEBUG +#endif + #if defined(__LINUX__) #define AFT_TDM_API_SUPPORT 1 -#define AFT_RTP_SUPPORT 1 #else #undef AFT_TDM_API_SUPPORT -#undef AFT_RTP_SUPPORT #endif #if defined(__LINUX__) @@ -154,8 +159,17 @@ static unsigned long stat_timeout; #undef AFT_API_SUPPORT #endif +#if defined(__LINUX__) +# define AFT_RTP_SUPPORT 1 +#else +# undef AFT_RTP_SUPPORT +#endif +#if defined(WANPIPE_64BIT_4G_DMA) +#warning "Wanpipe compiled for 64bit 4G DMA" +#endif + /* Trigger on Number of transactions * 1= 1x8 byte transactions @@ -198,6 +212,7 @@ enum { DEVICE_DOWN }; + enum { TX_DMA_BUSY, TX_HANDLER_BUSY, @@ -271,8 +286,6 @@ extern wan_iface_t wan_iface; extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); -extern sdla_t* card_list; - /**SECTOIN************************************************** * * Function Prototypes @@ -292,18 +305,15 @@ static int if_init (netdevice_t* dev); #endif static int if_open (netdevice_t* dev); static int if_close (netdevice_t* dev); -static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); - -static struct net_device_stats* if_stats (netdevice_t* dev); +static int if_do_ioctl(netdevice_t*, struct ifreq*, wan_ioctl_cmd_t); #if defined(__LINUX__) static int if_send (netskb_t* skb, netdevice_t* dev); -static int if_change_mtu(netdevice_t *dev, int new_mtu); +static struct net_device_stats* if_stats (netdevice_t* dev); #else static int if_send(netdevice_t*, netskb_t*, struct sockaddr*,struct rtentry*); #endif -static void callback_front_end_state(void *card_id); static void handle_front_end_state(void* card_id); static void enable_timer(void* card_id); static void enable_ec_timer(void* card_id); @@ -319,7 +329,8 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card); static void wp_aft_dma_per_port_isr(sdla_t *card); static void wp_aft_tdmv_per_port_isr(sdla_t *card); static void wp_aft_fifo_per_port_isr(sdla_t *card); -static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr); +static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr); +static void wp_aft_serial_status_isr(sdla_t *card, u32 status); /* Bottom half handlers */ #if defined(__LINUX__) @@ -381,14 +392,12 @@ static void aft_port_task (struct work_struct *work); static void aft_port_task (void * card_ptr, int arg); #endif - #if defined(AFT_RTP_SUPPORT) static int aft_rtp_config(sdla_t *card); static void aft_rtp_unconfig(sdla_t *card); static void aft_rtp_tap(void *card_ptr, u8 chan, u8* rx, u8* tx, u32 len); #endif - static int aft_devel_ioctl(sdla_t *card,struct ifreq *ifr); static int aft_write_bios(sdla_t *card, wan_cmd_api_t *api_cmd); static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd); @@ -420,8 +429,8 @@ static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb); static int aft_dma_tx (sdla_t *card,private_area_t *chan); static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset); static void aft_tx_dma_voice_handler(unsigned long data, int wdt, int reset); -static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *); -static void aft_rx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *); +static void aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *); +static void aft_rx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *); static void aft_index_tx_rx_dma_chains(private_area_t *chan); static void aft_init_tx_rx_dma_descr(private_area_t *chan); static void aft_free_rx_complete_list(private_area_t *chan); @@ -438,6 +447,7 @@ static void aft_data_mux_cfg(sdla_t *card); static void aft_data_mux_get_cfg(sdla_t *card); static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb); +static int aft_hdlc_repeat_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb, netskb_t **rkb); static int aft_tdmv_init(sdla_t *card, wandev_conf_t *conf); #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) @@ -474,7 +484,6 @@ static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb); #endif static int aft_tdm_ring_rsync(sdla_t *card); static void aft_critical_shutdown(sdla_t *card); -static void aft_critical_event(void *arg, int type); /* API VoIP event */ #if defined(AFT_API_SUPPORT) @@ -522,6 +531,9 @@ static unsigned char aft_read_ec (void*, unsigned short); static int aft_hwec_config(sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int ctrl); static int aft_find_master_if_and_dchan(sdla_t *card, int *master_if,u32 active_ch); +#if defined(NETGRAPH) +extern void wan_ng_link_state(wanpipe_common_t *common, int state); +#endif /**SECTION********************************************************* * @@ -569,6 +581,7 @@ int aft_global_hw_device_init(void) { memset(aft_hwdev,0,sizeof(aft_hwdev)); +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_TE1) aft_hwdev[WANOPT_AFT104].init = 1; aft_hwdev[WANOPT_AFT104].aft_global_chip_config = a104_global_chip_config; aft_hwdev[WANOPT_AFT104].aft_global_chip_unconfig = a104_global_chip_unconfig; @@ -582,7 +595,25 @@ int aft_global_hw_device_init(void) aft_hwdev[WANOPT_AFT104].aft_write_cpld = aft_te1_write_cpld; aft_hwdev[WANOPT_AFT104].aft_fifo_adjust = a104_fifo_adjust; aft_hwdev[WANOPT_AFT104].aft_check_ec_security = a104_check_ec_security; +#endif +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_SERIAL) + aft_hwdev[WANOPT_AFT_SERIAL].init = 1; + aft_hwdev[WANOPT_AFT_SERIAL].aft_global_chip_config = a104_global_chip_config; + aft_hwdev[WANOPT_AFT_SERIAL].aft_global_chip_unconfig = a104_global_chip_unconfig; + aft_hwdev[WANOPT_AFT_SERIAL].aft_chip_config = a104_chip_config; + aft_hwdev[WANOPT_AFT_SERIAL].aft_chip_unconfig = a104_chip_unconfig; + aft_hwdev[WANOPT_AFT_SERIAL].aft_chan_config = a104_chan_dev_config; + aft_hwdev[WANOPT_AFT_SERIAL].aft_chan_unconfig = a104_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT_SERIAL].aft_led_ctrl = a104_led_ctrl; + aft_hwdev[WANOPT_AFT_SERIAL].aft_test_sync = a104_test_sync; + aft_hwdev[WANOPT_AFT_SERIAL].aft_read_cpld = aft_te1_read_cpld; + aft_hwdev[WANOPT_AFT_SERIAL].aft_write_cpld = aft_te1_write_cpld; + aft_hwdev[WANOPT_AFT_SERIAL].aft_fifo_adjust = a104_fifo_adjust; + aft_hwdev[WANOPT_AFT_SERIAL].aft_check_ec_security = a104_check_ec_security; +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_RM) aft_hwdev[WANOPT_AFT_ANALOG].init = 1; aft_hwdev[WANOPT_AFT_ANALOG].aft_global_chip_config = aft_analog_global_chip_config; aft_hwdev[WANOPT_AFT_ANALOG].aft_global_chip_unconfig = aft_analog_global_chip_unconfig; @@ -595,8 +626,26 @@ int aft_global_hw_device_init(void) aft_hwdev[WANOPT_AFT_ANALOG].aft_read_cpld = aft_analog_read_cpld; aft_hwdev[WANOPT_AFT_ANALOG].aft_write_cpld = aft_analog_write_cpld; aft_hwdev[WANOPT_AFT_ANALOG].aft_fifo_adjust = aft_analog_fifo_adjust; - aft_hwdev[WANOPT_AFT_ANALOG].aft_check_ec_security = a200_check_ec_security; + aft_hwdev[WANOPT_AFT_ANALOG].aft_check_ec_security = a200_check_ec_security; +#endif +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + aft_hwdev[WANOPT_AFT_ISDN].init = 1; + aft_hwdev[WANOPT_AFT_ISDN].aft_global_chip_config = aft_bri_global_chip_config; + aft_hwdev[WANOPT_AFT_ISDN].aft_global_chip_unconfig = aft_bri_global_chip_unconfig; + aft_hwdev[WANOPT_AFT_ISDN].aft_chip_config = aft_bri_chip_config; + aft_hwdev[WANOPT_AFT_ISDN].aft_chip_unconfig = aft_bri_chip_unconfig; + aft_hwdev[WANOPT_AFT_ISDN].aft_chan_config = aft_bri_chan_dev_config; + aft_hwdev[WANOPT_AFT_ISDN].aft_chan_unconfig = aft_bri_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT_ISDN].aft_led_ctrl = aft_bri_led_ctrl; + aft_hwdev[WANOPT_AFT_ISDN].aft_test_sync = aft_bri_test_sync; + aft_hwdev[WANOPT_AFT_ISDN].aft_read_cpld = aft_bri_read_cpld; + aft_hwdev[WANOPT_AFT_ISDN].aft_write_cpld = aft_bri_write_cpld; + aft_hwdev[WANOPT_AFT_ISDN].aft_fifo_adjust = aft_bri_fifo_adjust; + aft_hwdev[WANOPT_AFT_ISDN].aft_check_ec_security = bri_check_ec_security; +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_56K) aft_hwdev[WANOPT_AFT_56K].init = 1; aft_hwdev[WANOPT_AFT_56K].aft_global_chip_config = a104_global_chip_config; aft_hwdev[WANOPT_AFT_56K].aft_global_chip_unconfig = a104_global_chip_unconfig; @@ -605,11 +654,12 @@ int aft_global_hw_device_init(void) aft_hwdev[WANOPT_AFT_56K].aft_chan_config = a104_chan_dev_config; aft_hwdev[WANOPT_AFT_56K].aft_chan_unconfig = a104_chan_dev_unconfig; aft_hwdev[WANOPT_AFT_56K].aft_led_ctrl = a104_led_ctrl; - aft_hwdev[WANOPT_AFT_56K].aft_test_sync = a104_test_sync; + aft_hwdev[WANOPT_AFT_56K].aft_test_sync = a104_test_sync; aft_hwdev[WANOPT_AFT_56K].aft_read_cpld = aft_56k_read_cpld; - aft_hwdev[WANOPT_AFT_56K].aft_write_cpld = aft_56k_write_cpld; + aft_hwdev[WANOPT_AFT_56K].aft_write_cpld = aft_56k_write_cpld; aft_hwdev[WANOPT_AFT_56K].aft_fifo_adjust = a104_fifo_adjust; - aft_hwdev[WANOPT_AFT_56K].aft_check_ec_security = a104_check_ec_security; + aft_hwdev[WANOPT_AFT_56K].aft_check_ec_security = a104_check_ec_security; +#endif return 0; } @@ -635,6 +685,7 @@ int aft_global_hw_device_init(void) * < 0 failure. */ +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_RM) int wp_aft_analog_init (sdla_t *card, wandev_conf_t* conf) { /* Verify configuration ID */ @@ -644,7 +695,6 @@ int wp_aft_analog_init (sdla_t *card, wandev_conf_t* conf) return -EINVAL; } - card->u.aft.chip_cfg_status=0; ASSERT_AFT_HWDEV(card->wandev.card_type); card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); @@ -667,24 +717,21 @@ int wp_aft_analog_init (sdla_t *card, wandev_conf_t* conf) /* Make special hardware initialization for Analog board */ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - wp_remora_iface_init(&card->wandev.fe_iface); + wp_remora_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; - card->fe.write_fe_reg = aft_analog_write_fe; - card->fe.read_fe_reg = aft_analog_read_fe; - card->fe.__read_fe_reg = __aft_analog_read_fe; + card->fe.write_fe_reg = card->hw_iface.fe_write; /* aft_analog_write_fe; */ + card->fe.read_fe_reg = card->hw_iface.fe_read; /* aft_analog_read_fe; */ + card->fe.__read_fe_reg = card->hw_iface.__fe_read; /* __aft_analog_read_fe; */ card->wandev.fe_enable_timer = enable_timer; card->wandev.ec_enable_timer = enable_ec_timer; - card->wandev.te_link_state = callback_front_end_state; + card->wandev.te_link_state = handle_front_end_state; if (card->wandev.comm_port == WANOPT_PRI){ conf->clocking = WANOPT_EXTERNAL; } - /* Use software RING buffer by default on Analog */ - wan_set_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status); - card->wandev.comm_port=card->fe.fe_cfg.line_no; if (card->wandev.comm_port != 0){ DEBUG_EVENT("%s: Error: Invalid port selected %d (Port 1)\n", @@ -694,17 +741,145 @@ int wp_aft_analog_init (sdla_t *card, wandev_conf_t* conf) card->u.aft.num_of_time_slots=MAX_REMORA_MODULES; + return wan_aft_init(card,conf); } +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) +int wp_aft_bri_init (sdla_t *card, wandev_conf_t* conf) +{ + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_ISDN_BRI) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + ASSERT_AFT_HWDEV(card->wandev.card_type); + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + + /* FIXME:hardcoded!! */ + card->u.aft.firm_id = AFT_DS_FE_CORE_ID; + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + + /* Make special hardware initialization for ISDN BRI board */ + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + wp_bri_iface_init(&card->wandev.fe_iface); + card->fe.name = card->devname; + card->fe.card = card; + card->fe.write_fe_reg = aft_bri_write_fe; + card->fe.read_fe_reg = aft_bri_read_fe; + card->fe.__read_fe_reg = __aft_bri_read_fe; + + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + + if (card->wandev.comm_port == WANOPT_PRI){ + conf->clocking = WANOPT_EXTERNAL; + } + +#if 1 + card->wandev.comm_port=0; + if (card->fe.fe_cfg.line_no >= MAX_BRI_MODULES) { + card->wandev.comm_port=1; + } +#else + card->wandev.comm_port=card->fe.fe_cfg.line_no; +#endif + + DEBUG_EVENT("%s: BRI CARD Line=%i Port=%i\n", + card->devname, card->wandev.comm_port, card->fe.fe_cfg.line_no); + + /* Set 'num_of_time_slots' to 31. This is needed for the d-chan, + which is always at the otherwise unused timeslot 31. + */ + card->u.aft.num_of_time_slots = MAX_TIMESLOTS; + + return wan_aft_init(card,conf); +} +#endif + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_SERIAL) + +int wp_aft_serial_init (sdla_t *card, wandev_conf_t* conf) +{ + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_SERIAL) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + ASSERT_AFT_HWDEV(card->wandev.card_type); + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + + + if (card->u.aft.firm_ver < AFT_SERIAL_MIN_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_SERIAL_MIN_FRMW_VER); + DEBUG_EVENT( "%s You seem to be running BETA hardware that is not supported any more.\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } + + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + + /* Make special hardware initialization for Serial board */ + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + + FE_MEDIA(&(card->fe.fe_cfg)) = WAN_MEDIA_SERIAL; + + wp_serial_iface_init(&card->wandev.fe_iface); + card->fe.name = card->devname; + card->fe.card = card; + card->fe.write_fe_reg = card->hw_iface.fe_write; /*aft_serial_write_fe;*/ + card->fe.read_fe_reg = card->hw_iface.fe_read; /*aft_serial_read_fe;*/ + card->fe.__read_fe_reg = card->hw_iface.__fe_read; /*__aft_serial_read_fe;*/ + + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + + card->wandev.comm_port=card->fe.fe_cfg.line_no; + + DEBUG_EVENT("%s: Serial A140 CARD Line=%i Port=%i Firm=0x%02X ID=0x%X\n", + card->devname, card->wandev.comm_port, card->fe.fe_cfg.line_no, + card->u.aft.firm_ver,card->u.aft.firm_id); + + card->u.aft.num_of_time_slots = 1; + + return wan_aft_init(card,conf); +} +#endif + + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_TE1) int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) { AFT_FUNC_DEBUG(); - wan_set_bit(CARD_DOWN,&card->wandev.critical); /* Verify configuration ID */ @@ -713,7 +888,7 @@ int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) card->devname, card->wandev.config_id); return -EINVAL; } - card->u.aft.chip_cfg_status=0; + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); @@ -736,10 +911,6 @@ int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) return -EINVAL; } -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); -#endif - /* TE1 Make special hardware initialization for T1/E1 board */ if (IS_TE1_MEDIA(&conf->fe_cfg)){ int max_ports = 4; @@ -748,40 +919,30 @@ int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) conf->fe_cfg.cfg.te_cfg.active_ch = -1; } - memset(&card->fe, 0, sizeof(sdla_fe_t)); memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { max_ports = 8; - sdla_ds_te1_iface_init(&card->wandev.fe_iface); + sdla_ds_te1_iface_init(&card->fe, &card->wandev.fe_iface); }else{ - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); } card->fe.name = card->devname; card->fe.card = card; - card->fe.write_fe_reg = a104_write_fe; - card->fe.read_fe_reg = a104_read_fe; - card->fe.__read_fe_reg = __a104_read_fe; + card->fe.write_fe_reg = card->hw_iface.fe_write; /*a104_write_fe;*/ + card->fe.read_fe_reg = card->hw_iface.fe_read; /*a104_read_fe;*/ + card->fe.__read_fe_reg = card->hw_iface.__fe_read; /*__a104_read_fe;*/ card->wandev.fe_enable_timer = enable_timer; card->wandev.ec_enable_timer = enable_ec_timer; - card->wandev.te_link_state = callback_front_end_state; - conf->interface = + card->wandev.te_link_state = handle_front_end_state; + conf->electrical_interface = IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; - card->wandev.critical_event = aft_critical_event; if (card->wandev.comm_port == WANOPT_PRI){ conf->clocking = WANOPT_EXTERNAL; } card->wandev.comm_port=card->fe.fe_cfg.line_no; -#if 0 -/* ALEX: This will check during t1/e1 configuration */ - if (card->wandev.comm_port < 0 || card->wandev.comm_port > max_ports-1){ - DEBUG_EVENT("%s: Error: Invalid port selected %d (Min=1 Max=%d)\n", - card->devname,card->wandev.comm_port, max_ports); - return -EINVAL; - } -#endif if (IS_T1_CARD(card)){ card->u.aft.num_of_time_slots=NUM_OF_T1_CHANNELS; @@ -798,13 +959,14 @@ int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) return wan_aft_init(card,conf); } +#endif +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_56K) int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) { AFT_FUNC_DEBUG(); - wan_set_bit(CARD_DOWN,&card->wandev.critical); /* Verify configuration ID */ @@ -814,7 +976,6 @@ int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) return -EINVAL; } - card->u.aft.chip_cfg_status=0; card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); @@ -836,11 +997,7 @@ int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) card->devname); return -EINVAL; } - -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); -#endif - + if (IS_56K_MEDIA(&conf->fe_cfg)){ conf->fe_cfg.cfg.te_cfg.active_ch = 1; @@ -855,22 +1012,18 @@ int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) return -EINVAL; } */ - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; -#if 1 - card->fe.write_fe_reg = a56k_write_fe; - card->fe.read_fe_reg = a56k_read_fe; - card->fe.__read_fe_reg = __a56k_read_fe; -#else - card->fe.write_fe_reg = a104_write_fe; - card->fe.read_fe_reg = a104_read_fe; - card->fe.__read_fe_reg = __a104_read_fe; -#endif + + card->fe.write_fe_reg = card->hw_iface.fe_write; /* a56k_write_fe;*/ + card->fe.read_fe_reg = card->hw_iface.fe_read; /* a56k_read_fe; */ + card->fe.__read_fe_reg = card->hw_iface.__fe_read; /* __a56k_read_fe; */ + card->wandev.fe_enable_timer = enable_timer; card->wandev.ec_enable_timer = enable_ec_timer; - card->wandev.te_link_state = callback_front_end_state; + card->wandev.te_link_state = handle_front_end_state; card->wandev.comm_port=0; @@ -885,6 +1038,7 @@ int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) return wan_aft_init(card,conf); } +#endif static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) { @@ -895,28 +1049,17 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) card->wandev.clocking = conf->clocking; card->wandev.ignore_front_end_status = conf->ignore_front_end_status; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; - card->wandev.comm_port = conf->comm_port; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.udp_port = conf->udp_port; card->wandev.new_if_cnt = 0; wan_atomic_set(&card->wandev.if_cnt,0); card->u.aft.chip_security_cnt=0; memcpy(&card->u.aft.cfg,&conf->u.aft,sizeof(wan_xilinx_conf_t)); + memcpy(&card->rtp_conf,&conf->rtp_conf,sizeof(conf->rtp_conf)); memset(card->u.aft.dev_to_ch_map,0,sizeof(card->u.aft.dev_to_ch_map)); memcpy(&card->tdmv_conf,&conf->tdmv_conf,sizeof(wan_tdmv_conf_t)); memcpy(&card->hwec_conf,&conf->hwec_conf,sizeof(wan_hwec_conf_t)); - memcpy(&card->rtp_conf,&conf->rtp_conf,sizeof(conf->rtp_conf)); - - if (card->u.aft.cfg.err_throttle_period == 0) { - card->u.aft.cfg.err_throttle_period=1; - } - - if (card->u.aft.cfg.err_throttle_timeout == 0) { - card->u.aft.cfg.err_throttle_timeout=10; - } - - card->u.aft.cfg.dma_per_ch = MAX_RX_BUF; card->u.aft.tdmv_api_rx = NULL; @@ -987,7 +1130,6 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) card->u.aft.cfg.mru = card->wandev.mtu; } - if (card->u.aft.cfg.mru > MAX_WP_PRI_MTU || card->u.aft.cfg.mru < MIN_WP_PRI_MTU){ @@ -1003,16 +1145,18 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) port_set_state(card,WAN_CONNECTING); - AFT_FUNC_DEBUG(); - WAN_TASKQ_INIT((&card->u.aft.port_task),0,aft_port_task,card); + + card->u.aft.chip_cfg_status=0; + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &used_cnt); - - card->hw_iface.getcfg(card->hw, SDLA_USEDCNT, &used_cnt); + /* ====================================================================== + * After this point we must call disable_comm() if we fail to configure + * =====================================================================*/ wan_clear_bit(CARD_DOWN,&card->wandev.critical); - __sdla_push_ptr_isr_array(card->hw,card,card->wandev.comm_port); + __sdla_push_ptr_isr_array(card->hw,card,WAN_FE_LINENO(&card->fe)); card->isr = &wp_aft_global_isr; @@ -1023,6 +1167,8 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) err=aft_global_chip_configuration(card, conf); if (err){ aft_global_chip_disable(card); + disable_comm(card); + wan_set_bit(CARD_DOWN,&card->wandev.critical); return err; } @@ -1034,6 +1180,8 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) err=aft_front_end_mismatch_check(card); if (err){ + disable_comm(card); + wan_set_bit(CARD_DOWN,&card->wandev.critical); return err; } @@ -1044,6 +1192,7 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) aft_read_security(card); + err=aft_chip_configure(card,conf); if (err){ AFT_FUNC_DEBUG(); @@ -1052,6 +1201,8 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) if (used_cnt==1){ aft_global_chip_disable(card); } + disable_comm(card); + wan_set_bit(CARD_DOWN,&card->wandev.critical); return err; } wan_set_bit(AFT_CHIP_CONFIGURED,&card->u.aft.chip_cfg_status); @@ -1071,7 +1222,6 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) aft_read_security(card); - DEBUG_EVENT("%s: Configuring Device :%s FrmVr=%02X\n", card->devname,card->devname,card->u.aft.firm_ver); DEBUG_EVENT("%s: Global MTU = %d\n", @@ -1111,6 +1261,16 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) } } + if(IS_BRI_CARD(card)){ + wan_set_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_set_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + } + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) { + wan_set_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status); + } + + DEBUG_EVENT("%s: Global TDM Int = %s\n", card->devname, wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status) ? @@ -1126,20 +1286,15 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) }else{ card->u.aft.tdmv_hw_dtmf = WANOPT_NO; } - DEBUG_EVENT("%s: Global TDM HW DTMF = %s\n", + DEBUG_EVENT("%s: TDM HW DTMF = %s\n", card->devname, (card->u.aft.tdmv_hw_dtmf == WANOPT_YES) ? "Enabled" : "Disabled"); - - DEBUG_EVENT("%s: IRQ Throttle Period=%i Timeout=%i\n", - card->devname, - card->u.aft.cfg.err_throttle_period, - card->u.aft.cfg.err_throttle_timeout); - err=aft_tdmv_init(card,conf); if (err){ disable_comm(card); + wan_set_bit(CARD_DOWN,&card->wandev.critical); return err; } @@ -1152,7 +1307,6 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) err == 0 ? "Enabled" : "Disabled"); #endif - card->wandev.read_ec = aft_read_ec; card->wandev.write_ec = aft_write_ec; return 0; @@ -1194,12 +1348,12 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t* dev; volatile private_area_t* chan; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -1219,17 +1373,6 @@ static int update (wan_device_t* wandev) return -EAGAIN; } -#if 0 -#warning "NENAD RTP TAP DEBUGGING" - if (card->wandev.rtp_tap_call_map) { - DEBUG_EVENT("%s: DISABLING RTP TAP\n",card->devname); - card->wandev.rtp_tap_call_map=0; - } else { - DEBUG_EVENT("%s: ENABLING RTP TAP\n",card->devname); - card->wandev.rtp_tap_call_map=0xFFFFFFFF; - } -#endif - DEBUG_TEST("%s: Chain Dma Status=0x%lX, TxCur=%d, TxPend=%d RxCur=%d RxPend=%d\n", chan->if_name, chan->dma_chain_status, @@ -1283,19 +1426,17 @@ static int update (wan_device_t* wandev) * < 0 failure (channel will not be created) */ +#ifdef AFT_TDM_API_SUPPORT static int aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) { -#ifdef AFT_TDM_API_SUPPORT int err=0; -#endif if (chan->common.usedby != TDM_VOICE_API && chan->common.usedby != TDM_VOICE_DCHAN) { return 0; } -#ifdef AFT_TDM_API_SUPPORT if (chan->tdmv_zaptel_cfg) { return 0; } @@ -1303,7 +1444,7 @@ aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) /* Initilaize TDM API Parameters */ chan->wp_tdm_api_dev.chan = chan; chan->wp_tdm_api_dev.card = card; - wan_spin_lock_init(&chan->wp_tdm_api_dev.lock); + wan_spin_lock_init(&chan->wp_tdm_api_dev.lock,"wp_aft_tdmapi_lock"); strncpy(chan->wp_tdm_api_dev.name,chan->if_name,WAN_IFNAME_SZ); if (conf->hdlc_streaming) { @@ -1317,6 +1458,7 @@ aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) chan->wp_tdm_api_dev.cfg.rx_disable = 0; chan->wp_tdm_api_dev.cfg.tx_disable = 0; + chan->wp_tdm_api_dev.tx_q_len = MAX_AFT_DMA_CHAINS; if (IS_TE1_CARD(card)) { if (IS_T1_CARD(card)){ @@ -1326,6 +1468,22 @@ aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot; } + + } else if (IS_BRI_CARD(card)) { + + if (chan->dchan_time_slot >= 0) { + chan->wp_tdm_api_dev.tdm_chan = 3; + } else { + chan->wp_tdm_api_dev.tdm_chan = (chan->first_time_slot % 2)+1; + } + + if (card->fe.fe_cfg.tdmv_law == WAN_TDMV_MULAW){ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_MULAW; + } else { + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; + } + chan->wp_tdm_api_dev.tx_q_len = 0; + } else { if (card->fe.fe_cfg.tdmv_law == WAN_TDMV_MULAW){ chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_MULAW; @@ -1333,21 +1491,28 @@ aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) } else { chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot+1; - } + } + + } - if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ - /* Convert active_ch bit map to user */ - chan->wp_tdm_api_dev.active_ch = conf->active_ch << 1; - }else{ + if (IS_E1_CARD(card)){ chan->wp_tdm_api_dev.active_ch = conf->active_ch; - } + }else{ + chan->wp_tdm_api_dev.active_ch = conf->active_ch << 1; + } + + DEBUG_TEST("%s: TDM API ACTIVE CH 0x%08X CHAN=%i\n", + chan->if_name, chan->wp_tdm_api_dev.active_ch,chan->wp_tdm_api_dev.tdm_chan); chan->wp_tdm_api_dev.cfg.idle_flag = conf->u.aft.idle_flag; chan->wp_tdm_api_dev.cfg.rbs_tx_bits = conf->u.aft.rbs_cas_idle; chan->wp_tdm_api_dev.tdm_span = card->tdmv_conf.span_no; + chan->wp_tdm_api_dev.dtmfsupport = card->u.aft.tdmv_hw_dtmf; + + err=wanpipe_tdm_api_reg(&chan->wp_tdm_api_dev); if (err){ return err; @@ -1355,13 +1520,8 @@ aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) wan_set_bit(0,&chan->wp_tdm_api_dev.init); return err; -#else - DEBUG_EVENT("%s: TDM API support not compiled in\n", - card->devname); - return -EINVAL; -#endif - } +#endif static int aft_tdm_api_free(sdla_t *card, private_area_t *chan) { @@ -1402,12 +1562,15 @@ static int aft_chan_if_init(sdla_t *card, netdevice_t *dev, private_area_t *chan WAN_IFQ_INIT(&chan->wp_tx_pending_list,0); WAN_IFQ_INIT(&chan->wp_tx_complete_list,0); - + WAN_IFQ_INIT(&chan->wp_tx_hdlc_rpt_list,0); + WAN_IFQ_INIT(&chan->wp_rx_free_list,0); WAN_IFQ_INIT(&chan->wp_rx_complete_list,0); WAN_IFQ_INIT(&chan->wp_rx_stack_complete_list, 0); + WAN_IFQ_INIT(&chan->wp_rx_bri_dchan_complete_list, 0); + wan_trace_info_init(&chan->trace_info,MAX_TRACE_QUEUE); /* Initiaize Tx/Rx DMA Chains */ @@ -1451,8 +1614,7 @@ static int aft_ss7_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *con chan->cfg.ss7_lssu_size); wan_spin_lock_irq(&card->wandev.lock,&smp_flags); - card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), - &lcfg_reg); + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),&lcfg_reg); if (chan->cfg.ss7_mode){ aft_lcfg_ss7_mode4096_cfg(&lcfg_reg,chan->cfg.ss7_lssu_size); }else{ @@ -1511,7 +1673,14 @@ static int aft_transp_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t * card->devname,chan->if_name, chan->idle_flag,chan->max_idle_size); - chan->idle_flag=0x7E; + + if(conf->u.aft.idle_flag){ + chan->idle_flag=conf->u.aft.idle_flag; + DEBUG_EVENT("%s: Idle flag :0x%02x\n", card->devname, chan->idle_flag); + } else { + chan->idle_flag=0x7E; + } + if (chan->tdmv_zaptel_cfg){ #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) @@ -1555,11 +1724,11 @@ static int aft_transp_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t * static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf, int channelized, int dchan) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; private_area_t* chan; int dma_per_ch=card->u.aft.cfg.dma_per_ch; - int err = 0; - + int err = 0, dma_alignment = 4, i =0; + DEBUG_EVENT( "%s: Configuring Interface: %s\n", card->devname, wan_netif_name(dev)); @@ -1569,7 +1738,6 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* return -EINVAL; } - if (card->adptr_subtype != AFT_SUBTYPE_SHARK){ if (card->u.aft.security_id != 0x01 && card->u.aft.security_cnt >= 2){ @@ -1594,7 +1762,6 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* memset(chan, 0, sizeof(private_area_t)); memcpy(&chan->cfg,&conf->u.aft,sizeof(chan->cfg)); - chan->true_if_encoding=conf->true_if_encoding; aft_chan_if_init(card,dev,chan); @@ -1604,14 +1771,37 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf->hdlc_streaming=0; } + if (card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI) { + chan->single_dma_chain = 1; + } + + /* If 'dchan_time_slot' is less than zero, it is NOT a dchan. + If 'dchan_time_slot' is greater or equal to zero it is a dchan. + NOTE: 'dchan' is NOT the same as 'hdlc_eng'. The 'hdlc_eng' is + a flag for AFT hardware to use it's HDLC core. + */ + chan->dchan_time_slot = dchan; + + if(IS_56K_CARD(card)){ chan->single_dma_chain = 1; conf->hdlc_streaming=1; } + + if (chan->cfg.hdlc_repeat) { + if (!conf->hdlc_streaming) { + DEBUG_EVENT("%s: HDLC Repeat configured for non hdlc channel!\n", + chan->if_name); + err= -EINVAL; + goto new_if_error; + } + chan->single_dma_chain = 1; + conf->hdlc_streaming=1; + } - if (channelized){ + if (channelized) { chan->channelized_cfg=1; - if (wan_netif_priv(dev)){ + if (wan_netif_priv(dev)) { #if 1 private_area_t *cptr; for (cptr=wan_netif_priv(dev);cptr->next!=NULL;cptr=cptr->next); @@ -1622,10 +1812,10 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* chan->next = wan_netif_priv(dev); wan_netif_set_priv(dev, chan); #endif - }else{ + } else { wan_netif_set_priv(dev, chan); } - }else{ + } else { chan->channelized_cfg=0; wan_netif_set_priv(dev, chan); } @@ -1799,6 +1989,11 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* DEBUG_EVENT( "%s:%s: Running in Stack mode.\n", card->devname,chan->if_name); + }else if (strcmp(conf->usedby, "NETGRAPH") == 0) { + chan->common.usedby = WP_NETGRAPH; + DEBUG_EVENT( "%s:%s: Running in Netgraph mode.\n", + card->devname,chan->if_name); + }else{ DEBUG_EVENT( "%s:%s: Error: Invalid IF operation mode %s\n", card->devname,chan->if_name,conf->usedby); @@ -1812,7 +2007,11 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* *==============================================*/ if (conf->hwec.enable){ - card->wandev.ec_enable_map |= conf->active_ch; + if (card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI) { + card->wandev.ec_enable_map = 0x3; + }else{ + card->wandev.ec_enable_map |= conf->active_ch; + } } /* Read user specified active_ch, we must do it @@ -1824,14 +2023,14 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* chan->time_slot_map); if (!chan->num_of_time_slots){ - DEBUG_EVENT("%s: Error: Invalid number of timeslots in map 0x%08lX!\n", + DEBUG_EVENT("%s: Error: Invalid number of timeslots in map 0x%08X!\n", chan->if_name,chan->time_slot_map); return -EINVAL; } if (card->wandev.config_id == WANCONFIG_AFT_ANALOG && chan->num_of_time_slots > 1) { DEBUG_EVENT( - "%s: Error: Invalid Analog number of timeslots in map 0x%08lX: (Valid=1)\n", + "%s: Error: Invalid Analog number of timeslots in map 0x%08X: (Valid=1)\n", chan->if_name,chan->time_slot_map); return -EINVAL; } @@ -1875,9 +2074,10 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* chan->hdlc_eng = conf->hdlc_streaming; - DEBUG_EVENT("%s: HDLC Eng :%s\n", + DEBUG_EVENT("%s: HDLC Eng :%s | %s\n", card->devname, - chan->hdlc_eng?"On":"Off (Transparent)"); + chan->hdlc_eng?"On":"Off (Transparent)", + chan->cfg.hdlc_repeat?"Repeat":"N/A"); /* Obtain the DMA MRU size based on user confgured @@ -1885,11 +2085,7 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* chan->dma_mru = chan->mtu; -#if defined(__LINUX__) chan->dma_mru = aft_valid_mtu(chan->dma_mru); -#else - chan->dma_mru = aft_valid_mtu(chan->dma_mru); -#endif if (!chan->dma_mru){ DEBUG_EVENT("%s:%s: Error invalid MTU %d MRU %d\n", card->devname, @@ -1899,13 +2095,11 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* goto new_if_error; } - if ((chan->dma_mru/2) > aft_rx_copyback) { - aft_rx_copyback=chan->dma_mru/2; - } - if (conf->single_tx_buf || - ((card->adptr_type == A101_ADPTR_2TE1 || card->adptr_type == A101_ADPTR_1TE1) && - card->u.aft.firm_id == AFT_DS_FE_CORE_ID)){ + IS_BRI_CARD(card) || + ((card->adptr_type == A101_ADPTR_2TE1 || + card->adptr_type == A101_ADPTR_1TE1) && + card->u.aft.firm_id == AFT_DS_FE_CORE_ID)){ chan->single_dma_chain=1; chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; dma_per_ch=MAX_AFT_DMA_CHAINS; @@ -1995,10 +2189,12 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* } +#ifdef AFT_TDM_API_SUPPORT err=aft_tdm_api_init(card,chan,conf); if (err){ goto new_if_error; } +#endif err=aft_hwec_config(card,chan,conf,1); if (err){ @@ -2017,7 +2213,94 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* chan->single_dma_chain?"Off":"On", card->wandev.ec_enable_map?"On":"Off"); - + /* New DMA support A-DMA */ + dma_alignment = 4; + if (chan->channelized_cfg && !chan->hdlc_eng){ + dma_alignment = 0x200; + } + + err = card->hw_iface.busdma_tag_create( card->hw, + &chan->rx_dma_chain_table[0], + dma_alignment, + chan->dma_mru, + MAX_AFT_DMA_CHAINS); + if (err) { + DEBUG_EVENT("%s: Failed to allocate DMA Rx mtag!\n", + card->devname); + err = -EINVAL; + goto new_if_error; + } + err = card->hw_iface.busdma_tag_create( card->hw, + &chan->tx_dma_chain_table[0], + dma_alignment, + chan->dma_mru, + MAX_AFT_DMA_CHAINS); + if (err) { + DEBUG_EVENT("%s: Failed to allocate DMA Tx mtag!\n", + card->devname); + err = card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + err = -EINVAL; + goto new_if_error; + } + + for (i=0;ihw_iface.busdma_alloc( + card->hw, + &chan->tx_dma_chain_table[i]); + if (err){ + DEBUG_EVENT( + "%s:%s: Unable to load TX DMA buffer %d (%d)!\n", + card->devname, chan->if_name, i, err); + err = -EINVAL; + break; + } + DEBUG_DMA("%s:%s: Alloc DMA TX buffer %d virt=%p len=%d\n", + card->devname, chan->if_name, i, + chan->tx_dma_chain_table[i].dma_virt, + chan->dma_mru); + + err = card->hw_iface.busdma_alloc( + card->hw, + &chan->rx_dma_chain_table[i]); + if (err){ + DEBUG_EVENT( + "%s:%s: Unable to load RX DMA buffer %d (%d)!\n", + card->devname, chan->if_name, i, err); + err = -EINVAL; + break; + } + DEBUG_DMA("%s:%s: Alloc DMA RX buffer %d virt=%p len=%d\n", + card->devname, chan->if_name, i, + chan->rx_dma_chain_table[i].dma_virt, + chan->dma_mru); + } + if (err){ + + for (i=0;ihw_iface.busdma_free( + card->hw, + &chan->rx_dma_chain_table[i]); + card->hw_iface.busdma_free( + card->hw, + &chan->tx_dma_chain_table[i]); + } + err = card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + err = card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + err = -EINVAL; + goto new_if_error; + } + err=aft_alloc_rx_dma_buff(card, chan, dma_per_ch,0); if (err){ @@ -2086,12 +2369,14 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* if_init(dev); # endif #else - chan->common.is_netdev = 1; + if (chan->common.usedby != TDM_VOICE && + chan->common.usedby != TDM_VOICE_API){ + chan->common.is_netdev = 1; + } chan->common.iface.open = &if_open; chan->common.iface.close = &if_close; chan->common.iface.output = &if_send; chan->common.iface.ioctl = &if_do_ioctl; - chan->common.iface.get_stats = &if_stats; chan->common.iface.tx_timeout= &if_tx_timeout; if (wan_iface.attach){ if (!ifunit(wan_netif_name(dev))){ @@ -2122,7 +2407,7 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* we have to go back to it */ chan->max_tx_bufs_orig = chan->max_tx_bufs; - chan->common.state = WAN_CONNECTING; + set_chan_state(card, dev, WAN_CONNECTING); //chan->common.state = WAN_CONNECTING; DEBUG_EVENT( "\n"); @@ -2136,10 +2421,11 @@ new_if_error: static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { int err=-EINVAL; - sdla_t *card=wandev->private; + sdla_t *card=wandev->priv; wan_netif_set_priv(dev, NULL); + if (IS_E1_CARD(card) && !(WAN_FE_FRAME(&card->fe) == WAN_FR_UNFRAMED)) { conf->active_ch = conf->active_ch << 1; wan_clear_bit(0,&conf->active_ch); @@ -2156,6 +2442,11 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) case WANCONFIG_AFT_ANALOG: err = wp_tdmv_remora_init(&card->tdmv_iface); break; +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + case WANCONFIG_AFT_ISDN_BRI: + err = wp_tdmv_bri_init(&card->tdmv_iface); + break; +#endif default: err = wp_tdmv_te1_init(&card->tdmv_iface); break; @@ -2185,14 +2476,23 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) err=-EINVAL; - if (strcmp(conf->usedby, "TDM_VOICE") == 0 || - strcmp(conf->usedby, "TDM_VOICE_API") == 0){ + if (strcmp(conf->usedby, "TDM_VOICE") == 0 || strcmp(conf->usedby, "TDM_VOICE_API") == 0){ int i=0,master_if=-1; u32 active_ch=conf->active_ch; + if(IS_BRI_CARD(card)) { + wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&card->u.aft.tdmv_dchan); + } + if (card->wandev.fe_iface.active_map){ - conf->active_ch = card->wandev.fe_iface.active_map(&card->fe); + conf->active_ch = card->wandev.fe_iface.active_map(&card->fe, 0); + + if(IS_BRI_CARD(card)) { + wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&conf->active_ch); + wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&card->tdmv_conf.dchan); + } + active_ch=conf->active_ch; } @@ -2201,12 +2501,12 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) return err; } - DEBUG_TEST("%s: TDM VOICE: TESTING FOR DCHAN CHAN in 0x%08X Timeslots=%i CFG DCHAN=0x%08X MasterIF=%i\n", + DEBUG_TEST("%s: TDM VOICE: DCHAN CHAN in 0x%08X Timeslots=%i CFG DCHAN=0x%08X MasterIF=%i\n", card->devname, active_ch, card->u.aft.num_of_time_slots, card->tdmv_conf.dchan,master_if); - for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&active_ch)){ int dchan=-1; conf->active_ch=0; @@ -2231,15 +2531,45 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) WAN_TDMV_CALL(software_init, (&card->wan_tdmv), err); } #endif - }else{ - card->tdmv_conf.dchan=0; - err=new_if_private(wandev,dev,conf,0,-1); + + if(IS_BRI_CARD(card)) { + + if (conf->active_ch & ~(0x07)) { + DEBUG_EVENT("%s: Error: BRI Active Channels range 1 to 3: Range 0x%08X invalid\n", + card->devname,conf->active_ch); + err=-EINVAL; + goto new_if_cfg_skip; + } + + if (wan_test_bit(BRI_DCHAN_ACTIVE_CFG_CHAN, &conf->active_ch)) { + /* if bit 2 is set, user wants to run on the bri dchan */ + wan_set_bit(BRI_DCHAN_LOGIC_CHAN, &card->u.aft.tdmv_dchan); + card->u.aft.tdmv_dchan = BRI_DCHAN_LOGIC_CHAN; + err=new_if_private(wandev,dev,conf,0, BRI_DCHAN_LOGIC_CHAN); + } else { + /* BRI B-Channels */ + card->u.aft.tdmv_dchan = 0; + conf->active_ch = conf->active_ch << (2*WAN_FE_LINENO(&card->fe)); + DEBUG_EVENT("%s: Configure BRI Active CH 0x%08X\n", + card->devname,conf->active_ch); + err=new_if_private(wandev,dev,conf,0,-1); + } + + } else { + + card->tdmv_conf.dchan=0; + err=new_if_private(wandev,dev,conf,0,-1); + } } - +new_if_cfg_skip: + if (err == 0 && wan_netif_priv(dev)) { wan_smp_flag_t flags; + int card_use_counter; + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_counter); /* If FRONT End is down, it means that the DMA * is disabled. In this case don't try to @@ -2247,20 +2577,28 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) * function do this, after front end has come up */ wan_spin_lock_irq(&card->wandev.lock,&flags); - + aft_dev_open(card, wan_netif_priv(dev)); - + if (card->wandev.state == WAN_CONNECTED){ set_chan_state(card, dev, WAN_CONNECTED); } wan_spin_unlock_irq(&card->wandev.lock,&flags); - if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) { + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG || + card->wandev.config_id == WANCONFIG_AFT_SERIAL) { + wan_spin_lock_irq(&card->wandev.lock,&flags); card->fe.fe_status = FE_CONNECTED; handle_front_end_state(card); set_chan_state(card, dev, WAN_CONNECTED); wan_spin_unlock_irq(&card->wandev.lock,&flags); + + } else if (card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI) { + + wan_spin_lock_irq(&card->wandev.lock,&flags); + enable_data_error_intr(card); + wan_spin_unlock_irq(&card->wandev.lock,&flags); } } else if (err && wan_netif_priv(dev)){ @@ -2270,7 +2608,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) wan_netif_set_priv(dev, NULL); } } - + return err; } @@ -2296,8 +2634,8 @@ static int del_if_private (wan_device_t* wandev, netdevice_t* dev) { private_area_t* chan = wan_netif_priv(dev); sdla_t* card; - netskb_t *skb; wan_smp_flag_t flags; + int i; if (!chan){ DEBUG_EVENT("%s: Critical Error del_if_private() chan=NULL!\n", @@ -2359,36 +2697,47 @@ static int del_if_private (wan_device_t* wandev, netdevice_t* dev) aft_free_tx_descriptors(chan); aft_free_rx_descriptors(chan); - - while ((skb=wan_skb_dequeue(&chan->wp_rx_free_list)) != NULL) { -#ifdef __LINUX__ - if (skb_shinfo(skb)->frag_list || - skb_shinfo(skb)->nr_frags) { - DEBUG_EVENT("%s: Warning: SKB Corruption ch=%li!\n", - chan->if_name,chan->logic_ch_num); - continue; - } -#endif - wan_skb_free(skb); - } - while ((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ - wan_skb_free(skb); - } - - while ((skb=wan_skb_dequeue(&chan->wp_rx_stack_complete_list)) != NULL){ - wan_skb_free(skb); - } + wan_spin_unlock_irq(&card->wandev.lock,&flags); - while ((skb=wan_skb_dequeue(&chan->wp_tx_pending_list)) != NULL){ - wan_skb_free(skb); - } + for (i=0;iwp_tx_complete_list)) != NULL){ - wan_skb_free(skb); + card->hw_iface.busdma_free( + card->hw, + &chan->rx_dma_chain_table[i]); + card->hw_iface.busdma_free( + card->hw, + &chan->tx_dma_chain_table[i]); } + card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + + wan_spin_lock_irq(&card->wandev.lock,&flags); + + WAN_IFQ_DMA_PURGE(&chan->wp_rx_free_list); + WAN_IFQ_DESTROY(&chan->wp_rx_free_list); + + WAN_IFQ_PURGE(&chan->wp_rx_complete_list); + WAN_IFQ_DESTROY(&chan->wp_rx_complete_list); + WAN_IFQ_PURGE(&chan->wp_rx_stack_complete_list); + WAN_IFQ_DESTROY(&chan->wp_rx_stack_complete_list); + + WAN_IFQ_PURGE(&chan->wp_tx_pending_list); + WAN_IFQ_DESTROY(&chan->wp_tx_pending_list); + WAN_IFQ_PURGE(&chan->wp_rx_bri_dchan_complete_list); + WAN_IFQ_DESTROY(&chan->wp_rx_bri_dchan_complete_list); + + WAN_IFQ_PURGE(&chan->wp_tx_complete_list); + WAN_IFQ_DESTROY(&chan->wp_tx_complete_list); + if (chan->tx_idle_skb){ wan_skb_free(chan->tx_idle_skb); chan->tx_idle_skb=NULL; @@ -2432,8 +2781,10 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) { private_area_t* chan=wan_netif_priv(dev); wan_smp_flag_t flags; - sdla_t *card; - + sdla_t *card; + int card_use_cnt=0; + int err=0; + if (!chan){ DEBUG_EVENT("%s: Critical Error del_if() chan=NULL!\n", wan_netif_name(dev)); @@ -2445,7 +2796,10 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) wan_netif_name(dev)); return 0; } + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + wan_spin_lock_irq(&card->wandev.lock,&flags); aft_dev_close(card,chan); wan_spin_unlock_irq(&card->wandev.lock,&flags); @@ -2469,9 +2823,34 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) * shutting down all TDMV channels */ wan_spin_lock_irq(&card->wandev.lock,&flags); - aft_tdm_intr_ctrl(card,0); - aft_fifo_intr_ctrl(card, 0); - + if (IS_BRI_CARD(card)) { + int card_use_cnt; + + card->wandev.state=WAN_DISCONNECTED; + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + if (card_use_cnt == 1) { + DEBUG_TEST("%s: BRI Disabling TDMV INTR\n", + card->devname); + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } else { + u32 dmareg; + /* By removing timeslot out of the global + interrupt we can disable the tdm global isr. + This code re-triggers it just in case */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,&dmareg); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),dmareg); + } + } else { + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } + /* Disable RTP Tap */ card->wandev.rtp_len=0; @@ -2505,10 +2884,14 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) aft_tdmv_free(card); } #endif - return 0; + + err=0; } else { - return del_if_private(wandev,dev); + err=del_if_private(wandev,dev); } + + return err; + } @@ -2556,7 +2939,12 @@ static int if_init (netdevice_t* dev) #endif dev->get_stats = &if_stats; +#if 0 + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = 2*HZ; +#else if (chan->common.usedby == TDM_VOICE || + chan->common.usedby == TDM_VOICE_DCHAN || chan->common.usedby == TDM_VOICE_API){ dev->tx_timeout = NULL; }else{ @@ -2564,8 +2952,8 @@ static int if_init (netdevice_t* dev) } dev->watchdog_timeo = 2*HZ; +#endif dev->do_ioctl = if_do_ioctl; - dev->change_mtu = if_change_mtu; if (chan->common.usedby == BRIDGE || chan->common.usedby == BRIDGE_NODE){ @@ -2586,6 +2974,8 @@ static int if_init (netdevice_t* dev) dev->type = ARPHRD_PPP; dev->mtu = chan->mtu; dev->hard_header_len = 0; + dev->hard_header = NULL; + dev->rebuild_header = NULL; if (chan->common.usedby == API || chan->common.usedby == STACK){ if (chan->hdlc_eng) { @@ -2670,7 +3060,9 @@ static int if_open (netdevice_t* dev) * how long has the interface been up */ wan_getcurrenttime(&chan->router_start_time, NULL); +#if !defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) WAN_NETIF_START_QUEUE(dev); +#endif if (card->wandev.state == WAN_CONNECTED){ set_chan_state(card, dev, WAN_CONNECTED); @@ -2749,7 +3141,7 @@ static int if_close (netdevice_t* dev) static void disable_comm (sdla_t *card) { - wan_smp_flag_t flags,flags1; + wan_smp_flag_t smp_flags,smp_flags1; int used_cnt; AFT_FUNC_DEBUG(); @@ -2758,69 +3150,64 @@ static void disable_comm (sdla_t *card) #else /* Unconfiging, only on shutdown */ - if (IS_TE1_CARD(card) || IS_56K_CARD(card)) { - wan_smp_flag_t smp_flags,smp_flags1; - if (card->wandev.fe_iface.pre_release){ - card->wandev.fe_iface.pre_release(&card->fe); - } - card->hw_iface.hw_lock(card->hw,&smp_flags1); - wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - __aft_fe_intr_ctrl(card, 0); - if (card->wandev.fe_iface.unconfig){ - card->wandev.fe_iface.unconfig(&card->fe); - } - __aft_fe_intr_ctrl(card, 1); - wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); - card->hw_iface.hw_unlock(card->hw,&smp_flags1); - + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); } - - wan_spin_lock_irq(&card->wandev.lock,&flags); - - wan_set_bit(CARD_DOWN,&card->wandev.critical); + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + __aft_fe_intr_ctrl(card, 0); + if (card->wandev.fe_iface.unconfig){ + card->wandev.fe_iface.unconfig(&card->fe); + } + __aft_fe_intr_ctrl(card, 1); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); /* Disable DMA ENGINE before we perform * core reset. Otherwise, we will receive * rx fifo errors on subsequent resetart. */ - disable_data_error_intr(card,DEVICE_DOWN); - + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + disable_data_error_intr(card,LINK_DOWN); #if defined(AFT_RTP_SUPPORT) aft_rtp_unconfig(card); #endif - - wan_spin_unlock_irq(&card->wandev.lock,&flags); - + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + aft_chip_unconfigure(card); + /* Only disable the irq completely once the + chip unconfigure is executed */ + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + disable_data_error_intr(card,DEVICE_DOWN); + wan_set_bit(CARD_DOWN,&card->wandev.critical); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + WP_DELAY(10); - card->hw_iface.getcfg(card->hw, SDLA_USEDCNT, &used_cnt); + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &used_cnt); - card->hw_iface.hw_lock(card->hw,&flags1); - wan_spin_lock_irq(&card->wandev.lock,&flags); + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); __aft_fe_intr_ctrl(card, 0); aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_ON); __aft_fe_intr_ctrl(card, 1); - wan_spin_unlock_irq(&card->wandev.lock,&flags); - card->hw_iface.hw_unlock(card->hw,&flags1); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); - __sdla_pull_ptr_isr_array(card->hw,card,card->wandev.comm_port); + __sdla_pull_ptr_isr_array(card->hw,card,WAN_FE_LINENO(&card->fe)); if (used_cnt<=1){ DEBUG_EVENT("%s: Global Chip Shutdown Usage=%d\n", card->devname,used_cnt); - wan_spin_lock_irq(&card->wandev.lock,&flags); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); aft_global_chip_disable(card); - wan_spin_unlock_irq(&card->wandev.lock,&flags); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); } -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); -#endif #endif return; } @@ -2853,7 +3240,7 @@ static void if_tx_timeout (netdevice_t *dev) * is only used as a last resort. */ - ++chan->if_stats.collisions; + WAN_NETIF_STATS_INC_COLLISIONS(&chan->common); //++chan->if_stats.collisions; DEBUG_EVENT( "%s: Transmit timed out on %s\n", card->devname, @@ -2870,7 +3257,7 @@ static void if_tx_timeout (netdevice_t *dev) chan->tx_pending_chain_indx, cur_dma_ptr, chan->tx_attempts, - chan->if_stats.tx_packets); + WAN_NETIF_STATS_TX_PACKETS(&chan->common)); if (wan_test_bit(TX_DMA_BUSY,&chan->dma_status)){ wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); @@ -2896,18 +3283,8 @@ static void if_tx_timeout (netdevice_t *dev) aft_list_tx_descriptors(chan); #endif - WAN_NETIF_WAKE_QUEUE(dev); - if (chan->common.usedby == API){ - wan_wakeup_api(chan); - }else if (chan->common.usedby == STACK){ - wanpipe_lip_kick(chan,0); - }else if (chan->common.usedby == TDM_VOICE_DCHAN){ -#ifdef AFT_TDM_API_SUPPORT - if (is_tdm_api(chan,&chan->wp_tdm_api_dev)){ - wanpipe_tdm_api_kick(&chan->wp_tdm_api_dev); - } -#endif - } + wanpipe_wake_stack(chan); + } @@ -2944,6 +3321,7 @@ static void if_tx_timeout (netdevice_t *dev) * non-0 packet may be re-transmitted * */ + #if defined(__LINUX__) static int if_send (netskb_t* skb, netdevice_t* dev) #else @@ -2953,6 +3331,7 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct private_area_t *chan = wan_netif_priv(dev); sdla_t *card = chan->card; int err; + netskb_t *rskb=NULL; wan_smp_flag_t smp_flags; /* Mark interface as busy. The kernel will not @@ -2970,6 +3349,7 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct return 0; } + DEBUG_TX("%s: Sending %d bytes\n", wan_netif_name(dev), wan_skb_len(skb)); /* Non 2.4 kernels used to call if_send() * after TX_TIMEOUT seconds have passed of interface * being busy. Same as if_tx_timeout() in 2.4 kernels */ @@ -2981,7 +3361,7 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct * that our device never stays busy more than 5 seconds. So this * is only used as a last resort. */ - ++chan->if_stats.collisions; + WAN_NETIF_STATS_COLLISIONS(&chan->common); //++chan->if_stats.collisions; if((SYSTEM_TICKS - chan->tick_counter) < (5 * HZ)) { return 1; } @@ -2992,13 +3372,14 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct err=0; if (chan->common.state != WAN_CONNECTED){ + #if 1 WAN_NETIF_STOP_QUEUE(dev); wan_netif_set_ticks(dev, SYSTEM_TICKS); - ++chan->if_stats.tx_carrier_errors; + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); //++chan->if_stats.tx_carrier_errors; return 1; #else - ++chan->if_stats.tx_carrier_errors; + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); //++chan->if_stats.tx_carrier_errors; wan_skb_free(skb); WAN_NETIF_START_QUEUE(dev); err=0; @@ -3006,6 +3387,7 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct #endif } + if (chan->channelized_cfg) { private_area_t *top_chan=wan_netif_priv(chan->common.dev); @@ -3024,10 +3406,15 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct err=0; goto if_send_exit_crit; } - - chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; + + if(IS_BRI_CARD(card)) { + chan=(private_area_t*)card->u.aft.dev_to_ch_map[BRI_DCHAN_LOGIC_CHAN]; + }else{ + chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; + } + if (!chan){ - DEBUG_EVENT("%s: DCHAN TX No DCHAN Configured by not preset!\n", + DEBUG_EVENT("%s: Warning: DCHAN TX: No DCHAN Configured (not preset)! Discarding data.\n", card->devname); wan_skb_free(skb); WAN_NETIF_START_QUEUE(dev); @@ -3035,7 +3422,7 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct goto if_send_exit_crit; } - if (!chan->hdlc_eng){ + if (!chan->hdlc_eng || (IS_BRI_CARD(card) && chan->dchan_time_slot < 0)){ wan_skb_free(skb); WAN_NETIF_START_QUEUE(dev); err=0; @@ -3052,32 +3439,43 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct /* For TDM_VOICE_API no tx is supported in if_send */ if (chan->common.usedby == TDM_VOICE_API){ - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); WAN_NETIF_START_QUEUE(dev); + err=0; goto if_send_exit_crit; } if (chan->common.usedby == API){ - + if (sizeof(api_tx_hdr_t) >= wan_skb_len(skb)){ + wan_skb_free(skb); - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); WAN_NETIF_START_QUEUE(dev); err=0; goto if_send_exit_crit; } - if (chan->cfg.ss7_enable){ + if (chan->cfg.ss7_enable) { err=aft_ss7_tx_mangle(card,chan,skb); if (err){ wan_skb_free(skb); - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); WAN_NETIF_START_QUEUE(dev); err=0; goto if_send_exit_crit; } - }else{ + } else if (chan->cfg.hdlc_repeat) { + err=aft_hdlc_repeat_mangle(card,chan,skb,&rskb); + if (err){ + wan_skb_free(skb); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + } else { wan_skb_pull(skb,sizeof(api_tx_hdr_t)); } } @@ -3092,7 +3490,7 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct chan->num_of_time_slots); } wan_skb_free(skb); - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; WAN_NETIF_START_QUEUE(dev); err=0; goto if_send_exit_crit; @@ -3105,11 +3503,43 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct chan->if_name,wan_skb_len(skb)); } wan_skb_free(skb); - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; WAN_NETIF_START_QUEUE(dev); err=0; goto if_send_exit_crit; } + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + if(IS_BRI_CARD(card)){ + if(chan->dchan_time_slot >= 0){ + + /* NOTE: BRI dchan tx has to be done inside hw lock. + It allows to synchronize access to SPI on the card. + */ + card->hw_iface.hw_lock(card->hw,&smp_flags); + + err=aft_bri_dchan_transmit(card, chan, + wan_skb_data(skb), + wan_skb_len(skb)); + + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + if (err == 0 ) { + WAN_NETIF_START_QUEUE(dev); + wan_skb_free(skb); + err=0; + goto if_send_exit_crit; + }else{ + err=1; + WAN_NETIF_STOP_QUEUE(dev); + goto if_send_exit_crit; + } + } else { + /* On b-channel data is transmitted using AFT DMA. + Drop down to code below */ + } + } +#endif wan_spin_lock_irq(&card->wandev.lock, &smp_flags); @@ -3118,7 +3548,6 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct aft_dma_tx(card,chan); wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); return 1; - } wan_skb_unlink(skb); @@ -3128,7 +3557,10 @@ static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct if(!chan->lip_atm){ aft_dma_tx(card,chan); /*not needed for LIP_ATM!!*/ } - + + if (rskb) { + wan_skb_queue_tail(&chan->wp_tx_hdlc_rpt_list,rskb); + } wan_netif_set_ticks(dev, SYSTEM_TICKS); WAN_NETIF_START_QUEUE(dev); @@ -3156,7 +3588,6 @@ if_send_exit_crit: return err; } - /*============================================================================ * if_stats * @@ -3165,6 +3596,7 @@ if_send_exit_crit: * * Return a pointer to struct net_device_stats. */ +#if defined(__LINUX__) static struct net_device_stats gstats; static struct net_device_stats* if_stats (netdevice_t* dev) { @@ -3179,53 +3611,22 @@ static struct net_device_stats* if_stats (netdevice_t* dev) #if !defined(AFT_IRQ_DEBUG) if (card) { #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) - if (card->wan_tdmv.sc && + if (card->wan_tdmv.sc && card->wandev.state == WAN_CONNECTED && card->wandev.config_id != WANCONFIG_AFT_ANALOG && chan->common.usedby == TDM_VOICE) { - chan->if_stats.rx_packets = card->wandev.stats.rx_packets; - chan->if_stats.tx_packets = card->wandev.stats.tx_packets; + chan->common.if_stats.rx_packets = card->wandev.stats.rx_packets; + chan->common.if_stats.tx_packets = card->wandev.stats.tx_packets; } #endif } #endif - return &chan->if_stats; + return &chan->common.if_stats; } - - - -#if defined(__LINUX__) -static int if_change_mtu(netdevice_t *dev, int new_mtu) -{ - private_area_t* chan= (private_area_t*)wan_netif_priv(dev); - - if (!chan || wan_test_bit(0,&chan->interface_down)) { - return -ENODEV; - } - - if (!chan->hdlc_eng) { - return -EINVAL; - } - - if (chan->common.usedby == API){ - new_mtu+=sizeof(api_tx_hdr_t); - }else if (chan->common.usedby == STACK){ - new_mtu+=32; - } - - if (new_mtu > chan->dma_mru) { - return -EINVAL; - } - - dev->mtu = new_mtu; - - return 0; -} #endif - /*======================================================================== * * if_do_ioctl - Ioctl handler for fr @@ -3245,13 +3646,12 @@ static int if_change_mtu(netdevice_t *dev, int new_mtu) * wanpipemon debugger * */ -static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +static int +if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t cmd) { private_area_t* chan= (private_area_t*)wan_netif_priv(dev); sdla_t *card; -#if defined(__LINUX__) wan_smp_flag_t smp_flags; -#endif wan_udp_pkt_t *wan_udp_pkt; int err=-EOPNOTSUPP; @@ -3279,9 +3679,9 @@ static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) wan_spin_lock_irq(&card->wandev.lock, &smp_flags); err=wan_bind_api_to_svc(chan,ifr->ifr_data); - chan->if_stats.rx_dropped=0; + WAN_NETIF_STATS_RX_DROPPED(&chan->common)=0; //chan->if_stats.rx_dropped=0; if (!chan->hdlc_eng){ - chan->if_stats.tx_carrier_errors=0; + WAN_NETIF_STATS_TX_CARRIER_ERRORS(&chan->common)=0; //chan->if_stats.tx_carrier_errors=0; } wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); break; @@ -3461,7 +3861,7 @@ static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) *******************************************************************/ -#define FIFO_RESET_TIMEOUT_CNT 500 +#define FIFO_RESET_TIMEOUT_CNT 1000 #define FIFO_RESET_TIMEOUT_US 10 static int aft_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char wait) { @@ -3494,9 +3894,9 @@ static int aft_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned cha reg=0; wan_set_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®); - DEBUG_TEST("%s: Clearing RX Fifo %s Ch=%ld DmaDescr=(0x%X) Reg=(0x%X)\n", + DEBUG_TEST("%s: Clearing RX Fifo %s Ch=%ld DmaDescr=(0x%X) Reg=(0x%X) WAIT=%s\n", __FUNCTION__,chan->if_name,chan->logic_ch_num, - dma_descr,reg); + dma_descr,reg,wait == WP_WAIT?"YES":"NO"); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -3512,8 +3912,11 @@ static int aft_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned cha } if (timeout){ - DEBUG_EVENT("%s:%s: Error: Rx fifo reset timedout %u us\n", - card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US); + DEBUG_EVENT("%s:%s: Error: Rx fifo reset timedout %u us (ch=%d)\n", + card->devname, + chan->if_name, + i*FIFO_RESET_TIMEOUT_US, + chan->logic_ch_num); }else{ DEBUG_TEST("%s:%s: Rx Fifo Reset Successful\n", card->devname,chan->if_name); @@ -3553,9 +3956,10 @@ static int aft_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned cha reg=0; wan_set_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®); - DEBUG_TEST("%s: Clearing TX Fifo %s DmaDescr=(0x%X) Reg=(0x%X)\n", - __FUNCTION__,chan->if_name, - dma_descr,reg); + + DEBUG_TEST("%s: Clearing TX Fifo %s Ch=%ld DmaDescr=(0x%X) Reg=(0x%X) WAIT=%s\n", + __FUNCTION__,chan->if_name,chan->logic_ch_num, + dma_descr,reg,wait == WP_WAIT?"YES":"NO"); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -3571,8 +3975,11 @@ static int aft_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned cha } if (timeout){ - DEBUG_EVENT("%s:%s: Error: Tx fifo reset timedout %u us\n", - card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US); + DEBUG_EVENT("%s:%s: Error: Tx fifo reset timedout %u us (ch=%d)\n", + card->devname, + chan->if_name, + i*FIFO_RESET_TIMEOUT_US, + chan->logic_ch_num); }else{ DEBUG_TEST("%s:%s: Tx Fifo Reset Successful\n", card->devname,chan->if_name); @@ -3654,7 +4061,8 @@ static void aft_channel_rxintr_ctrl(sdla_t *card, private_area_t *chan, int on) static void aft_dev_enable(sdla_t *card, private_area_t *chan) { - DEBUG_TEST("%s: Enabling Global Inter Mask !\n",chan->if_name); + + DEBUG_CFG("%s: Enabling Global Inter Mask !\n",chan->if_name); /* Enable TX DMA for Logic Channel */ aft_channel_txdma_ctrl(card,chan,1); @@ -3668,20 +4076,33 @@ static void aft_dev_enable(sdla_t *card, private_area_t *chan) aft_channel_rxintr_ctrl(card,chan,0); chan->tdmv_irq_cfg=1; }else{ + + DEBUG_CFG("%s: Enabling FOR NON CHANNELIZED !\n",chan->if_name); + aft_channel_txintr_ctrl(card,chan,1); aft_channel_rxintr_ctrl(card,chan,1); } wan_set_bit(chan->logic_ch_num,&card->u.aft.active_ch_map); + + + DEBUG_CFG("%s: ACTIVE CH MAP !\n",chan->if_name); } static void aft_dev_open_private(sdla_t *card, private_area_t *chan) { + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + /* BRI dchan does not use DMA thus + skip the dma config code below */ + return; + } + if (card->wandev.state == WAN_CONNECTED && wan_test_bit(0,&card->u.aft.comm_enabled)){ - DEBUG_TEST("%s: OPEN reseting fifo\n", - chan->if_name); + DEBUG_TEST("%s: OPEN reseting fifo Channel = %li\n", + chan->if_name,chan->logic_ch_num); aft_tslot_sync_ctrl(card,chan,0); @@ -3735,7 +4156,7 @@ static void aft_dev_open(sdla_t *card, private_area_t *gchan) } wan_set_bit(0,&card->u.aft.tdmv_master_if_up); - + if (card->wandev.state == WAN_CONNECTED && !wan_test_bit(0,&card->u.aft.comm_enabled)){ DEBUG_EVENT("%s: Master IF Starting %s Communications\n", @@ -3761,7 +4182,15 @@ static void aft_dev_close_private(sdla_t *card, private_area_t *chan) if (chan->logic_ch_num < 0){ return; } - + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + /* BRI dchan does not use DMA thus + skip the dma config code below */ + return; + } + + DEBUG_TEST("%s: Chan=%i\n",__FUNCTION__,chan->logic_ch_num); + /* Disable Logic Channel TX Interrupts */ aft_channel_txintr_ctrl(card,chan,0); @@ -3786,9 +4215,20 @@ static void aft_dev_close(sdla_t *card, private_area_t *gchan) if (chan->channelized_cfg){ - aft_tdm_intr_ctrl(card,0); - aft_fifo_intr_ctrl(card, 0); - + if (IS_BRI_CARD(card)) { + int card_use_cnt; + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + if (card_use_cnt == 1) { + DEBUG_TEST("%s: BRI Disabling TDMV INTR\n", + card->devname); + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } + } else { + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } + for (chan=gchan; chan != NULL; chan=chan->next){ aft_dev_close_private(card,chan); @@ -3801,6 +4241,10 @@ static void aft_dev_close(sdla_t *card, private_area_t *gchan) if (chan->cfg.tdmv_master_if){ wan_clear_bit(0,&card->u.aft.tdmv_master_if_up); } + + DEBUG_TEST("%s: Closing Ch=%ld MasterUP=%i\n", + chan->if_name,chan->logic_ch_num, + wan_test_bit(0,&card->u.aft.tdmv_master_if_up)); } }else{ wan_set_bit(0,&chan->interface_down); @@ -3846,7 +4290,11 @@ static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan, int wdt, in aft_dma_tx(card,chan); if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ - WAN_NETIF_WAKE_QUEUE(chan->common.dev); + /* Wakeup stack also wakes up DCHAN, + however, for DCHAN we must always + call the upper layer and let it decide + what to do */ + wanpipe_wake_stack(chan); #ifndef CONFIG_PRODUCT_WANPIPE_GENERIC if (chan->common.usedby == API){ wan_wakeup_api(chan); @@ -3854,8 +4302,8 @@ static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan, int wdt, in wanpipe_lip_kick(chan,0); } #endif - } - + } + if (chan->common.usedby == TDM_VOICE_DCHAN){ #ifdef AFT_TDM_API_SUPPORT if (is_tdm_api(chan,&chan->wp_tdm_api_dev)){ @@ -3871,7 +4319,8 @@ static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan, int wdt, in * aft_tx_post_complete * */ -static void aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb) +static void +aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb) { unsigned int reg = wan_skb_csum(skb); u32 dma_status = aft_txdma_hi_get_dma_status(reg); @@ -3897,10 +4346,8 @@ static void aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t * } if (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK){ - if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s:%s: Error: TxDMA Length not equal 0 (reg=0x%08X)\n", card->devname,chan->if_name,reg); - } chan->errstats.Tx_dma_errors++; } @@ -3934,7 +4381,7 @@ static void aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t * } } } - chan->if_stats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; goto tx_post_exit; } @@ -3942,8 +4389,8 @@ tx_post_ok: chan->opstats.Data_frames_Tx_count++; chan->opstats.Data_bytes_Tx_count+=wan_skb_len(skb); - chan->if_stats.tx_packets++; - chan->if_stats.tx_bytes+=wan_skb_len(skb); + WAN_NETIF_STATS_INC_TX_PACKETS(&chan->common); //chan->if_stats.tx_packets++; + WAN_NETIF_STATS_INC_TX_BYTES(&chan->common, wan_skb_len(skb)); //chan->if_stats.tx_bytes+=wan_skb_len(skb); #if 0 if (chan->common.usedby != TDM_VOICE){ @@ -3975,12 +4422,13 @@ static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, unsigned char *pkt_error) { - unsigned int len; + unsigned int len,data_error = 0; unsigned char *buf; wp_rx_element_t *rx_el; + u32 dma_status; rx_el=(wp_rx_element_t *)wan_skb_data(skb); - DEBUG_RX("%s:%s: RX HI=0x%X LO=0x%X\n DMA=0x%X", + DEBUG_RX("%s:%s: RX HI=0x%X LO=0x%X DMA=0x%X", __FUNCTION__, chan->if_name, rx_el->reg, @@ -3989,27 +4437,115 @@ static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, #if 0 /* debugging */ - chan->if_stats.rx_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; #endif rx_el->align&=AFT_RXDMA_LO_ALIGN_MASK; *pkt_error=0; *new_skb=NULL; + dma_status=aft_rxdma_hi_get_dma_status(rx_el->reg); + /* Checking Rx DMA Go bit. Has to be '0' */ if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,&rx_el->reg)){ DEBUG_TEST("%s:%s: Error: RxDMA Intr: GO bit set on Rx intr\n", card->devname,chan->if_name); - chan->if_stats.rx_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; chan->errstats.Rx_dma_descr_err++; goto rx_comp_error; } + + /* Checking Rx DMA PCI error status. Has to be '0's */ + if (dma_status){ - /* This is just a sanity check, it should have been caught by isr */ - if (aft_decode_dma_status(card,chan,rx_el->reg)) { + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_M_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Master: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Target: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: No 'DeviceSelect' from target: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: 'Retry' exceeds maximum (64k): pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + + chan->errstats.Rx_pci_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; + card->wandev.stats.rx_errors++; goto rx_comp_error; } + + if (chan->hdlc_eng){ + + /* Checking Rx DMA Frame start bit. (information for api) */ + if (!wan_test_bit(AFT_RXDMA_HI_START_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s RxDMA Intr: Start flag missing: MTU Mismatch! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->opstats.Rx_Data_discard_long_count++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + } + /* Checking Rx DMA Frame end bit. (information for api) */ + if (!wan_test_bit(AFT_RXDMA_HI_EOF_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: End flag missing: MTU Mismatch! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->opstats.Rx_Data_discard_long_count++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + + } else { /* Check CRC error flag only if this is the end of Frame */ + + if (wan_test_bit(AFT_RXDMA_HI_FCS_ERR_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: CRC Error! Reg=0x%X Len=%d\n", + card->devname,chan->if_name,rx_el->reg, + (rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK)>>2); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_crc_err_count++; + card->wandev.stats.rx_crc_errors++; + wan_set_bit(WP_CRC_ERROR_BIT,&rx_el->pkt_error); + data_error = 1; + } + + /* Check if this frame is an abort, if it is + * drop it and continue receiving */ + if (wan_test_bit(AFT_RXDMA_HI_FRM_ABORT_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: Abort! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_frame_errors++; + wan_set_bit(WP_ABORT_ERROR_BIT,&rx_el->pkt_error); + data_error = 1; + } + + if (chan->common.usedby != API && data_error){ + goto rx_comp_error; + } + } + } + + len = rx_el->len; +#if 0 + /* FIXME: Remove this later!!! */ len=rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK; if (chan->hdlc_eng){ @@ -4018,7 +4554,7 @@ static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, len=((((chan->dma_mru>>2)-1)-len)<<2) - (~(rx_el->align)&AFT_RXDMA_LO_ALIGN_MASK); if (len < 3 || len > chan->dma_mru){ - chan->if_stats.rx_frame_errors++; + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; chan->errstats.Rx_hdlc_corrupiton++; card->wandev.stats.rx_frame_errors++; goto rx_comp_error; @@ -4030,13 +4566,12 @@ static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, len=(((chan->mru>>2)-len)<<2) - (~(0x03)&AFT_RXDMA_LO_ALIGN_MASK); if (len < 1 || len > chan->mru){ - chan->if_stats.rx_frame_errors++; + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; card->wandev.stats.rx_frame_errors++; goto rx_comp_error; } } - - +#endif *pkt_error=rx_el->pkt_error; @@ -4062,12 +4597,14 @@ static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, } } - if (len > aft_rx_copyback){ /* The rx size is big enough, thus * send this buffer up the stack * and allocate another one */ memset(wan_skb_data(skb),0,sizeof(wp_rx_element_t)); +#if defined(__FreeBSD__) + wan_skb_trim(skb,sizeof(wp_rx_element_t)); +#endif wan_skb_put(skb,len); wan_skb_pull(skb, sizeof(wp_rx_element_t)); *new_skb=skb; @@ -4080,13 +4617,17 @@ static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, * buffer and pass it up */ *new_skb=wan_skb_alloc(len + 20); if (!*new_skb){ - DEBUG_EVENT("%s:%s: Failed to allocate rx skb pkt (len=%d)!\n", - card->devname,chan->if_name,(len+20)); - chan->if_stats.rx_dropped++; + DEBUG_EVENT( + "%s:%s: Failed to allocate rx skb pkt (len=%d)!\n", + card->devname,chan->if_name,(len+20)); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //chan->if_stats.rx_dropped++; goto rx_comp_error; } buf=wan_skb_put((*new_skb),len); +#if defined(__FreeBSD__) + wan_skb_trim(skb,sizeof(wp_rx_element_t)); +#endif memcpy(buf,wan_skb_tail(skb),len); aft_init_requeue_free_skb(chan, skb); @@ -4137,7 +4678,8 @@ static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb) return 0; } -static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, int irq) +static int +aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, int irq) { int i; netskb_t *skb; @@ -4145,7 +4687,6 @@ static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, in for (i=0;ichannelized_cfg && !chan->hdlc_eng){ #if defined(WANPIPE_64BIT_4G_DMA) -#warning "Wanpipe compiled for 64bit 4G DMA" /* On 64bit Systems greater than 4GB we must * allocated our DMA buffers using GFP_DMA * flag */ @@ -4176,8 +4717,6 @@ static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, in wan_skb_queue_tail(&chan->wp_rx_free_list,skb); } - - return 0; } @@ -4191,7 +4730,7 @@ static void enable_timer (void* card_id) #if !defined(WAN_IS_TASKQ_SCHEDULE) wan_smp_flag_t smp_flags; wan_smp_flag_t smp_flags1; - int err = 0; + int delay = 0; #endif if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ @@ -4200,7 +4739,7 @@ static void enable_timer (void* card_id) return; } - DEBUG_TEST("%s: %s Sdla Polling %p!\n",__FUNCTION__, + DEBUG_56K("%s: %s Sdla Polling %p!\n",__FUNCTION__, card->devname, card->wandev.fe_iface.polling); @@ -4211,9 +4750,12 @@ static void enable_timer (void* card_id) card->hw_iface.hw_lock(card->hw,&smp_flags1); wan_spin_lock_irq(&card->wandev.lock, &smp_flags); if (card->wandev.fe_iface.polling){ - err = card->wandev.fe_iface.polling(&card->fe); + delay = card->wandev.fe_iface.polling(&card->fe); } wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + if (delay){ + card->wandev.fe_iface.add_timer(&card->fe, delay); + } card->hw_iface.hw_unlock(card->hw,&smp_flags1); #endif @@ -4301,6 +4843,7 @@ static void wp_tdm_bh (void *data, int pending) } wan_set_bit(card->tdmv_conf.span_no,&tdm_check); #endif + WAN_TDMV_CALL(rx_tx_span, (card), err); WAN_TASKLET_END((&chan->common.bh_task)); @@ -4327,19 +4870,175 @@ wp_tdm_bh_exit: } +static void wp_bh_rx(private_area_t* chan, netskb_t *new_skb, u8 pkt_error, int len) +{ + sdla_t *card = chan->card; + + if (chan->common.usedby == API){ + + if (chan->hdlc_eng){ + if (card->u.aft.cfg.rx_crc_bytes == 3){ + wan_skb_put(new_skb,3); + }else if (card->u.aft.cfg.rx_crc_bytes == 2){ + wan_skb_put(new_skb,2); + } + } + + if (chan->common.sk == NULL){ + DEBUG_TEST("%s: No sock bound to channel rx dropping!\n", + chan->if_name); + + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + +#if defined(__LINUX__) +# ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + + + /* Only for API, we insert packet status + * byte to indicate a packet error. Take + * this byte and put it in the api header */ + + if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr= + (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + rx_hdr->error_flag=pkt_error; + }else{ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", + chan->if_name, + (u32)wan_skb_headroom(new_skb), + (u32)sizeof(api_rx_hdr_t)); + } + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + new_skb->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(new_skb); + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + +#if 0 + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); /* chan->if_stats.rx_frame_errors++; */ +#endif + + if (wan_api_rx(chan,new_skb) != 0){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + +# endif +#endif + + }else if (chan->common.usedby == TDM_VOICE_DCHAN){ + +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)) { + int err; + + DEBUG_RX("%s: RX TDM API DCHAN %d\n",chan->if_name, wan_skb_len(new_skb)); + + if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr = + (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + //rx_hdr->error_flag=pkt_error; + }else{ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", + chan->if_name, + (u32)wan_skb_headroom(new_skb), + (u32)sizeof(api_rx_hdr_t)); + } + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + err=wanpipe_tdm_api_rx_hdlc(&chan->wp_tdm_api_dev,new_skb); + if (err){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + }else +#endif + if (chan->tdmv_zaptel_cfg){ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + int err; + + + /* ADEBUG */ + WAN_TDMV_CALL(rx_dchan, + (&card->wan_tdmv,chan->tdmv_chan, + wan_skb_data(new_skb),wan_skb_len(new_skb)), + err); + DEBUG_RX("%s TDM DCHAN VOICE Rx Pkt Len=%i Chan=%i\n", + card->devname,wan_skb_len(new_skb), + chan->tdmv_chan); +#else + DEBUG_EVENT("%s: DCHAN Rx Packet critical error TDMV not compiled!\n",card->devname); +#endif + + wan_skb_free(new_skb); + /* Continue through since the above + * function returns void */ + + } else { + DEBUG_EVENT("%s: DCHAN Rx Packet critical error op not supported\n",card->devname); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + }else if (chan->common.usedby == TDM_VOICE){ + + DEBUG_EVENT("%s: TDM VOICE CRITICAL: IN BH!!!!\n",card->devname); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + + }else if (chan->common.usedby == STACK){ + + wan_skb_set_csum(new_skb,0); + + if (wanpipe_lip_rx(chan,new_skb) != 0){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + }else{ + protocol_recv(chan->card,chan,new_skb); + } + + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=len; + WAN_NETIF_STATS_INC_RX_PACKETS(&chan->common); /* chan->if_stats.rx_packets++; */ + WAN_NETIF_STATS_INC_RX_BYTES(&chan->common, len); /* chan->if_stats.rx_bytes+=len; */ + return; +} + #if defined(__LINUX__) static void wp_bh (unsigned long data) #else static void wp_bh (void *data, int pending) #endif { - private_area_t* chan = (private_area_t *)data; - sdla_t *card=chan->card; - netskb_t *new_skb,*skb; - unsigned char pkt_error; - unsigned long timeout=SYSTEM_TICKS; - private_area_t *top_chan; - int len; + private_area_t *chan = (private_area_t *)data; + sdla_t *card=chan->card; + netskb_t *new_skb,*skb; + unsigned char pkt_error; + wan_ticks_t timeout=SYSTEM_TICKS; + private_area_t *top_chan; + int len; #ifdef AFT_IRQ_STAT_DEBUG card->wandev.stats.collisions++; @@ -4356,8 +5055,8 @@ static void wp_bh (void *data, int pending) top_chan=chan; } - DEBUG_TEST("%s: ------------ BEGIN --------------: %u\n", - __FUNCTION__,SYSTEM_TICKS); + DEBUG_TEST("%s: ------------ BEGIN --------------: %ld\n", + __FUNCTION__,(u_int64_t)SYSTEM_TICKS); if (!wan_test_bit(0,&chan->up)){ if (WAN_NET_RATELIMIT()){ @@ -4369,20 +5068,16 @@ static void wp_bh (void *data, int pending) } while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ - #if 0 - chan->if_stats.rx_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; #endif - if (SYSTEM_TICKS-timeout > 1){ wan_skb_queue_head(&chan->wp_rx_complete_list,skb); break; } - + new_skb=NULL; pkt_error=0; - - /* The post function will take care * of the skb and new_skb buffer. @@ -4402,7 +5097,7 @@ static void wp_bh (void *data, int pending) * we have a 0 length frame. Thus discard * (only if HDLC engine enabled) */ if (len <= 3){ - ++chan->if_stats.rx_errors; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; wan_skb_free(new_skb); continue; } @@ -4414,199 +5109,53 @@ static void wp_bh (void *data, int pending) wan_capture_trace_packet(chan->card, &top_chan->trace_info, new_skb,TRC_INCOMING_FRM); - - if (chan->common.usedby == API){ - - if (chan->common.sk == NULL){ - DEBUG_TEST("%s: No sock bound to channel rx dropping!\n", - chan->if_name); - chan->if_stats.rx_dropped++; - wan_skb_free(new_skb); - continue; - } - - if (chan->hdlc_eng){ - if (card->u.aft.cfg.rx_crc_bytes == 3){ - wan_skb_put(new_skb,3); - }else if (card->u.aft.cfg.rx_crc_bytes == 2){ - wan_skb_put(new_skb,2); - } - } - -#if defined(__LINUX__) -# ifndef CONFIG_PRODUCT_WANPIPE_GENERIC - - - /* Only for API, we insert packet status - * byte to indicate a packet error. Take - * this byte and put it in the api header */ - - if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ - api_rx_hdr_t *rx_hdr= - (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); - memset(rx_hdr,0,sizeof(api_rx_hdr_t)); - rx_hdr->error_flag=pkt_error; - }else{ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", - chan->if_name, - (u32)wan_skb_headroom(new_skb), - (u32)sizeof(api_rx_hdr_t)); - } - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - - new_skb->protocol = htons(PVC_PROT); - wan_skb_reset_mac_header(new_skb); - new_skb->dev = chan->common.dev; - new_skb->pkt_type = WAN_PACKET_DATA; - -#if 0 - chan->if_stats.rx_frame_errors++; -#endif - - if (wan_api_rx(chan,new_skb) != 0){ - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - -# endif -#endif - - }else if (chan->common.usedby == TDM_VOICE_DCHAN){ - -#ifdef AFT_TDM_API_SUPPORT - if (is_tdm_api(chan,&chan->wp_tdm_api_dev)) { - int err; - - if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ - api_rx_hdr_t *rx_hdr = - (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); - memset(rx_hdr,0,sizeof(api_rx_hdr_t)); - //rx_hdr->error_flag=pkt_error; - }else{ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", - chan->if_name, - (u32)wan_skb_headroom(new_skb), - (u32)sizeof(api_rx_hdr_t)); - } - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - err=wanpipe_tdm_api_rx_hdlc(&chan->wp_tdm_api_dev,new_skb); - if (err){ - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - - }else -#endif - if (chan->tdmv_zaptel_cfg){ - -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) - int err; -/* ADEBUG */ - WAN_TDMV_CALL(rx_dchan, - (&card->wan_tdmv,chan->tdmv_chan, - wan_skb_data(new_skb),wan_skb_len(new_skb)), - err); - - DEBUG_TEST("%s TDM DCHAN VOICE Rx Pkt Len=%i Chan=%i\n", - card->devname,wan_skb_len(new_skb), - chan->tdmv_chan); -#else - DEBUG_EVENT("%s: DCHAN Rx Packet critical error TDMV not compiled!\n",card->devname); -#endif - - wan_skb_free(new_skb); - /* Continue through since the above - * function returns void */ - - } else { - DEBUG_EVENT("%s: DCHAN Rx Packet critical error op not supported\n",card->devname); - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - - }else if (chan->common.usedby == TDM_VOICE){ - - DEBUG_EVENT("%s: TDM VOICE CRITICAL: IN BH!!!!\n",card->devname); - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - - }else if (chan->common.usedby == STACK){ - - wan_skb_set_csum(new_skb,0); - - if (wanpipe_lip_rx(chan,new_skb) != 0){ - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - - }else{ - protocol_recv(chan->card,chan,new_skb); - } - - chan->opstats.Data_frames_Rx_count++; - chan->opstats.Data_bytes_Rx_count+=len; - chan->if_stats.rx_packets++; - chan->if_stats.rx_bytes+=len; + wp_bh_rx(chan, new_skb, pkt_error, len); } - } while((skb=wan_skb_dequeue(&chan->wp_rx_stack_complete_list)) != NULL){ len=wan_skb_len(skb); if (wanpipe_lip_rx(chan,skb) != 0){ - ++chan->if_stats.rx_dropped; + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //++chan->if_stats.rx_dropped; wan_skb_free(skb); }else{ chan->opstats.Data_frames_Rx_count++; chan->opstats.Data_bytes_Rx_count+=len; - chan->if_stats.rx_packets++; - chan->if_stats.rx_bytes+=len; + WAN_NETIF_STATS_INC_RX_PACKETS(&chan->common); //chan->if_stats.rx_packets++; + WAN_NETIF_STATS_INC_RX_BYTES(&chan->common,len); //chan->if_stats.rx_bytes+=len; } } + while((skb=wan_skb_dequeue(&chan->wp_rx_bri_dchan_complete_list)) != NULL){ + /* for BRI the rx data on D-chan is in 'wp_rx_bri_dchan_complete_list'. */ + wp_bh_rx(chan, skb, 0, wan_skb_len(skb)); + } + while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ aft_tx_post_complete (chan->card,chan,skb); wan_skb_free(skb); } - WAN_TASKLET_END((&chan->common.bh_task)); - + /* FIXME: If wanpipe goes down, do not schedule again */ if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ - WAN_TASKLET_END((&chan->common.bh_task)); return; } #if 1 - { - if ((len=wan_skb_queue_len(&chan->wp_rx_complete_list))){ WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); }else if ((len=wan_skb_queue_len(&chan->wp_tx_complete_list))){ WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); }else if ((len=wan_skb_queue_len(&chan->wp_rx_stack_complete_list))){ WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); - } - + }else if ((len=wan_skb_queue_len(&chan->wp_rx_bri_dchan_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); } #endif - DEBUG_TEST("%s: ------------ END -----------------: %u\n", - __FUNCTION__,SYSTEM_TICKS); - + DEBUG_TEST("%s: ------------ END -----------------: %ld\n", + __FUNCTION__,(u_int64_t)SYSTEM_TICKS); return; } @@ -4615,17 +5164,15 @@ static void wp_bh (void *data, int pending) * Interrupt Support Functions * **********************************************************/ -static void wp_aft_fifo_per_port_isr(sdla_t *card) + + + +static void __wp_aft_fifo_per_port_isr(sdla_t *card, u32 rx_status, u32 tx_status) { - u32 rx_status, tx_status; - u32 i; - private_area_t *chan; int num_of_logic_ch; u32 tmp_fifo_reg; - - /* Clear HDLC pending registers */ - __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tx_status); - __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG),&rx_status); + private_area_t *chan; + int i; tx_status&=card->u.aft.active_ch_map; rx_status&=card->u.aft.active_ch_map; @@ -4662,6 +5209,10 @@ static void wp_aft_fifo_per_port_isr(sdla_t *card) continue; } #endif + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + DEBUG_TEST("%s:%s: Warning TX Fifo Error on LogicCh=%ld Slot=%d!\n", card->devname,chan->if_name,chan->logic_ch_num,i); @@ -4688,7 +5239,7 @@ static void wp_aft_fifo_per_port_isr(sdla_t *card) #endif aft_tx_fifo_under_recover(card,chan); - ++chan->if_stats.tx_fifo_errors; + WAN_NETIF_STATS_INC_TX_FIFO_ERRORS(&chan->common); //++chan->if_stats.tx_fifo_errors; card->wandev.stats.tx_aborted_errors++; __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tmp_fifo_reg); } @@ -4708,6 +5259,10 @@ static void wp_aft_fifo_per_port_isr(sdla_t *card) continue; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + #ifdef AFT_RX_FIFO_DEBUG { u32 dma_descr,tmp1_reg,tmp_reg,cur_dma_ptr; @@ -4730,8 +5285,8 @@ static void wp_aft_fifo_per_port_isr(sdla_t *card) cur_dma_ptr, dma_descr, tmp_reg,tmp1_reg, -chan->rx_dma_chain_table[chan->rx_chain_indx].dma_addr, -0); + chan->rx_dma_chain_table[chan->rx_chain_indx].dma_addr, + 0); } DEBUG_EVENT("%s:%s: Warning RX Fifo Error on Ch=%ld End=%d Cur=%d: Reg=0x%X Addr=0x%X!\n", @@ -4744,8 +5299,8 @@ chan->rx_dma_chain_table[chan->rx_chain_indx].dma_addr, aft_list_descriptors(chan); #endif #endif - ++chan->if_stats.rx_fifo_errors; - ++chan->if_stats.rx_over_errors; + WAN_NETIF_STATS_INC_RX_FIFO_ERRORS(&chan->common); //++chan->if_stats.rx_fifo_errors; + WAN_NETIF_STATS_INC_RX_OVER_ERRORS(&chan->common); //++chan->if_stats.rx_over_errors; chan->errstats.Rx_overrun_err_count++; card->wandev.stats.rx_over_errors++; @@ -4767,34 +5322,59 @@ chan->rx_dma_chain_table[chan->rx_chain_indx].dma_addr, return; } -#if 1 +static void wp_aft_fifo_per_port_isr(sdla_t *card) +{ + u32 rx_status=0, tx_status=0; + u32 i; + + /* Clear HDLC pending registers */ + __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tx_status); + __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG),&rx_status); + + + if (IS_BRI_CARD(card)) { + void **card_list=__sdla_get_ptr_isr_array(card->hw); + sdla_t *tmp_card; + for (i=0;iwandev.state == WAN_CONNECTED) { + __wp_aft_fifo_per_port_isr(tmp_card,rx_status,tx_status); + } + } + } else { + __wp_aft_fifo_per_port_isr(card,rx_status,tx_status); + } + + return; +} static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock) { - void **card_list; - u32 max_number_of_ports, i; - sdla_t *tmp_card; - - max_number_of_ports = 8; /* 24 */ - card_list=__sdla_get_ptr_isr_array(card->hw); + if(IS_BRI_CARD(card)){ + + void **card_list; + u32 max_number_of_ports, i; + sdla_t *tmp_card; - DEBUG_TEST("%s(): card_list ptr: 0x%p\n", __FUNCTION__, card_list); + max_number_of_ports = MAX_BRI_LINES; /* 24 */ - for (i=0; ihw); - tmp_card=(sdla_t*)card_list[i]; - if (tmp_card == NULL || wan_test_bit(CARD_DOWN,&tmp_card->wandev.critical)) { - continue; - } - - DEBUG_TEST("%s(): card ptr: %s, tmp_card ptr: %s\n", __FUNCTION__, card->devname, tmp_card->devname); + DEBUG_TEST("%s(): card_list ptr: 0x%p\n", __FUNCTION__, card_list); - if (tmp_card->wandev.fe_iface.check_isr && - tmp_card->wandev.fe_iface.check_isr(&tmp_card->fe)) { + for (i=0; iwandev.fe_iface.isr && - tmp_card->wandev.fe_iface.isr(&tmp_card->fe)) { + tmp_card=(sdla_t*)card_list[i]; + if (tmp_card == NULL){ + continue; + } + + DEBUG_TEST("%s(): card ptr: 0x%p, tmp_card ptr: 0x%p\n", __FUNCTION__, card, tmp_card); + + if (tmp_card->wandev.fe_iface.isr) { + tmp_card->wandev.fe_iface.isr(&tmp_card->fe); if (lock) { wan_smp_flag_t smp_flags; @@ -4806,31 +5386,24 @@ static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock) } } } - } + } else { + if (card->wandev.fe_iface.isr){ + card->wandev.fe_iface.isr(&card->fe); - return; -} - -#else - -static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock) -{ - if (card->wandev.fe_iface.isr){ - card->wandev.fe_iface.isr(&card->fe); - - if (lock){ - wan_smp_flag_t smp_flags; - wan_spin_lock_irq(&card->wandev.lock,&smp_flags); - handle_front_end_state(card); - wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); - }else{ - handle_front_end_state(card); + if (lock){ + wan_smp_flag_t smp_flags; + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + }else{ + handle_front_end_state(card); + } } } return; } -#endif + /**SECTION*************************************************************** * * HARDWARE Interrupt Handlers @@ -4853,23 +5426,25 @@ static u32 aft_master_dev=0xF; static int gdma_cnt=0; #endif -#define EC_IRQ_TIMEOUT (HZ) +#define EC_IRQ_TIMEOUT (HZ/32) static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) { u32 reg_sec=0,reg=0; - u32 a108_reg=0, a56k_reg=0; + u32 a108_reg=0, a56k_reg=0, serial_reg=0; u32 fifo_port_intr=0; u32 dma_port_intr=0; u32 wdt_port_intr=0; u32 tdmv_port_intr=0; + u32 status_port_intr=0; u32 fe_intr=0; + u32 max_ports=IS_BRI_CARD(card)?MAX_BRI_LINES:8; WAN_IRQ_RETVAL_DECL(irq_ret); if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ DEBUG_TEST("%s: Card down, ignoring interrupt!!!!!!!\n", - card->devname); + card->devname); WAN_IRQ_RETURN(irq_ret); } @@ -4890,25 +5465,27 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) } #endif - wan_set_bit(0,&card->in_isr); + wan_set_bit(0,&card->in_isr); - /* -----------------2/6/2003 9:02AM------------------ - * Disable all chip Interrupts (offset 0x040) - * -- "Transmit/Receive DMA Engine" interrupt disable - * -- "FiFo/Line Abort Error" interrupt disable + /* -----------------2/6/2003 9:02AM------------------ + * Disable all chip Interrupts (offset 0x040) + * -- "Transmit/Receive DMA Engine" interrupt disable + * -- "FiFo/Line Abort Error" interrupt disable * --------------------------------------------------*/ - __sdla_bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); + __sdla_bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); reg_sec=reg; - if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,®)){ + DEBUG_ISR("%s:ISR = 0x%X\n",card->devname,reg); + + if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,®)){ #ifdef AFT_IRQ_STAT_DEBUG card->wandev.stats.rx_dropped++; -#endif +#endif if (wan_test_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®)) { - DEBUG_TEST("%s: Got Front End Interrupt 0x%08X\n", + DEBUG_ISR("%s: Got Front End Interrupt 0x%08X\n", card->devname,reg); WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); @@ -4916,23 +5493,26 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) #ifdef AFT_IRQ_STAT_DEBUG card->wandev.stats.tx_dropped++; #endif - fe_intr=1; + + if (card->wandev.fe_iface.check_isr && + card->wandev.fe_iface.check_isr(&card->fe)){ #if defined(__LINUX__) - wan_set_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); - WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); - __aft_fe_intr_ctrl(card,0); + wan_set_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + __aft_fe_intr_ctrl(card,0); #else - front_end_interrupt(card,reg,0); + front_end_interrupt(card,reg,0); #endif - } - } + } + + }/* if (wan_test_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®)) */ + + }/* if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,®)) */ /* New Octasic implementarion May 16 2006 */ #if defined(CONFIG_WANPIPE_HWEC) - if (card->wandev.ec_dev && - SYSTEM_TICKS-card->wandev.ec_intmask > EC_IRQ_TIMEOUT) { - card->wandev.ec_intmask=SYSTEM_TICKS; + if (card->wandev.ec_dev && wanpipe_ec_isr(card->wandev.ec_dev)){ if (!wan_test_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd)){ /* All work is done from ec_poll routine!!! */ wan_set_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); @@ -4941,54 +5521,78 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) } #endif - if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID || IS_BRI_CARD(card)) { - __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a108_reg); + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a108_reg); + fifo_port_intr = aft_chipcfg_a108_get_fifo_intr_stats(a108_reg); dma_port_intr = aft_chipcfg_a108_get_dma_intr_stats(a108_reg); wdt_port_intr = aft_chipcfg_a108_get_wdt_intr_stats(a108_reg); tdmv_port_intr = aft_chipcfg_a108_get_tdmv_intr_stats(a108_reg); - }else if(IS_56K_CARD(card)){ - __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a56k_reg); + } else if (IS_SERIAL_CARD(card)) { + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &serial_reg); + +#ifdef AFT_SERIAL_DEBUG +if (serial_reg) { + DEBUG_EVENT("%s: SERIAL ISR = 0x%08X\n", + card->devname,serial_reg); +} +#endif + + fifo_port_intr = aft_chipcfg_a108_get_fifo_intr_stats(serial_reg); + dma_port_intr = aft_chipcfg_a108_get_dma_intr_stats(serial_reg); + wdt_port_intr = aft_chipcfg_serial_get_wdt_intr_stats(serial_reg); + status_port_intr = aft_chipcfg_serial_get_status_intr_stats(serial_reg, card->wandev.comm_port); + + } else if(IS_56K_CARD(card)) { + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a56k_reg); fifo_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_FIFO_INTR_BIT,&a56k_reg); dma_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_DMA_INTR_BIT,&a56k_reg); wdt_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_WDT_INTR_BIT,&a56k_reg); - }else{ + } else { fifo_port_intr = aft_chipcfg_get_hdlc_intr_stats(reg); dma_port_intr = aft_chipcfg_get_dma_intr_stats(reg); wdt_port_intr = aft_chipcfg_get_wdt_intr_stats(reg); tdmv_port_intr = aft_chipcfg_get_tdmv_intr_stats(reg); - if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { tdmv_port_intr&=0x01; } } + DEBUG_ISR("%s: ISR: TDM=0x%08X DMA=0x%08X FIFO=0x%08X STAT=0x%08X WDT=0x%08X\n", + card->devname,tdmv_port_intr,dma_port_intr,fifo_port_intr, + status_port_intr,wdt_port_intr); + + if (tdmv_port_intr || - dma_port_intr || - fifo_port_intr || - dma_port_intr || - wdt_port_intr) { + dma_port_intr || + fifo_port_intr || + status_port_intr || + wdt_port_intr) { /* Pass Through */ } else { /* No more interrupts for us */ - goto aft_global_isr_exit; + goto aft_global_isr_exit; } - + + if (wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg) && wan_test_bit(card->wandev.comm_port,&fifo_port_intr)){ #ifdef AFT_IRQ_STAT_DEBUG card->wandev.stats.multicast++; #endif + wp_aft_fifo_per_port_isr(card); + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); } #if 1 if (wan_test_bit(AFT_LCFG_DMA_INTR_BIT,&card->u.aft.lcfg_reg) && wan_test_bit(card->wandev.comm_port,&dma_port_intr)){ - + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); wp_aft_dma_per_port_isr(card); @@ -5001,21 +5605,27 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) #if 1 if (wan_test_bit(0,&card->u.aft.comm_enabled) && - !wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg)){ + !wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg)){ aft_fifo_intr_ctrl(card, 1); } #else #warning "FIFO Interrupt Disabled" #endif } + + + #else #warning "NCDEBUG DMA IGNORED" #endif - if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { - - if (tdmv_port_intr && - !wan_test_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®)) { + + + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + + if (tdmv_port_intr && + !wan_test_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®)) { int ring_buf_enabled=wan_test_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); sdla_t *tmp_card; @@ -5023,7 +5633,6 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) void **card_list; int i; - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); #ifdef AFT_IRQ_STAT_DEBUG @@ -5032,26 +5641,27 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) if (ring_buf_enabled) { if (card->adptr_type == A104_ADPTR_4TE1 && - card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { - wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); } else { wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); - wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); } - __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); if (card->hw_iface.fe_test_bit(card->hw,1)) { - DEBUG_EVENT("%s: Global TDM Ring Resync\n",card->devname); - ring_rsync=1; - card->hw_iface.fe_clear_bit(card->hw,1); + DEBUG_EVENT("%s: Global TDM Ring Resync\n",card->devname); + ring_rsync=1; + card->hw_iface.fe_clear_bit(card->hw,1); } } card_list=__sdla_get_ptr_isr_array(card->hw); - for (i=0;i<8;i++){ + + //FIXME: Use value pre card type + for (i=0;iwandev.state == WAN_CONNECTED && wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&tmp_card->u.aft.lcfg_reg)) { #ifdef AFT_IRQ_STAT_DEBUG tmp_card->wandev.stats.rx_crc_errors++; @@ -5066,70 +5676,77 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) tmp_card->u.aft.tdm_rx_dma_toggle=0; } - tmp_card->u.aft.tdm_tx_dma_toggle++; + tmp_card->u.aft.tdm_tx_dma_toggle++; if (tmp_card->u.aft.tdm_tx_dma_toggle >= AFT_TDMV_CIRC_BUF_LEN) { tmp_card->u.aft.tdm_tx_dma_toggle=0; - } + } } } #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) - if (tmp_card->wan_tdmv.sc) { + if (tmp_card->wan_tdmv.sc) { + aft_voice_span_rx_tx(tmp_card, - ring_buf_enabled); + ring_buf_enabled); }else #endif { - wp_aft_tdmv_per_port_isr(tmp_card); + wp_aft_tdmv_per_port_isr(tmp_card); } } } if (!ring_buf_enabled) { if (card->adptr_type == A104_ADPTR_4TE1 && - card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { - wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); } else { wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); - wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); } - __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + } + } - } } else { - if (wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&card->u.aft.lcfg_reg) && - wan_test_bit(card->wandev.comm_port,&tdmv_port_intr)){ + if (wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&card->u.aft.lcfg_reg) && + wan_test_bit(card->wandev.comm_port,&tdmv_port_intr)){ - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); #ifdef AFT_IRQ_STAT_DEBUG - card->wandev.stats.rx_crc_errors++; + card->wandev.stats.rx_crc_errors++; #endif #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) - if (card->wan_tdmv.sc && - !card->wandev.rtp_len && - card->wandev.config_id != WANCONFIG_AFT_ANALOG) { - u32 dmareg; - aft_voice_span_rx_tx(card, 0); - card->hw_iface.bus_read_4(card->hw, - AFT_PORT_REG(card,AFT_DMA_CTRL_REG),&dmareg); - wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,&dmareg); - wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,&dmareg); - card->hw_iface.bus_write_4(card->hw, - AFT_PORT_REG(card,AFT_DMA_CTRL_REG),dmareg); - } else + + if (card->wan_tdmv.sc && + !card->wandev.rtp_len && + card->wandev.config_id != WANCONFIG_AFT_ANALOG) { + u32 dmareg; + aft_voice_span_rx_tx(card, 0); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,&dmareg); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),dmareg); + } else #endif - { - wp_aft_tdmv_per_port_isr(card); + { + wp_aft_tdmv_per_port_isr(card); + } } - } + } + + if (status_port_intr) { + wp_aft_serial_status_isr(card, status_port_intr); } if (wan_test_bit(card->wandev.comm_port,&wdt_port_intr)){ WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - wp_aft_wdt_per_port_isr(card,1); + wp_aft_wdt_per_port_isr(card,1); card->u.aft.wdt_tx_cnt=SYSTEM_TICKS; #ifdef AFT_IRQ_STAT_DEBUG card->wandev.stats.rx_fifo_errors++; @@ -5148,7 +5765,7 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) #endif /* -----------------2/6/2003 10:36AM----------------- - * Finish of the interupt handler + * Finish of the interupt handler * --------------------------------------------------*/ @@ -5170,7 +5787,7 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ - DEBUG_EVENT("%s: Critical: Echo Canceller Chip Security Compromised: Disabling Driver!\n", + DEBUG_EVENT("%s: Critical: Echo Canceller Chip Security Compromised: Disabling Driver!\n", card->devname); DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", card->devname); @@ -5189,155 +5806,77 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), &lcfg_reg); card->u.aft.lcfg_reg=lcfg_reg; if (wan_test_bit(AFT_LCFG_TX_FE_SYNC_STAT_BIT,&lcfg_reg) || - wan_test_bit(AFT_LCFG_RX_FE_SYNC_STAT_BIT,&lcfg_reg)){ - if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ - DEBUG_EVENT("%s: Critical: A108 Lost Sync with Front End: Disabling Driver (0x%08X : A108S=0x%08X)!\n", + wan_test_bit(AFT_LCFG_RX_FE_SYNC_STAT_BIT,&lcfg_reg)){ + if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ + DEBUG_EVENT("%s: Critical: A108 Lost Sync with Front End: Disabling Driver (0x%08X : A108S=0x%08X)!\n", card->devname, lcfg_reg,a108_reg); DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", card->devname); aft_critical_shutdown(card); - } + } } else { card->u.aft.chip_security_cnt=0; } - } else { - card->u.aft.chip_security_cnt=0; - } + } else { + card->u.aft.chip_security_cnt=0; + } #endif - DEBUG_TEST("---- ISR end.-------------------\n"); + DEBUG_TEST("---- ISR end.-------------------\n"); aft_global_isr_exit: - - -#ifdef AFT_IRQ_STAT_DEBUG - if (SYSTEM_TICKS - stat_timeout > (AFT_IRQ_STAT_TIMEOUT*HZ) ) { - stat_timeout=SYSTEM_TICKS; - DEBUG_EVENT("%s: T=%is ISR=%li FE=%li DMA=%li TDM=%li FIFO=%li WDTi=%li WDTp=%li BH=%li TASK=%li\n", - card->devname, - AFT_IRQ_STAT_TIMEOUT, - card->wandev.stats.rx_errors, /*ISR*/ - card->wandev.stats.tx_dropped, /*FE*/ - card->wandev.stats.rx_length_errors, /*DMA*/ - card->wandev.stats.rx_crc_errors, /* TDM */ - card->wandev.stats.multicast, /*FIFO*/ - card->wandev.stats.rx_fifo_errors, /* WDTi */ - card->wandev.stats.tx_aborted_errors, /* WDTp */ - card->wandev.stats.collisions, /* BH */ - card->wandev.stats.rx_missed_errors /* TASK */ - ); - card->wandev.stats.rx_errors=0; - card->wandev.stats.tx_dropped=0; - card->wandev.stats.rx_length_errors=0; - card->wandev.stats.rx_crc_errors=0; - card->wandev.stats.multicast=0; - card->wandev.stats.rx_fifo_errors=0; - card->wandev.stats.tx_aborted_errors=0; - card->wandev.stats.collisions=0; - card->wandev.stats.rx_missed_errors=0; - } -#endif - - if ((SYSTEM_TICKS - card->u.aft.rx_errors_timeout) > card->u.aft.cfg.err_throttle_period*HZ) { - - if (card->u.aft.rx_errors_down_timeout) { - if (SYSTEM_TICKS - card->u.aft.rx_errors_down_timeout > card->u.aft.cfg.err_throttle_timeout*HZ) { - card->u.aft.rx_errors_down_timeout=0; - DEBUG_EVENT("%s: Restarting Device after excessive rx errors!\n", - card->devname); - wan_set_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); - WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); - } - } else { - if (card->u.aft.rx_errors_hist > 5000) { - card->u.aft.rx_errors_over_cnt++; - DEBUG_EVENT("%s: Excessive Rx Errors ... %i (errs/s=%i)!\n", - card->devname,card->u.aft.rx_errors_over_cnt,card->u.aft.rx_errors_hist); -#if 0 - -/* NC: This is very dangrous. We have seen on some lines that it takes up to - 9 rx_errors_over_cnt for the line to stabilize. I will continue to print the - warning but will not disable the line. This way a customer would know that there - is something wrong with his system. Ericsson uses this feature in their systems - The driver stop on excess errors should be configurable. */ - - if (card->u.aft.rx_errors_over_cnt >= 2) { - DEBUG_EVENT("%s: Excessive Rx Errors ... stopping device!\n",card->devname); - card->u.aft.rx_errors_over_cnt=0; - disable_data_error_intr(card,LINK_DOWN); - aft_wdt_reset(card); - aft_wdt_set(card,AFT_WDTCTRL_TIMEOUT); - card->u.aft.rx_errors_down_timeout = SYSTEM_TICKS; - } -#endif - } else { - card->u.aft.rx_errors_over_cnt=0; - card->u.aft.rx_errors_down_timeout=0; - } - } - card->u.aft.rx_errors_hist=0; - card->u.aft.rx_errors_timeout=SYSTEM_TICKS; - } - - - wan_clear_bit(0,&card->in_isr); + wan_clear_bit(0,&card->in_isr); WAN_IRQ_RETURN(irq_ret); } -static void wp_aft_dma_per_port_isr(sdla_t *card) + +static void wp_aft_serial_status_isr(sdla_t *card, u32 serial_intr_status) +{ + u32 reg; + + __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG), ®); + card->u.aft.serial_status=reg; + + if (wan_test_bit(AFT_CHIPCFG_SERIAL_CTS_STATUS_INTR_BIT,&serial_intr_status)) { + DEBUG_EVENT("%s: CTS ISR Status 0x%02X\n", + card->devname, + wan_test_bit(AFT_SERIAL_LCFG_CTS_BIT,®)); + } + + if (wan_test_bit(AFT_CHIPCFG_SERIAL_DCD_STATUS_INTR_BIT,&serial_intr_status)) { + DEBUG_EVENT("%s: DCS ISR Status 0x%02X\n", + card->devname, + wan_test_bit(AFT_SERIAL_LCFG_DCD_BIT,®)); + } + + if (wan_test_bit(AFT_CHIPCFG_SERIAL_RTS_STATUS_INTR_BIT,&serial_intr_status)) { + DEBUG_EVENT("%s: RTS ISR Status 0x%02X\n", + card->devname, + wan_test_bit(AFT_SERIAL_LCFG_RTS_BIT,®)); + } +} + + +static void __wp_aft_per_per_port_isr(sdla_t *card, u32 dma_rx_reg, u32 dma_tx_reg) { - int i; - u32 dma_tx_reg,dma_rx_reg; private_area_t *chan; u32 dma_tx_voice=0; - - /* -----------------2/6/2003 9:37AM------------------ - * Checking for Interrupt source: - * 1. Receive DMA Engine - * 2. Transmit DMA Engine - * 3. Error conditions. - * --------------------------------------------------*/ - - int num_of_logic_ch; - num_of_logic_ch=card->u.aft.num_of_time_slots; - - /* Zaptel optimization. Dont waist time looking at - channels, when we know that only a single DCHAN - will use this code */ -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) - if (card->wan_tdmv.sc) { - __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); - __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); - if (card->u.aft.tdmv_dchan) { - chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; - if (chan && wan_test_bit(0,&chan->up)) { - aft_dma_rx_complete(card,chan,0); - aft_dma_tx_complete(card,chan,0,0); - } - } - goto isr_skb_rx; - } -#endif - - /* Receive DMA Engine */ - __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); - + int i; + dma_rx_reg&=card->u.aft.active_ch_map; - - if (dma_rx_reg == 0){ - goto isr_skb_rx; + if (!dma_rx_reg) { + goto isr_skb_rx; } dma_rx_reg &= card->u.aft.logic_ch_map; dma_rx_reg &= ~(card->u.aft.tdm_logic_ch_map); + for (i=0; iu.aft.num_of_time_slots;i++){ - for (i=0; iu.aft.dev_to_ch_map[i]; if (!chan){ DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", @@ -5354,13 +5893,16 @@ static void wp_aft_dma_per_port_isr(sdla_t *card) continue; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + #if 0 - chan->if_stats.rx_frame_errors++; + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; #endif - DEBUG_ISR("%s: RX Interrupt pend. \n", - card->devname); - + DEBUG_TEST("%s: RX Interrupt pend. \n", card->devname); + aft_dma_rx_complete(card,chan,0); @@ -5378,11 +5920,7 @@ static void wp_aft_dma_per_port_isr(sdla_t *card) isr_skb_rx: - /* Transmit DMA Engine */ - __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); - dma_tx_reg&=card->u.aft.active_ch_map; - dma_tx_reg&=~dma_tx_voice; if (dma_tx_reg == 0){ @@ -5393,7 +5931,7 @@ isr_skb_rx: dma_tx_reg &= ~(card->u.aft.tdm_logic_ch_map); - for (i=0; iu.aft.num_of_time_slots ;i++){ if (wan_test_bit(i,&dma_tx_reg)) { chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; @@ -5407,6 +5945,10 @@ isr_skb_rx: continue; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + DEBUG_ISR("---- TX Interrupt pend. --\n"); aft_dma_tx_complete(card,chan,0,0); } @@ -5415,6 +5957,63 @@ isr_skb_rx: isr_skb_tx: DEBUG_ISR("---- ISR SKB TX end.-------------------\n"); + return; +} + + +static void wp_aft_dma_per_port_isr(sdla_t *card) +{ + int i; + u32 dma_tx_reg=0,dma_rx_reg=0; + private_area_t *chan; + + /* -----------------2/6/2003 9:37AM------------------ + * Checking for Interrupt source: + * 1. Receive DMA Engine + * 2. Transmit DMA Engine + * 3. Error conditions. + * --------------------------------------------------*/ + + /* Zaptel optimization. Dont waist time looking at + channels, when we know that only a single DCHAN + will use this code */ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc) { + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); + if (card->u.aft.tdmv_dchan) { + chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; + if (chan && wan_test_bit(0,&chan->up)) { + aft_dma_rx_complete(card,chan,0); + aft_dma_tx_complete(card,chan,0,0); + } + } + return; + } +#endif + + /* Receive DMA Engine */ + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); + + DEBUG_TEST("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); + + if (IS_BRI_CARD(card)) { + void **card_list=__sdla_get_ptr_isr_array(card->hw); + sdla_t *tmp_card; + for (i=0;iwandev.state == WAN_CONNECTED && + !wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&tmp_card->u.aft.lcfg_reg)) { + + __wp_aft_per_per_port_isr(tmp_card,dma_rx_reg,dma_tx_reg); + } + } + } else { + __wp_aft_per_per_port_isr(card,dma_rx_reg,dma_tx_reg); + } + } @@ -5452,13 +6051,16 @@ static void wp_aft_tdmv_per_port_isr(sdla_t *card) continue; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } if (chan->channelized_cfg && !chan->hdlc_eng){ aft_dma_rx_tdmv(card,chan); } #if 0 - chan->if_stats.rx_frame_errors++; + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; #endif DEBUG_ISR("%s: RX Interrupt pend. \n", @@ -5469,33 +6071,51 @@ static void wp_aft_tdmv_per_port_isr(sdla_t *card) - - -static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) +static void __wp_aft_wdt_per_port_isr (sdla_t *card, int wdt_intr, int *wdt_disable, int *timeout) { - int i,wdt_disable = 0; - int timeout=AFT_WDTCTRL_TIMEOUT; - - aft_wdt_reset(card); - + int i; + + /* If TDM interrupt does not start in time + * we have to re-start it */ if (card->rsync_timeout){ - if (SYSTEM_TICKS - card->rsync_timeout > 3*HZ) { - card->rsync_timeout=0; - if (card->fe.fe_status == FE_CONNECTED) { - DEBUG_EVENT("%s: WAN IRQ Timeout \n", - card->devname); - wan_set_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); - WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + if (!IS_BRI_CARD(card)) { + if (SYSTEM_TICKS - card->rsync_timeout > 2*HZ) { + card->rsync_timeout=0; + if (card->fe.fe_status == FE_CONNECTED) { + DEBUG_EVENT("%s: TDM IRQ Timeout \n", + card->devname); + wan_set_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } } - } - aft_wdt_set(card,timeout); - return; + } else { + if (SYSTEM_TICKS - card->rsync_timeout > 1*HZ) { + int x; + void **card_list=__sdla_get_ptr_isr_array(card->hw); + sdla_t *first_card=NULL; + card->rsync_timeout=0; + + for (x=0;xu.aft.lcfg_reg)) { + break; + } + first_card=NULL; + } + + if (first_card) { + DEBUG_EVENT("%s: BRI TDM IRQ Timeout \n", + first_card->devname); + if (!wan_test_bit(AFT_FE_RESTART,&first_card->u.aft.port_task_cmd)) { + wan_set_bit(AFT_FE_RESTART,&first_card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&first_card->u.aft.port_task)); + } + } + } + } + return; } - if (card->u.aft.rx_errors_down_timeout) { - aft_wdt_set(card,timeout); - return; - } for (i=0; iu.aft.num_of_time_slots;i++){ @@ -5514,23 +6134,27 @@ static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) wan_test_bit(0,&chan->interface_down)){ continue; } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } #if 0 if (wdt_intr){ - ++chan->if_stats.tx_dropped; + WAN_NETIF_STATS_INC_TX_DROPPED(&chan->common); //++chan->if_stats.tx_dropped; }else{ - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; } #endif if (card->wandev.state == WAN_CONNECTED){ if (chan->single_dma_chain){ - wdt_disable=1; + *wdt_disable=1; continue; } #if 0 - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; #endif aft_dma_tx_complete (card,chan,1,0); @@ -5563,12 +6187,11 @@ static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) } } #if 0 - ++chan->if_stats.tx_dropped; + WAN_NETIF_STATS_INC_TX_DROPPED(&chan->common); //++chan->if_stats.tx_dropped; #endif #if 1 - timeout=1; - aft_wdt_set(card,timeout); + *timeout=1; WAN_TDMV_CALL(rx_tx_span, (card), err); #else #warning "NCDEBUG: rx_tx_span disabled poll" @@ -5580,6 +6203,34 @@ static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) #endif } + return; + +} + +static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) +{ + int wdt_disable = 0; + int timeout=AFT_WDTCTRL_TIMEOUT; + + aft_wdt_reset(card); + + if (IS_BRI_CARD(card)) { + int x; + void **card_list=__sdla_get_ptr_isr_array(card->hw); + sdla_t *first_card; + for (x=0;xwandev.critical)) { + __wp_aft_wdt_per_port_isr(first_card,wdt_intr,&wdt_disable,&timeout); + } + } + + } else { + __wp_aft_wdt_per_port_isr(card,wdt_intr,&wdt_disable,&timeout); + } + + + #ifdef AFT_WDT_ENABLE /* Since this fucntion can be called via interrupt or * via interrupt poll, only re-enable wdt interrupt @@ -5664,10 +6315,21 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, case AFT_MODEM_STATUS: wan_udp_pkt->wan_udp_return_code = 0; - if (card->wandev.state == WAN_CONNECTED){ - wan_udp_pkt->wan_udp_data[0]=0x28; - }else{ - wan_udp_pkt->wan_udp_data[0]=0; + wan_udp_pkt->wan_udp_data[0]=0; + + if (IS_SERIAL_CARD(card)) { + if (wan_test_bit(AFT_SERIAL_LCFG_DCD_BIT,&card->u.aft.serial_status)) { + wan_udp_pkt->wan_udp_data[0]|=0x08; + } + if (wan_test_bit(AFT_SERIAL_LCFG_CTS_BIT,&card->u.aft.serial_status)) { + wan_udp_pkt->wan_udp_data[0]|=0x20; + } + } else { + if (card->wandev.state == WAN_CONNECTED){ + wan_udp_pkt->wan_udp_data[0]=0x28; + }else{ + wan_udp_pkt->wan_udp_data[0]=0; + } } wan_udp_pkt->wan_udp_data_len=1; break; @@ -5900,8 +6562,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, case AFT_HWEC_STATUS: *(unsigned long *)&wan_udp_pkt->wan_udp_data[0] = - IS_E1_CARD(card) ? card->wandev.ec_map: - card->wandev.ec_map << 1; + card->wandev.fe_ec_map; wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); wan_udp_pkt->wan_udp_return_code = 0; break; @@ -5993,31 +6654,6 @@ static void port_set_state (sdla_t *card, int state) } } - -/*============================================================ - * callback_front_end_state - * - * Called by front end code to indicate that state has - * changed. We will call the poll task to update the state. - */ - -static void callback_front_end_state(void *card_id) -{ - sdla_t *card = (sdla_t*)card_id; - - if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ - return; - } - - /* Call the poll task to update the state */ - wan_set_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); - WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); - - return; -} - - - /*============================================================ * handle_front_end_state * @@ -6089,7 +6725,9 @@ static void handle_front_end_state(void *card_id) return; } - enable_data_error_intr(card); + if (!IS_BRI_CARD(card) || !wan_test_bit(0,&card->u.aft.comm_enabled)) { + enable_data_error_intr(card); + } port_set_state(card,WAN_CONNECTED); wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); @@ -6097,7 +6735,12 @@ static void handle_front_end_state(void *card_id) }else{ if (card->wandev.state == WAN_CONNECTED){ port_set_state(card,WAN_DISCONNECTED); - disable_data_error_intr(card,LINK_DOWN); + + if (!IS_BRI_CARD(card)) { + /* Never disable interrupts for BRI since + all cards are on same timslot map */ + disable_data_error_intr(card,LINK_DOWN); + } wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); /* We are already in the poll task here so @@ -6232,7 +6875,7 @@ static int aft_read(sdla_t *card, wan_cmd_api_t *api_cmd) api_cmd->len); } -#if defined(DEBUG_REG) +#if defined(WAN_DEBUG_REG) DEBUG_EVENT("%s: Reading Bar%d Offset=0x%X Data=%08X Len=%d\n", card->devname, api_cmd->bar, @@ -6268,7 +6911,7 @@ static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd) card->hw, api_cmd->offset, *(u8*)&api_cmd->data[0]); -#if defined(DEBUG_REG) +#if defined(WAN_DEBUG_REG) DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%02X\n", card->devname,api_cmd->offset, *(u8*)&api_cmd->data[0]); @@ -6278,7 +6921,7 @@ static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd) card->hw, api_cmd->offset, *(u16*)&api_cmd->data[0]); -#if defined(DEBUG_REG) +#if defined(WAN_DEBUG_REG) DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%04X\n", card->devname,api_cmd->offset, *(unsigned short*)&api_cmd->data[0]); @@ -6288,7 +6931,7 @@ static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd) card->hw, api_cmd->offset, *(unsigned int*)&api_cmd->data[0]); -#if defined(DEBUG_REG) +#if defined(WAN_DEBUG_REG) DEBUG_EVENT("ADEBUG: %s: Write Offset=0x%08X Data=0x%08X\n", card->devname,api_cmd->offset, *(u32*)&api_cmd->data[0]); @@ -6456,8 +7099,14 @@ static void enable_data_error_intr(sdla_t *card) { u32 reg; int i,err; + int card_use_cnt; - DEBUG_TEST("%s: %s()\n",card->devname,__FUNCTION__); + + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + + DEBUG_TEST("%s: %s() Card Port =%i Use Cnt = %i \n", + card->devname,__FUNCTION__,card->wandev.comm_port,card_use_cnt); card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); @@ -6483,16 +7132,16 @@ static void enable_data_error_intr(sdla_t *card) aft_wdt_reset(card); - /* Clean Tx/Rx DMA interrupts */ - card->hw_iface.bus_read_4(card->hw, - AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG), - ®); - - card->hw_iface.bus_read_4(card->hw, - AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG), - ®); - - + if (!IS_BRI_CARD(card) || (IS_BRI_CARD(card) && card_use_cnt == 1)) { + /* Clean Tx/Rx DMA interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG), + ®); + } err=aft_hwdev[card->wandev.card_type].aft_test_sync(card,0); if (err){ @@ -6503,13 +7152,13 @@ static void enable_data_error_intr(sdla_t *card) /*FIXME: How to recover from here, should never happen */ } - if (card->tdmv_conf.span_no){ card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); card->hw_iface.bus_write_4(card->hw, - AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + } for (i=0; iu.aft.num_of_time_slots;i++){ @@ -6528,6 +7177,9 @@ static void enable_data_error_intr(sdla_t *card) continue; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } DEBUG_TEST("%s: 1) Free Used DMA CHAINS %s\n", card->devname,chan->if_name); @@ -6566,7 +7218,6 @@ static void enable_data_error_intr(sdla_t *card) card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); /* For all channels clean Tx/Rx fifos */ - for (i=0; iu.aft.num_of_time_slots;i++){ private_area_t *chan; @@ -6583,6 +7234,9 @@ static void enable_data_error_intr(sdla_t *card) continue; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } DEBUG_TEST("%s: 3) Init interface fifo %s\n", card->devname,chan->if_name); @@ -6617,6 +7271,10 @@ static void enable_data_error_intr(sdla_t *card) continue; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + DEBUG_TEST("%s: 4) Init interface %s\n", card->devname,chan->if_name); @@ -6658,12 +7316,14 @@ static void enable_data_error_intr(sdla_t *card) continue; } + memset(&chan->swring,0,sizeof(chan->swring)); + if (!wan_test_bit(0,&chan->up)){ continue; } - if (wan_test_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status)) { - memset(&chan->swring,0,sizeof(chan->swring)); + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; } if (!chan->hdlc_eng){ @@ -6693,10 +7353,12 @@ static void enable_data_error_intr(sdla_t *card) AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); wan_set_bit(AFT_LCFG_DMA_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); if (card->tdmv_conf.span_no){ wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); } + card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); @@ -6709,38 +7371,36 @@ static void enable_data_error_intr(sdla_t *card) /* Enable Channelized Driver if configured */ if (card->tdmv_conf.span_no) { - + card->hw_iface.bus_read_4(card->hw, - AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), - ®); + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); card->hw_iface.bus_read_4(card->hw, - AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), - ®); - -#if 1 - + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); - if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { +#if 1 + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); /* Reset Global Fifo for the whole card */ - card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); wan_set_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®); - card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); - - /* Wait for Global Fifo Reset 1ms */ + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); WP_DELAY(1000); - + /* Clear Global Card Fifo reset */ wan_clear_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®); - + /* Enable TDM Quad DMA Ring buffer */ - if (wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status)) { + if (wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status)) { wan_set_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); card->hw_iface.fe_set_bit(card->hw,1); }else{ wan_clear_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); } - + #if 1 /* Global Acknowledge TDM Interrupt (Kickstart) */ if (card->adptr_type == A104_ADPTR_4TE1 && @@ -6753,6 +7413,7 @@ static void enable_data_error_intr(sdla_t *card) #endif card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + card->rsync_timeout=SYSTEM_TICKS; DEBUG_EVENT("%s: AFT Global TDM Intr\n", @@ -6766,18 +7427,17 @@ static void enable_data_error_intr(sdla_t *card) wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); - if (wan_test_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status)) { DEBUG_EVENT("%s: AFT Per Port TDM Intr (swring)\n",card->devname); } else { DEBUG_EVENT("%s: AFT Per Port TDM Intr\n",card->devname); } + } #endif - } + }/* if (card->u.aft.cfg.tdmv_span_no) */ - #ifdef AFT_WDT_ENABLE aft_wdt_set(card,AFT_WDTCTRL_TIMEOUT); #endif @@ -6791,12 +7451,19 @@ static void enable_data_error_intr(sdla_t *card) static void disable_data_error_intr(sdla_t *card, unsigned char event) { u32 reg; - + int card_use_cnt; + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + + if(IS_BRI_CARD(card) && card_use_cnt > 1){ + return; + } + DEBUG_TEST("%s: Event = %s\n",__FUNCTION__, event==DEVICE_DOWN?"Device Down": "Link Down"); - DEBUG_EVENT("%s: AFT communications disabled!\n", - card->devname); + DEBUG_EVENT("%s: AFT communications disabled! %d\n", + card->devname, card_use_cnt); aft_wdt_reset(card); @@ -6806,9 +7473,17 @@ static void disable_data_error_intr(sdla_t *card, unsigned char event) wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); wan_clear_bit(AFT_LCFG_TDMV_INTR_BIT,®); - if (event==DEVICE_DOWN){ - /* Disable Front End Interface */ - wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + + if (IS_BRI_CARD(card)) { + if (card_use_cnt == 1 && event==DEVICE_DOWN){ + /* Disable Front End Interface */ + wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + } + }else{ + if (event==DEVICE_DOWN){ + /* Disable Front End Interface */ + wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + } } card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); card->u.aft.lcfg_reg=reg; @@ -6850,12 +7525,19 @@ static int update_comms_stats(sdla_t* card) card->hw_iface.hw_lock(card->hw,&smp_flags); if (card->wandev.fe_iface.read_alarm) { - card->wandev.fe_iface.read_alarm(&card->fe, 0); + card->wandev.fe_iface.read_alarm(&card->fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); } /* TE1 Update T1/E1 perfomance counters */ +#if 0 +#warning "PMON DISABLED DUE TO ERROR" +#else if (card->wandev.fe_iface.read_pmon) { + wan_smp_flag_t flags; + wan_spin_lock_irq(&card->wandev.lock,&flags); card->wandev.fe_iface.read_pmon(&card->fe, 0); + wan_spin_unlock_irq(&card->wandev.lock,&flags); } +#endif card->hw_iface.hw_unlock(card->hw,&smp_flags); } @@ -6898,6 +7580,7 @@ static void aft_rx_fifo_over_recover(sdla_t *card, private_area_t *chan) aft_tslot_sync_ctrl(card,chan,1); + wanpipe_wake_stack(chan); } static void aft_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) @@ -6933,6 +7616,7 @@ static void aft_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) aft_reset_tx_chain_cnt(chan); aft_dma_tx(card,chan); + wanpipe_wake_stack(chan); } static int set_chan_state(sdla_t* card, netdevice_t* dev, int state) @@ -6993,6 +7677,12 @@ static int set_chan_state(sdla_t* card, netdevice_t* dev, int state) wanpipe_lip_disconnect(chan,0); } } + +#if defined(NETGRAPH) + if (chan->common.usedby == WP_NETGRAPH){ + wan_ng_link_state(&chan->common, state); + } +#endif return 0; } @@ -7122,10 +7812,22 @@ void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb) #endif #if defined(__LINUX__) + skb->protocol = htons(ETH_P_IP); skb->dev = chan->common.dev; wan_skb_reset_mac_header(skb); netif_rx(skb); + +#elif defined(__FreeBSD__) + + wan_skb_set_csum(skb,0); + + if (wan_iface.input && wan_iface.input(chan->common.dev, skb) != 0){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //++chan->if_stats.rx_dropped; + wan_skb_free(skb); + return; + } + #else DEBUG_EVENT("%s: Action not supported (IP)!\n", card->devname); @@ -7165,7 +7867,7 @@ static int aft_global_chip_disable(sdla_t *card) static int aft_chip_configure(sdla_t *card, wandev_conf_t* conf) { - return aft_hwdev[card->wandev.card_type].aft_chip_config(card); + return aft_hwdev[card->wandev.card_type].aft_chip_config(card, conf); } static int aft_chip_unconfigure(sdla_t *card) @@ -7191,13 +7893,13 @@ static int aft_dev_configure(sdla_t *card, private_area_t *chan, wanif_conf_t* c /* Channel definition section. If not channels defined * return error */ if (chan->time_slot_map == 0){ - DEBUG_EVENT("%s: Invalid Channel Selection 0x%lX\n", + DEBUG_EVENT("%s: Invalid Channel Selection 0x%X\n", card->devname,chan->time_slot_map); return -EINVAL; } - DEBUG_EVENT("%s: Active Ch Map :0x%08lX\n", + DEBUG_EVENT("%s: Active Ch Map :0x%08X\n", card->devname,chan->time_slot_map); @@ -7237,7 +7939,7 @@ static void aft_tx_dma_voice_handler(unsigned long data, int wdt, int reset) private_area_t *chan = (private_area_t *)data; sdla_t *card = chan->card; u32 reg,dma_descr,dma_status; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; if (wan_test_and_set_bit(TX_HANDLER_BUSY,&chan->dma_status)){ DEBUG_EVENT("%s: SMP Critical in %s\n", @@ -7313,14 +8015,14 @@ static void aft_tx_dma_voice_handler(unsigned long data, int wdt, int reset) } } } - chan->if_stats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; } chan->opstats.Data_frames_Tx_count++; chan->opstats.Data_bytes_Tx_count+=wan_skb_len(dma_chain->skb); - chan->if_stats.tx_packets++; - chan->if_stats.tx_bytes+=wan_skb_len(dma_chain->skb); + WAN_NETIF_STATS_INC_TX_PACKETS(&chan->common); //chan->if_stats.tx_packets++; + WAN_NETIF_STATS_INC_TX_BYTES(&chan->common,wan_skb_len(dma_chain->skb)); //chan->if_stats.tx_bytes+=wan_skb_len(dma_chain->skb); wan_clear_bit(0,&dma_chain->init); @@ -7341,7 +8043,7 @@ static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset) private_area_t *chan = (private_area_t *)data; sdla_t *card = chan->card; u32 reg,dma_descr; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; if (wan_test_and_set_bit(TX_HANDLER_BUSY,&chan->dma_status)){ DEBUG_EVENT("%s: SMP Critical in %s\n", @@ -7383,12 +8085,22 @@ static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset) DEBUG_TEST("%s: TX DMA Handler Chain %d\n",chan->if_name,dma_chain->index); if (chan->hdlc_eng){ - if (dma_chain->skb){ + + if (dma_chain->skb == chan->tx_hdlc_rpt_skb) { + if (wan_skb_queue_len(&chan->wp_tx_hdlc_rpt_list) == 0) { + wan_skb_queue_tail(&chan->wp_tx_hdlc_rpt_list,dma_chain->skb); + dma_chain->skb=NULL; + } else { + /* Drop down to init where packet will freed */ + } + chan->tx_hdlc_rpt_skb=NULL; + + } else if (dma_chain->skb){ wan_skb_set_csum(dma_chain->skb, reg); wan_skb_queue_tail(&chan->wp_tx_complete_list,dma_chain->skb); dma_chain->skb=NULL; } - }else{ + } else { if (dma_chain->skb != chan->tx_idle_skb){ wan_skb_set_csum(dma_chain->skb, reg); @@ -7434,7 +8146,7 @@ static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset) * aft_dma_chain_tx * */ -static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int intr,int fifo) +static int aft_dma_chain_tx(wan_dma_descr_t *dma_chain,private_area_t *chan, int intr,int fifo) { #define dma_descr dma_chain->dma_descr @@ -7449,8 +8161,9 @@ static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); - DEBUG_DMA("%s:%d: chan logic ch=%ld chain=%d dma_descr=0x%x set!\n", - __FUNCTION__,__LINE__,chan->logic_ch_num,dma_ch_indx,dma_descr); + DEBUG_DMA("%s: %s:%s: LogicCh=%ld ChIndex=%d DmaDesc=0x%x set\n", + __FUNCTION__, card->devname, chan->if_name, + chan->logic_ch_num,dma_ch_indx,dma_descr); card->hw_iface.bus_read_4(card->hw,dma_descr,®); @@ -7501,8 +8214,9 @@ static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int len_align=1; } - DEBUG_DMA("%s: TXDMA_LO=0x%X PhyAddr=0x%X DmaDescr=0x%X Len=%i\n", - __FUNCTION__,reg,(int)dma_chain->dma_addr,dma_descr,len); + DEBUG_DMA("%s: %s:%s: TXDMA_LO=0x%X PhyAddr=0x%X DmaDescr=0x%X Len=%d\n", + __FUNCTION__,card->devname,chan->if_name, + reg,dma_chain->dma_addr,dma_descr,len); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -7565,8 +8279,9 @@ static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int wan_set_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®); } - DEBUG_DMA("%s: TXDMA_HI=0x%X DmaDescr=0x%X Len=%d Intr=%d\n", - __FUNCTION__,reg,dma_descr,len,intr); + DEBUG_DMA("%s:: %s:%s: TXDMA_HI=0x%X DmaDescr=0x%X Len=%d Intr=%d\n", + __FUNCTION__,card->devname,chan->if_name, + reg,dma_descr,len,intr); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -7587,15 +8302,18 @@ static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int * aft_dma_chain_init * */ -static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_chain) +static void +aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain) { +#define card chan->card - if (dma_chain->dma_addr){ - chan->card->hw_iface.pci_unmap_dma(chan->card->hw, - dma_chain->dma_addr-dma_chain->dma_offset, - dma_chain->dma_map_len, - PCI_DMA_TODEVICE); - } + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, 1, + SDLA_DMA_POSTWRITE); + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTWRITE); if (dma_chain->skb){ if (!chan->hdlc_eng){ @@ -7612,34 +8330,29 @@ static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_cha dma_chain->skb=NULL; } } - - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - dma_chain->dma_map_len=dma_chain->dma_len; - wan_clear_bit(0,&dma_chain->init); +#undef card } -static void aft_rx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_chain) +static void +aft_rx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain) { +#define card chan->card - if (dma_chain->dma_addr){ - chan->card->hw_iface.pci_unmap_dma(chan->card->hw, - dma_chain->dma_addr-dma_chain->dma_offset, - dma_chain->dma_map_len, - PCI_DMA_FROMDEVICE); - } + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, 1, + SDLA_DMA_POSTREAD); + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTREAD); if (dma_chain->skb){ aft_init_requeue_free_skb(chan,dma_chain->skb); - dma_chain->skb=NULL; + dma_chain->skb = NULL; } - - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - dma_chain->dma_map_len=0; - wan_clear_bit(0,&dma_chain->init); +#undef card } @@ -7647,7 +8360,7 @@ static void aft_rx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_cha static int aft_dma_voice_tx(sdla_t *card, private_area_t *chan) { int err=0; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; u32 reg, dma_ram_desc; if (wan_test_and_set_bit(TX_DMA_BUSY,&chan->dma_status)){ @@ -7659,6 +8372,10 @@ static int aft_dma_voice_tx(sdla_t *card, private_area_t *chan) dma_chain = &chan->tx_dma_chain_table[0]; + DEBUG_DMA("%s: %s:%s:: Chain %d Used %ld\n", + __FUNCTION__,card->devname,chan->if_name, + dma_chain->index,dma_chain->init); + /* If the current DMA chain is in use,then * all chains are busy */ if (wan_test_and_set_bit(0,&dma_chain->init)){ @@ -7694,29 +8411,19 @@ static int aft_dma_voice_tx(sdla_t *card, private_area_t *chan) buf=wan_skb_put(dma_chain->skb,chan->mtu*2); memset(buf,chan->idle_flag,chan->mtu*2); - dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, - wan_skb_data(dma_chain->skb), - chan->dma_mru, - PCI_DMA_TODEVICE); - - if (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) { - dma_chain->dma_offset = - AFT_TDMV_BUF_MASK - (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) + 1; - - dma_chain->dma_virt = wan_skb_data(dma_chain->skb) + dma_chain->dma_offset; - dma_chain->dma_addr += dma_chain->dma_offset; - - } else { - dma_chain->dma_offset=0; - dma_chain->dma_virt = wan_skb_data(dma_chain->skb); - } - - dma_chain->dma_len = wan_skb_len(dma_chain->skb); - dma_chain->dma_map_len=chan->dma_mru; - + /* A-DMA */ + card->hw_iface.busdma_map( card->hw, + dma_chain, + wan_skb_data(dma_chain->skb), + wan_skb_len(dma_chain->skb), + chan->dma_mru, + SDLA_DMA_PREWRITE); + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, 1, + SDLA_DMA_PREWRITE); } - dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); @@ -7733,7 +8440,7 @@ static int aft_dma_voice_tx(sdla_t *card, private_area_t *chan) /* Drop the tx packet here */ aft_tx_dma_chain_init(chan,dma_chain); - chan->if_stats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; err=-EINVAL; goto aft_dma_voice_tx_exit; } @@ -7751,7 +8458,7 @@ aft_dma_voice_tx_exit: static int aft_dma_tx (sdla_t *card,private_area_t *chan) { int err=0, intr=0, cnt=0; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; netskb_t *skb=NULL; if (chan->channelized_cfg && !chan->hdlc_eng){ @@ -7807,11 +8514,37 @@ static int aft_dma_tx (sdla_t *card,private_area_t *chan) break; } - ++chan->if_stats.tx_carrier_errors; - }else{ - wan_clear_bit(0,&dma_chain->init); - wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); - break; + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); + + } else { + if (chan->cfg.hdlc_repeat) { + /* Pull the latest repeat frame out of the + repeat queue */ + for (;;) { + skb=wan_skb_dequeue(&chan->wp_tx_hdlc_rpt_list); + if (!skb) { + break; + } + if (wan_skb_queue_len(&chan->wp_tx_hdlc_rpt_list)){ + wan_skb_free(skb); + } else { + break; + } + } + + if (skb) { + chan->tx_hdlc_rpt_skb=skb; + } else { + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); + /* Pass throught to no skb condition */ + } + } + + if (!skb) { + wan_clear_bit(0,&dma_chain->init); + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + break; + } } } @@ -7825,7 +8558,7 @@ static int aft_dma_tx (sdla_t *card,private_area_t *chan) } wan_skb_free(skb); aft_tx_dma_chain_init(chan,dma_chain); - chan->if_stats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; chan->opstats.Tx_Data_discard_lgth_err_count++; continue; } @@ -7840,23 +8573,25 @@ static int aft_dma_tx (sdla_t *card,private_area_t *chan) } wan_skb_free(skb); aft_tx_dma_chain_init(chan,dma_chain); - chan->if_stats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; chan->opstats.Tx_Data_discard_lgth_err_count++; continue; } dma_chain->skb=skb; - - dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, + + /* A-DMA */ + card->hw_iface.busdma_map( card->hw, + dma_chain, wan_skb_data(dma_chain->skb), wan_skb_len(dma_chain->skb), - PCI_DMA_TODEVICE); + wan_skb_len(dma_chain->skb), + SDLA_DMA_PREWRITE); + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_PREWRITE); - dma_chain->dma_len = wan_skb_len(dma_chain->skb); - dma_chain->dma_map_len=dma_chain->dma_len; - dma_chain->dma_offset=0; - - DEBUG_TEST("%s: DMA Chain %d: Cur=%d Pend=%d\n", chan->if_name,dma_chain->index, chan->tx_chain_indx,chan->tx_pending_chain_indx); @@ -7893,7 +8628,7 @@ static int aft_dma_tx (sdla_t *card,private_area_t *chan) /* Drop the tx packet here */ aft_tx_dma_chain_init(chan,dma_chain); - chan->if_stats.tx_errors++; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; break; } @@ -7924,7 +8659,7 @@ static int aft_dma_tx (sdla_t *card,private_area_t *chan) * **********************************************************************/ -static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, int intr, int fifo) +static int aft_dma_chain_rx(wan_dma_descr_t *dma_chain, private_area_t *chan, int intr, int fifo) { #define dma_descr dma_chain->dma_descr #define reg dma_chain->reg @@ -7945,8 +8680,10 @@ static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, in dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); - DEBUG_DMA("%s: RxDMA_LO(%ld) = 0x%X, DmaDescr=0x%X\n", - __FUNCTION__,chan->logic_ch_num,reg,dma_descr); + DEBUG_DMA("%s: %s:%s: RxDMA_LO(%ld) = 0x%X, PhyAddr:%X DmaDescr=0x%X (%p)\n", + __FUNCTION__,card->devname,chan->if_name, + chan->logic_ch_num,reg, + dma_chain->dma_addr, dma_descr,dma_chain); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -7992,8 +8729,9 @@ static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, in wan_set_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®); } - DEBUG_DMA("%s: RXDMA_HI(%ld) = 0x%X, DmaDescr=0x%X\n", - __FUNCTION__,chan->logic_ch_num,reg,dma_descr); + DEBUG_DMA("%s: %s:%s: RXDMA_HI(%ld) = 0x%X, DmaDescr=0x%X\n", + __FUNCTION__,card->devname,chan->if_name, + chan->logic_ch_num,reg,dma_descr); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -8010,7 +8748,7 @@ static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, in static int aft_dma_voice_rx(sdla_t *card, private_area_t *chan) { int err=0; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; u32 reg, dma_ram_desc; if (wan_test_and_set_bit(RX_DMA_BUSY,&chan->dma_status)){ @@ -8021,6 +8759,9 @@ static int aft_dma_voice_rx(sdla_t *card, private_area_t *chan) dma_chain = &chan->rx_dma_chain_table[0]; + DEBUG_DMA("%s: %s:%s: Chain %d Used %ld\n", + __FUNCTION__,card->devname,chan->if_name, + dma_chain->index,dma_chain->init); /* If the current DMA chain is in use,then * all chains are busy */ @@ -8047,50 +8788,23 @@ static int aft_dma_voice_rx(sdla_t *card, private_area_t *chan) wan_skb_init(dma_chain->skb,16); wan_skb_trim(dma_chain->skb,0); - -#if defined(__LINUX__) - dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, - wan_skb_tail(dma_chain->skb), - chan->dma_mru, - PCI_DMA_FROMDEVICE); - - if (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) { - dma_chain->dma_offset = - AFT_TDMV_BUF_MASK - (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) + 1; - - dma_chain->dma_virt = wan_skb_tail(dma_chain->skb) + dma_chain->dma_offset; - dma_chain->dma_addr += dma_chain->dma_offset; - - } else { - dma_chain->dma_offset=0; - dma_chain->dma_virt = wan_skb_tail(dma_chain->skb); - } - - dma_chain->dma_len = chan->dma_mru-dma_chain->dma_offset; - dma_chain->dma_map_len=dma_chain->dma_len; - - DEBUG_TEST("%s: RXDMA PHY = 0x%08X VIRT = %p \n", + + /* A-DMA */ + card->hw_iface.busdma_map( + card->hw, + dma_chain, + wan_skb_tail(dma_chain->skb), + chan->dma_mru, + chan->dma_mru, + SDLA_DMA_PREREAD); + card->hw_iface.busdma_sync( + card->hw, + dma_chain, + MAX_AFT_DMA_CHAINS, chan->single_dma_chain, + SDLA_DMA_PREREAD); + DEBUG_DMA("%s: RXDMA PHY = 0x%08X VIRT = %p \n", chan->if_name, dma_chain->dma_addr,wan_skb_tail(dma_chain->skb)+dma_chain->dma_offset); -#else - dma_chain->dma_addr = - virt_to_phys(wan_skb_tail(dma_chain->skb)); - - if (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) { - dma_chain->dma_offset = - AFT_TDMV_BUF_MASK - - (dma_chain->dma_addr & AFT_TDMV_BUF_MASK) + 1; - dma_chain->dma_virt = wan_skb_tail(dma_chain->skb) + dma_chain->dma_offset; - dma_chain->dma_addr = virt_to_phys(wan_skb_tail(dma_chain->dma_virt)); - } else { - dma_chain->dma_offset=0; - dma_chain->dma_virt = wan_skb_tail(dma_chain->skb); - } - - dma_chain->dma_len = chan->dma_mru; - dma_chain->dma_map_len=dma_chain->dma_len; - -#endif }else{ wan_skb_init(dma_chain->skb,16); wan_skb_trim(dma_chain->skb,0); @@ -8107,7 +8821,7 @@ static int aft_dma_voice_rx(sdla_t *card, private_area_t *chan) DEBUG_EVENT("%s: Rx dma chain %d overrun error: should never happen!\n", chan->if_name,dma_chain->index); aft_rx_dma_chain_init(chan,dma_chain); - chan->if_stats.rx_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; } aft_dma_single_chain_rx_exit: @@ -8120,11 +8834,10 @@ aft_dma_single_chain_rx_exit: static int aft_dma_rx(sdla_t *card, private_area_t *chan) { int err=0, intr=0; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; int cur_dma_ptr, i,max_dma_cnt,free_queue_len; u32 reg, dma_ram_desc; - if (chan->channelized_cfg && !chan->hdlc_eng){ return aft_dma_voice_rx(card,chan); } @@ -8161,9 +8874,8 @@ static int aft_dma_rx(sdla_t *card, private_area_t *chan) max_dma_cnt = free_queue_len; } - - DEBUG_TEST("%s: DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", - card->devname,cur_dma_ptr,chan->rx_chain_indx,max_dma_cnt); + DEBUG_RX("%s: (line: %d) DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", + card->devname, __LINE__, cur_dma_ptr,chan->rx_chain_indx,max_dma_cnt); for (i=0;iskb=wan_skb_dequeue(&chan->wp_rx_complete_list); if (dma_chain->skb) { - chan->if_stats.rx_dropped++; + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //chan->if_stats.rx_dropped++; wan_skb_init(dma_chain->skb,16); wan_skb_trim(dma_chain->skb,0); }else{ @@ -8203,16 +8915,19 @@ static int aft_dma_rx(sdla_t *card, private_area_t *chan) } } - - dma_chain->dma_addr = card->hw_iface.pci_map_dma(card->hw, - wan_skb_tail(dma_chain->skb), - chan->dma_mru, - PCI_DMA_FROMDEVICE); - - dma_chain->dma_len = chan->dma_mru; - dma_chain->dma_map_len=dma_chain->dma_len; - dma_chain->dma_offset=0; + card->hw_iface.busdma_map( + card->hw, + dma_chain, + wan_skb_tail(dma_chain->skb), + chan->dma_mru, + chan->dma_mru, + SDLA_DMA_PREREAD); + card->hw_iface.busdma_sync( + card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_PREREAD); intr=0; if (!wan_test_bit(RX_INTR_PENDING,&chan->dma_chain_status)){ @@ -8246,7 +8961,7 @@ static int aft_dma_rx(sdla_t *card, private_area_t *chan) DEBUG_EVENT("%s: Rx dma chain %d overrun error: should never happen!\n", chan->if_name,dma_chain->index); aft_rx_dma_chain_init(chan,dma_chain); - chan->if_stats.rx_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; break; } @@ -8289,7 +9004,7 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) sdla_t *card = chan->card; u32 reg,dma_descr; wp_rx_element_t *rx_el; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; int i,max_dma_cnt, cur_dma_ptr; int rx_data_available=0; u32 dma_ram_desc; @@ -8307,8 +9022,8 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) max_dma_cnt = MAX_AFT_DMA_CHAINS; - DEBUG_TEST("%s: DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", - card->devname, + DEBUG_RX("%s: (line: %d) DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", + card->devname, __LINE__, cur_dma_ptr, chan->rx_chain_indx,max_dma_cnt); @@ -8318,7 +9033,7 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) for (i=0;irx_dma_chain_table[chan->rx_pending_chain_indx]; if (i>0 && chan->rx_pending_chain_indx == cur_dma_ptr){ @@ -8349,19 +9064,18 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) * is in process of being transmitted, thus * all are busy */ if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,®)){ - if (wan_test_bit(WP_FIFO_ERROR_BIT, &chan->pkt_error)){ break; } #if 0 if (chan->single_dma_chain){ - DEBUG_EVENT("%s: CRITICAL (%s) Pending chain %d Go bit still set!\n", - chan->if_name,__FUNCTION__,dma_chain->index); - ++chan->if_stats.rx_errors; + DEBUG_EVENT("%s: CRITICAL (%s) Pending chain %d Go bit still set!\n", + chan->if_name,__FUNCTION__,dma_chain->index); + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; }else{ - DEBUG_TEST("%s: Warning (%s) Pending chain %d Go bit still set!\n", - chan->if_name,__FUNCTION__,dma_chain->index); + DEBUG_TEST("%s: Warning (%s) Pending chain %d Go bit still set!\n", + chan->if_name,__FUNCTION__,dma_chain->index); } #endif break; @@ -8371,11 +9085,6 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) wan_clear_bit(RX_INTR_PENDING,&chan->dma_chain_status); } - card->hw_iface.pci_unmap_dma(card->hw, - dma_chain->dma_addr-dma_chain->dma_offset, - dma_chain->dma_map_len, - PCI_DMA_FROMDEVICE); - if (sizeof(wp_rx_element_t) > wan_skb_headroom(dma_chain->skb)){ if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s: Rx error: rx_el=%u > max head room=%u\n", @@ -8385,7 +9094,7 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) } aft_init_requeue_free_skb(chan, dma_chain->skb); - ++chan->if_stats.rx_errors; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; goto rx_hndlr_skip_rx; }else{ rx_el=(wp_rx_element_t *)wan_skb_push(dma_chain->skb, @@ -8393,7 +9102,7 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) memset(rx_el,0,sizeof(wp_rx_element_t)); } #if 0 - chan->if_stats.rx_frame_errors++; + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; #endif /* Reading Rx DMA descriptor information */ @@ -8408,32 +9117,45 @@ static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->reg); + /* New for FreeBSD/Solaris */ + rx_el->len=rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK; + if (chan->hdlc_eng){ + /* In HDLC mode, calculate rx length based + * on alignment value, received from DMA */ + rx_el->len=((((chan->dma_mru>>2)-1)-rx_el->len)<<2) - (~(rx_el->align)&AFT_RXDMA_LO_ALIGN_MASK); + }else{ + /* In Transparent mode, our RX buffer will always be + * aligned to the 32bit (word) boundary, because + * the RX buffers are all of equal length */ + rx_el->len=(((chan->mru>>2)-rx_el->len)<<2) - (~(0x03)&AFT_RXDMA_LO_ALIGN_MASK); + } + rx_el->pkt_error= dma_chain->pkt_error; rx_el->dma_addr = dma_chain->dma_addr; - /* Check for crc/abort here to prevent crc/abort storm */ - if (aft_decode_dma_status(card,chan,rx_el->reg)) { - aft_init_requeue_free_skb(chan, dma_chain->skb); - ++chan->if_stats.rx_errors; - card->u.aft.rx_errors_hist++; - goto rx_hndlr_skip_rx; - } + /* A-DMA */ + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_POSTREAD); + dma_chain->dma_len = rx_el->len; /* update real dma len*/ + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTREAD); +#if defined(__FreeBSD__) + wan_skb_put(dma_chain->skb, rx_el->len); +#endif wan_skb_queue_tail(&chan->wp_rx_complete_list,dma_chain->skb); rx_data_available=1; - DEBUG_TEST("%s: RxInt Pending chain %d Rxlist=%d LO:0x%X HI:0x%X Data=0x%X Len=%d!\n", + DEBUG_TEST("%s: RxInt Pending chain %d Rxlist=%d LO:0x%X HI:0x%X Len=%i!\n", chan->if_name,dma_chain->index, wan_skb_queue_len(&chan->wp_rx_complete_list), - rx_el->align,rx_el->reg, - (*(unsigned char*)wan_skb_data(dma_chain->skb)), - wan_skb_len(dma_chain->skb)); + rx_el->align,rx_el->reg, rx_el->len); rx_hndlr_skip_rx: dma_chain->skb=NULL; - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - dma_chain->dma_map_len=dma_chain->dma_len; dma_chain->pkt_error=0; wan_clear_bit(0,&dma_chain->init); @@ -8452,7 +9174,6 @@ rx_hndlr_skip_rx: aft_dma_rx(card,chan); - if (wan_skb_queue_len(&chan->wp_rx_complete_list)){ DEBUG_TEST("%s: Rx Queued list triggering\n",chan->if_name); WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); @@ -8503,6 +9224,10 @@ static void aft_init_tx_rx_dma_descr(private_area_t *chan) dma_cnt=1; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + return; + } + for (i=0;ilogic_ch_num<<4) + @@ -8528,7 +9253,7 @@ static void aft_free_rx_complete_list(private_area_t *chan) while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ DEBUG_TEST("%s: aft_free_rx_complete_list dropped\n", chan->if_name); - chan->if_stats.rx_dropped++; + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //chan->if_stats.rx_dropped++; aft_init_requeue_free_skb(chan, skb); } } @@ -8538,7 +9263,7 @@ static void aft_rx_cur_go_test(private_area_t *chan) #if 0 u32 reg,cur_dma_ptr; sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; u32 dma_descr; int i; u32 dma_ram_desc; @@ -8570,7 +9295,7 @@ static void aft_list_descriptors(private_area_t *chan) { u32 reg,cur_dma_ptr,lo_reg; sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; u32 dma_descr; int i; u32 dma_ram_desc; @@ -8624,7 +9349,7 @@ static void aft_list_tx_descriptors(private_area_t *chan) { u32 reg,cur_dma_ptr,lo_reg; sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; u32 dma_descr; int i; u32 dma_ram_desc; @@ -8718,7 +9443,7 @@ static void aft_free_rx_descriptors(private_area_t *chan) { u32 reg; sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; u32 dma_descr; int i; unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; @@ -8726,6 +9451,10 @@ static void aft_free_rx_descriptors(private_area_t *chan) if (chan->single_dma_chain){ dma_cnt=1; } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + return; + } for (i=0;ihw_iface.bus_write_4(card->hw,dma_descr,reg); - card->hw_iface.pci_unmap_dma(card->hw, - dma_chain->dma_addr-dma_chain->dma_offset, - dma_chain->dma_map_len, - PCI_DMA_FROMDEVICE); + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_POSTREAD); + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTREAD); if (dma_chain->skb){ aft_init_requeue_free_skb(chan, dma_chain->skb); } dma_chain->skb=NULL; - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - dma_chain->dma_map_len=dma_chain->dma_len; dma_chain->pkt_error=0; wan_clear_bit(0,&dma_chain->init); } @@ -8806,7 +9535,7 @@ static void aft_free_tx_descriptors(private_area_t *chan) { u32 reg,dma_descr; sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; + wan_dma_descr_t *dma_chain; int i; void *skb; unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; @@ -8815,6 +9544,10 @@ static void aft_free_tx_descriptors(private_area_t *chan) dma_cnt=1; } + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + return; + } + DEBUG_TEST("%s:%s: Tx: Freeing Descripors\n",card->devname,chan->if_name); for (i=0;idevname,card->u.aft.top_logic_ch); - + reg=0; card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); - aft_dmactrl_set_max_logic_ch(®,card->u.aft.top_logic_ch); - card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + max_logic_ch = aft_dmactrl_get_max_logic_ch(reg); + + DEBUG_TEST("%s: Maximum Logic Ch (current %i) set to %d \n", + card->devname, + max_logic_ch, + card->u.aft.top_logic_ch); + + if (card->u.aft.top_logic_ch > max_logic_ch) { + aft_dmactrl_set_max_logic_ch(®,card->u.aft.top_logic_ch); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + } } static int aft_tslot_sync_ctrl(sdla_t *card, private_area_t *chan, int mode) @@ -9062,8 +9803,12 @@ static void aft_port_task (struct work_struct *work) static void aft_port_task (void * card_ptr, int arg) #endif { -#if defined(__LINUX__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); +# else + sdla_t *card = (sdla_t *)card_ptr; +# endif #else sdla_t *card = (sdla_t *)card_ptr; #endif @@ -9073,7 +9818,7 @@ static void aft_port_task (void * card_ptr, int arg) return; } - DEBUG_TEST("%s: PORT TASK: 0x%X\n", card->devname,card->u.aft.port_task_cmd); + DEBUG_56K("%s: PORT TASK: 0x%X\n", card->devname,card->u.aft.port_task_cmd); #ifdef AFT_IRQ_STAT_DEBUG card->wandev.stats.rx_missed_errors++; @@ -9099,12 +9844,15 @@ static void aft_port_task (void * card_ptr, int arg) aft_fe_intr_ctrl(card, 0); if (card->wandev.fe_iface.polling){ wan_smp_flag_t smp_irq_flags; - int err = 0; - err = card->wandev.fe_iface.polling(&card->fe); - + int delay; + wan_spin_lock_irq(&card->wandev.lock,&smp_irq_flags); + delay = card->wandev.fe_iface.polling(&card->fe); handle_front_end_state(card); wan_spin_unlock_irq(&card->wandev.lock,&smp_irq_flags); + if (delay){ + card->wandev.fe_iface.add_timer(&card->fe, delay); + } } wan_clear_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); aft_fe_intr_ctrl(card, 1); @@ -9144,40 +9892,66 @@ static void aft_port_task (void * card_ptr, int arg) if (wan_test_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd)){ DEBUG_TEST("%s: PORT TASK: FE EC INTR\n", card->devname); - if (card->wandev.ec_dev){ - card->hw_iface.hw_ec_lock(card->hw,&smp_flags); - wanpipe_ec_poll(card->wandev.ec_dev, card); - wan_clear_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); - card->hw_iface.hw_ec_unlock(card->hw,&smp_flags); + int pending = 0; + pending = wanpipe_ec_poll(card->wandev.ec_dev, card); + /* Aug 10, 2007 + ** If EC poll return 1 (pending), re-schedule port_task again + ** (more dtmf events are available) */ + if (pending == 1){ + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + }else{ + wan_clear_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); + } } } #endif - if (wan_test_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd)){ - wan_clear_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); - if (card->fe.fe_status == FE_CONNECTED) { - DEBUG_EVENT("%s: WAN IRQ Restart\n", - card->devname); + wan_clear_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); + + if (IS_BRI_CARD(card)) { + + DEBUG_EVENT("%s: BRI IRQ Restart\n", + card->devname); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); - card->fe.fe_status = FE_DISCONNECTED; - handle_front_end_state(card); - card->fe.fe_status = FE_CONNECTED; - handle_front_end_state(card); + wan_clear_bit(0,&card->u.aft.comm_enabled); + enable_data_error_intr(card); wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); - } - } + + } else if (card->fe.fe_status == FE_CONNECTED) { + + DEBUG_EVENT("%s: TDM IRQ Restart\n", + card->devname); + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + card->fe.fe_status = FE_DISCONNECTED; + handle_front_end_state(card); + + /* BRI has special behaviour, we need to make sure + * that restart will trigger interrupts */ + wan_clear_bit(0,&card->u.aft.comm_enabled); + + card->fe.fe_status = FE_CONNECTED; + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + } + } + #if defined(AFT_RTP_SUPPORT) if (wan_test_bit(AFT_RTP_TAP_Q,&card->u.aft.port_task_cmd)){ netskb_t *skb; wan_clear_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd); while ((skb=wan_skb_dequeue(&card->u.aft.rtp_tap_list))) { - dev_queue_xmit(skb); + dev_queue_xmit(skb); } } #endif + + + return; } void __aft_fe_intr_ctrl(sdla_t *card, int status) @@ -9225,6 +9999,26 @@ static void aft_data_mux_get_cfg(sdla_t *card) } +static int aft_hdlc_repeat_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb, netskb_t **rskb) +{ + unsigned char *buf; + api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)wan_skb_data(skb); + + if (tx_hdr->wp_api_tx_hdr_hdlc_rpt_len == 0 || tx_hdr->wp_api_tx_hdr_hdlc_rpt_len > 8) { + return -1; + } + + *rskb=wan_skb_alloc(128); + if (!rskb) { + return -1; + } + + buf=wan_skb_put(*rskb,tx_hdr->wp_api_tx_hdr_hdlc_rpt_len); + memcpy(buf,tx_hdr->wp_api_tx_hdr_hdlc_rpt_data,tx_hdr->wp_api_tx_hdr_hdlc_rpt_len); + wan_skb_pull(skb,sizeof(api_tx_hdr_t)); + + return 0; +} static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb) { @@ -9259,7 +10053,7 @@ static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb) len+=4; } - if (tx_hdr->u.ss7.type == WANOPT_SS7_FISU){ + if (tx_hdr->hdr_u.ss7.type == WANOPT_SS7_FISU){ if (chan->cfg.ss7_mode == WANOPT_SS7_MODE_4096){ ss7_len=WANOPT_SS7_FISU_4096_SZ; }else{ @@ -9271,7 +10065,7 @@ static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb) wan_set_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl); } - if (tx_hdr->u.ss7.force_tx){ + if (tx_hdr->hdr_u.ss7.force_tx){ wan_set_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl); }else{ wan_clear_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl); @@ -9279,11 +10073,11 @@ static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb) DEBUG_TEST("%s: SS7 DATA = 0x%X 0x%X 0x%X\n", chan->if_name, - tx_hdr->u.ss7.data[0], - tx_hdr->u.ss7.data[1], - tx_hdr->u.ss7.data[2]); + tx_hdr->hdr_u.ss7.data[0], + tx_hdr->hdr_u.ss7.data[1], + tx_hdr->hdr_u.ss7.data[2]); - memcpy(&chan->tx_ss7_realign_buf[len],tx_hdr->u.ss7.data,ss7_len); + memcpy(&chan->tx_ss7_realign_buf[len],tx_hdr->hdr_u.ss7.data,ss7_len); len+=ss7_len; @@ -9451,7 +10245,7 @@ static int aft_tdmv_free(sdla_t *card) static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) { - + if (!chan->channelized_cfg){ return 0; } @@ -9479,7 +10273,7 @@ static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *co aft_hwdev[card->wandev.card_type].aft_fifo_adjust(card,AFT_TDMV_FIFO_LEVEL); - if (chan->common.usedby == TDM_VOICE) { + if (chan->common.usedby == TDM_VOICE) { #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE WAN_TDMV_CALL(check_mtu, (card, conf->active_ch, &chan->mtu), err); if (err){ @@ -9488,7 +10282,7 @@ static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *co } #endif } - + if (chan->common.usedby == TDM_VOICE_API) { switch (chan->mtu) { case 8: @@ -9496,14 +10290,14 @@ static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *co break; case 40: case 80: - if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { /* If Global TDM Feature is not enable then 40 and 80 bytes TDM are not available */ - chan->mtu=16; + chan->mtu=16; } - break; + break; default: - chan->mtu=16; + chan->mtu=16; break; } } @@ -9526,6 +10320,7 @@ static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *co chan->cfg.data_mux=0; } + #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE if (chan->tdmv_zaptel_cfg){ int channel; @@ -9538,12 +10333,20 @@ static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *co conf->active_ch=conf->active_ch>>1; } + if(IS_BRI_CARD(card)){ + if(chan->dchan_time_slot >= 0){ + conf->active_ch = 0x4<<(WAN_FE_LINENO(&card->fe)*2); + /* For the d-chan MUST set ONLY bit 2!! */ + } + } + WAN_TDMV_CALL(reg, (card, &conf->tdmv, conf->active_ch, conf->hwec.enable, chan->common.dev), channel); + if (channel < 0){ DEBUG_EVENT("%s: Error: Failed to register TDMV channel!\n", chan->if_name); @@ -9577,9 +10380,7 @@ static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *co } } #endif - return 0; - } @@ -9609,7 +10410,7 @@ static int aft_tdmv_if_free(sdla_t *card, private_area_t *chan) static int gtmp_cnt=0; static void aft_set_channel(sdla_t *card, int ch) { - aft_dma_chain_t *tx_dma_chain; + wan_dma_descr_t *tx_dma_chain; u8 *buf; private_area_t *chan=(private_area_t*)card->u.aft.dev_to_ch_map[ch]; @@ -9644,7 +10445,7 @@ static int aft_voice_span_rx_tx(sdla_t *card, int rotate) if (rotate) { WAN_TDMV_CALL(buf_rotate, (card,AFT_TDMV_CIRC_BUF,AFT_TDMV_BUF_MASK), err); - } + } if (!card->wandev.ec_enable || card->wandev.ec_enable_map == 0){ WAN_TDMV_CALL(ec_span, (card), err); @@ -9668,18 +10469,22 @@ static int aft_voice_span_rx_tx(sdla_t *card, int rotate) } #endif + static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) { int err; u32 rx_offset=0; u32 tx_offset=0; + + wan_dma_descr_t *tx_dma_chain; + wan_dma_descr_t *rx_dma_chain; + u8 *txbuf, *rxbuf; - aft_dma_chain_t *tx_dma_chain; - aft_dma_chain_t *rx_dma_chain; - tx_dma_chain = &chan->tx_dma_chain_table[0]; - rx_dma_chain = &chan->rx_dma_chain_table[0]; + rx_dma_chain = &chan->rx_dma_chain_table[0]; + + if (!tx_dma_chain || !rx_dma_chain){ DEBUG_EVENT("%s: %s:%d ASSERT ERROR TxDma=%p RxDma=%p\n", @@ -9695,19 +10500,20 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) return -EINVAL; } + rxbuf = (unsigned char*)rx_dma_chain->dma_virt+rx_offset; txbuf = (unsigned char*)tx_dma_chain->dma_virt+tx_offset; - if (wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status)) { + rx_offset= AFT_TDMV_CIRC_BUF * card->u.aft.tdm_rx_dma_toggle; tx_offset= AFT_TDMV_CIRC_BUF * card->u.aft.tdm_tx_dma_toggle; - + rxbuf = (unsigned char*)rx_dma_chain->dma_virt+rx_offset; txbuf = (unsigned char*)tx_dma_chain->dma_virt+tx_offset; } else if (wan_test_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status)) { - + chan->swring.rx_toggle = (chan->swring.rx_toggle + 1) % AFT_DMA_RING_MAX; memcpy(chan->swring.rbuf[chan->swring.rx_toggle].rxdata, rxbuf, @@ -9719,11 +10525,12 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) chan->mtu); chan->swring.tx_toggle = (chan->swring.tx_toggle + 1) % AFT_DMA_RING_MAX; txbuf = chan->swring.rbuf[chan->swring.tx_toggle].txdata; - } + + } + err=0; - #if 0 /*Measure the round trip delay*/ @@ -9748,26 +10555,88 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE if (card->wan_tdmv.sc){ +#if 0 +defined(AFT_TDMV_BH_ENABLE) + wan_dma_descr_t *tx_bh_dma_chain = &chan->tx_dma_chain_table[1]; + wan_dma_descr_t *rx_bh_dma_chain = &chan->rx_dma_chain_table[1]; + + if (!rx_bh_dma_chain->skb){ + rx_bh_dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!rx_bh_dma_chain->skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical TDM BH no free skb\n", + chan->if_name); + goto aft_tdm_bh_skip; + } + } + wan_skb_init(rx_bh_dma_chain->skb,16); + wan_skb_trim(rx_bh_dma_chain->skb,0); + } + + if (!tx_bh_dma_chain->skb){ + tx_bh_dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!tx_bh_dma_chain->skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical TDM BH no free skb\n", + chan->if_name); + goto aft_tdm_bh_skip; + } + } + wan_skb_init(tx_bh_dma_chain->skb,16); + wan_skb_trim(tx_bh_dma_chain->skb,0); + } + + memcpy(wan_skb_data(rx_bh_dma_chain->skb), + wan_skb_data(rx_dma_chain->skb),8); + + memcpy(wan_skb_data(tx_dma_chain->skb), + wan_skb_data(tx_bh_dma_chain->skb),8); + + rx_dma_chain=rx_bh_dma_chain; + tx_dma_chain=tx_bh_dma_chain; +aft_tdm_bh_skip: +#endif + DEBUG_TEST ("%s: Calling Rx Chan=%i TdmvChan=%i\n", card->devname,chan->logic_ch_num, chan->tdmv_chan); - if (card->wandev.rtp_len && card->wandev.rtp_tap) { card->wandev.rtp_tap(card, - IS_E1_CARD(card) ? chan->first_time_slot-1 : - chan->first_time_slot, + IS_T1_CARD(card) ? chan->first_time_slot : + chan->first_time_slot-1, rxbuf, txbuf, chan->mtu); } +#if 1 WAN_TDMV_CALL(rx_chan, (&card->wan_tdmv,chan->tdmv_chan, rxbuf, txbuf), err); - +#else +#warning "NCDEBUG rx_chan disabled irq" +#endif + +#if 0 + if (((u8*)(rx_dma_chain->dma_virt+offset))[0] != 0xFF && + ((u8*)(rx_dma_chain->dma_virt+offset))[0] != 0x7F && + tx_debug_cnt < 100){ + DEBUG_EVENT("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", + card->devname, + ((u8*)(rx_dma_chain->dma_virt+offset))[0], + ((u8*)(rx_dma_chain->dma_virt+offset))[1], + ((u8*)(rx_dma_chain->dma_virt+offset))[2], + ((u8*)(rx_dma_chain->dma_virt+offset))[3], + ((u8*)(rx_dma_chain->dma_virt+offset))[4], + ((u8*)(rx_dma_chain->dma_virt+offset))[5], + ((u8*)(rx_dma_chain->dma_virt+offset))[6], + ((u8*)(rx_dma_chain->dma_virt+offset))[7]); + tx_debug_cnt++; + } +#endif }else{ return 1; } @@ -9779,12 +10648,11 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) if (card->wandev.fe_iface.watchdog){ err = card->wandev.fe_iface.watchdog(&card->fe); } - + wanpipe_tdm_api_rx_tx(&chan->wp_tdm_api_dev, rxbuf, txbuf, chan->mtu); - #endif } @@ -9796,7 +10664,26 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) if (chan->tdmv_zaptel_cfg){ DEBUG_TEST ("%s: Calling Master Rx Tx Chan=%i\n", card->devname,chan->logic_ch_num); +#if 0 +defined(AFT_TDMV_BH_ENABLE) +#warning "AFT A104: TDM Driver compiled in BH mode!" + + if (WAN_TASKLET_RUNNING((&chan->common.bh_task))){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical Error: TDMV BH Overrun!\n", + card->devname); + } + } + + WAN_WP_TASKLET_SCHEDULE_PER_CPU((&chan->common.bh_task), + card->tdmv_conf.span_no); + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + +#else if (wan_test_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status)) { if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { @@ -9807,9 +10694,33 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) } } +#if 1 + card->hw_iface.busdma_sync( + card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS, + chan->single_dma_chain, + SDLA_DMA_POSTREAD); + WAN_TDMV_CALL(rx_tx_span, (card), err); - + card->hw_iface.busdma_sync( + card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS, + chan->single_dma_chain, + SDLA_DMA_PREWRITE); + card->hw_iface.busdma_sync( + card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS, + chan->single_dma_chain, + SDLA_DMA_PREREAD); + +#else +#warning "NCDEBUG: rx_tx_span disabled irq" +#endif + if (!wan_test_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status) && !wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); @@ -9817,7 +10728,7 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); } - + if (card->wan_tdmv.sc){ WAN_TDMV_CALL(is_rbsbits, (&card->wan_tdmv), err); if (err == 1){ @@ -9825,11 +10736,16 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); } } - } else { +#endif + }else{ #else if (!chan->tdmv_zaptel_cfg){ #endif + if (card->wandev.fe_iface.watchdog) { + err = card->wandev.fe_iface.watchdog(&card->fe); + } + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); @@ -9842,15 +10758,17 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) card->devname,chan->logic_ch_num); } - chan->opstats.Data_frames_Rx_count++; - chan->opstats.Data_bytes_Rx_count+=chan->mru; - chan->opstats.Data_frames_Tx_count++; - chan->opstats.Data_bytes_Tx_count+=chan->mtu; - chan->if_stats.rx_packets++; - chan->if_stats.rx_bytes += chan->mru; - chan->if_stats.tx_packets++; - chan->if_stats.tx_bytes += chan->mtu; - + if (card->wandev.state == WAN_CONNECTED) { + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=chan->mru; + chan->opstats.Data_frames_Tx_count++; + chan->opstats.Data_bytes_Tx_count+=chan->mtu; + WAN_NETIF_STATS_INC_RX_PACKETS(&chan->common); //chan->if_stats.rx_packets++; + WAN_NETIF_STATS_INC_RX_BYTES(&chan->common,chan->mru); //chan->if_stats.rx_bytes += chan->mru; + WAN_NETIF_STATS_INC_TX_PACKETS(&chan->common); //chan->if_stats.tx_packets++; + WAN_NETIF_STATS_INC_TX_BYTES(&chan->common,chan->mtu); //chan->if_stats.tx_bytes += chan->mtu; + } + return 0; } @@ -10353,7 +11271,7 @@ static void wp_tdmv_api_chan_rx_tx(sdla_t *card, if (!card->u.aft.tdmv_api_rx){ card->u.aft.tdmv_api_rx=wan_skb_alloc(card->u.aft.tdmv_mtu); if (!card->u.aft.tdmv_api_rx){ - ++chan->if_stats.rx_errors; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; goto wp_tdmv_api_rx_tx_chan_skip_rx; } } @@ -10361,13 +11279,13 @@ static void wp_tdmv_api_chan_rx_tx(sdla_t *card, if (wan_skb_len(card->u.aft.tdmv_api_rx) > (card->u.aft.tdmv_mtu-chan->mru)){ /* CRITICAL ERROR: We cannot fit the all timeslots into this * packet */ - ++chan->if_stats.rx_errors; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; goto wp_tdmv_api_rx_tx_chan_skip_rx; } buf=wan_skb_put(card->u.aft.tdmv_api_rx, chan->mru); memcpy(buf,rxdata,chan->mru); - ++chan->if_stats.rx_dropped; + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //++chan->if_stats.rx_dropped; wp_tdmv_api_rx_tx_chan_skip_rx: @@ -10375,7 +11293,7 @@ wp_tdmv_api_rx_tx_chan_skip_rx: card->u.aft.tdmv_api_tx=wan_skb_dequeue(&card->u.aft.tdmv_api_tx_list); if (!card->u.aft.tdmv_api_tx){ /* No tx packet, send idle frames */ - ++chan->if_stats.tx_carrier_errors; + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); //++chan->if_stats.tx_carrier_errors; memset(txdata,chan->idle_flag,chan->mtu); return; } @@ -10386,14 +11304,14 @@ wp_tdmv_api_rx_tx_chan_skip_rx: * The tx api packet must have info for all * timeslots */ memset(txdata,chan->idle_flag,chan->mtu); - ++chan->if_stats.tx_errors; + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; return; } buf=wan_skb_data(card->u.aft.tdmv_api_tx); memcpy(txdata,buf,chan->mtu); wan_skb_pull(card->u.aft.tdmv_api_tx,chan->mtu); - ++chan->if_stats.tx_dropped; + WAN_NETIF_STATS_INC_TX_DROPPED(&chan->common); //++chan->if_stats.tx_dropped; #endif return; @@ -10434,7 +11352,7 @@ static void wp_tdmv_api_rx_tx (sdla_t *card, private_area_t *chan) } card->u.aft.tdmv_api_rx->protocol = htons(PVC_PROT); - wan_skb_reset_mac_header(card->u.aft.tdmv_api_rx); + card->u.aft.tdmv_api_rx->mac.raw = card->u.aft.tdmv_api_rx->data; card->u.aft.tdmv_api_rx->dev = chan->common.dev; card->u.aft.tdmv_api_rx->pkt_type = WAN_PACKET_DATA; @@ -10610,13 +11528,48 @@ static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb) return -EINVAL; } + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + if(IS_BRI_CARD(card)){ + if(chan->dchan_time_slot >= 0){ +#if 0 + err=aft_bri_dchan_transmit(card, chan, NULL, 0); + if(err){ + /* still busy transmitting */ + return -EBUSY; + } +#endif + /* NOTE: BRI dchan tx has to be done inside IRQ lock. + It allows to synchronize access to SPI on the card. + */ + card->hw_iface.hw_lock(card->hw,&smp_flags); + err=aft_bri_dchan_transmit(card, chan, + wan_skb_data(skb), + wan_skb_len(skb)); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + if (err == 0) { + wan_skb_free(skb); + err = 0; + } else { + err = -EBUSY; + } + } else { + /* On b-channel data is transmitted using AFT DMA. */ + DEBUG_EVENT("%s: Error: BRI TX on non-D-channel!!\n", card->devname); + wan_skb_free(skb); + err = 0; + } + + return err; + } +#endif + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); if (wan_skb_queue_len(&chan->wp_tx_pending_list) > chan->max_tx_bufs){ aft_dma_tx(card,chan); wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); return -EBUSY; - } wan_skb_unlink(skb); @@ -10693,15 +11646,6 @@ static int aft_tdm_ring_rsync(sdla_t *card) return 0; } -static void aft_critical_event (void *arg, int type) -{ - sdla_t *card = (sdla_t*)arg; - DEBUG_EVENT("%s: Error: Card Critically Shutdown: Short Circuit Detected!\n", - card->devname); - aft_critical_shutdown(card); - return; -} - static void aft_critical_shutdown (sdla_t *card) { DEBUG_EVENT("%s: Error: Card Critically Shutdown!\n", @@ -10721,11 +11665,10 @@ static void aft_critical_shutdown (sdla_t *card) aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_OFF); } - static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int ctrl) { int err = 0; - unsigned int channel=0; + int fe_chan = 0; unsigned int tdmv_hwec_option=0; if (conf) { @@ -10735,28 +11678,41 @@ static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *co if (chan->common.usedby == TDM_VOICE_API || chan->common.usedby == TDM_VOICE){ + /* Nov 6, 2007 Calling EC function with FE channel number. */ if (IS_TE1_CARD(card)) { if (IS_T1_CARD(card)){ - channel = chan->first_time_slot; + fe_chan = chan->first_time_slot+1; }else{ - channel = chan->first_time_slot; + fe_chan = chan->first_time_slot; } + } else if (IS_FXOFXS_CARD(card)) { + fe_chan = chan->first_time_slot+1; } else { - channel = chan->first_time_slot; + fe_chan = chan->first_time_slot+1; } #if defined(CONFIG_WANPIPE_HWEC) if (ctrl == 0 && card->wandev.ec_enable){ - card->wandev.ec_enable(card, 0, channel); + card->wandev.ec_enable(card, 0, fe_chan); } else if (tdmv_hwec_option && card->wandev.ec_enable){ - DEBUG_HWEC("%s: HW echo canceller Enabled on channel %d\n", + + if(IS_BRI_CARD(card)){ + DEBUG_HWEC("%s(): original fe_chan: %d\n", __FUNCTION__, fe_chan); + + /* translate channel to be 0 or 1, nothing else!! */ + fe_chan = (fe_chan % 2); + DEBUG_HWEC("%s(): new fe_chan: %d\n", __FUNCTION__, fe_chan); + } + + DEBUG_HWEC("[HWEC] %s: Enable Echo Canceller on fe_chan %d\n", chan->if_name, - channel); - err = card->wandev.ec_enable(card, 1, channel); + fe_chan); + + err = card->wandev.ec_enable(card, 1, fe_chan); if (err) { - DEBUG_EVENT("%s: Failed to enable HWEC on channel %d\n", - chan->if_name,channel); + DEBUG_EVENT("%s: Failed to enable HWEC on fe chan %d\n", + chan->if_name,fe_chan); return err; } } @@ -10764,11 +11720,9 @@ static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *co } return err; - } - #if defined(AFT_RTP_SUPPORT) enum { WAN_TDM_RTP_NO_CHANGE, @@ -10779,8 +11733,8 @@ enum { static void aft_rtp_unconfig(sdla_t *card) { wan_rtp_chan_t *rtp_chan; - netskb_t *skb; int i; + netskb_t *skb; card->wandev.rtp_len=0; @@ -10843,7 +11797,7 @@ static int aft_rtp_config(sdla_t *card) card->wandev.rtp_len = (card->rtp_conf.rtp_sample * 8) + sizeof(wan_rtp_pkt_t); - if ((card->wandev.rtp_dev=wan_dev_get_by_name(card->rtp_conf.rtp_devname)) == NULL){ + if ((card->wandev.rtp_dev=dev_get_by_name(card->rtp_conf.rtp_devname)) == NULL){ DEBUG_EVENT("%s: Failed to open rtp tx device %s\n", card->devname, card->rtp_conf.rtp_devname); @@ -10866,7 +11820,7 @@ static int aft_rtp_config(sdla_t *card) aft_rtp_init_exit: - + aft_rtp_unconfig(card); DEBUG_EVENT("%s: Failed to configure rtp tap!\n",card->devname); @@ -10964,8 +11918,6 @@ static __inline void aft_rtp_tap_chan(sdla_t *card, u8 *data, u32 len, } } - - static void aft_rtp_tap(void *card_ptr, u8 chan, u8* rx, u8* tx, u32 len) { sdla_t *card = (sdla_t *)card_ptr; @@ -11030,7 +11982,6 @@ static void aft_rtp_tap(void *card_ptr, u8 chan, u8* rx, u8* tx, u32 len) } #endif - static int aft_find_master_if_and_dchan(sdla_t *card, int *master_if, u32 active_ch) { int dchan_found=0; @@ -11147,18 +12098,35 @@ static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt) buf = wan_skb_put(skb, wan_udp_pkt->wan_udp_data_len); memcpy(buf, wan_udp_pkt->wan_udp_data, wan_udp_pkt->wan_udp_data_len); - +#if defined(__LINUX__) skb->next = skb->prev = NULL; skb->dev = dev; skb->protocol = htons(ETH_P_IP); - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); dev_queue_xmit(skb); - +#elif defined(__FreeBSD__) || defined(__OpenBSD__) + DEBUG_EVENT("%s: WARNING: Digital loop test mode is not supported!\n", + card->devname); +#endif return 0; } - +void wanpipe_wake_stack(private_area_t* chan) +{ + WAN_NETIF_WAKE_QUEUE(chan->common.dev); + if (chan->common.usedby == API){ + wan_wakeup_api(chan); + }else if (chan->common.usedby == STACK){ + wanpipe_lip_kick(chan,0); + }else if (chan->common.usedby == TDM_VOICE_DCHAN){ +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)){ + wanpipe_tdm_api_kick(&chan->wp_tdm_api_dev); + } +#endif + } +} /****** End ****************************************************************/ diff --git a/patches/kdrivers/src/net/sdla_aft_te1.c~ b/patches/kdrivers/src/net/sdla_aft_te1.c~ new file mode 100644 index 0000000..65057f3 --- /dev/null +++ b/patches/kdrivers/src/net/sdla_aft_te1.c~ @@ -0,0 +1,11637 @@ +/***************************************************************************** +* sdla_aft_te1.c +* +* WANPIPE(tm) AFT TE1 Hardware Support +* +* Authors: Nenad Corbic +* +* Copyright: (c) 2003-2007 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +* Jan 07, 2003 Nenad Corbic Initial version. +* Oct 25, 2004 Nenad Corbic Support for QuadPort TE1 +* March 16, 2007 David Rokhvarg Support for ISDN BRI card. +*****************************************************************************/ + +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include /* Socket Driver common area */ +# include +# include +# include +#else +# include +# include +# include +# include +# include +# include /* Socket Driver common area */ +# include +# include +# include +# include +# include +#endif + +#if defined(CONFIG_WANPIPE_HWEC) +# include +#endif + +#define INIT_FE_ONLY 0 + +#undef DEBUG_REG + +#define BRI_INIT_FUNC() if(0)DEBUG_EVENT("%s(): line:%d\n", __FUNCTION__, __LINE__) +#define DEBUG_BRI_DCHAN if(0)DEBUG_EVENT + +#if 1 +#define AFT_FUNC_DEBUG() +#else +#define AFT_FUNC_DEBUG() DEBUG_EVENT("%s:%d\n",__FUNCTION__,__LINE__) +#endif + + +#if 0 +# define AFT_XTEST_UPDATE 1 +#else +# undef AFT_XTEST_UPDATE +#endif + + +#if 1 +# define AFT_SECURITY_CHECK 1 +#else +# undef AFT_SECURITY_CHECK +# warning "AFT_SECURITY_CHECK disabled" +#endif + +#if 1 +# define AFT_WDT_ENABLE 1 +#else +# warning "DISABLED WDT" +# undef AFT_WDT_ENABLE +#endif + +#if 0 +# define AFT_RX_FIFO_DEBUG 1 +# warning "AFT_RX_FIFO_DEBUG Flag used" +#else +# undef AFT_RX_FIFO_DEBUG +#endif + +#if 0 +# define AFT_TX_FIFO_DEBUG 1 +# warning "AFT_TX_FIFO_DEBUG Flag used" +#else +# undef AFT_TX_FIFO_DEBUG +#endif + +#if 0 +# define AFT_SINGLE_DMA_CHAIN 1 +# warning "AFT_SINGLE_DMA_CHAIN: SET" +#else +# undef AFT_SINGLE_DMA_CHAIN +#endif + +#if 1 +# define AFT_IFT_INTR_ENABLE 1 +#else +# warning "AFT_IFT_INTR_ENABLE NOT ENABLED" +# undef AFT_IFT_INTR_ENABLE +#endif + +#if 0 +# warning "IRQ INTR DEBUGGIN ON" +# define AFT_IRQ_DEBUG 1 +#else +# undef AFT_IRQ_DEBUG +#endif + +#if 0 +# warning "IRQ STAT DEBUGGIN ON" +# define AFT_IRQ_STAT_DEBUG 1 +#else +# undef AFT_IRQ_STAT_DEBUG +#endif + + +#if 0 +# define AFT_TDMV_BH_ENABLE 1 +# error "AFT_TDMV_BH_ENABLE flag used" +#else +# undef AFT_TDMV_BH_ENABLE +#endif + +#if 1 +# define AFT_TDMV_CHANNELIZATION 1 +#else +# undef AFT_TDMV_CHANNELIZATION +#endif + +#if 1 +# define AFT_CLOCK_SYNC 1 +#else +# undef AFT_CLOCK_SYNC +#endif + +#if defined(__LINUX__) +#define AFT_TDM_API_SUPPORT 1 +#else +#undef AFT_TDM_API_SUPPORT +#endif + +#if defined(__LINUX__) +#define AFT_API_SUPPORT 1 +#else +#undef AFT_API_SUPPORT +#endif + +#if defined(__LINUX__) +# define AFT_RTP_SUPPORT 1 +#else +# undef AFT_RTP_SUPPORT +#endif + +#if defined(WANPIPE_64BIT_4G_DMA) +#warning "Wanpipe compiled for 64bit 4G DMA" +#endif + + +/* Trigger on Number of transactions + * 1= 1x8 byte transactions + * 2= 2x8 byte transactions + * 3= 3x8 byte transactions + * 4= 4x8 byte transactions + */ +#define AFT_TDMV_FIFO_LEVEL 1 +#define AFT_TDMV_CIRC_BUF 128 +#define AFT_TDMV_CIRC_BUF_LEN 4 +#define AFT_TDMV_BUF_MASK 0x1FF + +#define AFT_SS7_CTRL_LEN_MASK 0x0F +#define AFT_SS7_CTRL_TYPE_BIT 4 +#define AFT_SS7_CTRL_FORCE_BIT 5 + +#define AFT_MAX_CHIP_SECURITY_CNT 100 + +#define AFT_FE_FIX_FIRM_VER 100 + +aft_hw_dev_t aft_hwdev[MAX_AFT_HW_DEV]; + +enum { + TDM_RUNNING, + TDM_PENDING, +}; + +/****** Defines & Macros ****************************************************/ + +/* Private critical flags */ +enum { + POLL_CRIT = PRIV_CRIT, + CARD_DOWN, + TE_CFG, + CARD_HW_EC +}; + +enum { + LINK_DOWN, + DEVICE_DOWN +}; + +enum { + AFT_CHIP_CONFIGURED, + AFT_FRONT_END_UP, + AFT_TDM_GLOBAL_ISR, + AFT_TDM_RING_BUF, + AFT_TDM_FAST_ISR +}; + +enum { + TX_DMA_BUSY, + TX_HANDLER_BUSY, + TX_INTR_PENDING, + + RX_HANDLER_BUSY, + RX_DMA_BUSY, + RX_INTR_PENDING +}; + +enum { + AFT_FE_CFG_ERR, + AFT_FE_CFG, + AFT_FE_INTR, + AFT_FE_POLL, + AFT_FE_TDM_RBS, + AFT_FE_LED, + AFT_FE_EC_POLL +}; + +#define MAX_IP_ERRORS 10 + +#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) + + +#if 1 +# define TRUE_FIFO_SIZE 1 +#else +# undef TRUE_FIFO_SIZE +# define HARD_FIFO_CODE 0x1F +#endif + + +/* Remove HDLC Address + * 1=Remove Enabled + * 0=Remove Disabled + */ + +#if 0 +#define WANPIPE_CODEC_CONVERTER 1 +#else +#undef WANPIPE_CODEC_CONVERTER +#endif + +static int aft_rx_copyback=500; +/******Data Structures*****************************************************/ + +/* This structure is placed in the private data area of the device structure. + * The card structure used to occupy the private area but now the following + * structure will incorporate the card structure along with Protocol specific data + */ + + +/* Route Status options */ +#define NO_ROUTE 0x00 +#define ADD_ROUTE 0x01 +#define ROUTE_ADDED 0x02 +#define REMOVE_ROUTE 0x03 + +#define WP_WAIT 0 +#define WP_NO_WAIT 1 + +/* variable for keeping track of enabling/disabling FT1 monitor status */ +/* static int rCount; */ + +/* Function interface between WANPIPE layer and kernel */ +extern wan_iface_t wan_iface; + +extern void disable_irq(unsigned int); +extern void enable_irq(unsigned int); + +extern sdla_t* card_list; + +/**SECTOIN************************************************** + * + * Function Prototypes + * + ***********************************************************/ +int wp_aft_te1default_devcfg(sdla_t* card, wandev_conf_t* conf); +int wp_aft_te1default_ifcfg(sdla_t* card, wanif_conf_t* conf); + +/* WAN link driver entry points. These are called by the WAN router module. */ +static int update (wan_device_t* wandev); +static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf); +static int del_if(wan_device_t *wandev, netdevice_t *dev); + +/* Network device interface */ +#if defined(__LINUX__) +static int if_init (netdevice_t* dev); +#endif +static int if_open (netdevice_t* dev); +static int if_close (netdevice_t* dev); +static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); + +#if defined(__LINUX__) +static int if_send (netskb_t* skb, netdevice_t* dev); +static struct net_device_stats* if_stats (netdevice_t* dev); +#else +static int if_send(netdevice_t*, netskb_t*, struct sockaddr*,struct rtentry*); +#endif + +static void handle_front_end_state(void* card_id); +static void enable_timer(void* card_id); +static void enable_ec_timer(void* card_id); +static void if_tx_timeout (netdevice_t *dev); + +/* Miscellaneous Functions */ +static void port_set_state (sdla_t *card, int); + +static void disable_comm (sdla_t *card); + +/* Interrupt handlers */ +static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card); +static void wp_aft_dma_per_port_isr(sdla_t *card); +static void wp_aft_tdmv_per_port_isr(sdla_t *card); +static void wp_aft_fifo_per_port_isr(sdla_t *card); +static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr); + +/* Bottom half handlers */ +#if defined(__LINUX__) +static void wp_bh (unsigned long); +static void wp_tdm_bh (unsigned long); +#else +static void wp_bh (void*,int); +static void wp_tdm_bh (void*,int); +#endif + +/* Miscellaneous functions */ +static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, + private_area_t*, + int local_dev); + +static int aft_global_chip_configuration(sdla_t *card, wandev_conf_t* conf); +static int aft_global_chip_disable(sdla_t *card); + +static int aft_chip_configure(sdla_t *card, wandev_conf_t* conf); +static int aft_chip_unconfigure(sdla_t *card); +static int aft_dev_configure(sdla_t *card, private_area_t *chan, wanif_conf_t* conf); +static void aft_dev_unconfigure(sdla_t *card, private_area_t *chan); + +static int aft_dma_rx(sdla_t *card, private_area_t *chan); +static void aft_dev_enable(sdla_t *card, private_area_t *chan); +static void aft_dev_close(sdla_t *card, private_area_t *chan); +static void aft_dev_open(sdla_t *card, private_area_t *gchan); +static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan,int wdt, int reset); + +static int aft_dma_rx_complete(sdla_t *card, private_area_t *chan, int reset); +static int aft_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char); +static int aft_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char); +static void aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb); +static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, + netskb_t *skb, + netskb_t **new_skb, + unsigned char *pkt_error); +static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan); +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_voice_span_rx_tx(sdla_t *card, int rotate); +#endif + +static void aft_channel_txdma_ctrl(sdla_t *card, private_area_t *chan, int on); +static void aft_channel_rxdma_ctrl(sdla_t *card, private_area_t *chan, int on); +static void aft_channel_txintr_ctrl(sdla_t *card, private_area_t *chan, int on); +static void aft_channel_rxintr_ctrl(sdla_t *card, private_area_t *chan, int on); + +static int aft_read_security(sdla_t *card); +static int aft_front_end_mismatch_check(sdla_t * card); +static int aft_tslot_sync_ctrl(sdla_t *card, private_area_t *chan, int mode); + +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +static void aft_port_task (void * card_ptr); +# else +static void aft_port_task (struct work_struct *work); +# endif +#else +static void aft_port_task (void * card_ptr, int arg); +#endif + +#if defined(AFT_RTP_SUPPORT) +static int aft_rtp_config(sdla_t *card); +static void aft_rtp_unconfig(sdla_t *card); +static void aft_rtp_tap(void *card_ptr, u8 chan, u8* rx, u8* tx, u32 len); +#endif + +static int aft_devel_ioctl(sdla_t *card,struct ifreq *ifr); +static int aft_write_bios(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_read(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_fe_write(sdla_t *card, wan_cmd_api_t *api_cmd); +static int aft_fe_read(sdla_t *card, wan_cmd_api_t *api_cmd); + +static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock); +static void enable_data_error_intr(sdla_t *card); +static void disable_data_error_intr(sdla_t *card, unsigned char); + +static void aft_tx_fifo_under_recover (sdla_t *card, private_area_t *chan); +static void aft_rx_fifo_over_recover(sdla_t *card, private_area_t *chan); + +static int set_chan_state(sdla_t* card, netdevice_t* dev, int state); + +static int update_comms_stats(sdla_t* card); + +static int protocol_init (sdla_t*card,netdevice_t *dev, + private_area_t *chan, wanif_conf_t* conf); +static int protocol_stop (sdla_t *card, netdevice_t *dev); +static int protocol_shutdown (sdla_t *card, netdevice_t *dev); +static void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb); + +static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, int irq); +static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb); + + +static int aft_dma_tx (sdla_t *card,private_area_t *chan); +static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset); +static void aft_tx_dma_voice_handler(unsigned long data, int wdt, int reset); +static void aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *); +static void aft_rx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *); +static void aft_index_tx_rx_dma_chains(private_area_t *chan); +static void aft_init_tx_rx_dma_descr(private_area_t *chan); +static void aft_free_rx_complete_list(private_area_t *chan); +static void aft_rx_cur_go_test(private_area_t *chan); +static void aft_free_rx_descriptors(private_area_t *chan); +static void aft_reset_rx_chain_cnt(private_area_t *chan); +static void aft_reset_tx_chain_cnt(private_area_t *chan); +static void aft_free_tx_descriptors(private_area_t *chan); + + +static int aft_realign_skb_pkt(private_area_t *chan, netskb_t *skb); + +static void aft_data_mux_cfg(sdla_t *card); +static void aft_data_mux_get_cfg(sdla_t *card); + +static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb); +static int aft_hdlc_repeat_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb, netskb_t **rkb); + +static int aft_tdmv_init(sdla_t *card, wandev_conf_t *conf); +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_tdmv_free(sdla_t *card); +#endif +static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf); +static int aft_tdmv_if_free(sdla_t *card, private_area_t *chan); + +static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt); + +#if 0 +static void wp_tdmv_api_chan_rx_tx(sdla_t *card, + private_area_t *chan, + unsigned char *rxdata, unsigned char *tx_data); +static void wp_tdmv_api_rx_tx (sdla_t *card, private_area_t *chan); +#endif + +static int aft_fifo_intr_ctrl(sdla_t *card, int ctrl); +static int aft_tdm_intr_ctrl(sdla_t *card, int ctrl); + +#if defined(__LINUX__) +static void aft_set_ss7_force_rx(sdla_t *card, private_area_t *chan); +#endif +static void aft_clear_ss7_force_rx(sdla_t *card, private_area_t *chan); + +#if defined(AFT_API_SUPPORT) || defined(AFT_TDM_API_SUPPORT) +static int aft_event_ctrl(void *chan_ptr, wan_event_ctrl_t *ctrl); +#endif + +#ifdef AFT_TDM_API_SUPPORT +static int aft_read_rbs_bits(void *chan_ptr, u32 ch, u8 *rbs_bits); +static int aft_write_rbs_bits(void *chan_ptr, u32 ch, u8 rbs_bits); +static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb); +#endif +static int aft_tdm_ring_rsync(sdla_t *card); +static void aft_critical_shutdown(sdla_t *card); +void wanpipe_wake_stack(private_area_t* chan); + +/* API VoIP event */ +#if defined(AFT_API_SUPPORT) +static int wan_aft_api_ioctl(sdla_t *card, private_area_t *chan, char *user_data); +static void wan_aft_api_dtmf (void* card_id, wan_event_t *event); +static void wan_aft_api_hook (void* card_id, wan_event_t *event); +static void wan_aft_api_ringtrip (void* card_id, wan_event_t *event); +static void wan_aft_api_ringdetect (void* card_id, wan_event_t *event); +#endif + +#if 0 +static void aft_list_descriptors(private_area_t *chan); +#endif +#if 0 +static void aft_list_dma_chain_regs(sdla_t *card); +#endif + +#if 0 +static void aft_list_tx_descriptors(private_area_t *chan); +#endif +#if 0 +static void aft_display_chain_history(private_area_t *chan); +static void aft_chain_history(private_area_t *chan,u8 end, u8 cur, u8 begin, u8 loc); +#endif + + +/* TE1 Control registers */ +#if 0 +static WRITE_FRONT_END_REG_T write_front_end_reg; +static READ_FRONT_END_REG_T read_front_end_reg; +#endif + +unsigned char aft_read_cpld(sdla_t *card, unsigned short cpld_off); +int aft_write_cpld(void *pcard, unsigned short off,unsigned char data); + +/* Procfs functions */ +static int wan_aft_get_info(void* pcard, struct seq_file* m, int* stop_cnt); + +static int wan_aft_init (sdla_t *card, wandev_conf_t* conf); + + +static unsigned char aft_write_ec (void*, unsigned short, unsigned char); +static unsigned char aft_read_ec (void*, unsigned short); + +static int aft_hwec_config(sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int ctrl); +static int aft_find_master_if_and_dchan(sdla_t *card, int *master_if,u32 active_ch); + +#if defined(NETGRAPH) +extern void wan_ng_link_state(wanpipe_common_t *common, int state); +#endif + +/**SECTION********************************************************* + * + * Public Functions + * + ******************************************************************/ + +int wp_aft_te1default_devcfg(sdla_t* card, wandev_conf_t* conf) +{ + conf->config_id = WANCONFIG_AFT_TE1; + conf->u.aft.dma_per_ch = MAX_RX_BUF; + conf->u.aft.mru = 1500; + return 0; +} + +int wp_aft_te1default_ifcfg(sdla_t* card, wanif_conf_t* conf) +{ + conf->protocol = WANCONFIG_HDLC; + memcpy(conf->usedby, "WANPIPE", 7); + conf->if_down = 0; + conf->ignore_dcd = WANOPT_NO; + conf->ignore_cts = WANOPT_NO; + conf->hdlc_streaming = WANOPT_NO; + conf->mc = 0; + conf->gateway = 0; + conf->active_ch = ENABLE_ALL_CHANNELS; + + return 0; +} + +#if 0 +static void aft_delay(int sec) +{ +#if 1 + unsigned long timeout=SYSTEM_TICKS; + while ((SYSTEM_TICKS-timeout)<(sec*HZ)){ + schedule(); + } +#endif +} +#endif + + +int aft_global_hw_device_init(void) +{ + memset(aft_hwdev,0,sizeof(aft_hwdev)); + + aft_hwdev[WANOPT_AFT104].init = 1; + aft_hwdev[WANOPT_AFT104].aft_global_chip_config = a104_global_chip_config; + aft_hwdev[WANOPT_AFT104].aft_global_chip_unconfig = a104_global_chip_unconfig; + aft_hwdev[WANOPT_AFT104].aft_chip_config = a104_chip_config; + aft_hwdev[WANOPT_AFT104].aft_chip_unconfig = a104_chip_unconfig; + aft_hwdev[WANOPT_AFT104].aft_chan_config = a104_chan_dev_config; + aft_hwdev[WANOPT_AFT104].aft_chan_unconfig = a104_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT104].aft_led_ctrl = a104_led_ctrl; + aft_hwdev[WANOPT_AFT104].aft_test_sync = a104_test_sync; + aft_hwdev[WANOPT_AFT104].aft_read_cpld = aft_te1_read_cpld; + aft_hwdev[WANOPT_AFT104].aft_write_cpld = aft_te1_write_cpld; + aft_hwdev[WANOPT_AFT104].aft_fifo_adjust = a104_fifo_adjust; + aft_hwdev[WANOPT_AFT104].aft_check_ec_security = a104_check_ec_security; + + aft_hwdev[WANOPT_AFT_ANALOG].init = 1; + aft_hwdev[WANOPT_AFT_ANALOG].aft_global_chip_config = aft_analog_global_chip_config; + aft_hwdev[WANOPT_AFT_ANALOG].aft_global_chip_unconfig = aft_analog_global_chip_unconfig; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chip_config = aft_analog_chip_config; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chip_unconfig = aft_analog_chip_unconfig; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chan_config = aft_analog_chan_dev_config; + aft_hwdev[WANOPT_AFT_ANALOG].aft_chan_unconfig = aft_analog_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT_ANALOG].aft_led_ctrl = aft_analog_led_ctrl; + aft_hwdev[WANOPT_AFT_ANALOG].aft_test_sync = aft_analog_test_sync; + aft_hwdev[WANOPT_AFT_ANALOG].aft_read_cpld = aft_analog_read_cpld; + aft_hwdev[WANOPT_AFT_ANALOG].aft_write_cpld = aft_analog_write_cpld; + aft_hwdev[WANOPT_AFT_ANALOG].aft_fifo_adjust = aft_analog_fifo_adjust; + aft_hwdev[WANOPT_AFT_ANALOG].aft_check_ec_security = a200_check_ec_security; + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + aft_hwdev[WANOPT_AFT_ISDN].init = 1; + aft_hwdev[WANOPT_AFT_ISDN].aft_global_chip_config = aft_bri_global_chip_config; + aft_hwdev[WANOPT_AFT_ISDN].aft_global_chip_unconfig = aft_bri_global_chip_unconfig; + aft_hwdev[WANOPT_AFT_ISDN].aft_chip_config = aft_bri_chip_config; + aft_hwdev[WANOPT_AFT_ISDN].aft_chip_unconfig = aft_bri_chip_unconfig; + aft_hwdev[WANOPT_AFT_ISDN].aft_chan_config = aft_bri_chan_dev_config; + aft_hwdev[WANOPT_AFT_ISDN].aft_chan_unconfig = aft_bri_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT_ISDN].aft_led_ctrl = aft_bri_led_ctrl; + aft_hwdev[WANOPT_AFT_ISDN].aft_test_sync = aft_bri_test_sync; + aft_hwdev[WANOPT_AFT_ISDN].aft_read_cpld = aft_bri_read_cpld; + aft_hwdev[WANOPT_AFT_ISDN].aft_write_cpld = aft_bri_write_cpld; + aft_hwdev[WANOPT_AFT_ISDN].aft_fifo_adjust = aft_bri_fifo_adjust; + aft_hwdev[WANOPT_AFT_ISDN].aft_check_ec_security = bri_check_ec_security; +#endif + + aft_hwdev[WANOPT_AFT_56K].init = 1; + aft_hwdev[WANOPT_AFT_56K].aft_global_chip_config = a104_global_chip_config; + aft_hwdev[WANOPT_AFT_56K].aft_global_chip_unconfig = a104_global_chip_unconfig; + aft_hwdev[WANOPT_AFT_56K].aft_chip_config = a104_chip_config; + aft_hwdev[WANOPT_AFT_56K].aft_chip_unconfig = a104_chip_unconfig; + aft_hwdev[WANOPT_AFT_56K].aft_chan_config = a104_chan_dev_config; + aft_hwdev[WANOPT_AFT_56K].aft_chan_unconfig = a104_chan_dev_unconfig; + aft_hwdev[WANOPT_AFT_56K].aft_led_ctrl = a104_led_ctrl; + aft_hwdev[WANOPT_AFT_56K].aft_test_sync = a104_test_sync; + aft_hwdev[WANOPT_AFT_56K].aft_read_cpld = aft_56k_read_cpld; + aft_hwdev[WANOPT_AFT_56K].aft_write_cpld = aft_56k_write_cpld; + aft_hwdev[WANOPT_AFT_56K].aft_fifo_adjust = a104_fifo_adjust; + aft_hwdev[WANOPT_AFT_56K].aft_check_ec_security = a104_check_ec_security; + + return 0; +} + + +/*============================================================================ + * wp_aft_te1_init - Cisco HDLC protocol initialization routine. + * + * @card: Wanpipe card pointer + * @conf: User hardware/firmware/general protocol configuration + * pointer. + * + * This routine is called by the main WANPIPE module + * during setup: ROUTER_SETUP ioctl(). + * + * At this point adapter is completely initialized + * and firmware is running. + * o read firmware version (to make sure it's alive) + * o configure adapter + * o initialize protocol-specific fields of the adapter data space. + * + * Return: 0 o.k. + * < 0 failure. + */ + +int wp_aft_analog_init (sdla_t *card, wandev_conf_t* conf) +{ + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_ANALOG) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + ASSERT_AFT_HWDEV(card->wandev.card_type); + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + if (card->u.aft.firm_ver < AFT_MIN_ANALOG_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT ANALOG firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_MIN_ANALOG_FRMW_VER); + DEBUG_EVENT( "%s Refer to /usr/share/doc/wanpipe/README.aft_firm_update\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + + /* Make special hardware initialization for Analog board */ + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + wp_remora_iface_init(&card->fe, &card->wandev.fe_iface); + card->fe.name = card->devname; + card->fe.card = card; + card->fe.write_fe_reg = aft_analog_write_fe; + card->fe.read_fe_reg = aft_analog_read_fe; + card->fe.__read_fe_reg = __aft_analog_read_fe; + + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + + if (card->wandev.comm_port == WANOPT_PRI){ + conf->clocking = WANOPT_EXTERNAL; + } + + card->wandev.comm_port=card->fe.fe_cfg.line_no; + if (card->wandev.comm_port != 0){ + DEBUG_EVENT("%s: Error: Invalid port selected %d (Port 1)\n", + card->devname,card->wandev.comm_port); + return -EINVAL; + } + + card->u.aft.num_of_time_slots=MAX_REMORA_MODULES; + + return wan_aft_init(card,conf); + +} + +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + +int wp_aft_bri_init (sdla_t *card, wandev_conf_t* conf) +{ + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_ISDN_BRI) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + ASSERT_AFT_HWDEV(card->wandev.card_type); + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + + /* FIXME:hardcoded!! */ + card->u.aft.firm_id = AFT_DS_FE_CORE_ID; + +#if 0 + FIXME: check firmware version + if (card->u.aft.firm_ver < AFT_MIN_ANALOG_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT BRI firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_MIN_ANALOG_FRMW_VER); + DEBUG_EVENT( "%s Refer to /usr/share/doc/wanpipe/README.aft_firm_update\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } +#endif + + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + + /* Make special hardware initialization for Analog board */ + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + wp_bri_iface_init(&card->wandev.fe_iface); + card->fe.name = card->devname; + card->fe.card = card; + card->fe.write_fe_reg = aft_bri_write_fe; + card->fe.read_fe_reg = aft_bri_read_fe; + card->fe.__read_fe_reg = __aft_bri_read_fe; + + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + + if (card->wandev.comm_port == WANOPT_PRI){ + conf->clocking = WANOPT_EXTERNAL; + } + + card->wandev.comm_port=card->fe.fe_cfg.line_no; + + /* Set 'num_of_time_slots' to 31. This is needed for the d-chan, + which is always at the otherwise unused timeslot 31. + */ + card->u.aft.num_of_time_slots = MAX_TIMESLOTS; + + return wan_aft_init(card,conf); +} +#endif + +int wp_aft_te1_init (sdla_t* card, wandev_conf_t* conf) +{ + + AFT_FUNC_DEBUG(); + + wan_set_bit(CARD_DOWN,&card->wandev.critical); + + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_TE1) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); + + if (card->u.aft.firm_ver < AFT_MIN_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_MIN_FRMW_VER); + DEBUG_EVENT( "%s Refer to /usr/share/doc/wanpipe/README.aft_firm_update\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } + + ASSERT_AFT_HWDEV(card->wandev.card_type); + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + +#if defined(WAN_DEBUG_MEM) + DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); +#endif + + /* TE1 Make special hardware initialization for T1/E1 board */ + if (IS_TE1_MEDIA(&conf->fe_cfg)){ + int max_ports = 4; + + if (conf->fe_cfg.cfg.te_cfg.active_ch == 0){ + conf->fe_cfg.cfg.te_cfg.active_ch = -1; + } + + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { + max_ports = 8; + sdla_ds_te1_iface_init(&card->fe, &card->wandev.fe_iface); + }else{ + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); + } + card->fe.name = card->devname; + card->fe.card = card; + card->fe.write_fe_reg = a104_write_fe; + card->fe.read_fe_reg = a104_read_fe; + card->fe.__read_fe_reg = __a104_read_fe; + + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + conf->electrical_interface = + IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; + + if (card->wandev.comm_port == WANOPT_PRI){ + conf->clocking = WANOPT_EXTERNAL; + } + + card->wandev.comm_port=card->fe.fe_cfg.line_no; +#if 0 +/* ALEX: This will check during t1/e1 configuration */ + if (card->wandev.comm_port < 0 || card->wandev.comm_port > max_ports-1){ + DEBUG_EVENT("%s: Error: Invalid port selected %d (Min=1 Max=%d)\n", + card->devname,card->wandev.comm_port, max_ports); + return -EINVAL; + } +#endif + + if (IS_T1_CARD(card)){ + card->u.aft.num_of_time_slots=NUM_OF_T1_CHANNELS; + }else{ + card->u.aft.num_of_time_slots=NUM_OF_E1_CHANNELS; + } + + }else{ + DEBUG_EVENT("%s: Invalid Front-End media type!!\n", + card->devname); + return -EINVAL; + } + + return wan_aft_init(card,conf); + +} + +int wp_aft_56k_init (sdla_t* card, wandev_conf_t* conf) +{ + + AFT_FUNC_DEBUG(); + + wan_set_bit(CARD_DOWN,&card->wandev.critical); + + /* Verify configuration ID */ + if (card->wandev.config_id != WANCONFIG_AFT_56K) { + DEBUG_EVENT( "%s: invalid configuration ID %u!\n", + card->devname, card->wandev.config_id); + return -EINVAL; + } + + + card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver); + card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id); +#if 0 + if (card->u.aft.firm_ver < AFT_56K_MIN_FRMW_VER){ + DEBUG_EVENT( "%s: Invalid/Obselete AFT firmware version %X (not >= %X)!\n", + card->devname, card->u.aft.firm_ver,AFT_56K_MIN_FRMW_VER); + DEBUG_EVENT( "%s Refer to /usr/share/doc/wanpipe/README.aft_firm_update\n", + card->devname); + DEBUG_EVENT( "%s: Please contact Sangoma Technologies for more info.\n", + card->devname); + return -EINVAL; + } +#endif + ASSERT_AFT_HWDEV(card->wandev.card_type); + + if (conf == NULL){ + DEBUG_EVENT("%s: Bad configuration structre!\n", + card->devname); + return -EINVAL; + } + +#if defined(WAN_DEBUG_MEM) + DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); +#endif + + if (IS_56K_MEDIA(&conf->fe_cfg)){ + + conf->fe_cfg.cfg.te_cfg.active_ch = 1; + + memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); + + DEBUG_56K("card->u.aft.firm_id: 0x%X\n", card->u.aft.firm_id); +/* + if(card->u.aft.firm_id != AFT_56K_FE_CORE_ID){ + DEBUG_EVENT("%s: Invalid (56K) Firmware ID: 0x%X!\n", + card->devname, card->u.aft.firm_id); + return -EINVAL; + } +*/ + sdla_56k_iface_init(&card->fe, &card->wandev.fe_iface); + + card->fe.name = card->devname; + card->fe.card = card; +#if 1 + card->fe.write_fe_reg = a56k_write_fe; + card->fe.read_fe_reg = a56k_read_fe; + card->fe.__read_fe_reg = __a56k_read_fe; +#else + card->fe.write_fe_reg = a104_write_fe; + card->fe.read_fe_reg = a104_read_fe; + card->fe.__read_fe_reg = __a104_read_fe; +#endif + card->wandev.fe_enable_timer = enable_timer; + card->wandev.ec_enable_timer = enable_ec_timer; + card->wandev.te_link_state = handle_front_end_state; + + card->wandev.comm_port=1; + + card->u.aft.num_of_time_slots=1; + + }else{ + DEBUG_EVENT("%s: Invalid Front-End media type!!\n", + card->devname); + return -EINVAL; + } + + return wan_aft_init(card,conf); + +} + +static int wan_aft_init (sdla_t *card, wandev_conf_t* conf) +{ + int err; + int used_cnt; + + /* Obtain hardware configuration parameters */ + card->wandev.clocking = conf->clocking; + card->wandev.ignore_front_end_status = conf->ignore_front_end_status; + card->wandev.ttl = conf->ttl; + card->wandev.electrical_interface = conf->electrical_interface; + card->wandev.udp_port = conf->udp_port; + card->wandev.new_if_cnt = 0; + wan_atomic_set(&card->wandev.if_cnt,0); + card->u.aft.chip_security_cnt=0; + + memcpy(&card->u.aft.cfg,&conf->u.aft,sizeof(wan_xilinx_conf_t)); + memcpy(&card->rtp_conf,&conf->rtp_conf,sizeof(conf->rtp_conf)); + memset(card->u.aft.dev_to_ch_map,0,sizeof(card->u.aft.dev_to_ch_map)); + memcpy(&card->tdmv_conf,&conf->tdmv_conf,sizeof(wan_tdmv_conf_t)); + memcpy(&card->hwec_conf,&conf->hwec_conf,sizeof(wan_hwec_conf_t)); + + card->u.aft.cfg.dma_per_ch = MAX_RX_BUF; + card->u.aft.tdmv_api_rx = NULL; + card->u.aft.tdmv_api_tx = NULL; + card->u.aft.tdmv_dchan=0; + wan_skb_queue_init(&card->u.aft.tdmv_api_tx_list); + + if (card->wandev.ignore_front_end_status == WANOPT_NO){ + DEBUG_EVENT( + "%s: Enabling front end link monitor\n", + card->devname); + }else{ + DEBUG_EVENT( + "%s: Disabling front end link monitor\n", + card->devname); + } + + AFT_FUNC_DEBUG(); + + /* WARNING: After this point the init function + * must return with 0. The following bind + * functions will cause problems if structures + * below are not initialized */ + + card->wandev.update = &update; + card->wandev.new_if = &new_if; + card->wandev.del_if = &del_if; + card->disable_comm = NULL; + + +#ifdef WANPIPE_ENABLE_PROC_FILE_HOOKS + /* Proc fs functions hooks */ + card->wandev.get_config_info = &get_config_info; + card->wandev.get_status_info = &get_status_info; + card->wandev.get_dev_config_info= &get_dev_config_info; + card->wandev.get_if_info = &get_if_info; + card->wandev.set_dev_config = &set_dev_config; + card->wandev.set_if_info = &set_if_info; +#endif + card->wandev.get_info = &wan_aft_get_info; + + /* Setup Port Bps */ + if(card->wandev.clocking) { + card->wandev.bps = conf->bps; + }else{ + card->wandev.bps = 0; + } + + /* For Primary Port 0 */ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + card->wandev.mtu = conf->mtu; + card->wan_tdmv.sc = NULL; +#else + card->wandev.mtu=conf->mtu; + if (card->wandev.mtu > MAX_WP_PRI_MTU || + card->wandev.mtu < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid Global MTU %d (Min=%d, Max=%d)\n", + card->devname,card->wandev.mtu, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + return -EINVAL; + } +#endif + + + if (!card->u.aft.cfg.mru){ + card->u.aft.cfg.mru = card->wandev.mtu; + } + + + if (card->u.aft.cfg.mru > MAX_WP_PRI_MTU || + card->u.aft.cfg.mru < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid Global MRU %d (Min=%d, Max=%d)\n", + card->devname,card->u.aft.cfg.mru, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + return -EINVAL; + } + + card->hw_iface.getcfg(card->hw, SDLA_BASEADDR, &card->u.aft.bar); + card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &card->u.aft.bar_virt); + + port_set_state(card,WAN_CONNECTING); + + WAN_TASKQ_INIT((&card->u.aft.port_task),0,aft_port_task,card); + + card->u.aft.chip_cfg_status=0; + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &used_cnt); + + wan_clear_bit(CARD_DOWN,&card->wandev.critical); + + __sdla_push_ptr_isr_array(card->hw,card,card->wandev.comm_port); + + card->isr = &wp_aft_global_isr; + + if (used_cnt==1){ + DEBUG_EVENT("%s: Global Chip Configuration: used=%d\n", + card->devname,used_cnt); + + err=aft_global_chip_configuration(card, conf); + if (err){ + aft_global_chip_disable(card); + return err; + } + + aft_data_mux_cfg(card); + + }else{ + + aft_data_mux_get_cfg(card); + + err=aft_front_end_mismatch_check(card); + if (err){ + return err; + } + + DEBUG_EVENT("%s: Global Chip Configuration skiped: used=%d\n", + card->devname,used_cnt); + } + card->wandev.ec_intmask=SYSTEM_TICKS; + + aft_read_security(card); + + err=aft_chip_configure(card,conf); + if (err){ + AFT_FUNC_DEBUG(); + + aft_chip_unconfigure(card); + if (used_cnt==1){ + aft_global_chip_disable(card); + } + return err; + } + wan_set_bit(AFT_CHIP_CONFIGURED,&card->u.aft.chip_cfg_status); + + if (wan_test_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status)){ + wan_smp_flag_t smp_flags; + DEBUG_TEST("%s: Front end up, retrying enable front end!\n", + card->devname); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + wan_clear_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status); + } + + AFT_FUNC_DEBUG(); + + aft_read_security(card); + + + DEBUG_EVENT("%s: Configuring Device :%s FrmVr=%02X\n", + card->devname,card->devname,card->u.aft.firm_ver); + DEBUG_EVENT("%s: Global MTU = %d\n", + card->devname, + card->wandev.mtu); + DEBUG_EVENT("%s: Global MRU = %d\n", + card->devname, + card->u.aft.cfg.mru); + DEBUG_EVENT("%s: Data Mux Map = 0x%08X\n", + card->devname, + card->u.aft.cfg.data_mux_map); + DEBUG_EVENT("%s: Rx CRC Bytes = %i\n", + card->devname, + card->u.aft.cfg.rx_crc_bytes); + + wan_clear_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_clear_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID) { + if ((card->adptr_type == A108_ADPTR_8TE1 && + card->u.aft.firm_ver >= 0x27) || + (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_ver >= 0x26) || + (card->adptr_type == A101_ADPTR_2TE1 && + card->u.aft.firm_ver >= 0x26) || + (card->adptr_type == A101_ADPTR_1TE1 && + card->u.aft.firm_ver >= 0x26)) { + wan_set_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_set_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + } + } else { + if ((card->adptr_type == A104_ADPTR_4TE1 && + card->adptr_subtype == AFT_SUBTYPE_SHARK && + card->u.aft.firm_ver >= 0x23)) { + wan_set_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_set_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + } + } + + if(IS_BRI_CARD(card)){ + wan_set_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status); + wan_set_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status); + } + + DEBUG_EVENT("%s: Global TDM Int = %s\n", + card->devname, + wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status) ? + "Enabled" : "Disabled"); + + DEBUG_EVENT("%s: Global TDM Ring= %s\n", + card->devname, + wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status) ? + "Enabled" : "Disabled"); + + if (card->wandev.ec_dev){ + card->u.aft.tdmv_hw_dtmf = conf->tdmv_conf.hw_dtmf; + }else{ + card->u.aft.tdmv_hw_dtmf = WANOPT_NO; + } + DEBUG_EVENT("%s: TDM HW DTMF = %s\n", + card->devname, + (card->u.aft.tdmv_hw_dtmf == WANOPT_YES) ? + "Enabled" : "Disabled"); + + err=aft_tdmv_init(card,conf); + if (err){ + disable_comm(card); + return err; + } + + card->disable_comm = &disable_comm; + +#if defined(AFT_RTP_SUPPORT) + err=aft_rtp_config(card); + DEBUG_EVENT("%s: RTP TAP = %s\n", + card->devname, + err == 0 ? "Enabled" : "Disabled"); +#endif + + card->wandev.read_ec = aft_read_ec; + card->wandev.write_ec = aft_write_ec; + return 0; + +} + + + + +/**SECTION************************************************************** + * + * WANPIPE Device Driver Entry Points + * + * *********************************************************************/ + + + +/*============================================================================ + * update - Update wanpipe device status & statistics + * + * @wandev: Wanpipe device pointer + * + * This procedure is called when updating the PROC file system. + * It returns various communications statistics. + * + * cat /proc/net/wanrouter/wanpipe# (where #=1,2,3...) + * + * These statistics are accumulated from 3 + * different locations: + * 1) The 'if_stats' recorded for the device. + * 2) Communication error statistics on the adapter. + * 3) Operational statistics on the adapter. + * + * The board level statistics are read during a timer interrupt. + * Note that we read the error and operational statistics + * during consecitive timer ticks so as to minimize the time + * that we are inside the interrupt handler. + * + */ +static int update (wan_device_t* wandev) +{ + sdla_t* card = wandev->priv; + netdevice_t* dev; + volatile private_area_t* chan; + + /* sanity checks */ + if((wandev == NULL) || (wandev->priv == NULL)) + return -EFAULT; + + if(wandev->state == WAN_UNCONFIGURED) + return -ENODEV; + + if(wan_test_bit(PERI_CRIT, (void*)&card->wandev.critical)) + return -EAGAIN; + + dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); + if(dev == NULL) + return -ENODEV; + + if((chan=wan_netif_priv(dev)) == NULL) + return -ENODEV; + + if(card->update_comms_stats){ + return -EAGAIN; + } + + DEBUG_TEST("%s: Chain Dma Status=0x%lX, TxCur=%d, TxPend=%d RxCur=%d RxPend=%d\n", + chan->if_name, + chan->dma_chain_status, + chan->tx_chain_indx, + chan->tx_pending_chain_indx, + chan->rx_chain_indx, + chan->rx_pending_chain_indx); + +#if 1 + update_comms_stats(card); +#else + #warning "COMM STATS DISABLED" +#endif + return 0; +} + + + +/*============================================================================ + * new_if - Create new logical channel. + * + * &wandev: Wanpipe device pointer + * &dev: Network device pointer + * &conf: User configuration options pointer + * + * This routine is called by the ROUTER_IFNEW ioctl, + * in wanmain.c. The ioctl passes us the user configuration + * options which we use to configure the driver and + * firmware. + * + * This functions main purpose is to allocate the + * private structure for protocol and bind it + * to dev->priv pointer. + * + * Also the dev->init pointer should also be initialized + * to the if_init() function. + * + * Any allocation necessary for the private strucutre + * should be done here, as well as proc/ file initializetion + * for the network interface. + * + * o parse media- and hardware-specific configuration + * o make sure that a new channel can be created + * o allocate resources, if necessary + * o prepare network device structure for registaration. + * o add network interface to the /proc/net/wanrouter + * + * The opposite of this function is del_if() + * + * Return: 0 o.k. + * < 0 failure (channel will not be created) + */ + +static int +aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ +#ifdef AFT_TDM_API_SUPPORT + int err=0; +#endif + + if (chan->common.usedby != TDM_VOICE_API && + chan->common.usedby != TDM_VOICE_DCHAN) { + return 0; + } + +#ifdef AFT_TDM_API_SUPPORT + if (chan->tdmv_zaptel_cfg) { + return 0; + } + + /* Initilaize TDM API Parameters */ + chan->wp_tdm_api_dev.chan = chan; + chan->wp_tdm_api_dev.card = card; + wan_spin_lock_init(&chan->wp_tdm_api_dev.lock); + strncpy(chan->wp_tdm_api_dev.name,chan->if_name,WAN_IFNAME_SZ); + + if (conf->hdlc_streaming) { + chan->wp_tdm_api_dev.hdlc_framing=1; + } + + chan->wp_tdm_api_dev.event_ctrl = aft_event_ctrl; + chan->wp_tdm_api_dev.read_rbs_bits = aft_read_rbs_bits; + chan->wp_tdm_api_dev.write_rbs_bits = aft_write_rbs_bits; + chan->wp_tdm_api_dev.write_hdlc_frame = aft_write_hdlc_frame; + + chan->wp_tdm_api_dev.cfg.rx_disable = 0; + chan->wp_tdm_api_dev.cfg.tx_disable = 0; + + if (IS_TE1_CARD(card)) { + if (IS_T1_CARD(card)){ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_MULAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot+1; + }else{ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot; + } + + } else if (IS_BRI_CARD(card)) { + + if (chan->dchan_time_slot >= 0) { + chan->wp_tdm_api_dev.tdm_chan = 3; + } else { + chan->wp_tdm_api_dev.tdm_chan = (chan->first_time_slot % 2) + 1; + } + + if (card->fe.fe_cfg.tdmv_law == WAN_TDMV_MULAW){ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_MULAW; + } else { + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; + } + + } else { + if (card->fe.fe_cfg.tdmv_law == WAN_TDMV_MULAW){ + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_MULAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot+1; + } else { + chan->wp_tdm_api_dev.cfg.hw_tdm_coding=WP_ALAW; + chan->wp_tdm_api_dev.tdm_chan = chan->first_time_slot+1; + } + + + } + + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + chan->wp_tdm_api_dev.active_ch = conf->active_ch << 1; + }else{ + chan->wp_tdm_api_dev.active_ch = conf->active_ch; + } + + DEBUG_TEST("%s: TDM API ACTIVE CH 0x%08X CHAN=%i\n", + chan->if_name, chan->wp_tdm_api_dev.active_ch,chan->wp_tdm_api_dev.tdm_chan); + + chan->wp_tdm_api_dev.cfg.idle_flag = conf->u.aft.idle_flag; + chan->wp_tdm_api_dev.cfg.rbs_tx_bits = conf->u.aft.rbs_cas_idle; + + chan->wp_tdm_api_dev.tdm_span = card->tdmv_conf.span_no; + + chan->wp_tdm_api_dev.dtmfsupport = card->u.aft.tdmv_hw_dtmf; + + err=wanpipe_tdm_api_reg(&chan->wp_tdm_api_dev); + if (err){ + return err; + } + + wan_set_bit(0,&chan->wp_tdm_api_dev.init); + return err; +#else + DEBUG_EVENT("%s: TDM API support not compiled in\n", + card->devname); + return -EINVAL; +#endif + +} + +static int aft_tdm_api_free(sdla_t *card, private_area_t *chan) +{ +#ifdef AFT_TDM_API_SUPPORT + int err=0; + if (wan_test_bit(0,&chan->wp_tdm_api_dev.init)){ + wan_clear_bit(0,&chan->wp_tdm_api_dev.init); + err=wanpipe_tdm_api_unreg(&chan->wp_tdm_api_dev); + if (err){ + wan_set_bit(0,&chan->wp_tdm_api_dev.init); + return err; + } + } +#endif + return 0; +} + + + +static int aft_chan_if_init(sdla_t *card, netdevice_t *dev, private_area_t *chan) +{ + chan->first_time_slot=-1; + chan->last_time_slot=-1; + chan->logic_ch_num=-1; +#if defined(AFT_SINGLE_DMA_CHAIN) + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; +#else + chan->single_dma_chain=0; + chan->max_tx_bufs=MAX_TX_BUF; +#endif + chan->tslot_sync=0; + + strncpy(chan->if_name, wan_netif_name(dev), WAN_IFNAME_SZ); + + chan->card = card; + chan->common.card = card; + + WAN_IFQ_INIT(&chan->wp_tx_pending_list,0); + WAN_IFQ_INIT(&chan->wp_tx_complete_list,0); + WAN_IFQ_INIT(&chan->wp_tx_hdlc_rpt_list,0); + + WAN_IFQ_INIT(&chan->wp_rx_free_list,0); + WAN_IFQ_INIT(&chan->wp_rx_complete_list,0); + + WAN_IFQ_INIT(&chan->wp_rx_stack_complete_list, 0); + + WAN_IFQ_INIT(&chan->wp_rx_bri_dchan_complete_list, 0); + + wan_trace_info_init(&chan->trace_info,MAX_TRACE_QUEUE); + + /* Initiaize Tx/Rx DMA Chains */ + aft_index_tx_rx_dma_chains(chan); + + /* Initialize the socket binding information + * These hooks are used by the API sockets to + * bind into the network interface */ + WAN_TASKLET_INIT((&chan->common.bh_task),0,wp_bh,chan); + chan->common.dev = dev; + chan->tracing_enabled = 0; + + return 0; +} + + + +static int aft_ss7_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ + if (chan->common.usedby != API){ + /* SS7 Support not supported in non API mode */ + chan->cfg.ss7_enable = 0; + return 0; + } + + DEBUG_EVENT("%s: SS7 Support :%s\n", + card->devname, + chan->cfg.ss7_enable?"On":"Off"); + + if (chan->cfg.ss7_enable){ + + wan_smp_flag_t smp_flags; + u32 lcfg_reg; + + DEBUG_EVENT("%s: SS7 Mode :%s\n", + card->devname, + chan->cfg.ss7_mode?"4096":"128"); + + DEBUG_EVENT("%s: SS7 LSSU Size :%d\n", + card->devname, + chan->cfg.ss7_lssu_size); + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),&lcfg_reg); + if (chan->cfg.ss7_mode){ + aft_lcfg_ss7_mode4096_cfg(&lcfg_reg,chan->cfg.ss7_lssu_size); + }else{ + aft_lcfg_ss7_mode128_cfg(&lcfg_reg,chan->cfg.ss7_lssu_size); + } + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), + lcfg_reg); + card->u.aft.lcfg_reg=lcfg_reg; + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + aft_hwdev[card->wandev.card_type].aft_fifo_adjust(card,AFT_TDMV_FIFO_LEVEL); + chan->single_dma_chain=1; + } + + return 0; +} + +static int aft_transp_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ + unsigned char *buf; + + if (chan->mtu&0x03){ + DEBUG_EVENT("%s:%s: Error, Transparent MTU must be word aligned!\n", + card->devname,chan->if_name); + return -EINVAL; + } + + chan->max_idle_size=chan->mtu; + + if (chan->tslot_sync && chan->mtu%chan->num_of_time_slots){ + DEBUG_EVENT("%s:%s: Error, Sync Transparent MTU must be timeslot aligned!\n", + card->devname,chan->if_name); + + DEBUG_EVENT("%s:%s: Error, MTU=%d not multiple of %d timeslots!\n", + card->devname,chan->if_name, + chan->mtu,chan->num_of_time_slots); + + return -EINVAL; + } + + if (conf->protocol != WANCONFIG_LIP_ATM && + conf->protocol != WANCONFIG_LIP_KATM && + chan->mru%chan->num_of_time_slots){ + DEBUG_EVENT("%s:%s: Error, Transparent MRU must be timeslot aligned!\n", + card->devname,chan->if_name); + + DEBUG_EVENT("%s:%s: Error, MRU=%d not multiple of %d timeslots!\n", + card->devname,chan->if_name, + chan->mru,chan->num_of_time_slots); + + return -EINVAL; + } + + + DEBUG_TEST("%s:%s: Config for Transparent mode: Idle=%X Len=%u\n", + card->devname,chan->if_name, + chan->idle_flag,chan->max_idle_size); + + chan->idle_flag=0x7E; + + if (chan->tdmv_zaptel_cfg){ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + chan->idle_flag = WAN_TDMV_IDLE_FLAG; +#endif + } + + /* We use the dma_mru value here, just because it will + * be easier to change the idle tx size on the fly */ + chan->tx_idle_skb = wan_skb_alloc(chan->dma_mru); + if (!chan->tx_idle_skb){ + return -EINVAL; + } + buf = wan_skb_put(chan->tx_idle_skb,chan->dma_mru); + + if(conf->protocol != WANCONFIG_LIP_ATM && + conf->protocol != WANCONFIG_LIP_KATM){ + memset(buf,chan->idle_flag,chan->dma_mru); + }else{ + chan->lip_atm = 1; + /* if running below LIP ATM, transmit idle cells */ + if(init_atm_idle_buffer((unsigned char*)buf, + wan_skb_len(chan->tx_idle_skb), + chan->if_name, + chan->cfg.data_mux )){ + + wan_skb_free(chan->tx_idle_skb); + chan->tx_idle_skb = NULL; + return -EINVAL; + } + } + + /* reset the tx idle buffer to the actual mtu size */ + wan_skb_init(chan->tx_idle_skb,16); + wan_skb_trim(chan->tx_idle_skb,0); + wan_skb_put(chan->tx_idle_skb,chan->max_idle_size); + + return 0; +} + + +static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf, int channelized, int dchan) +{ + sdla_t* card = wandev->priv; + private_area_t* chan; + int dma_per_ch=card->u.aft.cfg.dma_per_ch; + int err = 0, dma_alignment = 4, i =0; + + DEBUG_EVENT( "%s: Configuring Interface: %s\n", + card->devname, wan_netif_name(dev)); + + if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)){ + DEBUG_EVENT( "%s: Invalid interface name!\n", + card->devname); + return -EINVAL; + } + + if (card->adptr_subtype != AFT_SUBTYPE_SHARK){ + if (card->u.aft.security_id != 0x01 && + card->u.aft.security_cnt >= 2){ + DEBUG_EVENT("%s: Error: Security: Max HDLC channels(2) exceeded!\n", + card->devname); + DEBUG_EVENT("%s: Un-Channelised AFT supports 2 HDLC ifaces!\n", + card->devname); + return -EINVAL; + } + } + + /* ====================================== + * Allocate and initialize private data + * =====================================*/ + + chan = wan_kmalloc(sizeof(private_area_t)); + if(chan == NULL){ + WAN_MEM_ASSERT(card->devname); + return -ENOMEM; + } + + memset(chan, 0, sizeof(private_area_t)); + memcpy(&chan->cfg,&conf->u.aft,sizeof(chan->cfg)); + + chan->true_if_encoding=conf->true_if_encoding; + + aft_chan_if_init(card,dev,chan); + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) { + chan->single_dma_chain = 1; + conf->hdlc_streaming=0; + } + + if (card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI) { + chan->single_dma_chain = 1; + } + + /* If 'dchan_time_slot' is less than zero, it is NOT a dchan. + If 'dchan_time_slot' is greater or equal to zero it is a dchan. + NOTE: 'dchan' is NOT the same as 'hdlc_eng'. The 'hdlc_eng' is + a flag for AFT hardware to use it's HDLC core. + */ + chan->dchan_time_slot = dchan; + + DEBUG_BRI_DCHAN("%s(): chan->dchan_time_slot: 0x%X\n", __FUNCTION__, chan->dchan_time_slot); + + if(IS_56K_CARD(card)){ + chan->single_dma_chain = 1; + conf->hdlc_streaming=1; + } + + if (chan->cfg.hdlc_repeat) { + if (!conf->hdlc_streaming) { + DEBUG_EVENT("%s: HDLC Repeat configured for non hdlc channel!\n", + chan->if_name); + err= -EINVAL; + goto new_if_error; + } + chan->single_dma_chain = 1; + conf->hdlc_streaming=1; + } + + if (channelized) { + chan->channelized_cfg=1; + if (wan_netif_priv(dev)) { +#if 1 + private_area_t *cptr; + for (cptr=wan_netif_priv(dev);cptr->next!=NULL;cptr=cptr->next); + cptr->next=chan; + chan->next=NULL; +#else +#warning "DEBUG: Chan list backwards!" + chan->next = wan_netif_priv(dev); + wan_netif_set_priv(dev, chan); +#endif + } else { + wan_netif_set_priv(dev, chan); + } + } else { + chan->channelized_cfg=0; + wan_netif_set_priv(dev, chan); + } + + /* ====================================== + * Configure chan MTU and MRU Values + * And setup E1 timeslots + * =====================================*/ + chan->mtu = card->wandev.mtu; + if (conf->u.aft.mtu){ + chan->mtu=conf->u.aft.mtu; + if (chan->mtu > MAX_WP_PRI_MTU || + chan->mtu < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid %s MTU %d (Min=%d, Max=%d)\n", + card->devname,chan->if_name,chan->mtu, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + err= -EINVAL; + goto new_if_error; + } + + } + + chan->mru = card->u.aft.cfg.mru; + if (conf->u.aft.mru){ + chan->mru = conf->u.aft.mru; + if (chan->mru > MAX_WP_PRI_MTU || + chan->mru < MIN_WP_PRI_MTU){ + DEBUG_EVENT("%s: Error Invalid %s MRU %d (Min=%d, Max=%d)\n", + card->devname,chan->if_name,chan->mru, + MIN_WP_PRI_MTU,MAX_WP_PRI_MTU); + + err= -EINVAL; + goto new_if_error; + } + } + + /*==================================================== + * Interface connects top services to driver + * Interface can be used by the following services: + * WANPIPE = TCP/IP -> Driver + * API = Raw Socket Access -> Driver + * BRIDGE = Bridge to Ethernet -> Driver + * BRIDGE_NODE = TCP/IP to Ethernet -> Driver + * STACK = LIP -> Driver + * TDM_VOICE = Zaptel -> Trans Ch Driver + * TDM_VOICE_DCHAN = Zaptel -> Hdlc Driver (PRIVATE) + * TDM_VOICE_API = Raw Socket -> Transp Ch Driver + * TMD_API = Raw Socket -> Transp Channelized API + *===================================================*/ + + if(strcmp(conf->usedby, "WANPIPE") == 0) { + + DEBUG_EVENT( "%s: Running in WANPIPE mode\n", + wandev->name); + chan->common.usedby = WANPIPE; + + /* Used by GENERIC driver only otherwise protocols + * are in LIP layer */ + if (conf->protocol != WANOPT_NO){ + wan_netif_set_priv(dev, chan); + if ((err=protocol_init(card,dev,chan,conf)) != 0){ + wan_netif_set_priv(dev, NULL); + goto new_if_error; + } + } + +#if defined(__LINUX__) + + } else if( strcmp(conf->usedby, "TDM_API") == 0) { + + DEBUG_EVENT("%s:%s: Error: TDM API mode is not supported!\n", + card->devname,chan->if_name); + err=-EINVAL; + goto new_if_error; +#endif + +#if defined(AFT_API_SUPPORT) + } else if( strcmp(conf->usedby, "API") == 0) { + chan->common.usedby = API; + DEBUG_EVENT( "%s:%s: Running in API mode\n", + wandev->name,chan->if_name); + wan_reg_api(chan, dev, card->devname); + card->wandev.event_callback.dtmf = wan_aft_api_dtmf; + card->wandev.event_callback.hook = wan_aft_api_hook; + card->wandev.event_callback.ringtrip = wan_aft_api_ringtrip; + card->wandev.event_callback.ringdetect = wan_aft_api_ringdetect; +#endif + +#if defined(__LINUX__) + }else if (strcmp(conf->usedby, "BRIDGE") == 0) { + chan->common.usedby = BRIDGE; + DEBUG_EVENT( "%s:%s: Running in WANPIPE (BRIDGE) mode.\n", + card->devname,chan->if_name); +#endif + +#if defined(__LINUX__) + }else if (strcmp(conf->usedby, "BRIDGE_N") == 0) { + chan->common.usedby = BRIDGE_NODE; + DEBUG_EVENT( "%s:%s: Running in WANPIPE (BRIDGE_NODE) mode.\n", + card->devname,chan->if_name); +#endif + + }else if (strcmp(conf->usedby, "TDM_VOICE") == 0) { + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + chan->common.usedby = TDM_VOICE; + + chan->tdmv_zaptel_cfg=1; + card->u.aft.tdmv_zaptel_cfg=1; + conf->hdlc_streaming=0; + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; + + if (dchan >= 0){ +# ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN + chan->common.usedby = TDM_VOICE_DCHAN; + conf->hdlc_streaming=1; + chan->single_dma_chain=0; + chan->mru=chan->mtu=1500; +# else + DEBUG_EVENT("%s: Error: TDMV_DCHAN Option not compiled into the driver!\n", + card->devname); + err=-EINVAL; + goto new_if_error; +# endif + } + + DEBUG_EVENT( "%s:%s: Running in TDM %sVoice Zaptel Mode.\n", + card->devname,chan->if_name, + chan->common.usedby == TDM_VOICE_DCHAN?"DCHAN ":""); +#else + DEBUG_EVENT("\n"); + DEBUG_EVENT("%s:%s: Error: TDM VOICE prot not compiled\n", + card->devname,chan->if_name); + DEBUG_EVENT("%s:%s: during installation process!\n", + card->devname,chan->if_name); + err=-EINVAL; + goto new_if_error; +#endif + +#if defined(__LINUX__) + }else if (strcmp(conf->usedby, "TDM_VOICE_API") == 0) { + + chan->common.usedby = TDM_VOICE_API; + chan->cfg.data_mux=1; + conf->hdlc_streaming=0; + chan->single_dma_chain=1; + chan->tdmv_zaptel_cfg=0; + + if (dchan >= 0){ + chan->common.usedby = TDM_VOICE_DCHAN; + chan->cfg.data_mux=0; + chan->single_dma_chain=0; + conf->hdlc_streaming=1; + chan->mru=chan->mtu=1500; + } + + + if (chan->common.usedby == TDM_VOICE_DCHAN) { + DEBUG_EVENT( "%s:%s: Running in TDM Voice DCHAN API Mode.\n", + card->devname,chan->if_name); + } else { + DEBUG_EVENT( "%s:%s: Running in TDM Voice API Mode.\n", + card->devname,chan->if_name); + } +#endif + + }else if (strcmp(conf->usedby, "STACK") == 0) { + chan->common.usedby = STACK; + DEBUG_EVENT( "%s:%s: Running in Stack mode.\n", + card->devname,chan->if_name); + + }else if (strcmp(conf->usedby, "NETGRAPH") == 0) { + chan->common.usedby = WP_NETGRAPH; + DEBUG_EVENT( "%s:%s: Running in Netgraph mode.\n", + card->devname,chan->if_name); + + }else{ + DEBUG_EVENT( "%s:%s: Error: Invalid IF operation mode %s\n", + card->devname,chan->if_name,conf->usedby); + err=-EINVAL; + goto new_if_error; + } + + + /*=============================================== + * Interface Operation Setup + *==============================================*/ + + if (conf->hwec.enable){ + card->wandev.ec_enable_map |= conf->active_ch; + } + + /* Read user specified active_ch, we must do it + * here because the active_ch value might change + * for different user modes*/ + chan->time_slot_map=conf->active_ch; + chan->num_of_time_slots= + aft_get_num_of_slots(card->u.aft.num_of_time_slots, + chan->time_slot_map); + + if (!chan->num_of_time_slots){ + DEBUG_EVENT("%s: Error: Invalid number of timeslots in map 0x%08lX!\n", + chan->if_name,chan->time_slot_map); + return -EINVAL; + } + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG && chan->num_of_time_slots > 1) { + DEBUG_EVENT( + "%s: Error: Invalid Analog number of timeslots in map 0x%08lX: (Valid=1)\n", + chan->if_name,chan->time_slot_map); + return -EINVAL; + } + + + /* ===================== + * Interaface TDMV Setup + * + * Initialize the interface for TDMV + * operation, if TDMV is not used this + * function will just return */ + err=aft_tdmv_if_init(card,chan,conf); + if (err){ + err=-EINVAL; + goto new_if_error; + } + + + /* ===================== + * Interaface SS7 Setup + * + * Initialize the interface for TDMV + * operation, if TDMV is not used this + * function will just return */ + err=aft_ss7_if_init(card,chan,conf); + if (err){ + err=-EINVAL; + goto new_if_error; + } + + + /* Print out the current configuration */ + DEBUG_EVENT("%s: MRU :%d\n", + card->devname, + chan->mru); + + DEBUG_EVENT("%s: MTU :%d\n", + card->devname, + chan->mtu); + + + chan->hdlc_eng = conf->hdlc_streaming; + + DEBUG_EVENT("%s: HDLC Eng :%s | %s\n", + card->devname, + chan->hdlc_eng?"On":"Off (Transparent)", + chan->cfg.hdlc_repeat?"Repeat":"N/A"); + + + /* Obtain the DMA MRU size based on user confgured + * MRU. The DMA MRU must be of size 2^x */ + + chan->dma_mru = chan->mtu; + + chan->dma_mru = aft_valid_mtu(chan->dma_mru); + if (!chan->dma_mru){ + DEBUG_EVENT("%s:%s: Error invalid MTU %d MRU %d\n", + card->devname, + chan->if_name, + chan->mtu,chan->mru); + err= -EINVAL; + goto new_if_error; + } + + if (conf->single_tx_buf || + IS_BRI_CARD(card) || + ((card->adptr_type == A101_ADPTR_2TE1 || + card->adptr_type == A101_ADPTR_1TE1) && + card->u.aft.firm_id == AFT_DS_FE_CORE_ID)){ + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; + dma_per_ch=MAX_AFT_DMA_CHAINS; + } + + + if (!chan->hdlc_eng){ + /* If hardware HDLC engine is disabled: + * 1. Configure DMA chains for SINGLE DMA + * 2. Enable Timeslot Synchronization + * 3. Configure Interface for Transparent Operation */ + chan->single_dma_chain=1; + chan->max_tx_bufs=MAX_AFT_DMA_CHAINS; + + if (chan->channelized_cfg) { + dma_per_ch=MAX_AFT_DMA_CHAINS; + }else{ + dma_per_ch= (MAX_AFT_DMA_CHAINS*1500) / chan->mtu; + if (dma_per_ch < MAX_AFT_DMA_CHAINS) { + dma_per_ch=MAX_AFT_DMA_CHAINS; + } + } + + chan->tslot_sync=1; + + if(conf->protocol == WANCONFIG_LIP_ATM || + conf->protocol == WANCONFIG_LIP_KATM){ + chan->tslot_sync=0; + } + + err=aft_transp_if_init(card,chan,conf); + if (err){ + goto new_if_error; + } + + }else{ + /* If hardware HDLC engine is enabled: + * 1. Force Disable DATA MUX option + * just in case user made a mistake + */ + chan->cfg.data_mux=0; + } + DEBUG_EVENT("%s: Data Mux Ctrl :%s\n", + card->devname, + chan->cfg.data_mux?"On":"Off"); + + + + + /*================================================= + * AFT CHANNEL Configuration + * + * Configure the AFT Hardware for this + * logic channel. Enable the above selected + * operation modes. + *================================================*/ + + err=aft_dev_configure(card,chan,conf); + if (err){ + goto new_if_error; + } + + /*Set the actual logic ch number of this chan + *as the dchan. Due to HDLC security issue, the + *HDLC channels are mapped on first TWO logic channels */ + if (chan->common.usedby == TDM_VOICE_DCHAN){ + card->u.aft.tdmv_dchan=chan->logic_ch_num+1; + } + + /* Configure the DCHAN on LAST Master interface. + * We will use the master interface information, until + * the next interface with the current DCHAN info is + * configured. This must be done in order to register + * the DCHAN in zaptel. */ + if (card->u.aft.tdmv_dchan_cfg_on_master && + card->u.aft.tdmv_dchan){ + int dchan=card->u.aft.tdmv_dchan; + if (IS_T1_CARD(card)){ + dchan--; + } + if (wan_test_bit(dchan,&conf->active_ch)){ + DEBUG_EVENT("%s: TDMV DCHAN :%d\n", + card->devname,dchan); + card->u.aft.tdmv_chan_ptr=chan; + card->u.aft.tdmv_dchan=chan->logic_ch_num+1; + } + } + + + err=aft_tdm_api_init(card,chan,conf); + if (err){ + goto new_if_error; + } + + err=aft_hwec_config(card,chan,conf,1); + if (err){ + goto new_if_error; + } + + if (chan->channelized_cfg && !chan->hdlc_eng) { + chan->dma_mru = 1024; + dma_per_ch = 4; + } + + DEBUG_EVENT("%s: DMA/Len/Chain/EC :%d/%d/%s/%s\n", + card->devname, + dma_per_ch, + chan->dma_mru, + chan->single_dma_chain?"Off":"On", + card->wandev.ec_enable_map?"On":"Off"); + + /* New DMA support A-DMA */ + dma_alignment = 4; + if (chan->channelized_cfg && !chan->hdlc_eng){ + dma_alignment = 0x200; + } + + err = card->hw_iface.busdma_tag_create( card->hw, + &chan->rx_dma_chain_table[0], + dma_alignment, + chan->dma_mru, + MAX_AFT_DMA_CHAINS); + if (err) { + DEBUG_EVENT("%s: Failed to allocate DMA Rx mtag!\n", + card->devname); + err = -EINVAL; + goto new_if_error; + } + err = card->hw_iface.busdma_tag_create( card->hw, + &chan->tx_dma_chain_table[0], + dma_alignment, + chan->dma_mru, + MAX_AFT_DMA_CHAINS); + if (err) { + DEBUG_EVENT("%s: Failed to allocate DMA Tx mtag!\n", + card->devname); + err = card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + err = -EINVAL; + goto new_if_error; + } + + for (i=0;ihw_iface.busdma_alloc(card->hw,&chan->tx_dma_chain_table[i]); + if (err){ + DEBUG_EVENT("%s:%s: Unable to load TX DMA buffer %d (%d)!\n", + card->devname, chan->if_name, i, err); + err = -EINVAL; + break; + } + DEBUG_DMA("%s:%s: Alloc DMA TX buffer %d virt=%p len=%d\n", + card->devname, chan->if_name, i, + chan->tx_dma_chain_table[i].dma_virt, + chan->dma_mru); + + err = card->hw_iface.busdma_alloc(card->hw,&chan->rx_dma_chain_table[i]); + if (err){ + DEBUG_EVENT("%s:%s: Unable to load RX DMA buffer %d (%d)!\n", + card->devname, chan->if_name, i, err); + err = -EINVAL; + break; + } + DEBUG_DMA("%s:%s: Alloc DMA RX buffer %d virt=%p len=%d\n", + card->devname, chan->if_name, i, + chan->rx_dma_chain_table[i].dma_virt, + chan->dma_mru); + } + if (err){ + + for (i=0;ihw_iface.busdma_free(card->hw,&chan->rx_dma_chain_table[i]); + card->hw_iface.busdma_free(card->hw,&chan->tx_dma_chain_table[i]); + } + err = card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + err = card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + err = -EINVAL; + goto new_if_error; + } + + + err=aft_alloc_rx_dma_buff(card, chan, dma_per_ch,0); + if (err){ + goto new_if_error; + } + + /*======================================================= + * Interface OS Specific Configuration + *======================================================*/ + + + /* If gateway option is set, then this interface is the + * default gateway on this system. We must know that information + * in case DYNAMIC interface configuration is enabled. + * + * I.E. If the interface is brought down by the driver, the + * default route will also be removed. Once the interface + * is brought back up, we must know to re-astablish the + * default route. + */ + if ((chan->gateway = conf->gateway) == WANOPT_YES){ + DEBUG_EVENT( "%s: Interface %s is set as a gateway.\n", + card->devname,chan->if_name); + } + + /* Get Multicast Information from the user + * FIXME: This is IP relevant, since this is now + * a hardware interface this option should't + * be here */ + chan->mc = conf->mc; + + + /* The network interface "dev" has been passed as + * an argument from the above layer. We must initialize + * it so it can be registered into the kernel. + * + * The "dev" structure is the link between the kernel + * stack and the wanpipe driver. It contains all + * access hooks that kernel uses to communicate to + * the our driver. + * + * For now, just set the "dev" name to the user + * defined name and initialize: + * dev->if_init : function that will be called + * to further initialize + * dev structure on "ifconfig up" + * + * dev->priv : private structure allocated above + * + */ + + + /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * DO NOT PLACE ANY CODE BELOW THAT COULD RETURN ERROR + * + *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ + + + /* Only setup the dev pointer once the new_if function has + * finished successfully. DO NOT place any code below that + * can return an error */ +#if defined(__LINUX__) + dev->init = &if_init; +# if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + if_init(dev); +# endif +#else + chan->common.is_netdev = 1; + chan->common.iface.open = &if_open; + chan->common.iface.close = &if_close; + chan->common.iface.output = &if_send; + chan->common.iface.ioctl = &if_do_ioctl; + chan->common.iface.tx_timeout= &if_tx_timeout; + if (wan_iface.attach){ + if (!ifunit(wan_netif_name(dev))){ + wan_iface.attach(dev, NULL, chan->common.is_netdev); + } + }else{ + DEBUG_EVENT("%s: Failed to attach interface %s!\n", + card->devname, wan_netif_name(dev)); + wan_netif_set_priv(dev, NULL); + err = -EINVAL; + goto new_if_error; + } + wan_netif_set_mtu(dev, chan->mtu); +#endif + + /* + * Increment the number of network interfaces + * configured on this card. + */ + wan_atomic_inc(&card->wandev.if_cnt); + if (chan->hdlc_eng){ + ++card->u.aft.security_cnt; + } + + + + /* Keep the original tx queue len in case + we have to go back to it */ + chan->max_tx_bufs_orig = chan->max_tx_bufs; + + set_chan_state(card, dev, WAN_CONNECTING); //chan->common.state = WAN_CONNECTING; + + DEBUG_EVENT( "\n"); + + return 0; + +new_if_error: + + return err; +} + +static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) +{ + int err=-EINVAL; + sdla_t *card=wandev->priv; + + wan_netif_set_priv(dev, NULL); + + if (IS_E1_CARD(card) && !(WAN_FE_FRAME(&card->fe) == WAN_FR_UNFRAMED)) { + conf->active_ch = conf->active_ch << 1; + wan_clear_bit(0,&conf->active_ch); + }else if (IS_56K_CARD(card)) { + conf->active_ch = 1; + } + + + if (strcmp(conf->usedby, "TDM_VOICE") == 0) { +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (card->tdmv_conf.span_no){ + + switch(card->wandev.config_id){ + case WANCONFIG_AFT_ANALOG: + err = wp_tdmv_remora_init(&card->tdmv_iface); + break; + case WANCONFIG_AFT_ISDN_BRI: + err = wp_tdmv_bri_init(&card->tdmv_iface); + break; + default: + err = wp_tdmv_te1_init(&card->tdmv_iface); + break; + } + if (err){ + DEBUG_EVENT("%s: Error: Failed to initialize tdmv functions!\n", + card->devname); + return -EINVAL; + } + + WAN_TDMV_CALL(create, (card, &card->tdmv_conf), err); + if (err){ + DEBUG_EVENT("%s: Error: Failed to create tdmv span!\n", + card->devname); + return err; + } + } +#else + DEBUG_EVENT("\n"); + DEBUG_EVENT("%s: Error: TDM VOICE prot not compiled\n", + card->devname); + DEBUG_EVENT("%s: during installation process!\n", + card->devname); + return -EINVAL; +#endif + } + + err=-EINVAL; + + if (strcmp(conf->usedby, "TDM_VOICE") == 0 || strcmp(conf->usedby, "TDM_VOICE_API") == 0){ + + int i=0,master_if=-1; + u32 active_ch=conf->active_ch; + + if(IS_BRI_CARD(card)) { + wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&card->u.aft.tdmv_dchan); + } + + if (card->wandev.fe_iface.active_map){ + conf->active_ch = card->wandev.fe_iface.active_map(&card->fe, 0); + + if(IS_BRI_CARD(card)) { + wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&conf->active_ch); + wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&card->tdmv_conf.dchan); + } + + active_ch=conf->active_ch; + } + + err=aft_find_master_if_and_dchan(card,&master_if,active_ch); + if (err < 0) { + return err; + } + + DEBUG_TEST("%s: TDM VOICE: TESTING FOR DCHAN CHAN in 0x%08X Timeslots=%i CFG DCHAN=0x%08X MasterIF=%i\n", + card->devname, active_ch, card->u.aft.num_of_time_slots, + card->tdmv_conf.dchan,master_if); + + for (i=0;iu.aft.num_of_time_slots;i++){ + + if (wan_test_bit(i,&active_ch)){ + int dchan=-1; + conf->active_ch=0; + conf->u.aft.tdmv_master_if=0; + wan_set_bit(i,&conf->active_ch); + if (wan_test_bit(i,&card->tdmv_conf.dchan)){ + dchan=i; + } + if (i==master_if){ + conf->u.aft.tdmv_master_if=1; + } + + err=new_if_private(wandev,dev,conf,1,dchan); + if (err){ + break; + } + } + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (!err && card->u.aft.tdmv_zaptel_cfg){ + WAN_TDMV_CALL(software_init, (&card->wan_tdmv), err); + } +#endif + }else{ + + if(IS_BRI_CARD(card) && wan_test_bit(BRI_DCHAN_ACTIVE_CFG_CHAN, &conf->active_ch)) { + + /* if bit 2 is set, user wants to run on the bri dchan */ + wan_set_bit(BRI_DCHAN_LOGIC_CHAN, &card->u.aft.tdmv_dchan); + card->u.aft.tdmv_dchan = BRI_DCHAN_LOGIC_CHAN; + err=new_if_private(wandev,dev,conf,0, BRI_DCHAN_LOGIC_CHAN); + + } else { + + card->tdmv_conf.dchan=0; + err=new_if_private(wandev,dev,conf,0,-1); + } + } + + if (err == 0 && wan_netif_priv(dev)) { + wan_smp_flag_t flags; + int card_use_counter; + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_counter); + + /* If FRONT End is down, it means that the DMA + * is disabled. In this case don't try to + * reset fifo. Let the enable_data_error_intr() + * function do this, after front end has come up */ + + wan_spin_lock_irq(&card->wandev.lock,&flags); + + aft_dev_open(card, wan_netif_priv(dev)); + + if (card->wandev.state == WAN_CONNECTED){ + set_chan_state(card, dev, WAN_CONNECTED); + } + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG || + card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI) { + wan_spin_lock_irq(&card->wandev.lock,&flags); + card->fe.fe_status = FE_CONNECTED; + handle_front_end_state(card); + set_chan_state(card, dev, WAN_CONNECTED); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + } + + } else if (err && wan_netif_priv(dev)){ + del_if(wandev,dev); + if (wan_netif_priv(dev)){ + wan_free(wan_netif_priv(dev)); + wan_netif_set_priv(dev, NULL); + } + } + + return err; +} + + +/*============================================================================ + * del_if - Delete logical channel. + * + * @wandev: Wanpipe private device pointer + * @dev: Netowrk interface pointer + * + * This function is called by ROUTER_DELIF ioctl call + * to deallocate the network interface. + * + * The network interface and the private structure are + * about to be deallocated by the upper layer. + * We have to clean and deallocate any allocated memory. + * + * NOTE: DO NOT deallocate dev->priv here! It will be + * done by the upper layer. + * + */ +static int del_if_private (wan_device_t* wandev, netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card; + wan_smp_flag_t flags; + int i; + + if (!chan){ + DEBUG_EVENT("%s: Critical Error del_if_private() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + card = chan->card; + if (!card){ + DEBUG_EVENT("%s: Critical Error del_if_private() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + aft_hwec_config(card,chan,NULL,0); + + wan_spin_lock_irq(&card->wandev.lock,&flags); + aft_dev_unconfigure(card,chan); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + AFT_FUNC_DEBUG(); +#if INIT_FE_ONLY + return 0; +#endif + + WAN_TASKLET_KILL(&chan->common.bh_task); + + if (chan->common.usedby == API){ + wan_unreg_api(chan, card->devname); + + } + + if (aft_tdm_api_free(card,chan)) { + DEBUG_EVENT("%s: Error: Failed to del iface: TDM API Device in use!\n", + chan->if_name); + return -EBUSY; + } + + wan_spin_lock_irq(&card->wandev.lock,&flags); + aft_tdmv_if_free(card,chan); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + protocol_shutdown(card,dev); + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + if (wan_iface.detach){ + wan_iface.detach(dev, chan->common.is_netdev); + } +#endif + + /* We must set used by to API because + * the free_tx and free_rx are not allowed + * for TDM_VOICE mode in regular operation */ + + + wan_spin_lock_irq(&card->wandev.lock,&flags); + + chan->common.usedby = API; + + aft_free_tx_descriptors(chan); + aft_free_rx_descriptors(chan); + + for (i=0;ihw_iface.busdma_free(card->hw,&chan->rx_dma_chain_table[i]); + card->hw_iface.busdma_free(card->hw,&chan->tx_dma_chain_table[i]); + } + card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + card->hw_iface.busdma_tag_destroy( + card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS); + + WAN_IFQ_DMA_PURGE(&chan->wp_rx_free_list); + WAN_IFQ_DESTROY(&chan->wp_rx_free_list); + + WAN_IFQ_PURGE(&chan->wp_rx_complete_list); + WAN_IFQ_DESTROY(&chan->wp_rx_complete_list); + + WAN_IFQ_PURGE(&chan->wp_rx_stack_complete_list); + WAN_IFQ_DESTROY(&chan->wp_rx_stack_complete_list); + + WAN_IFQ_PURGE(&chan->wp_tx_pending_list); + WAN_IFQ_DESTROY(&chan->wp_tx_pending_list); + + WAN_IFQ_PURGE(&chan->wp_rx_bri_dchan_complete_list); + WAN_IFQ_DESTROY(&chan->wp_rx_bri_dchan_complete_list); + + WAN_IFQ_PURGE(&chan->wp_tx_complete_list); + WAN_IFQ_DESTROY(&chan->wp_tx_complete_list); + + if (chan->tx_idle_skb){ + wan_skb_free(chan->tx_idle_skb); + chan->tx_idle_skb=NULL; + } + + if (chan->tx_realign_buf){ + wan_free(chan->tx_realign_buf); + chan->tx_realign_buf=NULL; + } + + if (chan->tx_ss7_realign_buf){ + wan_free(chan->tx_ss7_realign_buf); + chan->tx_ss7_realign_buf=NULL; + } + + if (card->u.aft.tdmv_chan_ptr == chan){ + card->u.aft.tdmv_chan_ptr=NULL; + } + + chan->logic_ch_num=-1; + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + /* Delete interface name from proc fs. */ +#if 0 + wanrouter_proc_delete_interface(wandev, chan->if_name); +#endif + + /* Decrement the number of network interfaces + * configured on this card. + */ + wan_atomic_dec(&card->wandev.if_cnt); + if (chan->hdlc_eng){ + --card->u.aft.security_cnt; + } + + DEBUG_SUB_MEM(sizeof(private_area_t)); + return 0; +} + +static int del_if (wan_device_t* wandev, netdevice_t* dev) +{ + private_area_t* chan=wan_netif_priv(dev); + wan_smp_flag_t flags; + sdla_t *card; + int card_use_cnt=0; + + + if (!chan){ + DEBUG_EVENT("%s: Critical Error del_if() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + if (!(card=chan->card)){ + DEBUG_EVENT("%s: Critical Error del_if() chan=NULL!\n", + wan_netif_name(dev)); + return 0; + } + + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + + wan_spin_lock_irq(&card->wandev.lock,&flags); + aft_dev_close(card,chan); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + if (chan->channelized_cfg) { + + sdla_t *card=chan->card; + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (chan->tdmv_zaptel_cfg) { + sdla_t *card=chan->card; + int err; + WAN_TDMV_CALL(running, (card), err); + if (err){ + return -EBUSY; + } + } +#endif + + /* Disable the TDMV Interrupt first, before + * shutting down all TDMV channels */ + wan_spin_lock_irq(&card->wandev.lock,&flags); + + if (IS_BRI_CARD(card)) { + int card_use_cnt; + + card->wandev.state=WAN_DISCONNECTED; + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + if (card_use_cnt == 1) { + DEBUG_BRI("%s: BRI Disabling TDMV INTR\n", + card->devname); + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } else { + u32 dmareg; + /* By removing timeslot out of the global + interrupt we can disable the tdm global isr. + This code re-triggers it just in case */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,&dmareg); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),dmareg); + } + } else { + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } + + /* Disable RTP Tap */ + card->wandev.rtp_len=0; + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc) { + int err; + WAN_TDMV_CALL(state, (card, WAN_DISCONNECTED), err); + } +#endif + wan_spin_unlock_irq(&card->wandev.lock,&flags); + + while(chan){ + int err=del_if_private(wandev,dev); + if (err) { + return err; + } + if (chan->next) { + wan_netif_set_priv(dev, chan->next); + wan_free(chan); + chan = wan_netif_priv(dev); + } else { + /* Leave the last chan dev + * in dev->priv. It will get + * deallocated normally */ + break; + } + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc) { + aft_tdmv_free(card); + } +#endif + + return 0; + } else { + return del_if_private(wandev,dev); + } +} + + +/**SECTION*********************************************************** + * + * KERNEL Device Entry Interfaces + * + ********************************************************************/ + + + +/*============================================================================ + * if_init - Initialize Linux network interface. + * + * @dev: Network interface pointer + * + * During "ifconfig up" the upper layer calls this function + * to initialize dev access pointers. Such as transmit, + * stats and header. + * + * It is called only once for each interface, + * during Linux network interface registration. + * + * Returning anything but zero will fail interface + * registration. + */ +#if defined(__LINUX__) +static int if_init (netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card = chan->card; + wan_device_t* wandev = &card->wandev; +#if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + hdlc_device* hdlc; +#endif + + /* Initialize device driver entry points */ + dev->open = &if_open; + dev->stop = &if_close; +#if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + hdlc = dev_to_hdlc(dev); + hdlc->xmit = if_send; +#else + dev->hard_start_xmit = &if_send; +#endif + dev->get_stats = &if_stats; + +#if 0 + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = 2*HZ; +#else + if (chan->common.usedby == TDM_VOICE || + chan->common.usedby == TDM_VOICE_DCHAN || + chan->common.usedby == TDM_VOICE_API){ + dev->tx_timeout = NULL; + }else{ + dev->tx_timeout = &if_tx_timeout; + } + dev->watchdog_timeo = 2*HZ; + +#endif + dev->do_ioctl = if_do_ioctl; + + if (chan->common.usedby == BRIDGE || + chan->common.usedby == BRIDGE_NODE){ + + /* Setup the interface for Bridging */ + int hw_addr=0; + ether_setup(dev); + + /* Use a random number to generate the MAC address */ + memcpy(dev->dev_addr, "\xFE\xFC\x00\x00\x00\x00", 6); + get_random_bytes(&hw_addr, sizeof(hw_addr)); + *(int *)(dev->dev_addr + 2) += hw_addr; + + }else{ + + dev->flags |= IFF_POINTOPOINT; + dev->flags |= IFF_NOARP; + dev->type = ARPHRD_PPP; + dev->mtu = chan->mtu; + dev->hard_header_len = 0; + dev->hard_header = NULL; + dev->rebuild_header = NULL; + + if (chan->common.usedby == API || chan->common.usedby == STACK){ + if (chan->hdlc_eng) { + dev->mtu = chan->dma_mru+sizeof(api_tx_hdr_t); + }else{ + dev->mtu = chan->mtu+sizeof(api_tx_hdr_t); + } + } + + /* Enable Mulitcasting if user selected */ + if (chan->mc == WANOPT_YES){ + dev->flags |= IFF_MULTICAST; + } + + if (chan->true_if_encoding){ + DEBUG_EVENT("%s: Setting IF Type to Broadcast\n",chan->if_name); + dev->type = ARPHRD_PPP; /* This breaks the tcpdump */ + dev->flags &= ~IFF_POINTOPOINT; + dev->flags |= IFF_BROADCAST; + }else{ + dev->type = ARPHRD_PPP; + } + } + + /* Initialize hardware parameters */ + dev->irq = wandev->irq; + dev->dma = wandev->dma; + dev->base_addr = wandev->ioport; + card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &dev->mem_start); + card->hw_iface.getcfg(card->hw, SDLA_MEMEND, &dev->mem_end); + + /* Set transmit buffer queue length + * If too low packets will not be retransmitted + * by stack. + */ + dev->tx_queue_len = 100; + return 0; +} +#endif + +/*============================================================================ + * if_open - Open network interface. + * + * @dev: Network device pointer + * + * On ifconfig up, this function gets called in order + * to initialize and configure the private area. + * Driver should be configured to send and receive data. + * + * This functions starts a timer that will call + * frmw_config() function. This function must be called + * because the IP addresses could have been changed + * for this interface. + * + * Return 0 if O.k. or errno. + */ +static int if_open (netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card = chan->card; + + + +#if defined(__LINUX__) + /* Only one open per interface is allowed */ + if (open_dev_check(dev)){ + DEBUG_EVENT("%s: Open dev check failed!\n", + wan_netif_name(dev)); + return -EBUSY; + } +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s:%s: Card down: Failed to open interface!\n", + card->devname,chan->if_name); + return -EINVAL; + } + + + /* Initialize the router start time. + * Used by wanpipemon debugger to indicate + * how long has the interface been up */ + wan_getcurrenttime(&chan->router_start_time, NULL); + +#if !defined(WANPIPE_IFNET_QUEUE_POLICY_INIT_OFF) + WAN_NETIF_START_QUEUE(dev); +#endif + + if (card->wandev.state == WAN_CONNECTED){ + set_chan_state(card, dev, WAN_CONNECTED); + WAN_NETIF_CARRIER_ON(dev); + } else { + WAN_NETIF_CARRIER_OFF(dev); + } + + /* Increment the module usage count */ + wanpipe_open(card); + + + /* Wait for the front end interrupt + * before enabling the card */ + return 0; +} + +/*============================================================================ + * if_close - Close network interface. + * + * @dev: Network device pointer + * + * On ifconfig down, this function gets called in order + * to cleanup interace private area. + * + * IMPORTANT: + * + * No deallocation or unconfiguration should ever occur in this + * function, because the interface can come back up + * (via ifconfig up). + * + * Furthermore, in dynamic interfacace configuration mode, the + * interface will come up and down to reflect the protocol state. + * + * Any deallocation and cleanup can occur in del_if() + * function. That function is called before the dev interface + * itself is deallocated. + * + * Thus, we should only stop the net queue and decrement + * the wanpipe usage counter via wanpipe_close() function. + */ + +static int if_close (netdevice_t* dev) +{ + private_area_t* chan = wan_netif_priv(dev); + sdla_t* card = chan->card; + + WAN_NETIF_STOP_QUEUE(dev); + +#if defined(LINUX_2_1) + dev->start=0; +#endif + protocol_stop(card,dev); + + wanpipe_close(card); + + return 0; +} + + +/*============================================================= + * disable_comm - Main shutdown function + * + * @card: Wanpipe device pointer + * + * The command 'wanrouter stop' has been called + * and the whole wanpipe device is going down. + * This is the last function called to disable + * all comunications and deallocate any memory + * that is still allocated. + * + * o Disable communications, turn off interrupts + * o Deallocate memory used, if any + * o Unconfigure TE1 card + */ + +static void disable_comm (sdla_t *card) +{ + wan_smp_flag_t smp_flags,smp_flags1; + int used_cnt; + + AFT_FUNC_DEBUG(); +#if INIT_FE_ONLY + aft_chip_unconfigure(card); +#else + + /* Unconfiging, only on shutdown */ + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + __aft_fe_intr_ctrl(card, 0); + if (card->wandev.fe_iface.unconfig){ + card->wandev.fe_iface.unconfig(&card->fe); + } + __aft_fe_intr_ctrl(card, 1); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + + /* Disable DMA ENGINE before we perform + * core reset. Otherwise, we will receive + * rx fifo errors on subsequent resetart. */ + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + disable_data_error_intr(card,LINK_DOWN); +#if defined(AFT_RTP_SUPPORT) + aft_rtp_unconfig(card); +#endif + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + aft_chip_unconfigure(card); + + /* Only disable the irq completely once the + chip unconfigure is executed */ + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + disable_data_error_intr(card,DEVICE_DOWN); + wan_set_bit(CARD_DOWN,&card->wandev.critical); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + + WP_DELAY(10); + + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &used_cnt); + + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + __aft_fe_intr_ctrl(card, 0); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_ON); + __aft_fe_intr_ctrl(card, 1); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + + __sdla_pull_ptr_isr_array(card->hw,card,card->wandev.comm_port); + + if (used_cnt<=1){ + DEBUG_EVENT("%s: Global Chip Shutdown Usage=%d\n", + card->devname,used_cnt); + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + aft_global_chip_disable(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + } + + +#if defined(WAN_DEBUG_MEM) + DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); +#endif +#endif + return; +} + + + +/*============================================================================ + * if_tx_timeout + * + * Kernel networking stack calls this function in case + * the interface has been stopped for TX_TIMEOUT seconds. + * + * This would occur if we lost TX interrupts or the + * card has stopped working for some reason. + * + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout (netdevice_t *dev) +{ + private_area_t* chan = wan_netif_priv(dev); + private_area_t* ch_ptr; + sdla_t *card = chan->card; + unsigned int cur_dma_ptr; + u32 reg,dma_ram_desc; + wan_smp_flag_t smp_flags; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + WAN_NETIF_STATS_INC_COLLISIONS(&chan->common); //++chan->if_stats.collisions; + + DEBUG_EVENT( "%s: Transmit timed out on %s\n", + card->devname, + wan_netif_name(dev)); + + dma_ram_desc=chan->logic_ch_num*4+AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + + DEBUG_EVENT("%s: Chain TxPend=%d, TxCur=%d, TxPend=%d HwCur=%d TxA=%d TxC=%ld\n", + chan->if_name, + wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status), + chan->tx_chain_indx, + chan->tx_pending_chain_indx, + cur_dma_ptr, + chan->tx_attempts, + WAN_NETIF_STATS_TX_PACKETS(&chan->common)); + + if (wan_test_bit(TX_DMA_BUSY,&chan->dma_status)){ + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + } + + wan_netif_set_ticks(dev, SYSTEM_TICKS); + +#ifdef AFT_TX_FIFO_DEBUG + aft_list_tx_descriptors(chan); +#endif + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + if (chan->channelized_cfg){ + for (ch_ptr=chan;ch_ptr;ch_ptr=ch_ptr->next){ + aft_tx_fifo_under_recover(card,chan); + } + }else{ + aft_tx_fifo_under_recover(card,chan); + } + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + +#ifdef AFT_TX_FIFO_DEBUG + aft_list_tx_descriptors(chan); +#endif + + wanpipe_wake_stack(chan); + +} + + +/*============================================================================ + * if_send - Send a packet on a network interface. + * + * @dev: Network interface pointer + * @skb: Packet obtained from the stack or API + * that should be sent out the port. + * + * o Mark interface as stopped + * (marks start of the transmission) to indicate + * to the stack that the interface is busy. + * + * o Check link state. + * If link is not up, then drop the packet. + * + * o Copy the tx packet into the protocol tx buffers on + * the adapter. + * + * o If tx successful: + * Free the skb buffer and mark interface as running + * and return 0. + * + * o If tx failed, busy: + * Keep interface marked as busy + * Do not free skb buffer + * Enable Tx interrupt (which will tell the stack + * that interace is not busy) + * Return a non-zero value to tell the stack + * that the tx should be retried. + * + * Return: 0 complete (socket buffer must be freed) + * non-0 packet may be re-transmitted + * + */ + +#if defined(__LINUX__) +static int if_send (netskb_t* skb, netdevice_t* dev) +#else +static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct rtentry *rt) +#endif +{ + private_area_t *chan = wan_netif_priv(dev); + sdla_t *card = chan->card; + int err; + netskb_t *rskb=NULL; + wan_smp_flag_t smp_flags; + + /* Mark interface as busy. The kernel will not + * attempt to send any more packets until we clear + * this condition */ + + if (skb == NULL){ + /* This should never happen. Just a sanity check. + */ + DEBUG_EVENT( "%s: interface %s got kicked!\n", + card->devname, + wan_netif_name(dev)); + + WAN_NETIF_WAKE_QUEUE(dev); + return 0; + } + + DEBUG_TX("%s: Sending %d bytes\n", wan_netif_name(dev), wan_skb_len(skb)); + /* Non 2.4 kernels used to call if_send() + * after TX_TIMEOUT seconds have passed of interface + * being busy. Same as if_tx_timeout() in 2.4 kernels */ +#if defined(LINUX_2_1) + if (dev->tbusy){ + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + WAN_NETIF_STATS_COLLISIONS(&chan->common); //++chan->if_stats.collisions; + if((SYSTEM_TICKS - chan->tick_counter) < (5 * HZ)) { + return 1; + } + + if_tx_timeout(dev); + } +#endif + err=0; + + if (chan->common.state != WAN_CONNECTED){ + +#if 1 + WAN_NETIF_STOP_QUEUE(dev); + wan_netif_set_ticks(dev, SYSTEM_TICKS); + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); //++chan->if_stats.tx_carrier_errors; + return 1; +#else + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); //++chan->if_stats.tx_carrier_errors; + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; +#endif + } + + DEBUG_BRI_DCHAN("chan->channelized_cfg: %d\n", chan->channelized_cfg); + + if (chan->channelized_cfg) { + + private_area_t *top_chan=wan_netif_priv(chan->common.dev); + + DEBUG_TEST("%s:%ld Prev: Zaptel HDLC Tt TDMV_DCHAN=%i\n", + chan->if_name,chan->logic_ch_num, + card->u.aft.tdmv_dchan-1); + + if (!card->u.aft.tdmv_dchan || card->u.aft.tdmv_dchan>32){ + + DEBUG_EVENT("%s: DCHAN TX No DCHAN Configured!\n", + card->devname); + + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + if(IS_BRI_CARD(card)) { + chan=(private_area_t*)card->u.aft.dev_to_ch_map[BRI_DCHAN_LOGIC_CHAN]; + }else{ + chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; + } + + if (!chan){ + DEBUG_EVENT("%s: Warning: DCHAN TX: No DCHAN Configured (not preset)! Discarding data.\n", + card->devname); + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + DEBUG_BRI_DCHAN("chan->dchan_time_slot: %d\n", chan->dchan_time_slot); + + if (!chan->hdlc_eng || (IS_BRI_CARD(card) && chan->dchan_time_slot < 0)){ + wan_skb_free(skb); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + wan_capture_trace_packet(chan->card, &top_chan->trace_info, + skb,TRC_OUTGOING_FRM); + + DEBUG_TEST("%s:%ld Zaptel HDLC Tt TDMV_DCHAN=%i\n", + chan->if_name,chan->logic_ch_num, + card->u.aft.tdmv_dchan-1); + } + + /* For TDM_VOICE_API no tx is supported in if_send */ + if (chan->common.usedby == TDM_VOICE_API){ + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); + WAN_NETIF_START_QUEUE(dev); + + err=0; + goto if_send_exit_crit; + } + + if (chan->common.usedby == API){ + + if (sizeof(api_tx_hdr_t) >= wan_skb_len(skb)){ + + wan_skb_free(skb); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + if (chan->cfg.ss7_enable) { + err=aft_ss7_tx_mangle(card,chan,skb); + if (err){ + wan_skb_free(skb); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + } else if (chan->cfg.hdlc_repeat) { + err=aft_hdlc_repeat_mangle(card,chan,skb,&rskb); + if (err){ + wan_skb_free(skb); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + } else { + wan_skb_pull(skb,sizeof(api_tx_hdr_t)); + } + } + + if (!chan->hdlc_eng && chan->tslot_sync){ + if (wan_skb_len(skb)%chan->num_of_time_slots){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error pkt len(%d) not multiple of timeslots(%d)\n", + card->devname, + chan->if_name, + wan_skb_len(skb), + chan->num_of_time_slots); + } + wan_skb_free(skb); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + } + + if (!chan->hdlc_eng && !chan->lip_atm && (wan_skb_len(skb)%4)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Tx Error: Tx Length %i is not 32bit divisible\n", + chan->if_name,wan_skb_len(skb)); + } + wan_skb_free(skb); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; + WAN_NETIF_START_QUEUE(dev); + err=0; + goto if_send_exit_crit; + } + + if(IS_BRI_CARD(card)){ + if(chan->dchan_time_slot >= 0){ + + /* NOTE: BRI dchan tx has to be done inside hw lock. + It allows to synchronize access to SPI on the card. + */ + card->hw_iface.hw_lock(card->hw,&smp_flags); + + err=aft_bri_dchan_transmit(card, chan, + wan_skb_data(skb), + wan_skb_len(skb)); + + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + if (err == 0 ) { + WAN_NETIF_START_QUEUE(dev); + wan_skb_free(skb); + err=0; + goto if_send_exit_crit; + }else{ + err=1; + WAN_NETIF_STOP_QUEUE(dev); + goto if_send_exit_crit; + } + } else { + /* On b-channel data is transmitted using AFT DMA. + Drop down to code below */ + } + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + + if (wan_skb_queue_len(&chan->wp_tx_pending_list) > chan->max_tx_bufs){ + WAN_NETIF_STOP_QUEUE(dev); + aft_dma_tx(card,chan); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + return 1; + } + + wan_skb_unlink(skb); + + wan_skb_queue_tail(&chan->wp_tx_pending_list,skb); + + if(!chan->lip_atm){ + aft_dma_tx(card,chan); /*not needed for LIP_ATM!!*/ + } + + if (rskb) { + wan_skb_queue_tail(&chan->wp_tx_hdlc_rpt_list,rskb); + } + + wan_netif_set_ticks(dev, SYSTEM_TICKS); + WAN_NETIF_START_QUEUE(dev); + err=0; + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + +#if defined(__LINUX__) + if (dev->tx_queue_len < chan->max_tx_bufs && + dev->tx_queue_len > 0) { + DEBUG_EVENT("%s: Resizing Tx Queue Len to %li\n", + chan->if_name,dev->tx_queue_len); + chan->max_tx_bufs = dev->tx_queue_len; + } + + if (dev->tx_queue_len > chan->max_tx_bufs && + chan->max_tx_bufs != chan->max_tx_bufs_orig) { + DEBUG_EVENT("%s: Resizing Tx Queue Len to %i\n", + chan->if_name,chan->max_tx_bufs_orig); + chan->max_tx_bufs = chan->max_tx_bufs_orig; + } +#endif + +if_send_exit_crit: + + return err; +} + +/*============================================================================ + * if_stats + * + * Used by /proc/net/dev and ifconfig to obtain interface + * statistics. + * + * Return a pointer to struct net_device_stats. + */ +#if defined(__LINUX__) +static struct net_device_stats gstats; +static struct net_device_stats* if_stats (netdevice_t* dev) +{ + private_area_t* chan; + sdla_t *card; + + if ((chan=wan_netif_priv(dev)) == NULL) + return &gstats; + + card=chan->card; + +#if !defined(AFT_IRQ_DEBUG) + if (card) { +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc && + card->wandev.state == WAN_CONNECTED && + card->wandev.config_id != WANCONFIG_AFT_ANALOG && + chan->common.usedby == TDM_VOICE) { + chan->common.if_stats.rx_packets = card->wandev.stats.rx_packets; + chan->common.if_stats.tx_packets = card->wandev.stats.tx_packets; + } +#endif + } +#endif + + return &chan->common.if_stats; + +} +#endif + +/*======================================================================== + * + * if_do_ioctl - Ioctl handler for fr + * + * @dev: Device subject to ioctl + * @ifr: Interface request block from the user + * @cmd: Command that is being issued + * + * This function handles the ioctls that may be issued by the user + * to control or debug the protocol or hardware . + * + * It does both busy and security checks. + * This function is intended to be wrapped by callers who wish to + * add additional ioctl calls of their own. + * + * Used by: SNMP Mibs + * wanpipemon debugger + * + */ +static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +{ + private_area_t* chan= (private_area_t*)wan_netif_priv(dev); + sdla_t *card; + wan_smp_flag_t smp_flags; + wan_udp_pkt_t *wan_udp_pkt; + int err=-EOPNOTSUPP; + + if (!chan || !chan->card){ + DEBUG_EVENT("%s:%d: No Chan of card ptr\n", + __FUNCTION__,__LINE__); + return -ENODEV; + } + card=chan->card; + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s: Card down: Ignoring Ioctl call!\n", + card->devname); + return -ENODEV; + } + + switch(cmd) + { +#if defined(__LINUX__) + case SIOC_WANPIPE_BIND_SK: + if (!ifr){ + err= -EINVAL; + break; + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + err=wan_bind_api_to_svc(chan,ifr->ifr_data); + WAN_NETIF_STATS_RX_DROPPED(&chan->common)=0; //chan->if_stats.rx_dropped=0; + if (!chan->hdlc_eng){ + WAN_NETIF_STATS_TX_CARRIER_ERRORS(&chan->common)=0; //chan->if_stats.tx_carrier_errors=0; + } + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + break; + + case SIOC_WANPIPE_UNBIND_SK: + if (!ifr){ + err= -EINVAL; + break; + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + err=wan_unbind_api_from_svc(chan,ifr->ifr_data); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + + break; + + case SIOC_WANPIPE_CHECK_TX: + case SIOC_ANNEXG_CHECK_TX: + err=0; + break; + + case SIOC_WANPIPE_DEV_STATE: + err = chan->common.state; + break; + + case SIOC_ANNEXG_KICK: + err=0; + break; + + case SIOC_AFT_SS7_FORCE_RX: + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + aft_set_ss7_force_rx(card,chan); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + break; +#endif + +#if defined(AFT_API_SUPPORT) + case SIOC_WANPIPE_API: + DEBUG_TEST("%s: WANPIPE API IOCTL!\n", card->devname); + err = wan_aft_api_ioctl(card,chan,ifr->ifr_data); + break; +#endif + + case SIOC_WAN_DEVEL_IOCTL: + err = aft_devel_ioctl(card, ifr); + break; + + case SIOC_AFT_CUSTOMER_ID: + if (!ifr){ + return -EINVAL; + } else { + unsigned char cid=0; + wan_smp_flag_t smp_flags1; + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + cid=aft_read_cpld(card,CUSTOMER_CPLD_ID_REG); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + return WAN_COPY_TO_USER(ifr->ifr_data,&cid,sizeof(unsigned char)); + } + err=0; + break; + +#if defined(__LINUX__) + case SIOC_WANPIPE_GET_DEVICE_CONFIG_ID: + err=card->wandev.config_id; + break; +#endif + case SIOC_WANPIPE_SNMP: + case SIOC_WANPIPE_SNMP_IFSPEED: + return wan_snmp_data(card, dev, cmd, ifr); + + case SIOC_WANPIPE_PIPEMON: + + NET_ADMIN_CHECK(); + + if (wan_atomic_read(&chan->udp_pkt_len) != 0){ + return -EBUSY; + } + + wan_atomic_set(&chan->udp_pkt_len,MAX_LGTH_UDP_MGNT_PKT); + + /* For performance reasons test the critical + * here before spin lock */ + if (wan_test_bit(0,&card->in_isr)){ + wan_atomic_set(&chan->udp_pkt_len,0); + return -EBUSY; + } + + + wan_udp_pkt=(wan_udp_pkt_t*)chan->udp_pkt_data; + if (WAN_COPY_FROM_USER( + &wan_udp_pkt->wan_udp_hdr, + ifr->ifr_data, + sizeof(wan_udp_hdr_t))){ + wan_atomic_set(&chan->udp_pkt_len,0); + return -EFAULT; + } + + /* We have to check here again because we don't know + * what happened during spin_lock */ + if (wan_test_bit(0,&card->in_isr)) { + DEBUG_EVENT( "%s:%s Pipemon command failed, Driver busy: try again.\n", + card->devname, + wan_netif_name(dev)); + wan_atomic_set(&chan->udp_pkt_len,0); + return -EBUSY; + } + + process_udp_mgmt_pkt(card,dev,chan,1); + + /* This area will still be critical to other + * PIPEMON commands due to udp_pkt_len + * thus we can release the irq */ + + if (wan_atomic_read(&chan->udp_pkt_len) > sizeof(wan_udp_pkt_t)){ + DEBUG_EVENT( "%s: Error: Pipemon buf too bit on the way up! %d\n", + card->devname,wan_atomic_read(&chan->udp_pkt_len)); + wan_atomic_set(&chan->udp_pkt_len,0); + return -EINVAL; + } + + if (WAN_COPY_TO_USER( + ifr->ifr_data, + &wan_udp_pkt->wan_udp_hdr, + sizeof(wan_udp_hdr_t))){ + wan_atomic_set(&chan->udp_pkt_len,0); + return -EFAULT; + } + + wan_atomic_set(&chan->udp_pkt_len,0); + return 0; + +#if 0 + case SIOC_WAN_EC_IOCTL: + if (wan_test_and_set_bit(CARD_HW_EC,&card->wandev.critical)){ + DEBUG_EVENT("%s: Error: EC IOCTL Reentrant!\n", + card->devname); + return -EBUSY; + } + if (card->wandev.ec){ + err = wan_ec_ioctl(card->wandev.ec, ifr, card); + }else{ + err = -EINVAL; + } + wan_clear_bit(CARD_HW_EC,&card->wandev.critical); + break; +#endif + +/* + case SIOC_WAN_FE_IOCTL: + DEBUG_TEST("%s: Command %x not supported!\n", + card->devname,cmd); + return -EOPNOTSUPP; + break; +*/ + default: +#ifndef WANPIPE_GENERIC + DEBUG_TEST("%s: Command %x not supported!\n", + card->devname,cmd); + return -EOPNOTSUPP; +#else + if (card->wandev.ioctl){ + err = card->wandev.hdlc_ioctl(card, dev, ifr, cmd); + } +#endif + } + + return err; +} + + +/**SECTION********************************************************** + * + * FIRMWARE Specific Interface Functions + * + *******************************************************************/ + + +#define FIFO_RESET_TIMEOUT_CNT 1000 +#define FIFO_RESET_TIMEOUT_US 10 +static int aft_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char wait) +{ + + u32 reg; + u32 dma_descr; + u8 timeout=1; + u16 i; + unsigned int cur_dma_ptr; + u32 dma_ram_desc; + + /* Clean RX DMA fifo */ + + if (chan->single_dma_chain){ + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_rx_dma_addr(®,0); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + }else{ + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + dma_descr=(chan->logic_ch_num<<4) + (cur_dma_ptr*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + } + + reg=0; + wan_set_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®); + + DEBUG_TEST("%s: Clearing RX Fifo %s Ch=%ld DmaDescr=(0x%X) Reg=(0x%X) WAIT=%s\n", + __FUNCTION__,chan->if_name,chan->logic_ch_num, + dma_descr,reg,wait == WP_WAIT?"YES":"NO"); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + if (wait == WP_WAIT){ + for(i=0;ihw_iface.bus_read_4(card->hw,dma_descr,®); + if (wan_test_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®)){ + WP_DELAY(FIFO_RESET_TIMEOUT_US); + continue; + } + timeout=0; + break; + } + + if (timeout){ + DEBUG_EVENT("%s:%s: Error: Rx fifo reset timedout %u us (ch=%ld)\n", + card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US, + chan->logic_ch_num); + }else{ + DEBUG_TEST("%s:%s: Rx Fifo Reset Successful\n", + card->devname,chan->if_name); + } + }else{ + timeout=0; + } + + return timeout; +} + +static int aft_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char wait) +{ + u32 reg; + u32 dma_descr,dma_ram_desc; + u8 timeout=1; + u16 i; + unsigned int cur_dma_ptr; + + if (chan->single_dma_chain){ + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_tx_dma_addr(®,0); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + }else{ + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + + /* Clean TX DMA fifo */ + dma_descr=(chan->logic_ch_num<<4) + (cur_dma_ptr*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + } + + reg=0; + wan_set_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®); + + + DEBUG_TEST("%s: Clearing TX Fifo %s Ch=%ld DmaDescr=(0x%X) Reg=(0x%X) WAIT=%s\n", + __FUNCTION__,chan->if_name,chan->logic_ch_num, + dma_descr,reg,wait == WP_WAIT?"YES":"NO"); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + if (wait == WP_WAIT){ + for(i=0;ihw_iface.bus_read_4(card->hw,dma_descr,®); + if (wan_test_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®)){ + WP_DELAY(FIFO_RESET_TIMEOUT_US); + continue; + } + timeout=0; + break; + } + + if (timeout){ + DEBUG_EVENT("%s:%s: Error: Tx fifo reset timedout %u us (ch=%ld)\n", + card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US, + chan->logic_ch_num); + }else{ + DEBUG_TEST("%s:%s: Tx Fifo Reset Successful\n", + card->devname,chan->if_name); + } + }else{ + timeout=0; + } + + return timeout; +} + +static void aft_channel_txdma_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + /* Enable TX DMA for Logic Channel */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_CTRL_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_CTRL_REG), reg); + +} +static void aft_channel_rxdma_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + /* Enable TX DMA for Logic Channel */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_CTRL_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_CTRL_REG), reg); + +} + +static void aft_channel_txintr_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + + /* Enable Logic Channel TX Interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_INTR_MASK_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + + } + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_INTR_MASK_REG), reg); +} + +static void aft_channel_rxintr_ctrl(sdla_t *card, private_area_t *chan, int on) +{ + u32 reg; + + /* Enable Logic Channel TX Interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_INTR_MASK_REG), ®); + if (on){ + wan_set_bit(chan->logic_ch_num,®); + }else{ + wan_clear_bit(chan->logic_ch_num,®); + + } + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_INTR_MASK_REG), reg); +} + + +static void aft_dev_enable(sdla_t *card, private_area_t *chan) +{ + DEBUG_TEST("%s: Enabling Global Inter Mask !\n",chan->if_name); + + /* Enable TX DMA for Logic Channel */ + aft_channel_txdma_ctrl(card,chan,1); + + /* Enable RX DMA for Logic Channel */ + aft_channel_rxdma_ctrl(card,chan,1); + + /* Enable Logic Channel TX Interrupts */ + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_channel_txintr_ctrl(card,chan,0); + aft_channel_rxintr_ctrl(card,chan,0); + chan->tdmv_irq_cfg=1; + }else{ + aft_channel_txintr_ctrl(card,chan,1); + aft_channel_rxintr_ctrl(card,chan,1); + } + + wan_set_bit(chan->logic_ch_num,&card->u.aft.active_ch_map); +} + +static void aft_dev_open_private(sdla_t *card, private_area_t *chan) +{ + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + /* BRI dchan does not use DMA thus + skip the dma config code below */ + return; + } + + if (card->wandev.state == WAN_CONNECTED && + wan_test_bit(0,&card->u.aft.comm_enabled)){ + + DEBUG_TEST("%s: OPEN reseting fifo Channel = %li\n", + chan->if_name,chan->logic_ch_num); + + aft_tslot_sync_ctrl(card,chan,0); + + aft_init_rx_dev_fifo(card,chan,WP_NO_WAIT); + aft_init_tx_dev_fifo(card,chan,WP_NO_WAIT); + + aft_dev_enable(card,chan); + + aft_init_rx_dev_fifo(card,chan,WP_WAIT); + aft_init_tx_dev_fifo(card,chan,WP_WAIT); + + chan->dma_index=0; + memset(chan->dma_history,0,sizeof(chan->dma_history)); + + aft_reset_rx_chain_cnt(chan); + aft_dma_rx(card,chan); + + aft_tslot_sync_ctrl(card,chan,1); + + if (!chan->hdlc_eng){ + aft_reset_tx_chain_cnt(chan); + aft_dma_tx(card,chan); + } + }else{ + aft_dev_enable(card,chan); + } + +} + +static void aft_dev_open(sdla_t *card, private_area_t *gchan) +{ + private_area_t *chan=gchan; + + if (chan->channelized_cfg){ + + for (chan=gchan; chan != NULL; chan=chan->next){ + + aft_dev_open_private(card,chan); + + wan_set_bit(0,&chan->up); + + } + + if (gchan->common.usedby == TDM_VOICE_API){ + /* Set the global mtu value which is + * the sum of all timeslots mtus */ + wan_netif_set_mtu( + gchan->common.dev, + card->u.aft.tdmv_mtu+sizeof(api_tx_hdr_t)); + + } + + wan_set_bit(0,&card->u.aft.tdmv_master_if_up); + + if (card->wandev.state == WAN_CONNECTED && + !wan_test_bit(0,&card->u.aft.comm_enabled)){ + DEBUG_EVENT("%s: Master IF Starting %s Communications\n", + gchan->if_name,card->devname); + enable_data_error_intr(card); + } + }else{ + aft_dev_open_private(card,chan); + wan_set_bit(0,&chan->up); + } + + + if (gchan->cfg.ss7_enable){ + aft_clear_ss7_force_rx(card,gchan); + } + + return; +} + +static void aft_dev_close_private(sdla_t *card, private_area_t *chan) +{ + + if (chan->logic_ch_num < 0){ + return; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + /* BRI dchan does not use DMA thus + skip the dma config code below */ + return; + } + + DEBUG_TEST("%s: Chan=%i\n",__FUNCTION__,chan->logic_ch_num); + + /* Disable Logic Channel TX Interrupts */ + aft_channel_txintr_ctrl(card,chan,0); + + /* Disable Logic Channel RX Interrupts */ + aft_channel_rxintr_ctrl(card,chan,0); + + /* Disable TX DMA for Logic Channel */ + aft_channel_txdma_ctrl(card,chan,0); + + /* Disable RX DMA for Logic Channel */ + aft_channel_rxdma_ctrl(card,chan,0); + + /* Initialize DMA descriptors and DMA Chains */ + aft_init_tx_rx_dma_descr(chan); + +} + + +static void aft_dev_close(sdla_t *card, private_area_t *gchan) +{ + private_area_t *chan=gchan; + + if (chan->channelized_cfg){ + + if (IS_BRI_CARD(card)) { + int card_use_cnt; + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + if (card_use_cnt == 1) { + DEBUG_TEST("%s: BRI Disabling TDMV INTR\n", + card->devname); + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } + } else { + aft_tdm_intr_ctrl(card,0); + aft_fifo_intr_ctrl(card, 0); + } + + for (chan=gchan; chan != NULL; chan=chan->next){ + + aft_dev_close_private(card,chan); + + DEBUG_TEST("%s: Closing Ch=%ld\n", + chan->if_name,chan->logic_ch_num); + + wan_clear_bit(0,&chan->up); + wan_set_bit(0,&chan->interface_down); + if (chan->cfg.tdmv_master_if){ + wan_clear_bit(0,&card->u.aft.tdmv_master_if_up); + } + + DEBUG_TEST("%s: Closing Ch=%ld MasterUP=%i\n", + chan->if_name,chan->logic_ch_num, + wan_test_bit(0,&card->u.aft.tdmv_master_if_up)); + } + }else{ + wan_set_bit(0,&chan->interface_down); + wan_clear_bit(0,&chan->up); + aft_dev_close_private(card,chan); + + + } + return; +} + +/**SECTION************************************************************* + * + * TX Handlers + * + **********************************************************************/ + + +/*=============================================== + * aft_dma_tx_complete + * + */ +static void aft_dma_tx_complete (sdla_t *card, private_area_t *chan, int wdt, int reset) +{ + DEBUG_TEST("%s: Tx interrupt wdt=%d\n",chan->if_name,wdt); + + if (!wdt){ + wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_tx_dma_voice_handler((unsigned long)chan,wdt,reset); + }else{ + aft_tx_dma_chain_handler((unsigned long)chan,wdt,reset); + } + + wan_set_bit(0,&chan->idle_start); + + if (reset){ + return; + } + + aft_dma_tx(card,chan); + + if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ + /* Wakeup stack also wakes up DCHAN, + however, for DCHAN we must always + call the upper layer and let it decide + what to do */ + wanpipe_wake_stack(chan); + } else if (chan->common.usedby == TDM_VOICE_DCHAN){ +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)){ + wanpipe_tdm_api_kick(&chan->wp_tdm_api_dev); + } +#endif + } + + return; +} + +/*=============================================== + * aft_tx_post_complete + * + */ +static void +aft_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb) +{ + unsigned int reg = wan_skb_csum(skb); + u32 dma_status = aft_txdma_hi_get_dma_status(reg); + + wan_skb_set_csum(skb,0); + + if (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK){ + chan->errstats.Tx_dma_len_nonzero++; + } + + if ((wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)) || + (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK) || + dma_status){ + + DEBUG_TEST("%s:%s: Tx DMA Descriptor=0x%X\n", + card->devname,chan->if_name,reg); + + /* Checking Tx DMA Go bit. Has to be '0' */ + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + DEBUG_TEST("%s:%s: Error: TxDMA Intr: GO bit set on Tx intr\n", + card->devname,chan->if_name); + chan->errstats.Tx_dma_errors++; + } + + if (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK){ + DEBUG_EVENT("%s:%s: Error: TxDMA Length not equal 0 (reg=0x%08X)\n", + card->devname,chan->if_name,reg); + chan->errstats.Tx_dma_errors++; + } + + /* Checking Tx DMA PCI error status. Has to be '0's */ + if (dma_status){ + + chan->errstats.Tx_pci_errors++; + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_M_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Master: pci fatal error!\n", + card->devname,chan->if_name); + } + + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Target: pci fatal error!\n", + card->devname,chan->if_name); + } + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ + DEBUG_TEST("%s:%s: Tx Warning: PCI Latency Timeout!\n", + card->devname,chan->if_name); + chan->errstats.Tx_pci_latency++; + goto tx_post_ok; + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", + card->devname,chan->if_name); + } + } + } + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; + goto tx_post_exit; + } + +tx_post_ok: + + chan->opstats.Data_frames_Tx_count++; + chan->opstats.Data_bytes_Tx_count+=wan_skb_len(skb); + WAN_NETIF_STATS_INC_TX_PACKETS(&chan->common); //chan->if_stats.tx_packets++; + WAN_NETIF_STATS_INC_TX_BYTES(&chan->common, wan_skb_len(skb)); //chan->if_stats.tx_bytes+=wan_skb_len(skb); + +#if 0 + if (chan->common.usedby != TDM_VOICE){ + wan_capture_trace_packet(card, &chan->trace_info, skb, TRC_OUTGOING_FRM); + } +#endif + +tx_post_exit: + + return; +} + + + +/**SECTION************************************************************* + * + * RX Handlers + * + **********************************************************************/ + + +/*=============================================== + * aft_rx_post_complete + * + */ +static void aft_rx_post_complete (sdla_t *card, private_area_t *chan, + netskb_t *skb, + netskb_t **new_skb, + unsigned char *pkt_error) +{ + + unsigned int len,data_error = 0; + unsigned char *buf; + wp_rx_element_t *rx_el; + u32 dma_status; + rx_el=(wp_rx_element_t *)wan_skb_data(skb); + + DEBUG_RX("%s:%s: RX HI=0x%X LO=0x%X DMA=0x%X", + __FUNCTION__, + chan->if_name, + rx_el->reg, + rx_el->align, + rx_el->dma_addr); + +#if 0 + /* debugging */ + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; +#endif + + rx_el->align&=AFT_RXDMA_LO_ALIGN_MASK; + *pkt_error=0; + *new_skb=NULL; + + dma_status=aft_rxdma_hi_get_dma_status(rx_el->reg); + + /* Checking Rx DMA Go bit. Has to be '0' */ + if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: Error: RxDMA Intr: GO bit set on Rx intr\n", + card->devname,chan->if_name); + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; + chan->errstats.Rx_dma_descr_err++; + goto rx_comp_error; + } + + /* Checking Rx DMA PCI error status. Has to be '0's */ + if (dma_status){ + + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_M_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Master: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Target: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: No 'DeviceSelect' from target: pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + if (wan_test_bit(AFT_RXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Rx Error: 'Retry' exceeds maximum (64k): pci fatal error 0x%X!\n", + card->devname,chan->if_name,rx_el->reg); + } + } + + chan->errstats.Rx_pci_errors++; + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + } + + if (chan->hdlc_eng){ + + /* Checking Rx DMA Frame start bit. (information for api) */ + if (!wan_test_bit(AFT_RXDMA_HI_START_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s RxDMA Intr: Start flag missing: MTU Mismatch! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->opstats.Rx_Data_discard_long_count++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + } + + /* Checking Rx DMA Frame end bit. (information for api) */ + if (!wan_test_bit(AFT_RXDMA_HI_EOF_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: End flag missing: MTU Mismatch! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->opstats.Rx_Data_discard_long_count++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_errors++; + goto rx_comp_error; + + } else { /* Check CRC error flag only if this is the end of Frame */ + + if (wan_test_bit(AFT_RXDMA_HI_FCS_ERR_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: CRC Error! Reg=0x%X Len=%d\n", + card->devname,chan->if_name,rx_el->reg, + (rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK)>>2); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_crc_err_count++; + card->wandev.stats.rx_crc_errors++; + wan_set_bit(WP_CRC_ERROR_BIT,&rx_el->pkt_error); + data_error = 1; + } + + /* Check if this frame is an abort, if it is + * drop it and continue receiving */ + if (wan_test_bit(AFT_RXDMA_HI_FRM_ABORT_BIT,&rx_el->reg)){ + DEBUG_TEST("%s:%s: RxDMA Intr: Abort! Reg=0x%X\n", + card->devname,chan->if_name,rx_el->reg); + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_frame_errors++; + wan_set_bit(WP_ABORT_ERROR_BIT,&rx_el->pkt_error); + data_error = 1; + } + + if (chan->common.usedby != API && data_error){ + goto rx_comp_error; + } + } + } + + len = rx_el->len; +#if 0 + /* FIXME: Remove this later!!! */ + len=rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK; + + if (chan->hdlc_eng){ + /* In HDLC mode, calculate rx length based + * on alignment value, received from DMA */ + len=((((chan->dma_mru>>2)-1)-len)<<2) - (~(rx_el->align)&AFT_RXDMA_LO_ALIGN_MASK); + + if (len < 3 || len > chan->dma_mru){ + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + chan->errstats.Rx_hdlc_corrupiton++; + card->wandev.stats.rx_frame_errors++; + goto rx_comp_error; + } + }else{ + /* In Transparent mode, our RX buffer will always be + * aligned to the 32bit (word) boundary, because + * the RX buffers are all of equal length */ + len=(((chan->mru>>2)-len)<<2) - (~(0x03)&AFT_RXDMA_LO_ALIGN_MASK); + + if (len < 1 || len > chan->mru){ + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; + card->wandev.stats.rx_frame_errors++; + goto rx_comp_error; + } + } +#endif + + *pkt_error=rx_el->pkt_error; + + /* After a RX FIFO overflow, we must mark max 7 + * subsequent frames since firmware, cannot + * guarantee the contents of the fifo */ + + if (wan_test_bit(WP_FIFO_ERROR_BIT,&rx_el->pkt_error)){ + if (chan->hdlc_eng){ + if (++chan->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES){ + chan->rx_fifo_err_cnt=0; + } + }else{ + chan->rx_fifo_err_cnt=0; + } + wan_set_bit(WP_FIFO_ERROR_BIT,pkt_error); + }else{ + if (chan->rx_fifo_err_cnt){ + if (++chan->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES){ + chan->rx_fifo_err_cnt=0; + } + wan_set_bit(WP_FIFO_ERROR_BIT,pkt_error); + } + } + + if (len > aft_rx_copyback){ + /* The rx size is big enough, thus + * send this buffer up the stack + * and allocate another one */ + memset(wan_skb_data(skb),0,sizeof(wp_rx_element_t)); +#if defined(__FreeBSD__) + wan_skb_trim(skb,sizeof(wp_rx_element_t)); +#endif + wan_skb_put(skb,len); + wan_skb_pull(skb, sizeof(wp_rx_element_t)); + *new_skb=skb; + + aft_alloc_rx_dma_buff(card,chan,1,1); + }else{ + + /* The rx packet is very + * small thus, allocate a new + * buffer and pass it up */ + *new_skb=wan_skb_alloc(len + 20); + if (!*new_skb){ + DEBUG_EVENT("%s:%s: Failed to allocate rx skb pkt (len=%d)!\n", + card->devname,chan->if_name,(len+20)); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //chan->if_stats.rx_dropped++; + goto rx_comp_error; + } + + buf=wan_skb_put((*new_skb),len); +#if defined(__FreeBSD__) + wan_skb_trim(skb,sizeof(wp_rx_element_t)); +#endif + memcpy(buf,wan_skb_tail(skb),len); + + aft_init_requeue_free_skb(chan, skb); + } + +#if 0 + if (chan->hdlc_eng){ + buf=wan_skb_data(*new_skb); + if (buf[wan_skb_len(*new_skb)-1] != 0x7E && + buf[wan_skb_len(*new_skb)-1] != 0x7F){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Rx: Invalid packet len=%d: 0x%X 0x%X 0x%X\n", + card->devname, + wan_skb_len(*new_skb), + buf[wan_skb_len(*new_skb)-3], + buf[wan_skb_len(*new_skb)-2], + buf[wan_skb_len(*new_skb)-1]); + } + } + } +#endif + + return; + +rx_comp_error: + + aft_init_requeue_free_skb(chan, skb); + return; +} + + + +/**SECTION************************************************** + * + * Logic Channel Registration Support and + * Utility funcitons + * + **********************************************************/ + +static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb) +{ + WAN_ASSERT(skb == NULL); + + wan_skb_init(skb,16); + wan_skb_trim(skb,0); + wan_skb_queue_tail(&chan->wp_rx_free_list,skb); + + return 0; +} + +static int +aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, int irq) +{ + int i; + netskb_t *skb; + + for (i=0;ichannelized_cfg && !chan->hdlc_eng){ +#if defined(WANPIPE_64BIT_4G_DMA) + /* On 64bit Systems greater than 4GB we must + * allocated our DMA buffers using GFP_DMA + * flag */ + if (irq) { + skb=__dev_alloc_skb(chan->dma_mru,GFP_DMA|GFP_ATOMIC); + } else { + skb=__dev_alloc_skb(chan->dma_mru,GFP_DMA|GFP_KERNEL); + } +#else + if (irq) { + skb=wan_skb_alloc(chan->dma_mru); + } else { + skb=wan_skb_kalloc(chan->dma_mru); + } +#endif + } else { + if (irq) { + skb=wan_skb_alloc(chan->dma_mru); + } else { + skb=wan_skb_kalloc(chan->dma_mru); + } + } + if (!skb){ + DEBUG_EVENT("%s: %s no rx memory\n", + chan->if_name,__FUNCTION__); + return -ENOMEM; + } + wan_skb_queue_tail(&chan->wp_rx_free_list,skb); + } + + return 0; +} + + +/*============================================================================ + * Enable timer interrupt + */ +static void enable_timer (void* card_id) +{ + sdla_t* card = (sdla_t*)card_id; +#if !defined(WAN_IS_TASKQ_SCHEDULE) + wan_smp_flag_t smp_flags; + wan_smp_flag_t smp_flags1; + int err = 0; +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s: Card down: Ignoring enable_timer!\n", + card->devname); + return; + } + + DEBUG_56K("%s: %s Sdla Polling %p!\n",__FUNCTION__, + card->devname, + card->wandev.fe_iface.polling); + +#if defined(WAN_IS_TASKQ_SCHEDULE) + wan_set_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); +#else + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + if (card->wandev.fe_iface.polling){ + err = card->wandev.fe_iface.polling(&card->fe); + } + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); +#endif + + return; +} + +static void enable_ec_timer (void* card_id) +{ +#if defined(CONFIG_WANPIPE_HWEC) + sdla_t* card = (sdla_t*)card_id; +# if !defined(WAN_IS_TASKQ_SCHEDULE) + wan_smp_flag_t smp_flags; + wan_smp_flag_t smp_flags1; +# endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_EVENT("%s: Card down: Ignoring enable_timer!\n", + card->devname); + return; + } + + DEBUG_TEST("%s: %s Sdla EC Polling !\n",__FUNCTION__, + card->devname); + +# if defined(WAN_IS_TASKQ_SCHEDULE) + wan_set_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); +# else +# error "TASK Q Not defined" + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + + wanpipe_ec_poll(card->wandev.ec_dev, card); + + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); +# endif +#endif + return; +} +/**SECTION************************************************** + * + * API Bottom Half Handlers + * + **********************************************************/ + +static int tdm_check=0; + +#if defined(__LINUX__) +static void wp_tdm_bh (unsigned long data) +#else +static void wp_tdm_bh (void *data, int pending) +#endif +{ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + private_area_t* chan = (private_area_t *)data; + sdla_t *card=chan->card; + int err; + +#if 0 + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: TDM BH Running !\n", + chan->if_name); + } +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + goto wp_tdm_bh_exit; + } + + if (!wan_test_bit(0,&chan->up)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: wp_tdm_bh() chan not up!\n", + chan->if_name); + } + goto wp_tdm_bh_exit; + } + +#if 0 + if (tdm_check){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: TDM BH Already Running 0x%02X... cool!\n", + chan->if_name,tdm_check); + } + } + wan_set_bit(card->tdmv_conf.span_no,&tdm_check); +#endif + + WAN_TDMV_CALL(rx_tx_span, (card), err); + + WAN_TASKLET_END((&chan->common.bh_task)); + + if (card->wan_tdmv.sc){ + WAN_TDMV_CALL(is_rbsbits, (&card->wan_tdmv), err); + if (err == 1){ + wan_set_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } + +#if 0 + wan_clear_bit(card->tdmv_conf.span_no,&tdm_check); +#endif + tdm_check++; + + return; + +wp_tdm_bh_exit: + WAN_TASKLET_END((&chan->common.bh_task)); +#endif + return; +} + + +static void wp_bh_rx(private_area_t* chan, netskb_t *new_skb, u8 pkt_error, int len) +{ + sdla_t *card = chan->card; + + if (chan->common.usedby == API){ + + if (chan->hdlc_eng){ + if (card->u.aft.cfg.rx_crc_bytes == 3){ + wan_skb_put(new_skb,3); + }else if (card->u.aft.cfg.rx_crc_bytes == 2){ + wan_skb_put(new_skb,2); + } + } + + if (chan->common.sk == NULL){ + DEBUG_BRI("%s: No sock bound to channel rx dropping!\n", + chan->if_name); + + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + +#if defined(__LINUX__) +# ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + + + /* Only for API, we insert packet status + * byte to indicate a packet error. Take + * this byte and put it in the api header */ + + if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr= + (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + rx_hdr->error_flag=pkt_error; + }else{ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", + chan->if_name, + (u32)wan_skb_headroom(new_skb), + (u32)sizeof(api_rx_hdr_t)); + } + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + new_skb->protocol = htons(PVC_PROT); + new_skb->mac.raw = new_skb->data; + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + +#if 0 + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); /* chan->if_stats.rx_frame_errors++; */ +#endif + + if (wan_api_rx(chan,new_skb) != 0){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + +# endif +#endif + + }else if (chan->common.usedby == TDM_VOICE_DCHAN){ + +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)) { + int err; + + DEBUG_RX("%s: RX TDM API DCHAN %d\n",chan->if_name, wan_skb_len(new_skb)); + + if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr = + (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + //rx_hdr->error_flag=pkt_error; + }else{ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Error Rx pkt headroom %u < %u\n", + chan->if_name, + (u32)wan_skb_headroom(new_skb), + (u32)sizeof(api_rx_hdr_t)); + } + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + err=wanpipe_tdm_api_rx_hdlc(&chan->wp_tdm_api_dev,new_skb); + if (err){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + }else +#endif + if (chan->tdmv_zaptel_cfg){ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) + int err; + + BRI_INIT_FUNC(); + + /* ADEBUG */ + WAN_TDMV_CALL(rx_dchan, + (&card->wan_tdmv,chan->tdmv_chan, + wan_skb_data(new_skb),wan_skb_len(new_skb)), + err); + DEBUG_RX("%s TDM DCHAN VOICE Rx Pkt Len=%i Chan=%i\n", + card->devname,wan_skb_len(new_skb), + chan->tdmv_chan); +#else + DEBUG_EVENT("%s: DCHAN Rx Packet critical error TDMV not compiled!\n",card->devname); +#endif + + wan_skb_free(new_skb); + /* Continue through since the above + * function returns void */ + + } else { + DEBUG_EVENT("%s: DCHAN Rx Packet critical error op not supported\n",card->devname); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + }else if (chan->common.usedby == TDM_VOICE){ + + DEBUG_EVENT("%s: TDM VOICE CRITICAL: IN BH!!!!\n",card->devname); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + + }else if (chan->common.usedby == STACK){ + + wan_skb_set_csum(new_skb,0); + + if (wanpipe_lip_rx(chan,new_skb) != 0){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); /* ++chan->if_stats.rx_dropped; */ + wan_skb_free(new_skb); + return; + } + + }else{ + protocol_recv(chan->card,chan,new_skb); + } + + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=len; + WAN_NETIF_STATS_INC_RX_PACKETS(&chan->common); /* chan->if_stats.rx_packets++; */ + WAN_NETIF_STATS_INC_RX_BYTES(&chan->common, len); /* chan->if_stats.rx_bytes+=len; */ + return; +} + +#if defined(__LINUX__) +static void wp_bh (unsigned long data) +#else +static void wp_bh (void *data, int pending) +#endif +{ + private_area_t* chan = (private_area_t *)data; + sdla_t *card=chan->card; + netskb_t *new_skb,*skb; + unsigned char pkt_error; + unsigned long timeout=SYSTEM_TICKS; + private_area_t *top_chan; + int len; + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.collisions++; +#endif + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + WAN_TASKLET_END((&chan->common.bh_task)); + return; + } + + if (card->u.aft.tdmv_dchan){ + top_chan=wan_netif_priv(chan->common.dev); + }else{ + top_chan=chan; + } + + DEBUG_TEST("%s: ------------ BEGIN --------------: %u\n", + __FUNCTION__,SYSTEM_TICKS); + + if (!wan_test_bit(0,&chan->up)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: wp_bh() chan not up!\n", + chan->if_name); + } + WAN_TASKLET_END((&chan->common.bh_task)); + return; + } + + while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ +#if 0 + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; +#endif + if (SYSTEM_TICKS-timeout > 1){ + wan_skb_queue_head(&chan->wp_rx_complete_list,skb); + break; + } + + new_skb=NULL; + pkt_error=0; + + /* The post function will take care + * of the skb and new_skb buffer. + * If new_skb buffer exists, driver + * must pass it up the stack, or free it */ + aft_rx_post_complete (chan->card, chan, + skb, + &new_skb, + &pkt_error); + if (new_skb){ + + len=wan_skb_len(new_skb); + + if (chan->hdlc_eng){ + /* HDLC packets contain 2 byte crc and 1 byte + * flag. If data is not greater than 3, then + * we have a 0 length frame. Thus discard + * (only if HDLC engine enabled) */ + if (len <= 3){ + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; + wan_skb_free(new_skb); + continue; + } + + wan_skb_trim(new_skb,wan_skb_len(new_skb)-3); + len-=3; + } + + wan_capture_trace_packet(chan->card, &top_chan->trace_info, + new_skb,TRC_INCOMING_FRM); + + wp_bh_rx(chan, new_skb, pkt_error, len); + } + } + + while((skb=wan_skb_dequeue(&chan->wp_rx_stack_complete_list)) != NULL){ + len=wan_skb_len(skb); + if (wanpipe_lip_rx(chan,skb) != 0){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //++chan->if_stats.rx_dropped; + wan_skb_free(skb); + }else{ + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=len; + WAN_NETIF_STATS_INC_RX_PACKETS(&chan->common); //chan->if_stats.rx_packets++; + WAN_NETIF_STATS_INC_RX_BYTES(&chan->common,len); //chan->if_stats.rx_bytes+=len; + } + } + + while((skb=wan_skb_dequeue(&chan->wp_rx_bri_dchan_complete_list)) != NULL){ + /* for BRI the rx data on D-chan is in 'wp_rx_bri_dchan_complete_list'. */ + wp_bh_rx(chan, skb, 0, wan_skb_len(skb)); + } + + while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ + aft_tx_post_complete (chan->card,chan,skb); + wan_skb_free(skb); + } + + WAN_TASKLET_END((&chan->common.bh_task)); + /* FIXME: If wanpipe goes down, do not schedule again */ + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + return; + } + +#if 1 + if ((len=wan_skb_queue_len(&chan->wp_rx_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + }else if ((len=wan_skb_queue_len(&chan->wp_tx_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + }else if ((len=wan_skb_queue_len(&chan->wp_rx_stack_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + }else if ((len=wan_skb_queue_len(&chan->wp_rx_bri_dchan_complete_list))){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + } +#endif + + DEBUG_TEST("%s: ------------ END -----------------: %u\n", + __FUNCTION__,SYSTEM_TICKS); + return; +} + +/**SECTION************************************************** + * + * Interrupt Support Functions + * + **********************************************************/ +static void wp_aft_fifo_per_port_isr(sdla_t *card) +{ + u32 rx_status, tx_status; + u32 i; + private_area_t *chan; + int num_of_logic_ch; + u32 tmp_fifo_reg; + + /* Clear HDLC pending registers */ + __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tx_status); + __sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG),&rx_status); + + tx_status&=card->u.aft.active_ch_map; + rx_status&=card->u.aft.active_ch_map; + + num_of_logic_ch=card->u.aft.num_of_time_slots; + + if (!wan_test_bit(0,&card->u.aft.comm_enabled)){ + if (tx_status){ + card->wandev.stats.tx_aborted_errors++; + } + if (rx_status){ + card->wandev.stats.rx_over_errors++; + } + return; + } + + if (tx_status != 0){ + for (i=0;iu.aft.logic_ch_map)){ + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("Warning: ignoring tx fifo intr: no dev!\n"); + continue; + } + + if (wan_test_bit(0,&chan->interface_down)){ + continue; + } +#if 1 + if (!chan->hdlc_eng && !wan_test_bit(0,&chan->idle_start)){ + DEBUG_TEST("%s: Warning: ignoring tx fifo: dev idle start!\n", + chan->if_name); + continue; + } +#endif + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + + DEBUG_TEST("%s:%s: Warning TX Fifo Error on LogicCh=%ld Slot=%d!\n", + card->devname,chan->if_name,chan->logic_ch_num,i); + +#if 0 +{ + u32 dma_descr,tmp_reg; + dma_descr=(chan->logic_ch_num<<4) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + + card->hw_iface.bus_read_4(card->hw,dma_descr, &tmp_reg); + + DEBUG_EVENT("%s:%s: Warning TX Fifo Error on LogicCh=%ld Slot=%d Reg=0x%X!\n", + card->devname,chan->if_name,chan->logic_ch_num,i,tmp_reg); + +#if 1 + aft_list_tx_descriptors(chan); + aft_critical_shutdown(card); + break; + +#endif + +} +#endif + + aft_tx_fifo_under_recover(card,chan); + WAN_NETIF_STATS_INC_TX_FIFO_ERRORS(&chan->common); //++chan->if_stats.tx_fifo_errors; + card->wandev.stats.tx_aborted_errors++; + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tmp_fifo_reg); + } + } + } + + + if (rx_status != 0){ + for (i=0;iu.aft.logic_ch_map)){ + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (wan_test_bit(0,&chan->interface_down)){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + +#ifdef AFT_RX_FIFO_DEBUG +{ + u32 dma_descr,tmp1_reg,tmp_reg,cur_dma_ptr; + u32 dma_ram_desc=chan->logic_ch_num*4 + + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,&tmp_reg); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(tmp_reg); + + dma_descr=(chan->logic_ch_num<<4) + cur_dma_ptr*AFT_DMA_INDEX_OFFSET + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr, &tmp_reg); + card->hw_iface.bus_read_4(card->hw,(dma_descr-4), &tmp1_reg); + + + if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,&tmp_reg)){ + DEBUG_EVENT("%s: Rx Fifo Go Bit Set DMA=%d Addr=0x%X : HI=0x%08X LO=0x%08X OLO=0x%08X Cfg=0x%08X!\n", + card->devname, + cur_dma_ptr, + dma_descr, + tmp_reg,tmp1_reg, +chan->rx_dma_chain_table[chan->rx_chain_indx].dma_addr, +0); + } + + DEBUG_EVENT("%s:%s: Warning RX Fifo Error on Ch=%ld End=%d Cur=%d: Reg=0x%X Addr=0x%X!\n", + card->devname,chan->if_name,chan->logic_ch_num, + chan->rx_chain_indx,cur_dma_ptr,tmp_reg,dma_descr); + +} +#if 0 + aft_display_chain_history(chan); + aft_list_descriptors(chan); +#endif +#endif + WAN_NETIF_STATS_INC_RX_FIFO_ERRORS(&chan->common); //++chan->if_stats.rx_fifo_errors; + WAN_NETIF_STATS_INC_RX_OVER_ERRORS(&chan->common); //++chan->if_stats.rx_over_errors; + chan->errstats.Rx_overrun_err_count++; + card->wandev.stats.rx_over_errors++; + + aft_rx_fifo_over_recover(card,chan); + wan_set_bit(WP_FIFO_ERROR_BIT, &chan->pkt_error); + + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG),&tmp_fifo_reg); +#if 0 + /* Debuging Code used to stop the line in + * case of fifo errors */ + aft_list_descriptors(chan); + + aft_critical_shutdown(card); +#endif + } + } + } + + return; +} + +static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock) +{ + + if(IS_BRI_CARD(card)){ + + void **card_list; + u32 max_number_of_ports, i; + sdla_t *tmp_card; + + max_number_of_ports = MAX_BRI_LINES; /* 24 */ + + card_list=__sdla_get_ptr_isr_array(card->hw); + + DEBUG_BRI("%s(): card_list ptr: 0x%p\n", __FUNCTION__, card_list); + + for (i=0; iwandev.fe_iface.isr) { + tmp_card->wandev.fe_iface.isr(&tmp_card->fe); + + if (lock) { + wan_smp_flag_t smp_flags; + wan_spin_lock_irq(&tmp_card->wandev.lock,&smp_flags); + handle_front_end_state(tmp_card); + wan_spin_unlock_irq(&tmp_card->wandev.lock,&smp_flags); + } else { + handle_front_end_state(tmp_card); + } + } + } + } else { + if (card->wandev.fe_iface.isr){ + card->wandev.fe_iface.isr(&card->fe); + + if (lock){ + wan_smp_flag_t smp_flags; + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + }else{ + handle_front_end_state(card); + } + } + } + return; +} + + +/**SECTION*************************************************************** + * + * HARDWARE Interrupt Handlers + * + ***********************************************************************/ + + +/*============================================================================ + * wpfw_isr + * + * Main interrupt service routine. + * Determin the interrupt received and handle it. + * + */ +#if 0 +static u32 aft_shared_irq=0; +static u32 aft_master_dev=0xF; +#endif +#if 0 +static int gdma_cnt=0; +#endif + +#define EC_IRQ_TIMEOUT (HZ/32) + +static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card) +{ + u32 reg_sec=0,reg=0; + u32 a108_reg=0, a56k_reg=0; + u32 fifo_port_intr=0; + u32 dma_port_intr=0; + u32 wdt_port_intr=0; + u32 tdmv_port_intr=0; + u32 fe_intr=0; + u32 max_ports=IS_BRI_CARD(card)?SDLA_MAX_PORTS:8; + + WAN_IRQ_RETVAL_DECL(irq_ret); + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + DEBUG_TEST("%s: Card down, ignoring interrupt!!!!!!!\n", + card->devname); + WAN_IRQ_RETURN(irq_ret); + } + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_errors++; +#endif + + if (tdm_check > 0){ + card->wandev.stats.rx_errors=tdm_check; + } + +#ifdef AFT_IRQ_DEBUG + card->wandev.stats.rx_packets++; + if (SYSTEM_TICKS-card->u.aft.gtimeout >= HZ){ + card->wandev.stats.tx_packets=card->wandev.stats.rx_packets; + card->wandev.stats.rx_packets=0; + card->u.aft.gtimeout=SYSTEM_TICKS; + } +#endif + + wan_set_bit(0,&card->in_isr); + + /* -----------------2/6/2003 9:02AM------------------ + * Disable all chip Interrupts (offset 0x040) + * -- "Transmit/Receive DMA Engine" interrupt disable + * -- "FiFo/Line Abort Error" interrupt disable + * --------------------------------------------------*/ + __sdla_bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); + reg_sec=reg; + + if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,®)){ + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_dropped++; +#endif + DEBUG_BRI("%s(): line: %d\n", __FUNCTION__, __LINE__); + + if (wan_test_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®)) { + + DEBUG_BRI("%s: Got Front End Interrupt 0x%08X\n", + card->devname,reg); + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.tx_dropped++; +#endif + fe_intr=1; + + if (card->wandev.fe_iface.check_isr && + card->wandev.fe_iface.check_isr(&card->fe)){ +#if defined(__LINUX__) + wan_set_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + __aft_fe_intr_ctrl(card,0); +#else + front_end_interrupt(card,reg,0); +#endif + } + + }/* if (wan_test_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®)) */ + + }/* if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,®)) */ + +/* New Octasic implementarion May 16 2006 */ +#if defined(CONFIG_WANPIPE_HWEC) + if (card->wandev.ec_dev && + SYSTEM_TICKS-card->wandev.ec_intmask > EC_IRQ_TIMEOUT) { + card->wandev.ec_intmask=SYSTEM_TICKS; + if (!wan_test_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd)){ + /* All work is done from ec_poll routine!!! */ + wan_set_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } +#endif + + if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID || IS_BRI_CARD(card)) { + + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a108_reg); + + fifo_port_intr = aft_chipcfg_a108_get_fifo_intr_stats(a108_reg); + dma_port_intr = aft_chipcfg_a108_get_dma_intr_stats(a108_reg); + wdt_port_intr = aft_chipcfg_a108_get_wdt_intr_stats(a108_reg); + tdmv_port_intr = aft_chipcfg_a108_get_tdmv_intr_stats(a108_reg); + + }else if(IS_56K_CARD(card)){ + __sdla_bus_read_4(card->hw,AFT_CHIP_STAT_REG, &a56k_reg); + fifo_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_FIFO_INTR_BIT,&a56k_reg); + dma_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_DMA_INTR_BIT,&a56k_reg); + wdt_port_intr = wan_test_bit(AFT_CHIPCFG_A56K_WDT_INTR_BIT,&a56k_reg); + }else{ + fifo_port_intr = aft_chipcfg_get_hdlc_intr_stats(reg); + dma_port_intr = aft_chipcfg_get_dma_intr_stats(reg); + wdt_port_intr = aft_chipcfg_get_wdt_intr_stats(reg); + tdmv_port_intr = aft_chipcfg_get_tdmv_intr_stats(reg); + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + tdmv_port_intr&=0x01; + } + } + + if (tdmv_port_intr || + dma_port_intr || + fifo_port_intr || + dma_port_intr || + wdt_port_intr) { + /* Pass Through */ + } else { + /* No more interrupts for us */ + goto aft_global_isr_exit; + } + + + if (wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg) && + wan_test_bit(card->wandev.comm_port,&fifo_port_intr)){ +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.multicast++; +#endif + wp_aft_fifo_per_port_isr(card); + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + } + +#if 1 + if (wan_test_bit(AFT_LCFG_DMA_INTR_BIT,&card->u.aft.lcfg_reg) && + wan_test_bit(card->wandev.comm_port,&dma_port_intr)){ + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + + wp_aft_dma_per_port_isr(card); + + /* Only enable fifo interrupts after a first + * successful DMA interrupt */ +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_length_errors++; +#endif + +#if 1 + if (wan_test_bit(0,&card->u.aft.comm_enabled) && + !wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg)){ + aft_fifo_intr_ctrl(card, 1); + } +#else +#warning "FIFO Interrupt Disabled" +#endif + } + +#else +#warning "NCDEBUG DMA IGNORED" +#endif + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + + if (tdmv_port_intr && + !wan_test_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®)) { + + int ring_buf_enabled=wan_test_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); + sdla_t *tmp_card; + int ring_rsync=0; + void **card_list; + int i; + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_crc_errors++; +#endif + + if (ring_buf_enabled) { + if (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + } else { + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + } + __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + if (card->hw_iface.fe_test_bit(card->hw,1)) { + DEBUG_EVENT("%s: Global TDM Ring Resync\n",card->devname); + ring_rsync=1; + card->hw_iface.fe_clear_bit(card->hw,1); + } + } + + card_list=__sdla_get_ptr_isr_array(card->hw); + + //FIXME: Use value pre card type + for (i=0;iwandev.state == WAN_CONNECTED && + wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&tmp_card->u.aft.lcfg_reg)) { +#ifdef AFT_IRQ_STAT_DEBUG + tmp_card->wandev.stats.rx_crc_errors++; +#endif + + if (ring_buf_enabled) { + if (ring_rsync) { + aft_tdm_ring_rsync(tmp_card); + } else { + tmp_card->u.aft.tdm_rx_dma_toggle++; + if (tmp_card->u.aft.tdm_rx_dma_toggle >= AFT_TDMV_CIRC_BUF_LEN) { + tmp_card->u.aft.tdm_rx_dma_toggle=0; + } + + tmp_card->u.aft.tdm_tx_dma_toggle++; + if (tmp_card->u.aft.tdm_tx_dma_toggle >= AFT_TDMV_CIRC_BUF_LEN) { + tmp_card->u.aft.tdm_tx_dma_toggle=0; + } + } + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (tmp_card->wan_tdmv.sc) { + + aft_voice_span_rx_tx(tmp_card, + ring_buf_enabled); + }else +#endif + { + wp_aft_tdmv_per_port_isr(tmp_card); + } + } + } + + if (!ring_buf_enabled) { + if (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + } else { + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + } + __sdla_bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + } + } + + } else { + + if (wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&card->u.aft.lcfg_reg) && + wan_test_bit(card->wandev.comm_port,&tdmv_port_intr)){ + + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_crc_errors++; +#endif +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + + if (card->wan_tdmv.sc && + !card->wandev.rtp_len && + card->wandev.config_id != WANCONFIG_AFT_ANALOG) { + u32 dmareg; + aft_voice_span_rx_tx(card, 0); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,&dmareg); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,&dmareg); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),dmareg); + } else +#endif + { + wp_aft_tdmv_per_port_isr(card); + } + } + } + + if (wan_test_bit(card->wandev.comm_port,&wdt_port_intr)){ + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + wp_aft_wdt_per_port_isr(card,1); + card->u.aft.wdt_tx_cnt=SYSTEM_TICKS; +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_fifo_errors++; +#endif + } + +#ifdef AFT_WDT_ENABLE + else if (card->wandev.state == WAN_CONNECTED && + SYSTEM_TICKS-card->u.aft.wdt_tx_cnt > (HZ>>2)){ + wp_aft_wdt_per_port_isr(card,0); + card->u.aft.wdt_tx_cnt=SYSTEM_TICKS; +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.tx_aborted_errors++; +#endif + } +#endif + + /* -----------------2/6/2003 10:36AM----------------- + * Finish of the interupt handler + * --------------------------------------------------*/ + + +#if AFT_SECURITY_CHECK + + reg=reg_sec; + if (wan_test_bit(AFT_CHIPCFG_SECURITY_STAT_BIT,®)){ + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ + DEBUG_EVENT("%s: Critical: AFT Chip Security Compromised: Disabling Driver!(%08X)\n", + card->devname, reg); + DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", + card->devname); + + aft_critical_shutdown(card); + } + + } else if (aft_hwdev[card->wandev.card_type].aft_check_ec_security(card)){ + WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); + + if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ + DEBUG_EVENT("%s: Critical: Echo Canceller Chip Security Compromised: Disabling Driver!\n", + card->devname); + DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", + card->devname); + + card->u.aft.chip_security_cnt=0; + aft_critical_shutdown(card); + } + + } else if (card->u.aft.firm_id == AFT_DS_FE_CORE_ID && + card->wandev.state == WAN_CONNECTED && + SYSTEM_TICKS-card->u.aft.sec_chk_cnt > HZ) { + + u32 lcfg_reg; + + card->u.aft.sec_chk_cnt=SYSTEM_TICKS; + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), &lcfg_reg); + card->u.aft.lcfg_reg=lcfg_reg; + if (wan_test_bit(AFT_LCFG_TX_FE_SYNC_STAT_BIT,&lcfg_reg) || + wan_test_bit(AFT_LCFG_RX_FE_SYNC_STAT_BIT,&lcfg_reg)){ + if (++card->u.aft.chip_security_cnt > AFT_MAX_CHIP_SECURITY_CNT){ + DEBUG_EVENT("%s: Critical: A108 Lost Sync with Front End: Disabling Driver (0x%08X : A108S=0x%08X)!\n", + card->devname, + lcfg_reg,a108_reg); + DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", + card->devname); + + aft_critical_shutdown(card); + } + } else { + card->u.aft.chip_security_cnt=0; + } + } else { + card->u.aft.chip_security_cnt=0; + } +#endif + + DEBUG_TEST("---- ISR end.-------------------\n"); + +aft_global_isr_exit: + + wan_clear_bit(0,&card->in_isr); + WAN_IRQ_RETURN(irq_ret); +} + +static void wp_aft_dma_per_port_isr(sdla_t *card) +{ + int i; + u32 dma_tx_reg,dma_rx_reg; + private_area_t *chan; + u32 dma_tx_voice=0; + + /* -----------------2/6/2003 9:37AM------------------ + * Checking for Interrupt source: + * 1. Receive DMA Engine + * 2. Transmit DMA Engine + * 3. Error conditions. + * --------------------------------------------------*/ + + int num_of_logic_ch; + num_of_logic_ch=card->u.aft.num_of_time_slots; + + /* Zaptel optimization. Dont waist time looking at + channels, when we know that only a single DCHAN + will use this code */ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc) { + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); + if (card->u.aft.tdmv_dchan) { + chan=(private_area_t*)card->u.aft.dev_to_ch_map[card->u.aft.tdmv_dchan-1]; + if (chan && wan_test_bit(0,&chan->up)) { + aft_dma_rx_complete(card,chan,0); + aft_dma_tx_complete(card,chan,0,0); + } + } + goto isr_skb_rx; + } +#endif + + /* Receive DMA Engine */ + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG),&dma_rx_reg); + DEBUG_BRI("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); + + dma_rx_reg&=card->u.aft.active_ch_map; + + if (dma_rx_reg == 0){ + goto isr_skb_rx; + } + + dma_rx_reg &= card->u.aft.logic_ch_map; + DEBUG_BRI("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); + + dma_rx_reg &= ~(card->u.aft.tdm_logic_ch_map); + DEBUG_BRI("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg); + + for (i=0; iu.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", + card->devname,i); + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + wan_set_bit(i,&dma_tx_voice); + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + +#if 0 + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; +#endif + + DEBUG_BRI("%s: RX Interrupt pend. \n", card->devname); + + aft_dma_rx_complete(card,chan,0); + + +#if 0 + if (chan->cfg.tdmv_master_if && !chan->tdmv_irq_cfg){ + aft_channel_rxintr_ctrl(card,chan,1); + DEBUG_EVENT("%s: Master dev %s Synched to master irq\n", + card->devname,chan->if_name); + chan->tdmv_irq_cfg=1; + } +#endif + } + } + + +isr_skb_rx: + + /* Transmit DMA Engine */ + __sdla_bus_read_4(card->hw,AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),&dma_tx_reg); + + dma_tx_reg&=card->u.aft.active_ch_map; + + dma_tx_reg&=~dma_tx_voice; + + if (dma_tx_reg == 0){ + goto isr_skb_tx; + } + + dma_tx_reg &= card->u.aft.logic_ch_map; + dma_tx_reg &= ~(card->u.aft.tdm_logic_ch_map); + + + for (i=0; iu.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Tx logical ch=%d\n", + card->devname,i); + continue; + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + + DEBUG_ISR("---- TX Interrupt pend. --\n"); + aft_dma_tx_complete(card,chan,0,0); + } + } + +isr_skb_tx: + DEBUG_ISR("---- ISR SKB TX end.-------------------\n"); + + +} + +static void wp_aft_tdmv_per_port_isr(sdla_t *card) +{ + int i; + private_area_t *chan; + +#if 0 + DEBUG_EVENT("%s: TDMV Interrupt LogicCh=%i\n", + card->devname,card->u.aft.num_of_time_slots); +#endif + /* -----------------2/6/2003 9:37AM------------------ + * Checking for Interrupt source: + * 1. Receive DMA Engine + * 2. Transmit DMA Engine + * 3. Error conditions. + * --------------------------------------------------*/ + + + for (i=0; iu.aft.num_of_time_slots;i++){ + + if (!wan_test_bit(i,&card->u.aft.tdm_logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", + card->devname,i); + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_dma_rx_tdmv(card,chan); + } + +#if 0 + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; +#endif + + DEBUG_ISR("%s: RX Interrupt pend. \n", + card->devname); + + } +} + + + + + +static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr) +{ + int i,wdt_disable = 0; + int timeout=AFT_WDTCTRL_TIMEOUT; + + aft_wdt_reset(card); + + for (i=0; iu.aft.num_of_time_slots;i++){ + + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up) || + wan_test_bit(0,&chan->interface_down)){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + +#if 0 + if (wdt_intr){ + WAN_NETIF_STATS_INC_TX_DROPPED(&chan->common); //++chan->if_stats.tx_dropped; + }else{ + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; + } +#endif + + if (card->wandev.state == WAN_CONNECTED){ + + if (chan->single_dma_chain){ + wdt_disable=1; + continue; + } +#if 0 + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; +#endif + aft_dma_tx_complete (card,chan,1,0); + + } + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + else{ + if (chan->tdmv_zaptel_cfg && + wan_test_bit(0,&chan->up) && + chan->cfg.tdmv_master_if){ + /* If the line becomes disconnected + * keep calling TDMV zaptel in order to + * provide timing */ + if (wdt_intr && chan->cfg.tdmv_master_if){ + int i, err; + void **card_list=__sdla_get_ptr_isr_array(card->hw); + sdla_t *tmp_card; + for (i=0;i<8;i++) { + tmp_card=card_list[i]; + if (!tmp_card) { + continue; + } + if (tmp_card != card) { + /* Only run timing from a first + configured single card */ + DEBUG_TEST("%s: Disabling zaptel timing ! \n",card->devname); + return; + } else { + break; + } + } +#if 0 + WAN_NETIF_STATS_INC_TX_DROPPED(&chan->common); //++chan->if_stats.tx_dropped; +#endif + +#if 1 + timeout=1; + aft_wdt_set(card,timeout); + WAN_TDMV_CALL(rx_tx_span, (card), err); +#else +#warning "NCDEBUG: rx_tx_span disabled poll" +#endif + return; + } + } + } +#endif + } + +#ifdef AFT_WDT_ENABLE + /* Since this fucntion can be called via interrupt or + * via interrupt poll, only re-enable wdt interrupt + * if the function was called from the wdt_intr + * not from wdt poll */ + if (!wdt_disable && wdt_intr){ + aft_wdt_set(card,timeout); + } +#endif + + return; + +} + +/**SECTION*********************************************************** + * + * WANPIPE Debugging Interfaces + * + ********************************************************************/ + + + +/*============================================================================= + * process_udp_mgmt_pkt + * + * Process all "wanpipemon" debugger commands. This function + * performs all debugging tasks: + * + * Line Tracing + * Line/Hardware Statistics + * Protocol Statistics + * + * "wanpipemon" utility is a user-space program that + * is used to debug the WANPIPE product. + * + */ +#if 1 +static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, + private_area_t* chan, int local_dev ) +{ + unsigned short buffer_length; + wan_udp_pkt_t *wan_udp_pkt; + wan_trace_t *trace_info=NULL; + + wan_udp_pkt = (wan_udp_pkt_t *)chan->udp_pkt_data; + + if (wan_atomic_read(&chan->udp_pkt_len) == 0){ + return -ENODEV; + } + + trace_info=&chan->trace_info; + wan_udp_pkt = (wan_udp_pkt_t *)chan->udp_pkt_data; + + { + + netskb_t *skb; + + wan_udp_pkt->wan_udp_opp_flag = 0; + + switch(wan_udp_pkt->wan_udp_command) { + + case READ_CONFIGURATION: + wan_udp_pkt->wan_udp_return_code = 0; + wan_udp_pkt->wan_udp_data_len=0; + break; + + case READ_CODE_VERSION: + wan_udp_pkt->wan_udp_return_code = 0; + wan_udp_pkt->wan_udp_data[0]=card->u.aft.firm_ver; + wan_udp_pkt->wan_udp_data_len=1; + break; + + case AFT_LINK_STATUS: + wan_udp_pkt->wan_udp_return_code = 0; + if (card->wandev.state == WAN_CONNECTED){ + wan_udp_pkt->wan_udp_data[0]=1; + }else{ + wan_udp_pkt->wan_udp_data[0]=0; + } + wan_udp_pkt->wan_udp_data_len=1; + break; + + case AFT_MODEM_STATUS: + wan_udp_pkt->wan_udp_return_code = 0; + if (card->wandev.state == WAN_CONNECTED){ + wan_udp_pkt->wan_udp_data[0]=0x28; + }else{ + wan_udp_pkt->wan_udp_data[0]=0; + } + wan_udp_pkt->wan_udp_data_len=1; + break; + + case DIGITAL_LOOPTEST: + wan_udp_pkt->wan_udp_return_code = + digital_loop_test(card,wan_udp_pkt); + break; + + case READ_OPERATIONAL_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memcpy(wan_udp_pkt->wan_udp_data,&chan->opstats,sizeof(aft_op_stats_t)); + wan_udp_pkt->wan_udp_data_len=sizeof(aft_op_stats_t); + break; + + case FLUSH_OPERATIONAL_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memset(&chan->opstats,0,sizeof(aft_op_stats_t)); + wan_udp_pkt->wan_udp_data_len=0; + break; + + case READ_COMMS_ERROR_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memcpy(wan_udp_pkt->wan_udp_data,&chan->errstats,sizeof(aft_comm_err_stats_t)); + wan_udp_pkt->wan_udp_data_len=sizeof(aft_comm_err_stats_t); + break; + + case FLUSH_COMMS_ERROR_STATS: + wan_udp_pkt->wan_udp_return_code = 0; + memset(&chan->errstats,0,sizeof(aft_comm_err_stats_t)); + wan_udp_pkt->wan_udp_data_len=0; + break; + + + case ENABLE_TRACING: + + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = 0; + + if (!wan_test_bit(0,&trace_info->tracing_enabled)){ + + trace_info->trace_timeout = SYSTEM_TICKS; + + wan_trace_purge(trace_info); + + if (wan_udp_pkt->wan_udp_data[0] == 0){ + wan_clear_bit(1,&trace_info->tracing_enabled); + DEBUG_UDP("%s: ADSL L3 trace enabled!\n", + card->devname); + }else if (wan_udp_pkt->wan_udp_data[0] == 1){ + wan_clear_bit(2,&trace_info->tracing_enabled); + wan_set_bit(1,&trace_info->tracing_enabled); + DEBUG_UDP("%s: ADSL L2 trace enabled!\n", + card->devname); + }else{ + wan_clear_bit(1,&trace_info->tracing_enabled); + wan_set_bit(2,&trace_info->tracing_enabled); + DEBUG_UDP("%s: ADSL L1 trace enabled!\n", + card->devname); + } + wan_set_bit (0,&trace_info->tracing_enabled); + + }else{ + DEBUG_EVENT("%s: Error: ATM trace running!\n", + card->devname); + wan_udp_pkt->wan_udp_return_code = 2; + } + + break; + + case DISABLE_TRACING: + + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + + if(wan_test_bit(0,&trace_info->tracing_enabled)) { + + wan_clear_bit(0,&trace_info->tracing_enabled); + wan_clear_bit(1,&trace_info->tracing_enabled); + wan_clear_bit(2,&trace_info->tracing_enabled); + + wan_trace_purge(trace_info); + + DEBUG_UDP("%s: Disabling AFT trace\n", + card->devname); + + }else{ + /* set return code to line trace already + disabled */ + wan_udp_pkt->wan_udp_return_code = 1; + } + + break; + + case GET_TRACE_INFO: + + if(wan_test_bit(0,&trace_info->tracing_enabled)){ + trace_info->trace_timeout = SYSTEM_TICKS; + }else{ + DEBUG_EVENT("%s: Error ATM trace not enabled\n", + card->devname); + /* set return code */ + wan_udp_pkt->wan_udp_return_code = 1; + break; + } + + buffer_length = 0; + wan_udp_pkt->wan_udp_atm_num_frames = 0; + wan_udp_pkt->wan_udp_atm_ismoredata = 0; + +#if defined(__FreeBSD__) || defined(__OpenBSD__) + while (wan_skb_queue_len(&trace_info->trace_queue)){ + WAN_IFQ_POLL(&trace_info->trace_queue, skb); + if (skb == NULL){ + DEBUG_EVENT("%s: No more trace packets in trace queue!\n", + card->devname); + break; + } + if ((WAN_MAX_DATA_SIZE - buffer_length) < skb->m_pkthdr.len){ + /* indicate there are more frames on board & exit */ + wan_udp_pkt->wan_udp_atm_ismoredata = 0x01; + break; + } + + m_copydata(skb, + 0, + skb->m_pkthdr.len, + &wan_udp_pkt->wan_udp_data[buffer_length]); + buffer_length += skb->m_pkthdr.len; + WAN_IFQ_DEQUEUE(&trace_info->trace_queue, skb); + if (skb){ + wan_skb_free(skb); + } + wan_udp_pkt->wan_udp_atm_num_frames++; + } +#elif defined(__LINUX__) + while ((skb=skb_dequeue(&trace_info->trace_queue)) != NULL){ + + if((MAX_TRACE_BUFFER - buffer_length) < wan_skb_len(skb)){ + /* indicate there are more frames on board & exit */ + wan_udp_pkt->wan_udp_atm_ismoredata = 0x01; + if (buffer_length != 0){ + wan_skb_queue_head(&trace_info->trace_queue, skb); + }else{ + /* If rx buffer length is greater than the + * whole udp buffer copy only the trace + * header and drop the trace packet */ + + memcpy(&wan_udp_pkt->wan_udp_atm_data[buffer_length], + wan_skb_data(skb), + sizeof(wan_trace_pkt_t)); + + buffer_length = sizeof(wan_trace_pkt_t); + wan_udp_pkt->wan_udp_atm_num_frames++; + wan_skb_free(skb); + } + break; + } + + memcpy(&wan_udp_pkt->wan_udp_atm_data[buffer_length], + wan_skb_data(skb), + wan_skb_len(skb)); + + buffer_length += wan_skb_len(skb); + wan_skb_free(skb); + wan_udp_pkt->wan_udp_atm_num_frames++; + } +#endif + /* set the data length and return code */ + wan_udp_pkt->wan_udp_data_len = buffer_length; + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + break; + + case ROUTER_UP_TIME: + wan_getcurrenttime(&chan->router_up_time, NULL); + chan->router_up_time -= chan->router_start_time; + *(unsigned long *)&wan_udp_pkt->wan_udp_data = + chan->router_up_time; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); + wan_udp_pkt->wan_udp_return_code = 0; + break; + + case WAN_GET_MEDIA_TYPE: + if (card->wandev.fe_iface.get_fe_media){ + wan_udp_pkt->wan_udp_data[0] = + card->wandev.fe_iface.get_fe_media(&card->fe); + wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned char); + }else{ + wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; + } + break; +#if 0 + case WAN_FE_GET_STAT: + case WAN_FE_SET_LB_MODE: + case WAN_FE_FLUSH_PMON: + case WAN_FE_GET_CFG: + case WAN_FE_SET_DEBUG_MODE: + case WAN_FE_TX_MODE: + + if (IS_TE1_CARD(card)){ + wan_smp_flag_t smp_flags; + card->hw_iface.hw_lock(card->hw,&smp_flags); + card->wandev.fe_iface.process_udp( + &card->fe, + &wan_udp_pkt->wan_udp_cmd, + &wan_udp_pkt->wan_udp_data[0]); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + }else{ + wan_udp_pkt->wan_udp_return_code = WAN_UDP_INVALID_CMD; + } + break; +#endif + + case WAN_GET_PROTOCOL: + wan_udp_pkt->wan_udp_aft_num_frames = card->wandev.config_id; + wan_udp_pkt->wan_udp_return_code = CMD_OK; + wan_udp_pkt->wan_udp_data_len = 1; + break; + + case WAN_GET_PLATFORM: + wan_udp_pkt->wan_udp_data[0] = WAN_PLATFORM_ID; + wan_udp_pkt->wan_udp_return_code = CMD_OK; + wan_udp_pkt->wan_udp_data_len = 1; + break; + + case WAN_GET_MASTER_DEV_NAME: + wan_udp_pkt->wan_udp_data_len = 0; + wan_udp_pkt->wan_udp_return_code = 0xCD; + break; + + case AFT_HWEC_STATUS: + *(unsigned long *)&wan_udp_pkt->wan_udp_data[0] = + IS_E1_CARD(card) ? card->wandev.ec_map: + card->wandev.ec_map << 1; + wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); + wan_udp_pkt->wan_udp_return_code = 0; + break; + + default: + if ((wan_udp_pkt->wan_udp_command & 0xF0) == WAN_FE_UDP_CMD_START){ + /* FE udp calls */ + wan_smp_flag_t smp_flags,smp_flags1; + + card->hw_iface.hw_lock(card->hw,&smp_flags); + wan_spin_lock_irq(&card->wandev.lock,&smp_flags1); + card->wandev.fe_iface.process_udp( + &card->fe, + &wan_udp_pkt->wan_udp_cmd, + &wan_udp_pkt->wan_udp_data[0]); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + break; + } + wan_udp_pkt->wan_udp_data_len = 0; + wan_udp_pkt->wan_udp_return_code = 0xCD; + + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT( + "%s: Warning, Illegal UDP command attempted from network: %x\n", + card->devname,wan_udp_pkt->wan_udp_command); + } + break; + } /* end of switch */ + } /* end of else */ + + /* Fill UDP TTL */ + wan_udp_pkt->wan_ip_ttl= card->wandev.ttl; + + wan_udp_pkt->wan_udp_request_reply = UDPMGMT_REPLY; + return 1; + +} +#endif + + + +/**SECTION************************************************************* + * + * TASK Functions and Triggers + * + **********************************************************************/ + + +/*============================================================================ + * port_set_state + * + * Set PORT state. + * + */ +static void port_set_state (sdla_t *card, int state) +{ + struct wan_dev_le *devle; + netdevice_t *dev; + + if (card->wandev.state != state) + { +#if 0 + switch (state) + { + case WAN_CONNECTED: + DEBUG_EVENT( "%s: Front End Link connected!\n", + card->devname); + break; + + case WAN_CONNECTING: + DEBUG_EVENT( "%s: Front End Link connecting...\n", + card->devname); + break; + + case WAN_DISCONNECTED: + DEBUG_EVENT( "%s: Front End Link disconnected!\n", + card->devname); + break; + } +#endif + card->wandev.state = state; + WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ + dev = WAN_DEVLE2DEV(devle); + if (!dev) continue; + set_chan_state(card, dev, state); + } + } +} + +/*============================================================ + * handle_front_end_state + * + * Front end state indicates the physical medium that + * the Z80 backend connects to. + * + * S514-1/2/3: V32/RS232/FT1 Front End + * Front end state is determined via + * Modem/Status. + * S514-4/5/7/8: 56K/T1/E1 Front End + * Front end state is determined via + * link status interrupt received + * from the front end hardware. + * + * If the front end state handler is enabed by the + * user. The interface state will follow the + * front end state. I.E. If the front end goes down + * the protocol and interface will be declared down. + * + * If the front end state is UP, then the interface + * and protocol will be up ONLY if the protocol is + * also UP. + * + * Therefore, we must have three state variables + * 1. Front End State (card->wandev.front_end_status) + * 2. Protocol State (card->wandev.state) + * 3. Interface State (dev->flags & IFF_UP) + * + */ + +static void handle_front_end_state(void *card_id) +{ + sdla_t *card = (sdla_t*)card_id; + + if (!wan_test_bit(AFT_CHIP_CONFIGURED,&card->u.aft.chip_cfg_status) && + card->fe.fe_status == FE_CONNECTED) { + DEBUG_TEST("%s: Skipping Front Front End State = %x\n", + card->devname,card->fe.fe_status); + + wan_set_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status); + return; + } + + + if (card->wandev.ignore_front_end_status == WANOPT_YES) { + if (card->wandev.state != WAN_CONNECTED){ + enable_data_error_intr(card); + port_set_state(card,WAN_CONNECTED); + wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + } + return; + } + + if (card->fe.fe_status == FE_CONNECTED){ + if (card->wandev.state != WAN_CONNECTED){ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc){ + int err; + WAN_TDMV_CALL(state, (card, WAN_CONNECTED), err); + } +#endif + /* WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); */ + + if (card->tdmv_conf.span_no && + !wan_test_bit(0,&card->u.aft.tdmv_master_if_up)){ + DEBUG_EVENT("%s: Skipping AFT Communication wait for MasterIF\n", + card->devname); + return; + } + + enable_data_error_intr(card); + port_set_state(card,WAN_CONNECTED); + wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + + } + }else{ + if (card->wandev.state == WAN_CONNECTED){ + port_set_state(card,WAN_DISCONNECTED); + disable_data_error_intr(card,LINK_DOWN); + + wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + /* We are already in the poll task here so + * no need to schedule. because next check in the + * poll routine would be the AFT_FE_LED */ + /* WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); */ + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) + if (card->wan_tdmv.sc){ + int err; + WAN_TDMV_CALL(state, (card, WAN_DISCONNECTED), err); + } +#endif + } + } + +} + +unsigned char aft_read_cpld(sdla_t *card, unsigned short cpld_off) +{ + return aft_hwdev[card->wandev.card_type].aft_read_cpld(card,cpld_off); +} + +int aft_write_cpld(void *pcard, unsigned short off,unsigned char data) +{ + sdla_t *card = (sdla_t *)pcard; + return aft_hwdev[card->wandev.card_type].aft_write_cpld(card,off,data); +} + +#if 0 +/*============================================================================ + * Read TE1/56K Front end registers + */ +static unsigned char +write_front_end_reg (void* card1, unsigned short off, unsigned char value) +{ + sdla_t* card = (sdla_t*)card1; + + if (card->wandev.card_type == WANOPT_AFT_ANALOG){ + DEBUG_EVENT("%s: Internal Error (%s:%d)\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + return aft_hwdev[card->wandev.card_type].aft_write_fe(card1,off,value); +} + +/*============================================================================ + * Read TE1/56K Front end registers + */ +static unsigned char +read_front_end_reg (void* card1, unsigned short off) +{ + sdla_t* card = (sdla_t*)card1; + + if (card->wandev.card_type == WANOPT_AFT_ANALOG){ + DEBUG_EVENT("%s: Internal Error (%s:%d)\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + return aft_hwdev[card->wandev.card_type].aft_read_fe(card1,off); +} +#endif + +static unsigned char +aft_write_ec (void* card1, unsigned short off, unsigned char value) +{ + DEBUG_EVENT("ADEBUG: Write Octasic Offset %04X Value %02X!\n", + off, value); + return 0; +} + +/*============================================================================ + * Read from Octasic board + */ +static unsigned char +aft_read_ec (void* card1, unsigned short off) +{ + u8 value = 0x00; + + DEBUG_EVENT("ADEBUG: Read Octasic offset %04X Value %02X (temp)!\n", + off, value); + return value; +} + + + +static int aft_read(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + WAN_ASSERT(card == NULL); + WAN_ASSERT(api_cmd == NULL); + + if(api_cmd->len == 1){ + if (api_cmd->offset <= 0x3C){ + card->hw_iface.pci_read_config_byte( + card->hw, + api_cmd->offset, + (u8*)&api_cmd->data[0]); + }else{ + card->hw_iface.bus_read_1( + card->hw, + api_cmd->offset, + (u8*)&api_cmd->data[0]); + } + }else if (api_cmd->len == 2){ + if (api_cmd->offset <= 0x3C){ + card->hw_iface.pci_read_config_word( + card->hw, + api_cmd->offset, + (u16*)&api_cmd->data[0]); + }else{ + card->hw_iface.bus_read_2( + card->hw, + api_cmd->offset, + (u16*)&api_cmd->data[0]); + } + }else if (api_cmd->len == 4){ + if (api_cmd->offset <= 0x3C){ + card->hw_iface.pci_read_config_dword(card->hw, + api_cmd->offset, + (u32*)&api_cmd->data[0]); + }else{ + WAN_ASSERT(card->hw_iface.bus_read_4 == NULL); + card->hw_iface.bus_read_4( + card->hw, + api_cmd->offset, + (u32*)&api_cmd->data[0]); + } + }else{ + card->hw_iface.peek(card->hw, + api_cmd->offset, + &api_cmd->data[0], + api_cmd->len); + } + +#if defined(DEBUG_REG) + DEBUG_EVENT("%s: Reading Bar%d Offset=0x%X Data=%08X Len=%d\n", + card->devname, + api_cmd->bar, + api_cmd->offset, + *(u32*)&api_cmd->data[0], + api_cmd->len); +#endif + + return 0; +} + +static int aft_fe_read(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + wan_smp_flag_t smp_flags; + + card->hw_iface.hw_lock(card->hw,&smp_flags); + api_cmd->data[0] = (u8)card->fe.read_fe_reg(card, (int)api_cmd->offset); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + +#ifdef DEB_XILINX + DEBUG_EVENT("%s: Reading Bar%d Offset=0x%X Len=%d Val=%02X\n", + card->devname,api_cmd->bar,api_cmd->offset,api_cmd->len, api_cmd->data[0]); +#endif + + return 0; +} + +static int aft_write(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + + if (api_cmd->len == 1){ + card->hw_iface.bus_write_1( + card->hw, + api_cmd->offset, + *(u8*)&api_cmd->data[0]); +#if defined(DEBUG_REG) + DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%02X\n", + card->devname,api_cmd->offset, + *(u8*)&api_cmd->data[0]); +#endif + }else if (api_cmd->len == 2){ + card->hw_iface.bus_write_2( + card->hw, + api_cmd->offset, + *(u16*)&api_cmd->data[0]); +#if defined(DEBUG_REG) + DEBUG_EVENT("%s: Write Offset=0x%08X Data=0x%04X\n", + card->devname,api_cmd->offset, + *(unsigned short*)&api_cmd->data[0]); +#endif + }else if (api_cmd->len == 4){ + card->hw_iface.bus_write_4( + card->hw, + api_cmd->offset, + *(unsigned int*)&api_cmd->data[0]); +#if defined(DEBUG_REG) + DEBUG_EVENT("ADEBUG: %s: Write Offset=0x%08X Data=0x%08X\n", + card->devname,api_cmd->offset, + *(u32*)&api_cmd->data[0]); +#endif + }else{ + card->hw_iface.poke( + card->hw, + api_cmd->offset, + (u8*)&api_cmd->data[0], + api_cmd->len); +#if 0 + memcpy_toio((unsigned char*)vector, + (unsigned char*)&api_cmd->data[0], api_cmd->len); +#endif + } + + return 0; +} + +static int aft_fe_write(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + wan_smp_flag_t smp_flags; + +#ifdef DEB_XILINX + DEBUG_EVENT("%s: Writting Bar%d Offset=0x%X Len=%d Val=%02X\n", + card->devname, + api_cmd->bar, + api_cmd->offset, + api_cmd->len, + api_cmd->data[0]); +#endif + + + card->hw_iface.hw_lock(card->hw,&smp_flags); + card->fe.write_fe_reg (card, (int)api_cmd->offset, (int)api_cmd->data[0]); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + return 0; + +} + + + +static int aft_write_bios(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + +#ifdef DEB_XILINX + DEBUG_EVENT("Setting PCI 0xX=0x%08lX 0x3C=0x%08X\n", + (card->wandev.S514_cpu_no[0] == SDLA_CPU_A) ? 0x10 : 0x14, + card->u.aft.bar,card->wandev.irq); +#endif + card->hw_iface.pci_write_config_dword(card->hw, + (card->wandev.S514_cpu_no[0] == SDLA_CPU_A) ? 0x10 : 0x14, + card->u.aft.bar); + card->hw_iface.pci_write_config_dword(card->hw, 0x3C, card->wandev.irq); + card->hw_iface.pci_write_config_dword(card->hw, 0x0C, 0x0000ff00); + + return 0; +} + +#if 0 +extern int OctDrvIoctl(sdla_t*, int cmd, void*); +#endif + +static int aft_hwec(sdla_t *card, wan_cmd_api_t *api_cmd) +{ + +#if 0 + if (api_cmd->offset){ + /* Use direct read/write to/from octasic chip */ + if (api_cmd->len){ + /* Write */ + aft_write_ec (card, api_cmd->offset, api_cmd->data[0]); + }else{ + /* Read */ + api_cmd->data[0] = aft_read_ec (card, api_cmd->offset); + api_cmd->len = 1; + } + }else +#endif + { +#if 0 + OctDrvIoctl(card, api_cmd->cmd, api_cmd->data); +#endif + } + + return 0; +} + +static int aft_devel_ioctl(sdla_t *card, struct ifreq *ifr) +{ + wan_cmd_api_t api_cmd; + int err = -EINVAL; + + if (!ifr || !ifr->ifr_data){ + DEBUG_EVENT("%s: Error: No ifr or ifr_data\n",__FUNCTION__); + return -EFAULT; + } + + if (WAN_COPY_FROM_USER(&api_cmd,ifr->ifr_data,sizeof(wan_cmd_api_t))){ + return -EFAULT; + } + + switch(api_cmd.cmd){ + case SIOC_WAN_READ_REG: + err=aft_read(card, &api_cmd); + break; + case SIOC_WAN_WRITE_REG: + err=aft_write(card, &api_cmd); + break; + + case SIOC_WAN_FE_READ_REG: + err=aft_fe_read(card, &api_cmd); + break; + + case SIOC_WAN_FE_WRITE_REG: + err=aft_fe_write(card, &api_cmd); + break; + + case SIOC_WAN_SET_PCI_BIOS: + err=aft_write_bios(card, &api_cmd); + break; + + case SIOC_WAN_EC_REG: + err = aft_hwec(card, &api_cmd); + break; + } + if (WAN_COPY_TO_USER(ifr->ifr_data,&api_cmd,sizeof(wan_cmd_api_t))){ + return -EFAULT; + } + return err; +} + + +/*========================================= + * enable_data_error_intr + * + * Description: + * + * Run only after the front end comes + * up from down state. + * + * Clean the DMA Tx/Rx pending interrupts. + * (Ignore since we will reconfigure + * all dma descriptors. DMA controler + * was already disabled on link down) + * + * For all channels clean Tx/Rx Fifo + * + * Enable DMA controler + * (This starts the fifo cleaning + * process) + * + * For all channels reprogram Tx/Rx DMA + * descriptors. + * + * Clean the Tx/Rx Error pending interrupts. + * (Since dma fifo's are now empty) + * + * Enable global DMA and Error interrutps. + * + */ + +static void enable_data_error_intr(sdla_t *card) +{ + u32 reg; + int i,err; + int card_use_cnt; + + + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + + DEBUG_TEST("%s: %s() Card Port =%i Use Cnt = %i \n", + card->devname,__FUNCTION__,card->wandev.comm_port,card_use_cnt); + + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + if (wan_test_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®)){ + DEBUG_EVENT("%s: Warning: Skipping data enable wait for cfg!\n", + card->devname); + return; + } + +#if 0 + aft_list_dma_chain_regs(card); +#endif + + if (card->tdmv_conf.span_no && + !wan_test_bit(0,&card->u.aft.tdmv_master_if_up)){ + DEBUG_EVENT("%s: Critical error: Enable Card while Master If Not up!\n", + card->devname); + } + + if (wan_test_bit(0,&card->u.aft.comm_enabled)){ + disable_data_error_intr(card,LINK_DOWN); + } + + aft_wdt_reset(card); + + if (!IS_BRI_CARD(card) || (IS_BRI_CARD(card) && card_use_cnt == 1)) { + /* Clean Tx/Rx DMA interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_DMA_INTR_PENDING_REG), + ®); + } + + + err=aft_hwdev[card->wandev.card_type].aft_test_sync(card,0); + if (err){ + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + DEBUG_EVENT("%s: Error: Front End Interface out of sync! (0x%X)\n", + card->devname,reg); + + /*FIXME: How to recover from here, should never happen */ + } + + if (card->tdmv_conf.span_no){ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + } + + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + + DEBUG_TEST("%s: 1) Free Used DMA CHAINS %s\n", + card->devname,chan->if_name); + + aft_free_rx_complete_list(chan); + aft_free_rx_descriptors(chan); + + DEBUG_TEST("%s: 1) Free UNUSED DMA CHAINS %s\n", + card->devname,chan->if_name); + + wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_tx_dma_voice_handler((unsigned long)chan,0,1); + }else{ + aft_tx_dma_chain_handler((unsigned long)chan,0,1); + } + + aft_free_tx_descriptors(chan); + + DEBUG_TEST("%s: 2) Init interface fifo no wait %s\n", + card->devname,chan->if_name); + + aft_tslot_sync_ctrl(card,chan,0); + + aft_init_rx_dev_fifo(card, chan, WP_NO_WAIT); + aft_init_tx_dev_fifo(card, chan, WP_NO_WAIT); + + } + + + /* Enable Global DMA controler, in order to start the + * fifo cleaning */ + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_GLOBAL_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + + /* For all channels clean Tx/Rx fifos */ + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + + DEBUG_TEST("%s: 3) Init interface fifo %s\n", + card->devname,chan->if_name); + + aft_init_rx_dev_fifo(card, chan, WP_WAIT); + aft_init_tx_dev_fifo(card, chan, WP_WAIT); + + DEBUG_TEST("%s: Clearing Fifo and idle_flag %s\n", + card->devname,chan->if_name); + wan_clear_bit(0,&chan->idle_start); + } +#if 0 + aft_list_dma_chain_regs(card); +#endif + /* For all channels, reprogram Tx/Rx DMA descriptors. + * For Tx also make sure that the BUSY flag is clear + * and previoulsy Tx packet is deallocated */ + + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + + DEBUG_TEST("%s: 4) Init interface %s\n", + card->devname,chan->if_name); + + chan->dma_index=0; + memset(chan->dma_history,0,sizeof(chan->dma_history)); + + aft_reset_rx_chain_cnt(chan); + +#if 0 + aft_list_descriptors(chan); +#endif + + aft_dma_rx(card,chan); + aft_tslot_sync_ctrl(card,chan,1); + + DEBUG_TEST("%s: DMA RX SETUP %s\n", + card->devname,chan->if_name); +#if 0 + aft_list_descriptors(chan); +#endif + } + + /* Clean Tx/Rx Error interrupts, since fifos are now + * empty, and Tx fifo may generate an underrun which + * we want to ignore :) */ + + card->u.aft.tdm_rx_dma_toggle=0; + card->u.aft.tdm_tx_dma_toggle=0; + + for (i=0; iu.aft.num_of_time_slots;i++){ + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + continue; + } + + if (!chan->hdlc_eng){ + aft_reset_tx_chain_cnt(chan); + aft_dma_tx(card,chan); + } + + if (chan->cfg.ss7_enable){ + aft_clear_ss7_force_rx(card,chan); + } + + if (chan->tdmv_zaptel_cfg && !chan->hdlc_eng){ + aft_dma_rx_tdmv(card,chan); + } + } + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + + + /* Enable Global DMA and Error Interrupts */ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + wan_set_bit(AFT_LCFG_DMA_INTR_BIT,®); + + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); + if (card->tdmv_conf.span_no){ + wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + card->u.aft.lcfg_reg=reg; + + + wan_set_bit(0,&card->u.aft.comm_enabled); + DEBUG_EVENT("%s: AFT communications enabled!\n", + card->devname); + + /* Enable Channelized Driver if configured */ + if (card->tdmv_conf.span_no) { + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + +#if 1 + + if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); + + /* Reset Global Fifo for the whole card */ + if (!IS_BRI_CARD(card) || (IS_BRI_CARD(card) && card_use_cnt == 1)) { + wan_set_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + /* Wait for Global Fifo Reset 1ms */ + WP_DELAY(1000); + } + + /* Clear Global Card Fifo reset */ + wan_clear_bit(AFT_CHIPCFG_A108_A104_TDM_FIFO_SYNC_BIT,®); + + /* Enable TDM Quad DMA Ring buffer */ + if (wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status)) { + wan_set_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); + card->hw_iface.fe_set_bit(card->hw,1); + }else{ + wan_clear_bit(AFT_CHIPCFG_A108_A104_TDM_DMA_RINGBUF_BIT,®); + } + +#if 1 + /* Global Acknowledge TDM Interrupt (Kickstart) */ + if (card->adptr_type == A104_ADPTR_4TE1 && + card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + wan_set_bit(AFT_CHIPCFG_A104_TDM_ACK_BIT,®); + } else { + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_RX_INTR_ACK,®); + wan_set_bit(AFT_CHIPCFG_A108_TDM_GLOBAL_TX_INTR_ACK,®); + } + +#endif + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + + DEBUG_EVENT("%s: AFT Global TDM Intr\n", + card->devname); + + } else { + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + DEBUG_EVENT("%s: AFT Per Port TDM Intr\n",card->devname); + } + +#endif + }/* if (card->u.aft.cfg.tdmv_span_no) */ + +#ifdef AFT_WDT_ENABLE + aft_wdt_set(card,AFT_WDTCTRL_TIMEOUT); +#endif + + DEBUG_TEST("%s: %s() end: reg=0x%X!\n" + ,card->devname,__FUNCTION__,reg); + AFT_FUNC_DEBUG(); + +} + +static void disable_data_error_intr(sdla_t *card, unsigned char event) +{ + u32 reg; + int card_use_cnt; + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &card_use_cnt); + + if(IS_BRI_CARD(card) && card_use_cnt > 1){ + return; + } + + DEBUG_TEST("%s: Event = %s\n",__FUNCTION__, + event==DEVICE_DOWN?"Device Down": "Link Down"); + + DEBUG_EVENT("%s: AFT communications disabled! %d\n", + card->devname, card_use_cnt); + + aft_wdt_reset(card); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + wan_clear_bit(AFT_LCFG_DMA_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); + wan_clear_bit(AFT_LCFG_TDMV_INTR_BIT,®); + + + if (IS_BRI_CARD(card)) { + if (card_use_cnt == 1 && event==DEVICE_DOWN){ + /* Disable Front End Interface */ + wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + } + }else{ + if (event==DEVICE_DOWN){ + /* Disable Front End Interface */ + wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,®); + } + } + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + card->u.aft.lcfg_reg=reg; + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_clear_bit(AFT_DMACTRL_GLOBAL_INTR_BIT,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + + + if (event==DEVICE_DOWN){ + wan_set_bit(CARD_DOWN,&card->wandev.critical); + }else{ + if (card->tdmv_conf.span_no){ + DEBUG_EVENT("%s: Starting TDMV 1ms Timer\n", + card->devname); +#ifdef AFT_WDT_ENABLE + aft_wdt_set(card,1); +#endif + } + } + + wan_clear_bit(0,&card->u.aft.comm_enabled); +} + + +/*============================================================================ + * Update communications error and general packet statistics. + */ +static int update_comms_stats(sdla_t* card) +{ + /* 1. On the first timer interrupt, update T1/E1 alarms + * and PMON counters (only for T1/E1 card) (TE1) + */ + + /* TE1 Update T1/E1 alarms */ + if (IS_TE1_CARD(card) && card->hw) { + wan_smp_flag_t smp_flags; + + card->hw_iface.hw_lock(card->hw,&smp_flags); + + if (card->wandev.fe_iface.read_alarm) { + card->wandev.fe_iface.read_alarm(&card->fe, 0); + } + /* TE1 Update T1/E1 perfomance counters */ +#if 0 +#warning "PMON DISABLED DUE TO ERROR" +#else + if (card->wandev.fe_iface.read_pmon) { + wan_smp_flag_t flags; + wan_spin_lock_irq(&card->wandev.lock,&flags); + card->wandev.fe_iface.read_pmon(&card->fe, 0); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + } +#endif + + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } + + return 0; +} + +static void aft_rx_fifo_over_recover(sdla_t *card, private_area_t *chan) +{ + + if (chan->channelized_cfg && !chan->hdlc_eng){ + return; + } + +#if 0 + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s Rx Fifo Recovery!\n", + card->devname,chan->if_name); + } +#endif + + aft_channel_rxdma_ctrl(card, chan, 0); + + aft_tslot_sync_ctrl(card,chan,0); + + aft_free_rx_complete_list(chan); + aft_free_rx_descriptors(chan); + + aft_init_rx_dev_fifo(card, chan, WP_NO_WAIT); + + aft_channel_rxdma_ctrl(card, chan, 1); + + aft_init_rx_dev_fifo(card, chan, WP_WAIT); + + chan->dma_index=0; + memset(chan->dma_history,0,sizeof(chan->dma_history)); + + aft_reset_rx_chain_cnt(chan); + aft_dma_rx(card,chan); + + aft_tslot_sync_ctrl(card,chan,1); + + wanpipe_wake_stack(chan); +} + +static void aft_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) +{ + if (chan->channelized_cfg && !chan->hdlc_eng){ + return; + } + +#if 0 + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s Tx Fifo Recovery!\n", + card->devname,chan->if_name); + } +#endif + /* Enable DMA controler, in order to start the + * fifo cleaning */ + + aft_channel_txdma_ctrl(card, chan, 0); + +#if 0 + aft_list_tx_descriptors(chan); +#endif + aft_dma_tx_complete(card,chan,0, 1); + + aft_free_tx_descriptors(chan); + aft_init_tx_dev_fifo(card,chan,WP_NO_WAIT); + + aft_channel_txdma_ctrl(card, chan, 1); + + aft_init_tx_dev_fifo(card,chan,WP_WAIT); + wan_clear_bit(0,&chan->idle_start); + + aft_reset_tx_chain_cnt(chan); + aft_dma_tx(card,chan); + + wanpipe_wake_stack(chan); +} + +static int set_chan_state(sdla_t* card, netdevice_t* dev, int state) +{ + private_area_t *chan = wan_netif_priv(dev); + private_area_t *ch_ptr; + + if (!chan){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: %s:%d No chan ptr!\n", + card->devname,__FUNCTION__,__LINE__); + } + return -EINVAL; + } + + chan->common.state = state; + for (ch_ptr=chan; ch_ptr != NULL; ch_ptr=ch_ptr->next){ + ch_ptr->common.state=state; + + if (ch_ptr->tdmv_zaptel_cfg) { + continue; + } + + if (ch_ptr->common.usedby == TDM_VOICE_API || + ch_ptr->common.usedby == TDM_VOICE_DCHAN) { +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(ch_ptr,&ch_ptr->wp_tdm_api_dev)) { + wanpipe_tdm_api_update_state(&ch_ptr->wp_tdm_api_dev, state); + } +#endif + } + } + + if (state == WAN_CONNECTED){ + wan_clear_bit(0,&chan->idle_start); + WAN_NETIF_START_QUEUE(dev); + chan->opstats.link_active_count++; + WAN_NETIF_CARRIER_ON(dev); + WAN_NETIF_WAKE_QUEUE(dev); + }else{ + chan->opstats.link_inactive_modem_count++; + WAN_NETIF_CARRIER_OFF(dev); + WAN_NETIF_STOP_QUEUE(dev); + } + +#if defined(__LINUX__) +# if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + if (chan->common.usedby == API) { + wan_update_api_state(chan); + } +#endif +#endif + + if (chan->common.usedby == STACK){ + if (state == WAN_CONNECTED){ + wanpipe_lip_connect(chan,0); + }else{ + wanpipe_lip_disconnect(chan,0); + } + } + +#if defined(NETGRAPH) + if (chan->common.usedby == WP_NETGRAPH){ + wan_ng_link_state(&chan->common, state); + } +#endif + return 0; +} + + + +/**SECTION************************************************************* + * + * Protocol API Support Functions + * + **********************************************************************/ + + +static int protocol_init (sdla_t *card, netdevice_t *dev, + private_area_t *chan, + wanif_conf_t* conf) +{ + + chan->common.protocol = conf->protocol; + + DEBUG_TEST("%s: Protocol init 0x%X PPP=0x0%x FR=0x0%X\n", + wan_netif_name(dev), chan->common.protocol, + WANCONFIG_PPP, + WANCONFIG_FR); + +#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + DEBUG_EVENT("%s: AFT Driver doesn't directly support any protocols!\n", + chan->if_name); + return -1; + +#else + if (chan->common.protocol == WANCONFIG_PPP || + chan->common.protocol == WANCONFIG_CHDLC){ + + struct ifreq ifr; + struct if_settings ifsettings; + + wanpipe_generic_register(card, dev, wan_netif_name(dev)); + chan->common.prot_ptr = dev; + + if (chan->common.protocol == WANCONFIG_CHDLC){ + DEBUG_EVENT("%s: Starting Kernel CISCO HDLC protocol\n", + chan->if_name); + ifsettings.type = IF_PROTO_CISCO; + }else{ + DEBUG_EVENT("%s: Starting Kernel Sync PPP protocol\n", + chan->if_name); + ifsettings.type = IF_PROTO_PPP; + + } + ifr.ifr_data = (caddr_t)&ifsettings; + if (wp_lite_set_proto(dev, &ifr)){ + wanpipe_generic_unregister(dev); + return -EINVAL; + } + + }else if (chan->common.protocol == WANCONFIG_GENERIC){ + chan->common.prot_ptr = dev; + + }else{ + DEBUG_EVENT("%s:%s: Unsupported protocol %d\n", + card->devname,chan->if_name,chan->common.protocol); + return -EPROTONOSUPPORT; + } +#endif + + return 0; +} + + +static int protocol_stop (sdla_t *card, netdevice_t *dev) +{ + private_area_t *chan=wan_netif_priv(dev); + int err = 0; + + if (!chan) + return 0; + + return err; +} + +static int protocol_shutdown (sdla_t *card, netdevice_t *dev) +{ + private_area_t *chan=wan_netif_priv(dev); + + if (!chan) + return 0; + +#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC + + return 0; +#else + + if (chan->common.protocol == WANCONFIG_PPP || + chan->common.protocol == WANCONFIG_CHDLC){ + + chan->common.prot_ptr = NULL; + wanpipe_generic_unregister(dev); + + }else if (chan->common.protocol == WANCONFIG_GENERIC){ + DEBUG_EVENT("%s:%s Protocol shutdown... \n", + card->devname, chan->if_name); + } +#endif + return 0; +} + +void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb) +{ + +#ifdef CONFIG_PRODUCT_WANPIPE_GENERIC + if (chan->common.protocol == WANCONFIG_PPP || + chan->common.protocol == WANCONFIG_CHDLC){ + wanpipe_generic_input(chan->common.dev, skb); + return 0; + } + +#if defined(__LINUX__) + if (chan->common.protocol == WANCONFIG_GENERIC){ + skb->protocol = htons(ETH_P_HDLC); + skb->dev = chan->common.dev; + skb->mac.raw = wan_netif_data(skb); + netif_rx(skb); + return 0; + } +#endif + +#endif + +#if defined(__LINUX__) + + skb->protocol = htons(ETH_P_IP); + skb->dev = chan->common.dev; + skb->mac.raw = wan_skb_data(skb); + netif_rx(skb); + +#elif defined(__FreeBSD__) + + wan_skb_set_csum(skb,0); + + if (wan_iface.input && wan_iface.input(chan->common.dev, skb) != 0){ + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //++chan->if_stats.rx_dropped; + wan_skb_free(skb); + return; + } + +#else + DEBUG_EVENT("%s: Action not supported (IP)!\n", + card->devname); + wan_skb_free(skb); +#endif + + return; +} + + +/**SECTION************************************************************* + * + * TE1 Config Code + * + **********************************************************************/ +static int aft_global_chip_configuration(sdla_t *card, wandev_conf_t* conf) +{ + int err=0; + + err = aft_hwdev[card->wandev.card_type].aft_global_chip_config(card); + return err; +} + +static int aft_global_chip_disable(sdla_t *card) +{ + + aft_hwdev[card->wandev.card_type].aft_global_chip_unconfig(card); + + return 0; +} + +/*========================================================= + * aft_chip_configure + * + */ + +static int aft_chip_configure(sdla_t *card, wandev_conf_t* conf) +{ + + return aft_hwdev[card->wandev.card_type].aft_chip_config(card); +} + +static int aft_chip_unconfigure(sdla_t *card) +{ + u32 reg=0; + + AFT_FUNC_DEBUG(); + + wan_set_bit(CARD_DOWN,&card->wandev.critical); + + aft_hwdev[card->wandev.card_type].aft_chip_unconfig(card); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),&card->u.aft.lcfg_reg); + card->u.aft.lcfg_reg=reg; + return 0; +} + + +static int aft_dev_configure(sdla_t *card, private_area_t *chan, wanif_conf_t* conf) +{ + chan->logic_ch_num=-1; + + /* Channel definition section. If not channels defined + * return error */ + if (chan->time_slot_map == 0){ + DEBUG_EVENT("%s: Invalid Channel Selection 0x%lX\n", + card->devname,chan->time_slot_map); + return -EINVAL; + } + + + DEBUG_EVENT("%s: Active Ch Map :0x%08lX\n", + card->devname,chan->time_slot_map); + + + DEBUG_TEST("%s:%d: GOT Logic ch %ld Base 0x%X Size=0x%X\n", + __FUNCTION__,__LINE__,chan->logic_ch_num, + chan->fifo_base_addr, chan->fifo_size_code); + + + return aft_hwdev[card->wandev.card_type].aft_chan_config(card,chan); +} + +static void aft_dev_unconfigure(sdla_t *card, private_area_t *chan) +{ + aft_hwdev[card->wandev.card_type].aft_chan_unconfig(card,chan); + return ; +} + + +#define BIT_DEV_ADDR_CLEAR 0x600 + + + +/**SECTION************************************************************* + * + * TE1 Tx Functions + * DMA Chains + * + **********************************************************************/ + + +/*=============================================== + * aft_tx_dma_voice_handler + * + */ +static void aft_tx_dma_voice_handler(unsigned long data, int wdt, int reset) +{ + private_area_t *chan = (private_area_t *)data; + sdla_t *card = chan->card; + u32 reg,dma_descr,dma_status; + wan_dma_descr_t *dma_chain; + + if (wan_test_and_set_bit(TX_HANDLER_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return; + } + + dma_chain = &chan->tx_dma_chain_table[0]; + + if (reset){ + wan_clear_bit(0,&dma_chain->init); + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + card->hw_iface.bus_write_4(card->hw,dma_descr,0); + goto aft_tx_dma_voice_handler_exit; + } + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (!wan_test_bit(0,&dma_chain->init)){ + goto aft_tx_dma_voice_handler_exit; + } + + dma_descr=(chan->logic_ch_num<<4) + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + goto aft_tx_dma_voice_handler_exit; + } + + dma_status = aft_txdma_hi_get_dma_status(reg); + + if (reg & AFT_TXDMA_HI_DMA_LENGTH_MASK){ + chan->errstats.Tx_dma_len_nonzero++; + chan->errstats.Tx_dma_errors++; + } + + if (dma_status){ + + DEBUG_TEST("%s:%s: Tx DMA Descriptor=0x%X\n", + card->devname,chan->if_name,reg); + + + /* Checking Tx DMA PCI error status. Has to be '0's */ + if (dma_status){ + + chan->errstats.Tx_pci_errors++; + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_M_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Master: pci fatal error!\n", + card->devname,chan->if_name); + } + + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_T_ABRT,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: Abort from Target: pci fatal error!\n", + card->devname,chan->if_name); + } + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_DS_TOUT,&dma_status)){ + DEBUG_TEST("%s:%s: Tx Warning: PCI Latency Timeout!\n", + card->devname,chan->if_name); + chan->errstats.Tx_pci_latency++; + goto aft_tx_dma_voice_handler_exit; + } + if (wan_test_bit(AFT_TXDMA_HIDMASTATUS_PCI_RETRY,&dma_status)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s:%s: Tx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", + card->devname,chan->if_name); + } + } + } + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; + } + + + chan->opstats.Data_frames_Tx_count++; + chan->opstats.Data_bytes_Tx_count+=wan_skb_len(dma_chain->skb); + WAN_NETIF_STATS_INC_TX_PACKETS(&chan->common); //chan->if_stats.tx_packets++; + WAN_NETIF_STATS_INC_TX_BYTES(&chan->common,wan_skb_len(dma_chain->skb)); //chan->if_stats.tx_bytes+=wan_skb_len(dma_chain->skb); + + wan_clear_bit(0,&dma_chain->init); + +aft_tx_dma_voice_handler_exit: + wan_clear_bit(TX_HANDLER_BUSY,&chan->dma_status); + + return; +} + + + +/*=============================================== + * aft_tx_dma_chain_handler + * + */ +static void aft_tx_dma_chain_handler(unsigned long data, int wdt, int reset) +{ + private_area_t *chan = (private_area_t *)data; + sdla_t *card = chan->card; + u32 reg,dma_descr; + wan_dma_descr_t *dma_chain; + + if (wan_test_and_set_bit(TX_HANDLER_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return; + } + + dma_chain = &chan->tx_dma_chain_table[chan->tx_pending_chain_indx]; + + for (;;){ + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (!wan_test_bit(0,&dma_chain->init)){ + break; + } + + dma_descr=(chan->logic_ch_num<<4) + (chan->tx_pending_chain_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + break; + } + + if (!wan_test_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®)){ + wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); + if (wdt){ + DEBUG_TEST("%s:%s TX WDT Timer got Interrtup pkt!\n", + card->devname,chan->if_name); + } + } + + + DEBUG_TEST("%s: TX DMA Handler Chain %d\n",chan->if_name,dma_chain->index); + + if (chan->hdlc_eng){ + + if (dma_chain->skb == chan->tx_hdlc_rpt_skb) { + if (wan_skb_queue_len(&chan->wp_tx_hdlc_rpt_list) == 0) { + wan_skb_queue_tail(&chan->wp_tx_hdlc_rpt_list,dma_chain->skb); + dma_chain->skb=NULL; + } else { + /* Drop down to init where packet will freed */ + } + chan->tx_hdlc_rpt_skb=NULL; + + } else if (dma_chain->skb){ + wan_skb_set_csum(dma_chain->skb, reg); + wan_skb_queue_tail(&chan->wp_tx_complete_list,dma_chain->skb); + dma_chain->skb=NULL; + } + } else { + if (dma_chain->skb != chan->tx_idle_skb){ + + wan_skb_set_csum(dma_chain->skb, reg); + aft_tx_post_complete(chan->card,chan,dma_chain->skb); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + /* Voice code uses the rx buffer to + * transmit! So put the rx buffer back + * into the rx queue */ + aft_init_requeue_free_skb(chan, dma_chain->skb); + }else{ + wan_skb_free(dma_chain->skb); + } + + dma_chain->skb=NULL; + } + } + + aft_tx_dma_chain_init(chan,dma_chain); + + if (chan->single_dma_chain){ + break; + } + + if (++chan->tx_pending_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->tx_pending_chain_indx=0; + } + + dma_chain = &chan->tx_dma_chain_table[chan->tx_pending_chain_indx]; + + } + + wan_clear_bit(TX_HANDLER_BUSY,&chan->dma_status); + + if (wan_skb_queue_len(&chan->wp_tx_complete_list)){ + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + } + + return; +} + +/*=============================================== + * aft_dma_chain_tx + * + */ +static int aft_dma_chain_tx(wan_dma_descr_t *dma_chain,private_area_t *chan, int intr,int fifo) +{ + +#define dma_descr dma_chain->dma_descr +#define reg dma_chain->reg +#define dma_ch_indx dma_chain->index +#define len_align dma_chain->len_align +#define card chan->card + + unsigned int len = dma_chain->dma_len; + unsigned int ss7_ctrl=0; + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + DEBUG_DMA("%s: %s:%s: LogicCh=%ld ChIndex=%d DmaDesc=0x%x set\n", + __FUNCTION__, card->devname, chan->if_name, + chan->logic_ch_num,dma_ch_indx,dma_descr); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + if (wan_test_bit(AFT_TXDMA_HI_GO_BIT,®)){ + DEBUG_EVENT("%s: Error: TxDMA GO Ready bit set on dma (chain=0x%X) Desc=0x%X Tx 0x%X\n", + card->devname,dma_descr,dma_ch_indx,reg); + /* Nothing we can do here, just reset + descriptor and keep going */ + card->hw_iface.bus_write_4(card->hw,dma_descr,0); + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + } + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_LO_DESCR_BASE_REG); + + /* Write the pointer of the data packet to the + * DMA address register */ + reg=dma_chain->dma_addr; + + + if (chan->cfg.ss7_enable){ + ss7_ctrl=wan_skb_csum(dma_chain->skb); + wan_skb_set_csum(dma_chain->skb,0); + if (ss7_ctrl&AFT_SS7_CTRL_LEN_MASK){ + len-=4; + len+=ss7_ctrl&AFT_SS7_CTRL_LEN_MASK; + } + if (!wan_test_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl)){ + /*FISU*/ + if (chan->cfg.ss7_mode == WANOPT_SS7_MODE_4096){ + len-=WANOPT_SS7_FISU_4096_SZ; + }else{ + len-=WANOPT_SS7_FISU_128_SZ; + } + }else{ + /*LSSU*/ + len-=chan->cfg.ss7_lssu_size; + } + } + + /* Set the 32bit alignment of the data length. + * Used to pad the tx packet to the 32 bit + * boundary */ + aft_txdma_lo_set_alignment(®,len); + + len_align=0; + if (len&0x03){ + len_align=1; + } + + DEBUG_DMA("%s: %s:%s: TXDMA_LO=0x%X PhyAddr=0x%X DmaDescr=0x%X Len=%d\n", + __FUNCTION__,card->devname,chan->if_name, + reg,dma_chain->dma_addr,dma_descr,len); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + reg=0; + + if (chan->cfg.ss7_enable){ + if (wan_test_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl)){ + wan_set_bit(AFT_TXDMA_HI_SS7_FISU_OR_LSSU_BIT,®); + }else{ + wan_clear_bit(AFT_TXDMA_HI_SS7_FISU_OR_LSSU_BIT,®); + } + if (wan_test_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl)){ + wan_set_bit(AFT_TXDMA_HI_SS7_FI_LS_FORCE_TX_BIT,®); + }else{ + wan_clear_bit(AFT_TXDMA_HI_SS7_FI_LS_FORCE_TX_BIT,®); + } + } + + aft_txdma_hi_set_dma_length(®,len,len_align); + + if (chan->single_dma_chain){ + wan_clear_bit(AFT_TXDMA_HI_LAST_DESC_BIT,®); + wan_clear_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + wan_set_bit(AFT_TXDMA_HI_LAST_DESC_BIT,®); + } + }else{ + wan_set_bit(AFT_TXDMA_HI_LAST_DESC_BIT,®); + + if (intr){ + DEBUG_TEST("%s: Setting Interrupt on index=%d\n", + chan->if_name,dma_ch_indx); + wan_clear_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®); + }else{ + wan_set_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®); + } + } + + if (chan->hdlc_eng){ + /* Only enable the Frame Start/Stop on + * non-transparent hdlc configuration */ + wan_set_bit(AFT_TXDMA_HI_START_BIT,®); + wan_set_bit(AFT_TXDMA_HI_EOF_BIT,®); + }else{ + /* Used for transparent time slot + * synchronization */ + + if (chan->tslot_sync){ + wan_set_bit(AFT_TXDMA_HI_START_BIT,®); + } + } + + wan_set_bit(AFT_TXDMA_HI_GO_BIT,®); + if (fifo){ + /* Clear fifo command */ + wan_set_bit(AFT_TXDMA_HI_DMA_CMD_BIT,®); + } + + DEBUG_DMA("%s:: %s:%s: TXDMA_HI=0x%X DmaDescr=0x%X Len=%d Intr=%d\n", + __FUNCTION__,card->devname,chan->if_name, + reg,dma_descr,len,intr); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + +#if 1 + ++chan->tx_attempts; +#endif + + return 0; + +#undef dma_descr +#undef reg +#undef dma_ch_indx +#undef len_align +#undef card +} + +/*=============================================== + * aft_dma_chain_init + * + */ +static void aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain) +{ +#define card chan->card + + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, 1, + SDLA_DMA_POSTWRITE); + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTWRITE); + + if (dma_chain->skb){ + if (!chan->hdlc_eng){ + if (dma_chain->skb != chan->tx_idle_skb){ + if (chan->channelized_cfg && !chan->hdlc_eng){ + aft_init_requeue_free_skb(chan, dma_chain->skb); + }else{ + wan_skb_free(dma_chain->skb); + } + } + dma_chain->skb=NULL; + }else{ + wan_skb_free(dma_chain->skb); + dma_chain->skb=NULL; + } + } + wan_clear_bit(0,&dma_chain->init); +#undef card +} + +static void aft_rx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain) +{ +#define card chan->card + + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, 1, + SDLA_DMA_POSTREAD); + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTREAD); + + if (dma_chain->skb){ + aft_init_requeue_free_skb(chan,dma_chain->skb); + dma_chain->skb = NULL; + } + wan_clear_bit(0,&dma_chain->init); +#undef card +} + + + +static int aft_dma_voice_tx(sdla_t *card, private_area_t *chan) +{ + int err=0; + wan_dma_descr_t *dma_chain; + u32 reg, dma_ram_desc; + + if (wan_test_and_set_bit(TX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + + return -EBUSY; + } + + dma_chain = &chan->tx_dma_chain_table[0]; + + DEBUG_DMA("%s: %s:%s:: Chain %d Used %ld\n", + __FUNCTION__,card->devname,chan->if_name, + dma_chain->index,dma_chain->init); + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + err=-EBUSY; + goto aft_dma_voice_tx_exit; + } + + if (!dma_chain->skb){ + unsigned char *buf; + + /* Take already preallocated buffer from rx queue. + * We are only using a single buffer for rx and tx */ + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!dma_chain->skb){ + DEBUG_EVENT("%s: Warning Tx chain = %d: no free tx bufs\n", + chan->if_name,dma_chain->index); + wan_clear_bit(0,&dma_chain->init); + err=-EINVAL; + goto aft_dma_voice_tx_exit; + } + + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + + /*NC: We must set the initial value of the + * frist DMA TX transfer to 2*MTU. This is + * to avoid potential Tx FIFO underrun. + * + * This is equivalent of transmitting twice + * very fist time. */ + + + buf=wan_skb_put(dma_chain->skb,chan->mtu*2); + memset(buf,chan->idle_flag,chan->mtu*2); + + /* A-DMA */ + card->hw_iface.busdma_map( card->hw, + dma_chain, + wan_skb_data(dma_chain->skb), + wan_skb_len(dma_chain->skb), + chan->dma_mru, + SDLA_DMA_PREWRITE); + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, 1, + SDLA_DMA_PREWRITE); + } + + dma_ram_desc=chan->logic_ch_num*4 + + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_tx_dma_addr(®,1); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + + /* We set inital TX DMA with FIFO Reset option. This funciton + * will ONLY run once in TDM mode. After the inital TX the + * DMA Reload will be used to tx the Voice frame */ + err=aft_dma_chain_tx(dma_chain,chan,1,1); + if (err){ + DEBUG_EVENT("%s: Tx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + + /* Drop the tx packet here */ + aft_tx_dma_chain_init(chan,dma_chain); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; + err=-EINVAL; + goto aft_dma_voice_tx_exit; + } + +aft_dma_voice_tx_exit: + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + + return 0; +} + +/*=============================================== + * aft_dma_tx + * + */ +static int aft_dma_tx (sdla_t *card,private_area_t *chan) +{ + int err=0, intr=0, cnt=0; + wan_dma_descr_t *dma_chain; + netskb_t *skb=NULL; + + if (chan->channelized_cfg && !chan->hdlc_eng){ + return aft_dma_voice_tx(card,chan); + } + + if (wan_test_and_set_bit(TX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + + return -EBUSY; + } + + if (chan->tx_chain_indx >= MAX_AFT_DMA_CHAINS){ + DEBUG_EVENT("%s: MAJOR ERROR: TE1 Tx: Dma tx chain = %d\n", + chan->if_name,chan->tx_chain_indx); + return -EBUSY; + } + + + /* The cnt is not used, its used only as a + * sanity check. The code below should break + * out of the loop before MAX_TX_BUF runs out! */ + for (cnt=0;cnttx_dma_chain_table[chan->tx_chain_indx]; + + /* FIXME: Reset TX Watchdog */ + /* aft_reset_tx_watchdog(card); */ + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + break; + } + + if(!chan->lip_atm){ + skb=wan_skb_dequeue(&chan->wp_tx_pending_list); + }else{ + skb=atm_tx_skb_dequeue(&chan->wp_tx_pending_list, chan->tx_idle_skb, chan->if_name); + } + + if (!skb){ + if (!chan->hdlc_eng){ + + skb=chan->tx_idle_skb; + if (!skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical Error: Transparent tx no skb!\n", + chan->if_name); + } + break; + } + + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); + + } else { + if (chan->cfg.hdlc_repeat) { + /* Pull the latest repeat frame out of the + repeat queue */ + for (;;) { + skb=wan_skb_dequeue(&chan->wp_tx_hdlc_rpt_list); + if (!skb) { + break; + } + if (wan_skb_queue_len(&chan->wp_tx_hdlc_rpt_list)){ + wan_skb_free(skb); + } else { + break; + } + } + + if (skb) { + chan->tx_hdlc_rpt_skb=skb; + } else { + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); + /* Pass throught to no skb condition */ + } + } + + if (!skb) { + wan_clear_bit(0,&dma_chain->init); + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + break; + } + } + } + + if ((unsigned long)wan_skb_data(skb) & 0x03){ + + err=aft_realign_skb_pkt(chan,skb); + if (err){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Tx Error: Non Aligned packet %p: dropping...\n", + chan->if_name,wan_skb_data(skb)); + } + wan_skb_free(skb); + aft_tx_dma_chain_init(chan,dma_chain); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; + chan->opstats.Tx_Data_discard_lgth_err_count++; + continue; + } + } + + + if (!chan->hdlc_eng && (wan_skb_len(skb)%4)){ + + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Tx Error: Tx Length %i not 32bit aligned: dropping...\n", + chan->if_name,wan_skb_len(skb)); + } + wan_skb_free(skb); + aft_tx_dma_chain_init(chan,dma_chain); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; + chan->opstats.Tx_Data_discard_lgth_err_count++; + continue; + } + + dma_chain->skb=skb; + + /* A-DMA */ + card->hw_iface.busdma_map( card->hw, + dma_chain, + wan_skb_data(dma_chain->skb), + wan_skb_len(dma_chain->skb), + wan_skb_len(dma_chain->skb), + SDLA_DMA_PREWRITE); + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_PREWRITE); + + DEBUG_TEST("%s: DMA Chain %d: Cur=%d Pend=%d\n", + chan->if_name,dma_chain->index, + chan->tx_chain_indx,chan->tx_pending_chain_indx); + + intr=0; + if (!wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status)){ + int pending_indx=chan->tx_pending_chain_indx; + if (chan->tx_chain_indx >= pending_indx){ + intr = ((MAX_AFT_DMA_CHAINS-(chan->tx_chain_indx - + pending_indx))<=2); + }else{ + intr = ((pending_indx - chan->tx_chain_indx)<=2); + } + + if (intr){ + DEBUG_TEST("%s: Setting tx interrupt on chain=%d\n", + chan->if_name,dma_chain->index); + wan_set_bit(TX_INTR_PENDING,&chan->dma_chain_status); + } + } + + + err=aft_dma_chain_tx(dma_chain,chan,intr,0); + if (err){ + DEBUG_EVENT("%s: Tx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + + +#if 0 + aft_list_tx_descriptors(chan); + aft_critical_shutdown(card); + break; +#endif + + /* Drop the tx packet here */ + aft_tx_dma_chain_init(chan,dma_chain); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //chan->if_stats.tx_errors++; + break; + } + + if (skb){ + wan_capture_trace_packet(card, &chan->trace_info, skb, TRC_OUTGOING_FRM); + } + + if (chan->single_dma_chain){ + break; + }else{ + if (++chan->tx_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->tx_chain_indx=0; + } + } + } + + wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); + + return 0; +} + + + +/**SECTION************************************************************* + * + * TE1 Rx Functions + * DMA Chains + * + **********************************************************************/ + +static int aft_dma_chain_rx(wan_dma_descr_t *dma_chain, private_area_t *chan, int intr, int fifo) +{ +#define dma_descr dma_chain->dma_descr +#define reg dma_chain->reg +#define len dma_chain->dma_len +#define dma_ch_indx dma_chain->index +#define len_align dma_chain->len_align +#define card chan->card + + /* Write the pointer of the data packet to the + * DMA address register */ + reg=dma_chain->dma_addr; + + /* Set the 32bit alignment of the data length. + * Since we are setting up for rx, set this value + * to Zero */ + aft_rxdma_lo_set_alignment(®,0); + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + DEBUG_DMA("%s: %s:%s: RxDMA_LO(%ld) = 0x%X, PhyAddr:%X DmaDescr=0x%X (%p)\n", + __FUNCTION__,card->devname,chan->if_name, + chan->logic_ch_num,reg, + dma_chain->dma_addr, dma_descr,dma_chain); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + dma_descr=(chan->logic_ch_num<<4) + (dma_ch_indx*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + reg =0; + + if (chan->single_dma_chain){ + wan_clear_bit(AFT_RXDMA_HI_LAST_DESC_BIT,®); + wan_clear_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®); + + if (chan->channelized_cfg && !chan->hdlc_eng){ + wan_set_bit(AFT_RXDMA_HI_LAST_DESC_BIT,®); + } + + }else{ + wan_set_bit(AFT_RXDMA_HI_LAST_DESC_BIT,®); + +#if AFT_IFT_INTR_ENABLE + wan_set_bit(AFT_RXDMA_HI_IFT_INTR_ENB_BIT,®); +#else + wan_clear_bit(AFT_RXDMA_HI_IFT_INTR_ENB_BIT,®); +#endif + + if (intr){ + DEBUG_TEST("%s: Setting Rx Interrupt on index=%d\n", + chan->if_name,dma_ch_indx); + wan_clear_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®); + }else{ + wan_set_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®); + } + } + + if (chan->hdlc_eng){ + aft_rxdma_hi_set_dma_length(®,chan->dma_mru,1); + }else{ + aft_rxdma_hi_set_dma_length(®,chan->mru,0); + } + + wan_set_bit(AFT_RXDMA_HI_GO_BIT,®); + if (fifo){ + wan_set_bit(AFT_RXDMA_HI_DMA_CMD_BIT,®); + } + + DEBUG_DMA("%s: %s:%s: RXDMA_HI(%ld) = 0x%X, DmaDescr=0x%X\n", + __FUNCTION__,card->devname,chan->if_name, + chan->logic_ch_num,reg,dma_descr); + + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + return 0; + +#undef dma_descr +#undef reg +#undef len +#undef dma_ch_indx +#undef len_align +#undef card +} + +static int aft_dma_voice_rx(sdla_t *card, private_area_t *chan) +{ + int err=0; + wan_dma_descr_t *dma_chain; + u32 reg, dma_ram_desc; + + if (wan_test_and_set_bit(RX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return -EBUSY; + } + + dma_chain = &chan->rx_dma_chain_table[0]; + + DEBUG_DMA("%s: %s:%s: Chain %d Used %ld\n", + __FUNCTION__,card->devname,chan->if_name, + dma_chain->index,dma_chain->init); + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + DEBUG_TEST("%s: Warning: %s():%d dma chain busy %d!\n", + card->devname, __FUNCTION__, __LINE__, + dma_chain->index); + err=-EBUSY; + goto aft_dma_single_chain_rx_exit; + } + + /* This will only be done on the first time. The dma_chain + * skb will be re-used all the time, thus no need for + * rx_free_list any more */ + if (!dma_chain->skb){ + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!dma_chain->skb){ + DEBUG_EVENT("%s: Warning Rx Voice chain = %d: no free rx bufs\n", + chan->if_name,dma_chain->index); + wan_clear_bit(0,&dma_chain->init); + err=-EINVAL; + goto aft_dma_single_chain_rx_exit; + } + + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + + /* A-DMA */ + card->hw_iface.busdma_map( card->hw, + dma_chain, + wan_skb_tail(dma_chain->skb), + chan->dma_mru, + chan->dma_mru, + SDLA_DMA_PREREAD); + card->hw_iface.busdma_sync( card->hw, + dma_chain, + MAX_AFT_DMA_CHAINS, chan->single_dma_chain, + SDLA_DMA_PREREAD); + DEBUG_DMA("%s: RXDMA PHY = 0x%08X VIRT = %p \n", + chan->if_name, + dma_chain->dma_addr,wan_skb_tail(dma_chain->skb)+dma_chain->dma_offset); + }else{ + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + } + + dma_ram_desc=chan->logic_ch_num*4 + + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + aft_dmachain_set_rx_dma_addr(®,1); + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + + err=aft_dma_chain_rx(dma_chain,chan,1,1); + if (err){ + DEBUG_EVENT("%s: Rx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + aft_rx_dma_chain_init(chan,dma_chain); + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; + } + +aft_dma_single_chain_rx_exit: + + wan_clear_bit(RX_DMA_BUSY,&chan->dma_status); + return err; +} + + +static int aft_dma_rx(sdla_t *card, private_area_t *chan) +{ + int err=0, intr=0; + wan_dma_descr_t *dma_chain; + int cur_dma_ptr, i,max_dma_cnt,free_queue_len; + u32 reg, dma_ram_desc; + + if (chan->channelized_cfg && !chan->hdlc_eng){ + return aft_dma_voice_rx(card,chan); + } + + if (wan_test_and_set_bit(RX_DMA_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return -EBUSY; + } + + free_queue_len=wan_skb_queue_len(&chan->wp_rx_free_list); + if (!chan->single_dma_chain && + free_queue_len < MAX_AFT_DMA_CHAINS){ + aft_free_rx_complete_list(chan); + free_queue_len=wan_skb_queue_len(&chan->wp_rx_free_list); + if (free_queue_len < MAX_AFT_DMA_CHAINS){ + DEBUG_EVENT("%s: %s() CRITICAL ERROR: No free rx buffers\n", + card->devname,__FUNCTION__); + goto te1rx_skip; + } + } + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + +#if 0 + aft_chain_history(chan,chan->rx_chain_indx, cur_dma_ptr, chan->rx_pending_chain_indx,1); +#endif + max_dma_cnt = MAX_AFT_DMA_CHAINS; + + if (!chan->single_dma_chain && + free_queue_len < max_dma_cnt){ + max_dma_cnt = free_queue_len; + } + + DEBUG_RX("%s: (line: %d) DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", + card->devname, __LINE__, cur_dma_ptr,chan->rx_chain_indx,max_dma_cnt); + + for (i=0;irx_dma_chain_table[chan->rx_chain_indx]; + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (wan_test_and_set_bit(0,&dma_chain->init)){ + DEBUG_TEST("%s: Warning: %s():%d dma chain busy %d!\n", + card->devname, __FUNCTION__, __LINE__, + dma_chain->index); + + err=-EBUSY; + break; + } + + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!dma_chain->skb){ + /* If this ever happends, it means that wp_bh is stuck for some + * reason, thus start using the completed buffers, thus + * overflow the data */ + dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_complete_list); + if (dma_chain->skb) { + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //chan->if_stats.rx_dropped++; + wan_skb_init(dma_chain->skb,16); + wan_skb_trim(dma_chain->skb,0); + }else{ + DEBUG_EVENT("%s: Critical Rx chain = %d: no free rx bufs (Free=%i Comp=%i)\n", + chan->if_name,dma_chain->index, + wan_skb_queue_len(&chan->wp_rx_free_list), + wan_skb_queue_len(&chan->wp_rx_complete_list)); + wan_clear_bit(0,&dma_chain->init); + + aft_critical_shutdown(card); + err=-EINVAL; + break; + } + + } + + card->hw_iface.busdma_map( card->hw, + dma_chain, + wan_skb_tail(dma_chain->skb), + chan->dma_mru, + chan->dma_mru, + SDLA_DMA_PREREAD); + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_PREREAD); + intr=0; + if (!wan_test_bit(RX_INTR_PENDING,&chan->dma_chain_status)){ + + free_queue_len--; + + if (free_queue_len <= 2){ + DEBUG_TEST("%s: DBG: Setting intr queue size low\n", + card->devname); + intr=1; + }else{ + if (chan->rx_chain_indx >= cur_dma_ptr){ + intr = ((MAX_AFT_DMA_CHAINS - + (chan->rx_chain_indx-cur_dma_ptr)) <=4); + }else{ + intr = ((cur_dma_ptr - chan->rx_chain_indx)<=4); + } + } + + if (intr){ + DEBUG_TEST("%s: Setting Rx interrupt on chain=%d\n", + chan->if_name,dma_chain->index); + wan_set_bit(RX_INTR_PENDING,&chan->dma_chain_status); + } + } + + DEBUG_TEST("%s: Setting Buffer on Rx Chain = %d Intr=%d\n", + chan->if_name,dma_chain->index, intr); + + err=aft_dma_chain_rx(dma_chain,chan,intr,0); + if (err){ + DEBUG_EVENT("%s: Rx dma chain %d overrun error: should never happen!\n", + chan->if_name,dma_chain->index); + aft_rx_dma_chain_init(chan,dma_chain); + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //chan->if_stats.rx_errors++; + break; + } + + if (chan->single_dma_chain){ + break; + }else{ + if (++chan->rx_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->rx_chain_indx=0; + } + } + } + +#if 0 + aft_chain_history(chan,chan->rx_chain_indx, cur_dma_ptr, chan->rx_pending_chain_indx,2); + + if (chan->rx_chain_indx == cur_dma_ptr && + chan->rx_pending_chain_indx == cur_dma_ptr && + cur_dma_ptr != 0){ + DEBUG_EVENT("%s :Location 1 Listing Descr!\n", + chan->if_name); + aft_list_descriptors(chan); + } +#endif + aft_rx_cur_go_test(chan); + +te1rx_skip: + + wan_clear_bit(RX_DMA_BUSY,&chan->dma_status); + + return err; +} + +/*=============================================== + * aft_rx_dma_chain_handler + * + */ +/*N1*/ +static int aft_rx_dma_chain_handler(private_area_t *chan, int reset) +{ + sdla_t *card = chan->card; + u32 reg,dma_descr; + wp_rx_element_t *rx_el; + wan_dma_descr_t *dma_chain; + int i,max_dma_cnt, cur_dma_ptr; + int rx_data_available=0; + u32 dma_ram_desc; + + if (wan_test_and_set_bit(RX_HANDLER_BUSY,&chan->dma_status)){ + DEBUG_EVENT("%s: SMP Critical in %s\n", + chan->if_name,__FUNCTION__); + return rx_data_available; + } + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + max_dma_cnt = MAX_AFT_DMA_CHAINS; + + DEBUG_RX("%s: (line: %d) DMA RX: CBoardPtr=%d Driver=%d MaxDMA=%d\n", + card->devname, __LINE__, + cur_dma_ptr, + chan->rx_chain_indx,max_dma_cnt); + +#if 0 + aft_chain_history(chan,chan->rx_chain_indx, cur_dma_ptr, chan->rx_pending_chain_indx,3); +#endif + + + for (i=0;irx_dma_chain_table[chan->rx_pending_chain_indx]; + + if (i>0 && chan->rx_pending_chain_indx == cur_dma_ptr){ + break; + } + + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + /* If the current DMA chain is in use,then + * all chains are busy */ + if (!wan_test_bit(0,&dma_chain->init)){ + DEBUG_TEST("%s: Warning (%s) Pending chain %d empty!\n", + chan->if_name,__FUNCTION__,dma_chain->index); + + break; + } + + dma_descr=(chan->logic_ch_num<<4) + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + if (wan_test_bit(AFT_RXDMA_HI_GO_BIT,®)){ + if (wan_test_bit(WP_FIFO_ERROR_BIT, &chan->pkt_error)){ + break; + } + +#if 0 + if (chan->single_dma_chain){ + DEBUG_EVENT("%s: CRITICAL (%s) Pending chain %d Go bit still set!\n", + chan->if_name,__FUNCTION__,dma_chain->index); + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; + }else{ + DEBUG_TEST("%s: Warning (%s) Pending chain %d Go bit still set!\n", + chan->if_name,__FUNCTION__,dma_chain->index); + } +#endif + break; + } + + if (!wan_test_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®)){ + wan_clear_bit(RX_INTR_PENDING,&chan->dma_chain_status); + } + + if (sizeof(wp_rx_element_t) > wan_skb_headroom(dma_chain->skb)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Rx error: rx_el=%u > max head room=%u\n", + chan->if_name, + (u32)sizeof(wp_rx_element_t), + (u32)wan_skb_headroom(dma_chain->skb)); + } + + aft_init_requeue_free_skb(chan, dma_chain->skb); + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; + goto rx_hndlr_skip_rx; + }else{ + rx_el=(wp_rx_element_t *)wan_skb_push(dma_chain->skb, + sizeof(wp_rx_element_t)); + memset(rx_el,0,sizeof(wp_rx_element_t)); + } +#if 0 + WAN_NETIF_STATS_INC_RX_FRAME_ERRORS(&chan->common); //chan->if_stats.rx_frame_errors++; +#endif + + /* Reading Rx DMA descriptor information */ + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->align); + rx_el->align&=AFT_RXDMA_LO_ALIGN_MASK; + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->reg); + + /* New for FreeBSD/Solaris */ + rx_el->len=rx_el->reg&AFT_RXDMA_HI_DMA_LENGTH_MASK; + if (chan->hdlc_eng){ + /* In HDLC mode, calculate rx length based + * on alignment value, received from DMA */ + rx_el->len=((((chan->dma_mru>>2)-1)-rx_el->len)<<2) - (~(rx_el->align)&AFT_RXDMA_LO_ALIGN_MASK); + }else{ + /* In Transparent mode, our RX buffer will always be + * aligned to the 32bit (word) boundary, because + * the RX buffers are all of equal length */ + rx_el->len=(((chan->mru>>2)-rx_el->len)<<2) - (~(0x03)&AFT_RXDMA_LO_ALIGN_MASK); + } + + rx_el->pkt_error= dma_chain->pkt_error; + rx_el->dma_addr = dma_chain->dma_addr; + + /* A-DMA */ + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_POSTREAD); + dma_chain->dma_len = rx_el->len; /* update real dma len*/ + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTREAD); + + wan_skb_queue_tail(&chan->wp_rx_complete_list,dma_chain->skb); + rx_data_available=1; + + DEBUG_BRI("%s: RxInt Pending chain %d Rxlist=%d LO:0x%X HI:0x%X!\n", + chan->if_name,dma_chain->index, + wan_skb_queue_len(&chan->wp_rx_complete_list), + rx_el->align,rx_el->reg); + +rx_hndlr_skip_rx: + dma_chain->skb=NULL; + dma_chain->pkt_error=0; + wan_clear_bit(0,&dma_chain->init); + + if (chan->single_dma_chain){ + break; + } + + if (++chan->rx_pending_chain_indx >= MAX_AFT_DMA_CHAINS){ + chan->rx_pending_chain_indx=0; + } + } + + if (reset){ + goto reset_skip_rx_setup; + } + + aft_dma_rx(card,chan); + + if (wan_skb_queue_len(&chan->wp_rx_complete_list)){ + DEBUG_TEST("%s: Rx Queued list triggering\n",chan->if_name); + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + } + +reset_skip_rx_setup: + + wan_clear_bit(RX_HANDLER_BUSY,&chan->dma_status); + + + return rx_data_available; +} + +static int aft_dma_rx_complete(sdla_t *card, private_area_t *chan, int reset) +{ + if (chan->cfg.ss7_enable){ + aft_clear_ss7_force_rx(card,chan); + } + return aft_rx_dma_chain_handler(chan,reset); +} + +/*=============================================== + * TE1 DMA Chains Utility Funcitons + * + */ + + +static void aft_index_tx_rx_dma_chains(private_area_t *chan) +{ + int i; + + for (i=0;itx_dma_chain_table[i].index=i; + chan->rx_dma_chain_table[i].index=i; + } +} + + +static void aft_init_tx_rx_dma_descr(private_area_t *chan) +{ + int i; + u32 reg=0; + sdla_t *card=chan->card; + unsigned long tx_dma_descr,rx_dma_descr; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + return; + } + + for (i=0;ilogic_ch_num<<4) + + (i*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + rx_dma_descr=(chan->logic_ch_num<<4) + + (i*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_write_4(card->hw,tx_dma_descr,reg); + card->hw_iface.bus_write_4(card->hw,rx_dma_descr,reg); + + aft_tx_dma_chain_init(chan,&chan->tx_dma_chain_table[i]); + aft_rx_dma_chain_init(chan,&chan->rx_dma_chain_table[i]); + } +} + +static void aft_free_rx_complete_list(private_area_t *chan) +{ + void *skb; + + while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ + DEBUG_TEST("%s: aft_free_rx_complete_list dropped\n", + chan->if_name); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //chan->if_stats.rx_dropped++; + aft_init_requeue_free_skb(chan, skb); + } +} + +static void aft_rx_cur_go_test(private_area_t *chan) +{ +#if 0 + u32 reg,cur_dma_ptr; + sdla_t *card=chan->card; + wan_dma_descr_t *dma_chain; + u32 dma_descr; + int i; + u32 dma_ram_desc; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + dma_descr=(chan->logic_ch_num<<4) +(cur_dma_ptr*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + if (!wan_test_bit(AFT_RXDMA_HI_GO_BIT,®)){ + DEBUG_EVENT("%s: CRITICAL Cur =%d not Got bit set!\n", + chan->if_name, + cur_dma_ptr); + + + aft_list_descriptors(chan); + } +#endif +} + + +#if 0 +static void aft_list_descriptors(private_area_t *chan) +{ + u32 reg,cur_dma_ptr,lo_reg; + sdla_t *card=chan->card; + wan_dma_descr_t *dma_chain; + u32 dma_descr; + int i; + u32 dma_ram_desc; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + + DEBUG_TEST("%s: RX Chain DMA List: End=%d Begin=%d Cur=%d \n", + chan->if_name, + chan->rx_chain_indx, + chan->rx_pending_chain_indx, + cur_dma_ptr); + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + for (i=0;irx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,&lo_reg); + + DEBUG_EVENT("%s: RX DMA=%d : Go=%u Intr=%u Used=%lu A=0%X R=0x%X L=0x%08X C=%i\n", + chan->if_name, + dma_chain->index, + wan_test_bit(AFT_RXDMA_HI_GO_BIT,®), + !wan_test_bit(AFT_RXDMA_HI_INTR_DISABLE_BIT,®), + dma_chain->init,dma_descr,reg,lo_reg,(lo_reg&0x1FF)/128); + } +} +#endif + +#if 0 +static void aft_list_tx_descriptors(private_area_t *chan) +{ + u32 reg,cur_dma_ptr,lo_reg; + sdla_t *card=chan->card; + wan_dma_descr_t *dma_chain; + u32 dma_descr; + int i; + u32 dma_ram_desc; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + + + DEBUG_TEST("%s: TX Chain DMA List: Cur(End)=%d, Pend(Begin)=%d HWCur=%d\n", + chan->if_name, + chan->tx_chain_indx, + chan->tx_pending_chain_indx, + cur_dma_ptr); + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + for (i=0;itx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) + + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + dma_descr=(chan->logic_ch_num<<4) + + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,&lo_reg); + + DEBUG_EVENT("%s: TX DMA=%d : Go=%u Intr=%u Used=%lu A=0%X R=0x%08X L=0x%08X C=%i\n", + chan->if_name, + dma_chain->index, + wan_test_bit(AFT_TXDMA_HI_GO_BIT,®), + wan_test_bit(AFT_TXDMA_HI_INTR_DISABLE_BIT,®) ? 0:1, + dma_chain->init, + dma_descr, + reg,lo_reg,(lo_reg&0x1FF)/128); + + } +} +#endif + +#if 0 +static void aft_list_dma_chain_regs(sdla_t *card) +{ + u32 reg; + int i; + u32 dma_ram_desc; + + for (i=0; iu.aft.num_of_time_slots;i++){ + + private_area_t *chan; + + if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + continue; + } + + if (!wan_test_bit(0,&chan->up)){ + continue; + } + + dma_ram_desc=chan->logic_ch_num*4 + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + + DEBUG_EVENT("%s: DMA CHAIN: %i: 0x%08X\n", + card->devname,i,reg); + + } +} +#endif + + +static void aft_free_rx_descriptors(private_area_t *chan) +{ + u32 reg; + sdla_t *card=chan->card; + wan_dma_descr_t *dma_chain; + u32 dma_descr; + int i; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + return; + } + + for (i=0;irx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) + + (dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_RX_DMA_HI_DESCR_BASE_REG); + + DEBUG_TEST("%s:%s: Rx: Freeing Descripors Ch=%ld Desc=0x%X\n", + card->devname,chan->if_name,chan->logic_ch_num,dma_descr); + + card->hw_iface.bus_read_4(card->hw,dma_descr,®); + + /* If GO bit is set, then the current DMA chain + * is in process of being transmitted, thus + * all are busy */ + reg=0; + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + card->hw_iface.busdma_sync( card->hw, + dma_chain, + 1, chan->single_dma_chain, + SDLA_DMA_POSTREAD); + card->hw_iface.busdma_unmap( card->hw, + dma_chain, + SDLA_DMA_POSTREAD); + + if (dma_chain->skb){ + aft_init_requeue_free_skb(chan, dma_chain->skb); + } + + dma_chain->skb=NULL; + dma_chain->pkt_error=0; + wan_clear_bit(0,&dma_chain->init); + } + +} + +static void aft_reset_rx_chain_cnt(private_area_t *chan) +{ + u32 dma_ram_desc,reg,cur_dma_ptr; + sdla_t *card=chan->card; + + dma_ram_desc=chan->logic_ch_num*4+ + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_rx_dma_addr(reg); + chan->rx_pending_chain_indx = chan->rx_chain_indx = cur_dma_ptr; + DEBUG_TEST("%s: Setting Rx Index to %d\n", + chan->if_name,cur_dma_ptr); + +} + +static void aft_reset_tx_chain_cnt(private_area_t *chan) +{ + u32 dma_ram_desc,reg,cur_dma_ptr; + sdla_t *card=chan->card; + + dma_ram_desc=chan->logic_ch_num*4+ + AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + cur_dma_ptr=aft_dmachain_get_tx_dma_addr(reg); + chan->tx_pending_chain_indx = chan->tx_chain_indx = cur_dma_ptr; + DEBUG_TEST("%s: Setting Tx Index to %d\n", + chan->if_name,cur_dma_ptr); + +} + + + +static void aft_free_tx_descriptors(private_area_t *chan) +{ + u32 reg,dma_descr; + sdla_t *card=chan->card; + wan_dma_descr_t *dma_chain; + int i; + void *skb; + unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; + + if (chan->single_dma_chain){ + dma_cnt=1; + } + + if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){ + return; + } + + DEBUG_TEST("%s:%s: Tx: Freeing Descripors\n",card->devname,chan->if_name); + + for (i=0;itx_dma_chain_table[i]; + if (!dma_chain){ + DEBUG_EVENT("%s:%d Assertion Error !!!!\n", + __FUNCTION__,__LINE__); + break; + } + + dma_descr=(chan->logic_ch_num<<4) +(dma_chain->index*AFT_DMA_INDEX_OFFSET) + + AFT_PORT_REG(card,AFT_TX_DMA_HI_DESCR_BASE_REG); + + DEBUG_TEST("%s:%s: Tx: Freeing Descripors Ch=%ld Desc=0x%X\n", + card->devname,chan->if_name,chan->logic_ch_num,dma_descr); + reg=0; + card->hw_iface.bus_write_4(card->hw,dma_descr,reg); + + aft_tx_dma_chain_init(chan, dma_chain); + } + + chan->tx_chain_indx = chan->tx_pending_chain_indx; + + while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ + wan_skb_free(skb); + } +} + + +/*===================================================== + * Chanalization/Logic Channel utilites + * + */ +void aft_free_logical_channel_num (sdla_t *card, int logic_ch) +{ + wan_clear_bit (logic_ch,&card->u.aft.logic_ch_map); + card->u.aft.dev_to_ch_map[logic_ch]=NULL; + + if (logic_ch >= card->u.aft.top_logic_ch){ + int i; + + card->u.aft.top_logic_ch=AFT_DEFLT_ACTIVE_CH; + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (card->u.aft.dev_to_ch_map[i]){ + card->u.aft.top_logic_ch=i; + } + } + + + aft_dma_max_logic_ch(card); + } + +} + +void aft_dma_max_logic_ch(sdla_t *card) +{ + u32 reg; + + DEBUG_TEST("%s: Maximum Logic Ch set to %d \n", + card->devname,card->u.aft.top_logic_ch); + + reg=0; + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + aft_dmactrl_set_max_logic_ch(®,card->u.aft.top_logic_ch); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); +} + +static int aft_tslot_sync_ctrl(sdla_t *card, private_area_t *chan, int mode) +{ + u32 dma_ram_reg,reg; + + if (chan->hdlc_eng){ + return 0; + } + + + dma_ram_reg=AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + dma_ram_reg+=(chan->logic_ch_num*4); + + card->hw_iface.bus_read_4(card->hw, dma_ram_reg, ®); + + if (mode){ + wan_set_bit(AFT_DMACHAIN_RX_SYNC_BIT,®); + }else{ + wan_clear_bit(AFT_DMACHAIN_RX_SYNC_BIT,®); + } + + card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg); + + return 0; +} + + + +static int aft_read_security(sdla_t *card) +{ + int adptr_security; + wan_smp_flag_t flags,smp_flags; + + if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ + /* Shark cards are always channelized */ + card->u.aft.security_id=0x01; + return 0; + } + + card->hw_iface.hw_lock(card->hw,&smp_flags); + wan_spin_lock_irq(&card->wandev.lock,&flags); + adptr_security=aft_read_cpld(card,0x09); + wan_spin_unlock_irq(&card->wandev.lock,&flags); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + adptr_security=(adptr_security>>2)&0x03; + card->u.aft.security_id=adptr_security; + + if (adptr_security == 0x00){ + DEBUG_EVENT("%s: AFT Security: UnChannelised\n", + card->devname); + }else if (adptr_security == 0x01){ + DEBUG_EVENT("%s: AFT Security: Channelised\n", + card->devname); + }else{ + DEBUG_EVENT("%s: AFT Security: Unknown\n", + card->devname); + return -EINVAL; + } + + card->u.aft.security_cnt=0; + + return 0; +} + + +static int aft_front_end_mismatch_check(sdla_t * card) +{ + u32 reg; + + if (card->u.aft.firm_id == AFT_PMC_FE_CORE_ID) { + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG, ®); + + if (IS_T1_CARD(card)){ + if (wan_test_bit(AFT_CHIPCFG_TE1_CFG_BIT,®)){ + DEBUG_EVENT("%s: Global Cfg Error: Initial front end cfg: E1\n", + card->devname); + return -EINVAL; + } + }else{ + if (!wan_test_bit(AFT_CHIPCFG_TE1_CFG_BIT,®)){ + DEBUG_EVENT("%s: Global Cfg Error: Initial front end cfg: T1\n", + card->devname); + return -EINVAL; + } + } + } + + return 0; +} + +static int aft_realign_skb_pkt(private_area_t *chan, netskb_t *skb) +{ + unsigned char *data=wan_skb_data(skb); + int len = wan_skb_len(skb); + + if (len > chan->dma_mru){ + DEBUG_EVENT("%s: Critical error: Tx unalign pkt(%d) > MTU buf(%d)!\n", + chan->if_name,len,chan->dma_mru); + return -ENOMEM; + } + + if (!chan->tx_realign_buf){ + chan->tx_realign_buf=wan_malloc(chan->dma_mru); + if (!chan->tx_realign_buf){ + DEBUG_EVENT("%s: Error: Failed to allocate tx memory buf\n", + chan->if_name); + return -ENOMEM; + }else{ + DEBUG_EVENT("%s: AFT Realign buffer allocated Len=%d\n", + chan->if_name,chan->dma_mru); + + } + } + + memcpy(chan->tx_realign_buf,data,len); + + wan_skb_init(skb,0); + wan_skb_trim(skb,0); + + if (wan_skb_tailroom(skb) < len){ + DEBUG_EVENT("%s: Critical error: Tx unalign pkt tail room(%i) < unalign len(%i)!\n", + chan->if_name,wan_skb_tailroom(skb),len); + + return -ENOMEM; + } + + data=wan_skb_put(skb,len); + + if ((unsigned long)data & 0x03){ + /* At this point pkt should be realigned. If not + * there is something really wrong! */ + return -EINVAL; + } + + memcpy(data,chan->tx_realign_buf,len); + + chan->opstats.Data_frames_Tx_realign_count++; + + return 0; +} + +void aft_wdt_set(sdla_t *card, unsigned char val) +{ + u8 reg; + u32 wdt_ctrl_reg=AFT_WDT_1TO4_CTRL_REG+card->wandev.comm_port; + + if (card->wandev.comm_port > 3) { + wdt_ctrl_reg=AFT_WDT_4TO8_CTRL_REG+(card->wandev.comm_port%4); + } + + card->hw_iface.bus_read_1(card->hw,wdt_ctrl_reg, ®); + aft_wdt_ctrl_set(®,val); + card->hw_iface.bus_write_1(card->hw,wdt_ctrl_reg, reg); +} +void aft_wdt_reset(sdla_t *card) +{ + u8 reg; + u32 wdt_ctrl_reg=AFT_WDT_1TO4_CTRL_REG+card->wandev.comm_port; + + if (card->wandev.comm_port > 3) { + wdt_ctrl_reg=AFT_WDT_4TO8_CTRL_REG+(card->wandev.comm_port%4); + } + + card->hw_iface.bus_read_1(card->hw, wdt_ctrl_reg, ®); + aft_wdt_ctrl_reset(®); + card->hw_iface.bus_write_1(card->hw, wdt_ctrl_reg, reg); +} + +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +static void aft_port_task (void * card_ptr) +# else +static void aft_port_task (struct work_struct *work) +# endif +#else +static void aft_port_task (void * card_ptr, int arg) +#endif +{ +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) + sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); +# else + sdla_t *card = (sdla_t *)card_ptr; +# endif +#else + sdla_t *card = (sdla_t *)card_ptr; +#endif + wan_smp_flag_t smp_flags; + + if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ + return; + } + + DEBUG_56K("%s: PORT TASK: 0x%X\n", card->devname,card->u.aft.port_task_cmd); + +#ifdef AFT_IRQ_STAT_DEBUG + card->wandev.stats.rx_missed_errors++; +#endif + + + if (wan_test_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd)){ + + DEBUG_TEST("%s: PORT TASK: FE INTER\n", card->devname); + + card->hw_iface.hw_lock(card->hw,&smp_flags); + aft_fe_intr_ctrl(card, 0); + front_end_interrupt(card,0,1); + wan_clear_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); + aft_fe_intr_ctrl(card, 1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + } + + if (wan_test_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd)){ + DEBUG_TEST("%s: PORT TASK: FE POLL\n", card->devname); + card->hw_iface.hw_lock(card->hw,&smp_flags); + aft_fe_intr_ctrl(card, 0); + if (card->wandev.fe_iface.polling){ + wan_smp_flag_t smp_irq_flags; + int err = 0; + wan_spin_lock_irq(&card->wandev.lock,&smp_irq_flags); + err = card->wandev.fe_iface.polling(&card->fe); + + handle_front_end_state(card); + wan_spin_unlock_irq(&card->wandev.lock,&smp_irq_flags); + } + wan_clear_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); + aft_fe_intr_ctrl(card, 1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } + + if (wan_test_bit(AFT_FE_LED,&card->u.aft.port_task_cmd)){ + DEBUG_TEST("%s: PORT TASK: FE LED\n", card->devname); + card->hw_iface.hw_lock(card->hw,&smp_flags); + aft_fe_intr_ctrl(card, 0); + if (card->wandev.state == WAN_CONNECTED){ + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_OFF); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_ON); + }else{ + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_OFF); + } + wan_clear_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); + aft_fe_intr_ctrl(card, 1); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (wan_test_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd)){ + int err; + DEBUG_TEST("%s: PORT TASK: FE RBS\n", card->devname); + card->hw_iface.hw_lock(card->hw,&smp_flags); + + WAN_TDMV_CALL(rbsbits_poll, (&card->wan_tdmv, card), err); + + wan_clear_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + } +#endif + +#if defined(CONFIG_WANPIPE_HWEC) + if (wan_test_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd)){ + + DEBUG_TEST("%s: PORT TASK: FE EC INTR\n", card->devname); + + if (card->wandev.ec_dev){ + card->hw_iface.hw_ec_lock(card->hw,&smp_flags); + wanpipe_ec_poll(card->wandev.ec_dev, card); + wan_clear_bit(AFT_FE_EC_POLL,&card->u.aft.port_task_cmd); + card->hw_iface.hw_ec_unlock(card->hw,&smp_flags); + } + } +#endif +} + +void __aft_fe_intr_ctrl(sdla_t *card, int status) +{ + u32 reg; + + if (!card->fe_no_intr || !status){ + card->hw_iface.bus_read_4(card->hw,AFT_CHIP_CFG_REG,®); + if (status){ + wan_set_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); + }else{ + wan_clear_bit(AFT_CHIPCFG_FE_INTR_CFG_BIT,®); + } + card->hw_iface.bus_write_4(card->hw,AFT_CHIP_CFG_REG,reg); + } +} + +void aft_fe_intr_ctrl(sdla_t *card, int status) +{ + wan_smp_flag_t smp_flags; + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); + __aft_fe_intr_ctrl(card,status); + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); + +} + +static void aft_data_mux_cfg(sdla_t *card) +{ + if (!card->u.aft.cfg.data_mux_map){ + card->u.aft.cfg.data_mux_map=AFT_DEFAULT_DATA_MUX_MAP; + } + + card->hw_iface.bus_write_4(card->hw, AFT_DATA_MUX_REG, + card->u.aft.cfg.data_mux_map); + + DEBUG_EVENT("%s: AFT Data Mux Bit Map: 0x%08X\n", + card->devname,card->u.aft.cfg.data_mux_map); +} + +static void aft_data_mux_get_cfg(sdla_t *card) +{ + card->hw_iface.bus_read_4(card->hw, AFT_DATA_MUX_REG, + &card->u.aft.cfg.data_mux_map); + +} + +static int aft_hdlc_repeat_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb, netskb_t **rskb) +{ + unsigned char *buf; + api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)wan_skb_data(skb); + + if (tx_hdr->wp_api_tx_hdr_hdlc_rpt_len == 0 || tx_hdr->wp_api_tx_hdr_hdlc_rpt_len > 8) { + return -1; + } + + *rskb=wan_skb_alloc(128); + if (!rskb) { + return -1; + } + + buf=wan_skb_put(*rskb,tx_hdr->wp_api_tx_hdr_hdlc_rpt_len); + memcpy(buf,tx_hdr->wp_api_tx_hdr_hdlc_rpt_data,tx_hdr->wp_api_tx_hdr_hdlc_rpt_len); + wan_skb_pull(skb,sizeof(api_tx_hdr_t)); + + return 0; +} + +static int aft_ss7_tx_mangle(sdla_t *card,private_area_t *chan, netskb_t *skb) +{ + int ss7_len=0,len=0; + unsigned int ss7_ctrl=0; + unsigned char *buf; + api_tx_hdr_t *tx_hdr = &chan->tx_api_hdr; + + memcpy(&chan->tx_api_hdr,wan_skb_data(skb),sizeof(api_tx_hdr_t)); + wan_skb_pull(skb,sizeof(api_tx_hdr_t)); + + if (!chan->tx_ss7_realign_buf){ + chan->tx_ss7_realign_buf=wan_malloc(chan->dma_mru); + if (!chan->tx_ss7_realign_buf){ + DEBUG_EVENT("%s: Error: Failed to allocate ss7 tx memory buf\n", + chan->if_name); + return -ENOMEM; + }else{ + DEBUG_TEST("%s: AFT SS7 Realign buffer allocated Len=%d\n", + chan->if_name,chan->dma_mru); + } + } + + memset(chan->tx_ss7_realign_buf,0,chan->dma_mru); + memcpy(chan->tx_ss7_realign_buf,wan_skb_data(skb),wan_skb_len(skb)); + len=wan_skb_len(skb); + + /* Align the end of the frame to 32 byte boundary */ + ss7_ctrl=(len%4)&AFT_SS7_CTRL_LEN_MASK; + if (ss7_ctrl != 0){ + len-=len%4; + len+=4; + } + + if (tx_hdr->hdr_u.ss7.type == WANOPT_SS7_FISU){ + if (chan->cfg.ss7_mode == WANOPT_SS7_MODE_4096){ + ss7_len=WANOPT_SS7_FISU_4096_SZ; + }else{ + ss7_len=WANOPT_SS7_FISU_128_SZ; + } + wan_clear_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl); + }else{ + ss7_len=chan->cfg.ss7_lssu_size; + wan_set_bit(AFT_SS7_CTRL_TYPE_BIT,&ss7_ctrl); + } + + if (tx_hdr->hdr_u.ss7.force_tx){ + wan_set_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl); + }else{ + wan_clear_bit(AFT_SS7_CTRL_FORCE_BIT,&ss7_ctrl); + } + + DEBUG_TEST("%s: SS7 DATA = 0x%X 0x%X 0x%X\n", + chan->if_name, + tx_hdr->hdr_u.ss7.data[0], + tx_hdr->hdr_u.ss7.data[1], + tx_hdr->hdr_u.ss7.data[2]); + + memcpy(&chan->tx_ss7_realign_buf[len],tx_hdr->hdr_u.ss7.data,ss7_len); + + len+=ss7_len; + + wan_skb_init(skb,0); + wan_skb_trim(skb,0); + + if (wan_skb_tailroom(skb) < len){ + DEBUG_EVENT("%s: Critical error: SS7 Tx unalign pkt tail room(%i) < len(%i)!\n", + chan->if_name,wan_skb_tailroom(skb),len); + + return -ENOMEM; + } + + buf=wan_skb_put(skb,len); + memcpy(buf,chan->tx_ss7_realign_buf,len); + + wan_skb_set_csum(skb, ss7_ctrl); + +#if 0 + debug_print_skb_pkt(chan->if_name, wan_skb_data(skb), wan_skb_len(skb), 0); +#endif + return 0; +} + + + + +#if 0 +static void aft_chain_history(private_area_t *chan,u8 end, u8 cur, u8 begin, u8 loc) +{ + dma_history_t *dma_hist = &chan->dma_history[chan->dma_index]; + + dma_hist->loc=loc; + dma_hist->end=end; + dma_hist->cur=cur; + dma_hist->begin=begin; + dma_hist->status=0; + + if (end > begin){ + if (cur > end || + cur < begin){ + DEBUG_TEST("%s: Rx: Critical: RxPendChain=%d HWDMA=%d RxEndChain=%d\n", + chan->if_name,begin,cur,end); + dma_hist->status=1; + } + }else if (end < begin){ + if (cur < begin && + cur > end){ + DEBUG_TEST("%s: Rx: Critical: RxEndChain=%d HWDMA=%d RxPendingChain=%d\n", + chan->if_name,begin,cur,end); + dma_hist->status=1; + + } + } + + if (++chan->dma_index >= MAX_DMA_HIST_SIZE){ + chan->dma_index=0; + } +} +#endif + +#if 0 +static void aft_display_chain_history(private_area_t *chan) +{ + int start=chan->dma_index; + int i; + dma_history_t *dma_hist = &chan->dma_history[start]; + + for (i=0;iloc == 0){ + continue; + } + + DEBUG_EVENT("%s: Loc=%02i End=%02d Cur=%02d Beg=%02d St=%s\n", + chan->if_name, + dma_hist->loc, + dma_hist->end, + dma_hist->cur, + dma_hist->begin, + dma_hist->status?"Error":"Ok"); + + start++; + if (start >= MAX_DMA_HIST_SIZE){ + start=0; + } + dma_hist = &chan->dma_history[start]; + } +} +#endif + +/* + * ****************************************************************** + * Proc FS function + */ +static int wan_aft_get_info(void* pcard, struct seq_file *m, int *stop_cnt) +{ + sdla_t *card = (sdla_t*)pcard; + + if (card->wandev.fe_iface.update_alarm_info){ + m->count = + WAN_FECALL( + &card->wandev, + update_alarm_info, + (&card->fe, m, stop_cnt)); + } + if (card->wandev.fe_iface.update_pmon_info){ + m->count = + WAN_FECALL( + &card->wandev, + update_pmon_info, + (&card->fe, m, stop_cnt)); + } + + return m->count; +} + +static int aft_tdmv_init(sdla_t *card, wandev_conf_t *conf) +{ + + int err; + int valid_firmware_ver=AFT_TDMV_FRM_VER; + + err=0; + DEBUG_EVENT("%s: TDMV Span = %d : %s\n", + card->devname, + card->tdmv_conf.span_no, + card->tdmv_conf.span_no?"Enabled":"Disabled"); + + if (card->tdmv_conf.span_no) { + if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) { + valid_firmware_ver=AFT_MIN_ANALOG_FRMW_VER; + } + + if (card->u.aft.firm_ver < valid_firmware_ver){ + DEBUG_EVENT("%s: Error: Obselete AFT Firmware version: %X\n", + card->devname,card->u.aft.firm_ver); + DEBUG_EVENT("%s: Error: AFT TDMV Support depends on Firmware Ver >= %X\n", + card->devname,valid_firmware_ver); + return -EINVAL; + } + } + + + + return 0; + +} + + +/************************************************************** + * TDMV VOICE Functions + **************************************************************/ +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_tdmv_free(sdla_t *card) +{ + if (card->tdmv_conf.span_no && card->wan_tdmv.sc){ + int err; + WAN_TDMV_CALL(remove, (card), err); + } + return 0; +} +#endif + + +static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf) +{ + BRI_INIT_FUNC(); + + if (!chan->channelized_cfg){ + BRI_INIT_FUNC(); + return 0; + } + + if (!card->tdmv_conf.span_no){ + DEBUG_EVENT("%s: Error: TDMV Span No is not set!\n", + card->devname); + return -EINVAL; + } + + if (chan->cfg.tdmv_master_if){ + DEBUG_EVENT("%s: Configuring TDMV Master dev %s\n", + card->devname,chan->if_name); + + /* Initialize a TDM bottom half handler + * Optionally used */ + WAN_TASKLET_INIT((&chan->common.bh_task),0,wp_tdm_bh,chan); + } + + if (conf->hdlc_streaming == 0){ + + int err; + + err=0; + + aft_hwdev[card->wandev.card_type].aft_fifo_adjust(card,AFT_TDMV_FIFO_LEVEL); + + if (chan->common.usedby == TDM_VOICE) { +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + WAN_TDMV_CALL(check_mtu, (card, conf->active_ch, &chan->mtu), err); + if (err){ + DEBUG_EVENT("Error: TMDV mtu check failed!"); + return -EINVAL; + } +#endif + } + + if (chan->common.usedby == TDM_VOICE_API) { + switch (chan->mtu) { + case 8: + case 16: + break; + case 40: + case 80: + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + /* If Global TDM Feature is not enable + then 40 and 80 bytes TDM are not available */ + chan->mtu=16; + } + break; + default: + chan->mtu=16; + break; + } + } + + chan->mru = chan->mtu; + + card->u.aft.tdmv_mtu += chan->mtu; + + if (chan->tdmv_zaptel_cfg){ + chan->cfg.data_mux=1; + } + + conf->hdlc_streaming=0; + chan->tx_realign_buf = NULL; +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + card->wan_tdmv.brt_enable=0; +#endif + + }else{ + chan->cfg.data_mux=0; + } + + BRI_INIT_FUNC(); + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (chan->tdmv_zaptel_cfg){ + int channel; + + /* The TDMV drivers always starts from number + * ZERO. Wanpipe driver doesn't allow timeslot + * ZERO. Thus, the active_ch map must me adjusted + * before calling tdmv_reg */ + if (IS_E1_CARD(card)){ + conf->active_ch=conf->active_ch>>1; + } + + if(IS_BRI_CARD(card)){ + if(chan->dchan_time_slot >= 0){ + conf->active_ch = 0x4<<(WAN_FE_LINENO(&card->fe)*2); + /* For the d-chan MUST set ONLY bit 2!! */ + } + } + + WAN_TDMV_CALL(reg, + (card, + &conf->tdmv, + conf->active_ch, + conf->hwec.enable, + chan->common.dev), channel); + + if (channel < 0){ + DEBUG_EVENT("%s: Error: Failed to register TDMV channel!\n", + chan->if_name); + + return -EINVAL; + } + chan->tdmv_chan=channel; + + + if (card->u.aft.tdmv_dchan_cfg_on_master && chan->cfg.tdmv_master_if){ + u32 orig_ch=conf->active_ch; + + conf->active_ch=card->u.aft.tdmv_dchan_cfg_on_master; + + WAN_TDMV_CALL(reg, + (card, + &conf->tdmv, + conf->active_ch, + conf->hwec.enable, + chan->common.dev), channel); + if (channel < 0){ + DEBUG_EVENT("%s: Error: Failed to register TDMV channel!\n", + chan->if_name); + + return -EINVAL; + } + + card->u.aft.tdmv_chan=channel; + card->u.aft.tdmv_dchan_active_ch=conf->active_ch; + conf->active_ch=orig_ch; + } + } +#endif + return 0; +} + + +static int aft_tdmv_if_free(sdla_t *card, private_area_t *chan) +{ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (chan->tdmv_zaptel_cfg){ + int err; + WAN_TDMV_CALL(unreg, (card, chan->time_slot_map), err); + if (err){ + return err; + } + + if (card->u.aft.tdmv_dchan_cfg_on_master && chan->cfg.tdmv_master_if){ + DEBUG_EVENT("%s: Card Unregistering DCHAN\n", + card->devname); + WAN_TDMV_CALL(unreg, (card, card->u.aft.tdmv_dchan_active_ch), err); + card->u.aft.tdmv_dchan_cfg_on_master=0; + } + } +#endif + return 0; +} + +#if 0 +/* NCDEBUG */ +static int gtmp_cnt=0; +static void aft_set_channel(sdla_t *card, int ch) +{ + wan_dma_descr_t *tx_dma_chain; + u8 *buf; + private_area_t *chan=(private_area_t*)card->u.aft.dev_to_ch_map[ch]; + + if (!chan) return; + + tx_dma_chain = &chan->tx_dma_chain_table[0]; + if (!tx_dma_chain){ + return; + } + buf = (u8*)wan_skb_data(tx_dma_chain->skb); + buf[0]=gtmp_cnt++; + buf[1]=gtmp_cnt++; + buf[2]=gtmp_cnt++; + buf[3]=gtmp_cnt++; + buf[4]=gtmp_cnt++; + buf[5]=gtmp_cnt++; + buf[6]=gtmp_cnt++; + buf[7]=gtmp_cnt++; + + card->wandev.stats.tx_packets++; +} +#endif + + +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) +static int aft_voice_span_rx_tx(sdla_t *card, int rotate) +{ + int err; + err=0; + + if (card->wan_tdmv.sc){ + + if (rotate) { + WAN_TDMV_CALL(buf_rotate, (card,AFT_TDMV_CIRC_BUF,AFT_TDMV_BUF_MASK), err); + } + + if (!card->wandev.ec_enable || card->wandev.ec_enable_map == 0){ + WAN_TDMV_CALL(ec_span, (card), err); + } + + WAN_TDMV_CALL(rx_tx_span, (card), err); + + WAN_TDMV_CALL(is_rbsbits, (&card->wan_tdmv), err); + if (err == 1){ + wan_set_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + +#if !defined(AFT_IRQ_DEBUG) + card->wandev.stats.rx_packets++; + card->wandev.stats.tx_packets++; +#endif + + } + return 0; +} +#endif + +static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan) +{ + int err; + u32 rx_offset=0; + u32 tx_offset=0; + + wan_dma_descr_t *tx_dma_chain; + wan_dma_descr_t *rx_dma_chain; + + tx_dma_chain = &chan->tx_dma_chain_table[0]; + rx_dma_chain = &chan->rx_dma_chain_table[0]; + + + if (wan_test_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status)) { + rx_offset= AFT_TDMV_CIRC_BUF * card->u.aft.tdm_rx_dma_toggle; + tx_offset= AFT_TDMV_CIRC_BUF * card->u.aft.tdm_tx_dma_toggle; + } + + err=0; + + if (!tx_dma_chain || !rx_dma_chain){ + DEBUG_EVENT("%s: %s:%d ASSERT ERROR TxDma=%p RxDma=%p\n", + card->devname,__FUNCTION__,__LINE__, + tx_dma_chain,rx_dma_chain); + return -EINVAL; + } + + if (!rx_dma_chain->skb || !tx_dma_chain->skb){ + DEBUG_TEST("%s: %s:%d ASSERT ERROR TxSkb=%p RxSkb=%p\n", + card->devname,__FUNCTION__,__LINE__, + rx_dma_chain->skb,tx_dma_chain->skb); + return -EINVAL; + } + +#if 0 + /*Measure the round trip delay*/ + if (!chan->tdmv_rx_delay_cfg){ + int i; + unsigned char *buf=rx_dma_chain->dma_virt+offset; + for (i=0;i<8;i++){ + if (buf[i]==0x55){ + chan->tdmv_rx_delay_cfg=1; + DEBUG_EVENT("%s: Chan=%ld Delay=%d\n", + chan->if_name,chan->logic_ch_num, + chan->tdmv_rx_delay); + break; + } + chan->tdmv_rx_delay++; + } + } +#endif + + + if (chan->tdmv_zaptel_cfg){ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (card->wan_tdmv.sc){ + +#if 0 +defined(AFT_TDMV_BH_ENABLE) + wan_dma_descr_t *tx_bh_dma_chain = &chan->tx_dma_chain_table[1]; + wan_dma_descr_t *rx_bh_dma_chain = &chan->rx_dma_chain_table[1]; + + if (!rx_bh_dma_chain->skb){ + rx_bh_dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!rx_bh_dma_chain->skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical TDM BH no free skb\n", + chan->if_name); + goto aft_tdm_bh_skip; + } + } + wan_skb_init(rx_bh_dma_chain->skb,16); + wan_skb_trim(rx_bh_dma_chain->skb,0); + } + + if (!tx_bh_dma_chain->skb){ + tx_bh_dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); + if (!tx_bh_dma_chain->skb){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical TDM BH no free skb\n", + chan->if_name); + goto aft_tdm_bh_skip; + } + } + wan_skb_init(tx_bh_dma_chain->skb,16); + wan_skb_trim(tx_bh_dma_chain->skb,0); + } + + memcpy(wan_skb_data(rx_bh_dma_chain->skb), + wan_skb_data(rx_dma_chain->skb),8); + + memcpy(wan_skb_data(tx_dma_chain->skb), + wan_skb_data(tx_bh_dma_chain->skb),8); + + rx_dma_chain=rx_bh_dma_chain; + tx_dma_chain=tx_bh_dma_chain; +aft_tdm_bh_skip: +#endif + + DEBUG_TEST ("%s: Calling Rx Chan=%i TdmvChan=%i\n", + card->devname,chan->logic_ch_num, + chan->tdmv_chan); + + if (card->wandev.rtp_len && card->wandev.rtp_tap) { + card->wandev.rtp_tap(card, + IS_T1_CARD(card) ? chan->first_time_slot : + chan->first_time_slot-1, + (unsigned char*)rx_dma_chain->dma_virt+rx_offset, + (unsigned char*)tx_dma_chain->dma_virt+tx_offset, + chan->mtu); + } + +#if 1 + WAN_TDMV_CALL(rx_chan, + (&card->wan_tdmv,chan->tdmv_chan, + (unsigned char*)rx_dma_chain->dma_virt+rx_offset, + (unsigned char*)tx_dma_chain->dma_virt+tx_offset), + err); +#else +#warning "NCDEBUG rx_chan disabled irq" +#endif + +#if 0 + if (((u8*)(rx_dma_chain->dma_virt+offset))[0] != 0xFF && + ((u8*)(rx_dma_chain->dma_virt+offset))[0] != 0x7F && + tx_debug_cnt < 100){ + DEBUG_EVENT("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", + card->devname, + ((u8*)(rx_dma_chain->dma_virt+offset))[0], + ((u8*)(rx_dma_chain->dma_virt+offset))[1], + ((u8*)(rx_dma_chain->dma_virt+offset))[2], + ((u8*)(rx_dma_chain->dma_virt+offset))[3], + ((u8*)(rx_dma_chain->dma_virt+offset))[4], + ((u8*)(rx_dma_chain->dma_virt+offset))[5], + ((u8*)(rx_dma_chain->dma_virt+offset))[6], + ((u8*)(rx_dma_chain->dma_virt+offset))[7]); + tx_debug_cnt++; + } +#endif + }else{ + return 1; + } +#endif + }else{ + +#ifdef AFT_TDM_API_SUPPORT + + + + wanpipe_tdm_api_rx_tx(&chan->wp_tdm_api_dev, + rx_dma_chain->dma_virt+rx_offset, + tx_dma_chain->dma_virt+tx_offset, + chan->mtu); +#endif + } + + if (chan->cfg.tdmv_master_if){ + u32 reg; + int err; + err=0; +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE + if (chan->tdmv_zaptel_cfg){ + DEBUG_TEST ("%s: Calling Master Rx Tx Chan=%i\n", + card->devname,chan->logic_ch_num); +#if 0 +defined(AFT_TDMV_BH_ENABLE) +#warning "AFT A104: TDM Driver compiled in BH mode!" + + if (WAN_TASKLET_RUNNING((&chan->common.bh_task))){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: Critical Error: TDMV BH Overrun!\n", + card->devname); + } + } + + WAN_WP_TASKLET_SCHEDULE_PER_CPU((&chan->common.bh_task), + card->tdmv_conf.span_no); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + +#else + +#if 1 + card->hw_iface.busdma_sync( card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS, + chan->single_dma_chain, + SDLA_DMA_POSTREAD); + + WAN_TDMV_CALL(rx_tx_span, (card), err); + + card->hw_iface.busdma_sync( card->hw, + &chan->tx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS, + chan->single_dma_chain, + SDLA_DMA_PREWRITE); + card->hw_iface.busdma_sync( card->hw, + &chan->rx_dma_chain_table[0], + MAX_AFT_DMA_CHAINS, + chan->single_dma_chain, + SDLA_DMA_PREREAD); + +#else +#warning "NCDEBUG: rx_tx_span disabled irq" +#endif + + + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + } + + if (card->wan_tdmv.sc){ + WAN_TDMV_CALL(is_rbsbits, (&card->wan_tdmv), err); + if (err == 1){ + wan_set_bit(AFT_FE_TDM_RBS,&card->u.aft.port_task_cmd); + WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); + } + } +#endif + }else{ +#else + if (!chan->tdmv_zaptel_cfg){ + +#endif + if (card->wandev.fe_iface.watchdog) { + err = card->wandev.fe_iface.watchdog(&card->fe); + } + + if (!wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status)) { + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),®); + wan_set_bit(AFT_DMACTRL_TDMV_RX_TOGGLE,®); + wan_set_bit(AFT_DMACTRL_TDMV_TX_TOGGLE,®); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_DMA_CTRL_REG),reg); + } + } + + DEBUG_TEST("%s: Master device tx rx %i!\n", + card->devname,chan->logic_ch_num); + } + + chan->opstats.Data_frames_Rx_count++; + chan->opstats.Data_bytes_Rx_count+=chan->mru; + chan->opstats.Data_frames_Tx_count++; + chan->opstats.Data_bytes_Tx_count+=chan->mtu; + WAN_NETIF_STATS_INC_RX_PACKETS(&chan->common); //chan->if_stats.rx_packets++; + WAN_NETIF_STATS_INC_RX_BYTES(&chan->common,chan->mru); //chan->if_stats.rx_bytes += chan->mru; + WAN_NETIF_STATS_INC_TX_PACKETS(&chan->common); //chan->if_stats.tx_packets++; + WAN_NETIF_STATS_INC_TX_BYTES(&chan->common,chan->mtu); //chan->if_stats.tx_bytes += chan->mtu; + + return 0; +} + +static int aft_fifo_intr_ctrl(sdla_t *card, int ctrl) +{ + u32 reg; + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + if (ctrl){ + wan_set_bit(AFT_LCFG_FIFO_INTR_BIT,®); + }else{ + wan_clear_bit(AFT_LCFG_FIFO_INTR_BIT,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + card->u.aft.lcfg_reg=reg; + + + if (!ctrl){ + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG), + ®); + + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG), + ®); + } + + return 0; +} + +static int aft_tdm_intr_ctrl(sdla_t *card, int ctrl) +{ + u32 reg; + card->hw_iface.bus_read_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), ®); + + if (ctrl){ + wan_set_bit(AFT_LCFG_TDMV_INTR_BIT,®); + + }else{ + wan_clear_bit(AFT_LCFG_TDMV_INTR_BIT,®); + } + + card->hw_iface.bus_write_4(card->hw, + AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg); + + card->u.aft.lcfg_reg=reg; + + return 0; +} + +#if defined(AFT_API_SUPPORT) +static int wan_aft_api_ioctl(sdla_t *card, private_area_t *chan, char *user_data) +{ + api_tx_hdr_t tx_hdr; + wan_event_ctrl_t event_ctrl; + int err = -EINVAL; + + if (WAN_COPY_FROM_USER(&tx_hdr, user_data, sizeof(api_tx_hdr_t))){ + DEBUG_EVENT("%s: Failed to copy data from user space!\n", + card->devname); + return -EFAULT; + } + memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); + switch(tx_hdr.wp_api_tx_hdr_event_type){ + case WP_API_EVENT_DTMF: + DEBUG_TEST("%s: %s HW DTMF events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_EC_DTMF; + event_ctrl.ts_map = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + case WP_API_EVENT_RM_DTMF: + DEBUG_TEST("%s: %s RM DTMF events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_DTMF; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + case WP_API_EVENT_RXHOOK: + DEBUG_TEST("%s: %s OFFHOOK/ONHOOK events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_LC; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_RING: + DEBUG_TEST("%s: %s RING events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_RING; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TONE: + DEBUG_TEST("%s: %s TONE events!\n", + card->devname, + (tx_hdr.wp_api_tx_hdr_event_mode==WP_API_EVENT_ENABLE)? + "Enable": "Disable"); + event_ctrl.type = WAN_EVENT_RM_TONE; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + switch(tx_hdr.wp_api_tx_hdr_event_tone){ + case WP_API_EVENT_TONE_DIAL: + event_ctrl.tone = WAN_EVENT_TONE_DIAL; + break; + case WP_API_EVENT_TONE_BUSY: + event_ctrl.tone = WAN_EVENT_TONE_BUSY; + break; + case WP_API_EVENT_TONE_RING: + event_ctrl.tone = WAN_EVENT_TONE_RING; + break; + case WP_API_EVENT_TONE_CONGESTION: + event_ctrl.tone = WAN_EVENT_TONE_CONGESTION; + break; + default: + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + DEBUG_EVENT("%s: Unsupported tone type %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_tone); + return -EINVAL; + } + break; + } + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + case WP_API_EVENT_TXSIG_KEWL: + DEBUG_EVENT("%s: TXSIG KEWL for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_KEWL; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TXSIG_START: + DEBUG_EVENT("%s: TXSIG START for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_START; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TXSIG_OFFHOOK: + DEBUG_EVENT("%s: RM TXSIG OFFHOOK for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_OFFHOOK; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_TXSIG_ONHOOK: + DEBUG_EVENT("%s: RM TXSIG ONHOOK for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_TXSIG_ONHOOK; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_ONHOOKTRANSFER: + DEBUG_EVENT("%s: RM ONHOOKTRANSFER for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_ONHOOKTRANSFER; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + event_ctrl.ohttimer = tx_hdr.wp_api_tx_hdr_event_ohttimer; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_SETPOLARITY: + DEBUG_EVENT("%s: RM SETPOLARITY for module %d!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_SETPOLARITY; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + event_ctrl.polarity = tx_hdr.wp_api_tx_hdr_event_polarity; + err = aft_event_ctrl(chan, &event_ctrl); + break; + case WP_API_EVENT_RING_DETECT: + DEBUG_EVENT("%s: %s: RM RING DETECT events for module %d!\n", + card->devname, + WP_API_EVENT_MODE_DECODE(tx_hdr.wp_api_tx_hdr_event_mode), + tx_hdr.wp_api_tx_hdr_event_channel); + event_ctrl.type = WAN_EVENT_RM_RING_DETECT; + event_ctrl.mod_no = tx_hdr.wp_api_tx_hdr_event_channel; + if (tx_hdr.wp_api_tx_hdr_event_mode == WP_API_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + err = aft_event_ctrl(chan, &event_ctrl); + break; + + default: + DEBUG_EVENT("%s: Unknown event type %02X!\n", + card->devname, + tx_hdr.wp_api_tx_hdr_event_type); + err = -EINVAL; + break; + } + return err; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_dtmf (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + private_area_t *chan = NULL; + netskb_t *new_skb = NULL; + api_rx_hdr_t *rx_hdr; + int i; + + if (event->type == WAN_EVENT_EC_DTMF){ + DEBUG_TEST("%s: Received DTMF Event at AFT API (%d:%c:%s:%s)!\n", + card->devname, + event->channel, + event->digit, + (event->dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", + (event->dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP"); + }else if (event->type == WAN_EVENT_RM_DTMF){ + DEBUG_TEST("%s: Received DTMF Event at AFT API (%d:%c)!\n", + card->devname, + event->channel, + event->digit); + } + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&card->u.aft.logic_ch_map)){ + unsigned long ts_map; + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + ts_map = chan->time_slot_map; + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + ts_map = ts_map << 1; + } + if (wan_test_bit(event->channel,&ts_map)){ + break; + } + chan = NULL; + } + } + if (chan == NULL){ + DEBUG_EVENT("%s: Failed to find channel device (channel=%d)!\n", + card->devname, event->channel); + return; + } +#if defined(__LINUX__) + new_skb=wan_skb_alloc(sizeof(api_rx_element_t)); + if (new_skb == NULL) return; + + rx_hdr=(api_rx_hdr_t*)wan_skb_put(new_skb,sizeof(api_rx_element_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + + rx_hdr->error_flag = 0; + rx_hdr->event_type = WP_API_EVENT_DTMF; + rx_hdr->wp_api_rx_hdr_event_channel = event->channel; + rx_hdr->wp_api_rx_hdr_event_dtmf_digit = event->digit; + rx_hdr->wp_api_rx_hdr_event_dtmf_type = event->dtmf_type; + rx_hdr->wp_api_rx_hdr_event_dtmf_port = event->dtmf_port; + + new_skb->protocol = htons(PVC_PROT); + new_skb->mac.raw = new_skb->data; + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + + //if (wan_api_rx_dtmf(chan,new_skb) != 0){ + if (wan_api_rx(chan,new_skb) != 0){ + DEBUG_EVENT("%s: Failed to send up DTMF event!\n", + card->devname); + wan_skb_free(new_skb); + } +#else + DEBUG_EVENT("%s:%s: DTMF Event report is not supported!\n", + card->devname, chan->if_name); + new_skb = NULL; + rx_hdr = NULL; +#endif + return; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_hook (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + private_area_t *chan = NULL; + netskb_t *new_skb = NULL; + api_rx_hdr_t *rx_hdr; + int i; + + if (event->type != WAN_EVENT_RM_LC){ + DEBUG_EVENT("ERROR: %s: Invalid Event type (%04X)!\n", + card->devname, event->type); + return; + } + DEBUG_EVENT("%s: Received %s (%d) Event at AFT API (%d)!\n", + card->devname, + WAN_EVENT_RXHOOK_DECODE(event->rxhook), event->rxhook, + event->channel); + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&card->u.aft.logic_ch_map)){ + unsigned long ts_map; + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + ts_map = chan->time_slot_map; + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + ts_map = ts_map << 1; + } + if (wan_test_bit(event->channel,&ts_map)){ + break; + } + chan = NULL; + } + } + if (chan == NULL){ + DEBUG_EVENT("%s: Failed to find channel device (channel=%d)!\n", + card->devname, event->channel); + return; + } +#if defined(__LINUX__) + new_skb=wan_skb_alloc(sizeof(api_rx_element_t)); + if (new_skb == NULL) return; + + rx_hdr=(api_rx_hdr_t*)wan_skb_put(new_skb,sizeof(api_rx_element_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + + rx_hdr->error_flag = 0; + rx_hdr->event_type = WP_API_EVENT_RXHOOK; + rx_hdr->wp_api_rx_hdr_event_channel = event->channel; + if (event->rxhook == WAN_EVENT_RXHOOK_OFF){ + rx_hdr->wp_api_rx_hdr_event_rxhook_state = WP_API_EVENT_RXHOOK_OFF; + }else if (event->rxhook == WAN_EVENT_RXHOOK_ON){ + rx_hdr->wp_api_rx_hdr_event_rxhook_state = WP_API_EVENT_RXHOOK_ON; + } + + new_skb->protocol = htons(PVC_PROT); + new_skb->mac.raw = new_skb->data; + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + + if (wan_api_rx(chan,new_skb) != 0){ + DEBUG_EVENT("%s: Failed to send up HOOK event!\n", + card->devname); + wan_skb_free(new_skb); + } +#else + DEBUG_EVENT("%s:%s: RXHOOK Event report is not supported!\n", + card->devname, chan->if_name); + new_skb = NULL; + rx_hdr = NULL; +#endif + return; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_ringtrip (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + + DEBUG_EVENT("%s: Unsupported event!\n", card->devname); + return; +} +#endif + +#if defined(AFT_API_SUPPORT) +static void wan_aft_api_ringdetect (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + private_area_t *chan = NULL; + netskb_t *new_skb = NULL; + api_rx_hdr_t *rx_hdr; + int i; + + if (event->type != WAN_EVENT_RM_RING_DETECT){ + DEBUG_EVENT("ERROR: %s: Invalid Event type (%04X)!\n", + card->devname, event->type); + return; + } + DEBUG_EVENT("%s: Received Ring Detect %s (%d) Event at AFT API (%d)!\n", + card->devname, + WAN_EVENT_RING_DECODE(event->ring_mode), event->ring_mode, + event->channel); + + for (i=0;iu.aft.num_of_time_slots;i++){ + if (wan_test_bit(i,&card->u.aft.logic_ch_map)){ + unsigned long ts_map; + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + ts_map = chan->time_slot_map; + if (IS_T1_CARD(card) || IS_FXOFXS_CARD(card)){ + /* Convert active_ch bit map to user */ + ts_map = ts_map << 1; + } + if (wan_test_bit(event->channel,&ts_map)){ + break; + } + chan = NULL; + } + } + if (chan == NULL){ + DEBUG_EVENT("%s: Failed to find channel device (channel=%d)!\n", + card->devname, event->channel); + return; + } +#if defined(__LINUX__) + new_skb=wan_skb_alloc(sizeof(api_rx_element_t)); + if (new_skb == NULL) return; + + rx_hdr=(api_rx_hdr_t*)wan_skb_put(new_skb,sizeof(api_rx_element_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + + rx_hdr->error_flag = 0; + rx_hdr->event_type = WP_API_EVENT_RING_DETECT; + rx_hdr->wp_api_rx_hdr_event_channel = event->channel; + if (event->ring_mode == WAN_EVENT_RING_PRESENT){ + rx_hdr->wp_api_rx_hdr_event_ringdetect_state = WAN_EVENT_RING_PRESENT; + }else if (event->ring_mode == WAN_EVENT_RING_STOP){ + rx_hdr->wp_api_rx_hdr_event_ringdetect_state = WAN_EVENT_RING_STOP; + }else{ + DEBUG_EVENT("%s: Invalid Rind Detect mode (%d)!\n", + card->devname, event->ring_mode); + wan_skb_free(new_skb); + return ; + } + + new_skb->protocol = htons(PVC_PROT); + new_skb->mac.raw = new_skb->data; + new_skb->dev = chan->common.dev; + new_skb->pkt_type = WAN_PACKET_DATA; + + if (wan_api_rx(chan,new_skb) != 0){ + DEBUG_EVENT("%s: Failed to send up HOOK event!\n", + card->devname); + wan_skb_free(new_skb); + } +#else + DEBUG_EVENT("%s:%s: RXHOOK Event report is not supported!\n", + card->devname, chan->if_name); + new_skb = NULL; + rx_hdr = NULL; +#endif + return; +} +#endif + +#if 0 +static void wp_tdmv_api_chan_rx_tx(sdla_t *card, + private_area_t *chan, + unsigned char *rxdata, unsigned char *txdata) +{ +#if defined(__LINUX__) + unsigned char *buf; + + if (!card->u.aft.tdmv_api_rx){ + card->u.aft.tdmv_api_rx=wan_skb_alloc(card->u.aft.tdmv_mtu); + if (!card->u.aft.tdmv_api_rx){ + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; + goto wp_tdmv_api_rx_tx_chan_skip_rx; + } + } + + if (wan_skb_len(card->u.aft.tdmv_api_rx) > (card->u.aft.tdmv_mtu-chan->mru)){ + /* CRITICAL ERROR: We cannot fit the all timeslots into this + * packet */ + WAN_NETIF_STATS_INC_RX_ERRORS(&chan->common); //++chan->if_stats.rx_errors; + goto wp_tdmv_api_rx_tx_chan_skip_rx; + } + + buf=wan_skb_put(card->u.aft.tdmv_api_rx, chan->mru); + memcpy(buf,rxdata,chan->mru); + WAN_NETIF_STATS_INC_RX_DROPPED(&chan->common); //++chan->if_stats.rx_dropped; + +wp_tdmv_api_rx_tx_chan_skip_rx: + + if (!card->u.aft.tdmv_api_tx){ + card->u.aft.tdmv_api_tx=wan_skb_dequeue(&card->u.aft.tdmv_api_tx_list); + if (!card->u.aft.tdmv_api_tx){ + /* No tx packet, send idle frames */ + WAN_NETIF_STATS_INC_TX_CARRIER_ERRORS(&chan->common); //++chan->if_stats.tx_carrier_errors; + memset(txdata,chan->idle_flag,chan->mtu); + return; + } + } + + if (wan_skb_len(card->u.aft.tdmv_api_tx) < chan->mtu){ + /* CRITICAL ERROR: + * The tx api packet must have info for all + * timeslots */ + memset(txdata,chan->idle_flag,chan->mtu); + WAN_NETIF_STATS_INC_TX_ERRORS(&chan->common); //++chan->if_stats.tx_errors; + return; + } + + buf=wan_skb_data(card->u.aft.tdmv_api_tx); + memcpy(txdata,buf,chan->mtu); + wan_skb_pull(card->u.aft.tdmv_api_tx,chan->mtu); + WAN_NETIF_STATS_INC_TX_DROPPED(&chan->common); //++chan->if_stats.tx_dropped; + +#endif + return; +} + +/*================================================ + * wp_tdmv_api_rx_tx + * + * + */ + +static void wp_tdmv_api_rx_tx (sdla_t *card, private_area_t *chan) +{ +#if defined(__LINUX__) + chan=(private_area_t*)wan_netif_priv(chan->common.dev); + + if (!card->u.aft.tdmv_api_rx){ + /* CRITICAL ERROR: + * There should be an rx api packet here */ + goto wp_tdmv_api_rx_tx_skip_rx; + } + + if (wan_skb_len(card->u.aft.tdmv_api_rx) != card->u.aft.tdmv_mtu){ + wan_skb_free(card->u.aft.tdmv_api_rx); + card->u.aft.tdmv_api_rx=NULL; + goto wp_tdmv_api_rx_tx_skip_rx; + } + + if (wan_skb_headroom(card->u.aft.tdmv_api_rx) >= sizeof(api_rx_hdr_t)){ + api_rx_hdr_t *rx_hdr= + (api_rx_hdr_t*)skb_push(card->u.aft.tdmv_api_rx, + sizeof(api_rx_hdr_t)); + memset(rx_hdr,0,sizeof(api_rx_hdr_t)); + }else{ + wan_skb_free(card->u.aft.tdmv_api_rx); + card->u.aft.tdmv_api_rx=NULL; + goto wp_tdmv_api_rx_tx_skip_rx; + } + + card->u.aft.tdmv_api_rx->protocol = htons(PVC_PROT); + card->u.aft.tdmv_api_rx->mac.raw = card->u.aft.tdmv_api_rx->data; + card->u.aft.tdmv_api_rx->dev = chan->common.dev; + card->u.aft.tdmv_api_rx->pkt_type = WAN_PACKET_DATA; + + if (wan_api_rx(chan,card->u.aft.tdmv_api_rx) != 0){ + wan_skb_free(card->u.aft.tdmv_api_rx); + } + + card->u.aft.tdmv_api_rx=NULL; + +wp_tdmv_api_rx_tx_skip_rx: + + if (card->u.aft.tdmv_api_tx){ + + if (wan_skb_len(card->u.aft.tdmv_api_tx) != 0){ + /*CRITICAL ERROR: + * Length must be zero, because we pulled + * all timeslots out*/ + } + + wan_skb_free(card->u.aft.tdmv_api_tx); + card->u.aft.tdmv_api_tx=NULL; + + if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ + WAN_NETIF_WAKE_QUEUE(chan->common.dev); + wan_wakeup_api(chan); + } + } +#endif + return; +} +#endif + +#if defined(__LINUX__) +/*============================================= + * aft_set_ss7_force_rx + * + * Force the firmware to pass up a single + * ss7 packet. Otherwise, the ss7 engine + * will wait for the next different packet. + */ +static void aft_set_ss7_force_rx(sdla_t *card, private_area_t *chan) +{ + u32 reg, dma_ram_desc; + + if (wan_test_and_set_bit(0,&chan->ss7_force_rx)){ + DEBUG_TEST("%s: FORCE BUSY RX\n",card->devname); + return; + } + + dma_ram_desc=chan->logic_ch_num*4+AFT_PORT_REG(card,AFT_DMA_CHAIN_RAM_BASE_REG); + card->hw_iface.bus_read_4(card->hw,dma_ram_desc,®); + if (wan_test_bit(AFT_DMACHAIN_SS7_FORCE_RX,®)){ + wan_clear_bit(AFT_DMACHAIN_SS7_FORCE_RX,®); + }else{ + wan_set_bit(AFT_DMACHAIN_SS7_FORCE_RX,®); + } + card->hw_iface.bus_write_4(card->hw,dma_ram_desc,reg); + + DEBUG_TEST("%s: FORCE RX\n",card->devname); +} +#endif + +/*============================================= + * aft_clear_ss7_force_rx + * + * Reset the ss7 force rx logic. + * This must be done before trying to enable + * force rx again. + * Note: That first_time_slot must be cleared LAST. + * Thus the reverse clear order. + */ +static void aft_clear_ss7_force_rx(sdla_t *card, private_area_t *chan) +{ + wan_clear_bit(0,&chan->ss7_force_rx); +} + + +#if defined(AFT_API_SUPPORT) || defined(AFT_TDM_API_SUPPORT) +static int aft_event_ctrl(void *chan_ptr, wan_event_ctrl_t *p_event) +{ + sdla_t *card = NULL; + private_area_t *chan = (private_area_t *)chan_ptr; + wan_event_ctrl_t *event_ctrl; + int err = -EINVAL; + + card = chan->card; + event_ctrl = wan_malloc(sizeof(wan_event_ctrl_t)); + if (event_ctrl == NULL){ + DEBUG_EVENT("%s: Failed to allocate event control!\n", + card->devname); + return -EFAULT; + } + memset(event_ctrl, 0, sizeof(wan_event_ctrl_t)); + memcpy(event_ctrl, p_event, sizeof(wan_event_ctrl_t)); + + if (event_ctrl->type == WAN_EVENT_EC_DTMF && card->wandev.ec_dev){ +#if defined(CONFIG_WANPIPE_HWEC) + DEBUG_TEST("%s: Event control request EC_DTMF...\n", + chan->if_name); + err = wanpipe_ec_event_ctrl(card->wandev.ec_dev, card, event_ctrl); +#endif + }else if (chan->card->wandev.fe_iface.event_ctrl){ + + DEBUG_TEST("%s: FE Event control request...\n", + chan->if_name); + err = chan->card->wandev.fe_iface.event_ctrl( + &chan->card->fe, event_ctrl); + }else{ + DEBUG_TEST("%s: Unsupported event control request (%lX)\n", + chan->if_name, event_ctrl->type); + } + if (err){ + if (event_ctrl) wan_free(event_ctrl); + } + return err; +} +#endif + +#ifdef AFT_TDM_API_SUPPORT +static int aft_read_rbs_bits(void *chan_ptr, u32 ch, u8 *rbs_bits) +{ + private_area_t *chan = (private_area_t *)chan_ptr; + wan_smp_flag_t flags; + + if (!chan_ptr){ + return -EINVAL; + } + + chan->card->hw_iface.hw_lock(chan->card->hw,&flags); + *rbs_bits = chan->card->wandev.fe_iface.read_rbsbits( + &chan->card->fe, + chan->logic_ch_num+1, + WAN_TE_RBS_UPDATE); + chan->card->hw_iface.hw_unlock(chan->card->hw,&flags); + + return 0; + +} + +static int aft_write_rbs_bits(void *chan_ptr, u32 ch, u8 rbs_bits) +{ + private_area_t *chan = (private_area_t *)chan_ptr; + wan_smp_flag_t flags; + int err; + + if (!chan_ptr){ + return -EINVAL; + } + + chan->card->hw_iface.hw_lock(chan->card->hw,&flags); + err = chan->card->wandev.fe_iface.set_rbsbits(&chan->card->fe, + chan->logic_ch_num+1, + rbs_bits); + chan->card->hw_iface.hw_unlock(chan->card->hw,&flags); + + return err; +} + + +static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb) +{ + private_area_t *chan = (private_area_t *)chan_ptr; + sdla_t *card=chan->card; + wan_smp_flag_t smp_flags; + int err=-EINVAL; + + if (!chan_ptr || !chan->common.dev || !card){ + WAN_ASSERT(1); + return -EINVAL; + } + + if (wan_skb_len(skb) > chan->mtu) { + return -EINVAL; + } + + + + if(IS_BRI_CARD(card)){ + if(chan->dchan_time_slot >= 0){ + /* NOTE: BRI dchan tx has to be done inside IRQ lock. + It allows to synchronize access to SPI on the card. + */ + card->hw_iface.hw_lock(card->hw,&smp_flags); + err=aft_bri_dchan_transmit(card, chan, + wan_skb_data(skb), + wan_skb_len(skb)); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + if (err == 0) { + wan_skb_free(skb); + err = 0; + } else { + err = -EBUSY; + } + } else { + /* On b-channel data is transmitted using AFT DMA. */ + DEBUG_EVENT("%s: Error: BRI TX on non-dchanel!!\n", card->devname); + wan_skb_free(skb); + err = 0; + } + + return err; + } + + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + + if (wan_skb_queue_len(&chan->wp_tx_pending_list) > chan->max_tx_bufs){ + aft_dma_tx(card,chan); + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + return -EBUSY; + } + + wan_skb_unlink(skb); + wan_skb_queue_tail(&chan->wp_tx_pending_list,skb); + aft_dma_tx(card,chan); + + + err=0; + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + + + + return err; +} +#endif + + +static int aft_tdm_ring_rsync(sdla_t *card) +{ + int i; + private_area_t *chan; + for (i=0; iu.aft.num_of_time_slots;i++){ + + if (!wan_test_bit(i,&card->u.aft.tdm_logic_ch_map)){ + continue; + } + + chan=(private_area_t*)card->u.aft.dev_to_ch_map[i]; + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", + card->devname,i); + continue; + } + + if (chan->channelized_cfg && !chan->hdlc_eng && chan->cfg.tdmv_master_if){ + + u32 lo_reg; + u32 dma_descr=(chan->logic_ch_num<<4) + + AFT_PORT_REG(card,AFT_RX_DMA_LO_DESCR_BASE_REG); + + card->hw_iface.bus_read_4(card->hw,dma_descr,&lo_reg); + + lo_reg=(lo_reg&AFT_TDMV_BUF_MASK)/AFT_TDMV_CIRC_BUF; + + if (card->wandev.ec_enable){ + /* HW EC standard */ + if (lo_reg > 0) { + card->u.aft.tdm_rx_dma_toggle = lo_reg-1; + } else { + card->u.aft.tdm_rx_dma_toggle = 3; + } + } else { + /* Software ec moves spike to 8bytes */ + card->u.aft.tdm_rx_dma_toggle=lo_reg+1; + if (card->u.aft.tdm_rx_dma_toggle > 3) { + card->u.aft.tdm_rx_dma_toggle=0; + } + } + + if (lo_reg < 3) { + card->u.aft.tdm_tx_dma_toggle = lo_reg+1; + } else { + card->u.aft.tdm_tx_dma_toggle = 0; + } + + DEBUG_EVENT("%s: Card TDM Rsync Rx=%i Tx=%i\n", + card->devname, + card->u.aft.tdm_rx_dma_toggle, + card->u.aft.tdm_tx_dma_toggle); + } + } + + return 0; +} + +static void aft_critical_shutdown (sdla_t *card) +{ + DEBUG_EVENT("%s: Error: Card Critically Shutdown!\n", + card->devname); + + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } + if (card->wandev.fe_iface.unconfig){ + card->wandev.fe_iface.unconfig(&card->fe); + } + disable_data_error_intr(card,DEVICE_DOWN); + wan_set_bit(CARD_DOWN,&card->wandev.critical); + port_set_state(card,WAN_DISCONNECTED); + + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); + aft_hwdev[card->wandev.card_type].aft_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_OFF); +} + +static int aft_hwec_config (sdla_t *card, private_area_t *chan, wanif_conf_t *conf, int ctrl) +{ + int err = 0; + unsigned int channel=0; + unsigned int tdmv_hwec_option=0; + + if (conf) { + tdmv_hwec_option=conf->hwec.enable; + } + + if (chan->common.usedby == TDM_VOICE_API || + chan->common.usedby == TDM_VOICE){ + + if (IS_TE1_CARD(card)) { + if (IS_T1_CARD(card)){ + channel = chan->first_time_slot; + }else{ + channel = chan->first_time_slot; + } + } else { + channel = chan->first_time_slot; + } + +#if defined(CONFIG_WANPIPE_HWEC) + if (ctrl == 0 && card->wandev.ec_enable){ + card->wandev.ec_enable(card, 0, channel); + + } else if (tdmv_hwec_option && card->wandev.ec_enable){ + DEBUG_HWEC("%s: HW echo canceller Enabled on channel %d\n", + chan->if_name, + channel); + err = card->wandev.ec_enable(card, 1, channel); + if (err) { + DEBUG_EVENT("%s: Failed to enable HWEC on channel %d\n", + chan->if_name,channel); + return err; + } + } +#endif + } + + return err; +} + + +#if defined(AFT_RTP_SUPPORT) +enum { + WAN_TDM_RTP_NO_CHANGE, + WAN_TDM_RTP_CALL_START, + WAN_TDM_RTP_CALL_STOP +}; + +static void aft_rtp_unconfig(sdla_t *card) +{ + wan_rtp_chan_t *rtp_chan; + int i; + + card->wandev.rtp_len=0; + + card->rtp_conf.rtp_ip=0; + card->rtp_conf.rtp_sample=0; + + if (card->wandev.rtp_dev) { + dev_put(card->wandev.rtp_dev); + card->wandev.rtp_dev=NULL; + } + + for (i=0;i<32;i++) { + rtp_chan=&card->wandev.rtp_chan[i]; + if (rtp_chan->rx_skb) { + wan_skb_free(rtp_chan->rx_skb); + rtp_chan->rx_skb=NULL; + } + if (rtp_chan->tx_skb) { + wan_skb_free(rtp_chan->tx_skb); + rtp_chan->rx_skb=NULL; + } + } + +} +#endif + + +#if defined(AFT_RTP_SUPPORT) +static int aft_rtp_config(sdla_t *card) +{ + netdevice_t *dev; + card->wandev.rtp_tap=NULL; + + if (!card->rtp_conf.rtp_ip || !card->rtp_conf.rtp_sample) { + return 1; + } + + if (card->rtp_conf.rtp_sample < 10 || card->rtp_conf.rtp_sample > 150) { + DEBUG_EVENT("%s: Error: Invalid RTP Sample %d [Min=10 Max=150ms]\n", + card->devname,card->rtp_conf.rtp_sample); + goto aft_rtp_init_exit; + } + + DEBUG_EVENT("%s: RTP TAP [ %d.%d.%d.%d:%d %dms %s %02X:%02X:%02X:%02X:%02X:%02X ]\n", + card->devname, + NIPQUAD(card->rtp_conf.rtp_ip), + card->rtp_conf.rtp_port, + card->rtp_conf.rtp_sample, + card->rtp_conf.rtp_devname, + card->rtp_conf.rtp_mac[0], + card->rtp_conf.rtp_mac[1], + card->rtp_conf.rtp_mac[2], + card->rtp_conf.rtp_mac[3], + card->rtp_conf.rtp_mac[4], + card->rtp_conf.rtp_mac[5]); + + card->wandev.rtp_len = (card->rtp_conf.rtp_sample * 8) + sizeof(wan_rtp_pkt_t); + + if ((card->wandev.rtp_dev=dev_get_by_name(card->rtp_conf.rtp_devname)) == NULL){ + DEBUG_EVENT("%s: Failed to open rtp tx device %s\n", + card->devname, + card->rtp_conf.rtp_devname); + goto aft_rtp_init_exit; + } + + dev=(netdevice_t*)card->wandev.rtp_dev; + + memcpy(card->rtp_conf.rtp_local_mac,dev->dev_addr,dev->addr_len); + card->rtp_conf.rtp_local_ip=wan_get_ip_address(card->wandev.rtp_dev,WAN_LOCAL_IP); + if (card->rtp_conf.rtp_local_ip == 0) { + goto aft_rtp_init_exit; + } + + card->wandev.rtp_tap=&aft_rtp_tap; + + memset(card->wandev.rtp_chan,0,sizeof(card->wandev.rtp_chan)); + + return 0; + +aft_rtp_init_exit: + + + aft_rtp_unconfig(card); + + DEBUG_EVENT("%s: Failed to configure rtp tap!\n",card->devname); + + return -1; + +} + + +static __inline void aft_rtp_tap_chan(sdla_t *card, u8 *data, u32 len, + netskb_t **skb_q, + u32 *timestamp, + u8 call_status, + u32 chan) +{ + wan_rtp_pkt_t *pkt; + u8 *buf; + netskb_t *skb; + u32 ts; + + if ((skb=*skb_q) == NULL) { + *skb_q=wan_skb_alloc(card->wandev.rtp_len+128); + if (!*skb_q) { + return; + } + skb=*skb_q; + pkt = (wan_rtp_pkt_t*)wan_skb_put(skb,sizeof(wan_rtp_pkt_t)); + memset(pkt,0,sizeof(wan_rtp_pkt_t)); + pkt->rtp_hdr.version=2; + if (IS_T1_CARD(card)) { + pkt->rtp_hdr.pt=0; + } else { + pkt->rtp_hdr.pt=1; + } + DEBUG_TEST("%s: RTP(%d) SKB Allocated Len=%i \n", + card->devname,chan,card->wandev.rtp_len); + } + + pkt = (wan_rtp_pkt_t*)wan_skb_data(skb); + + if (call_status == WAN_TDM_RTP_CALL_START) { + pkt->rtp_hdr.seq=0; + pkt->rtp_hdr.ts=0; + *timestamp=0; + } + + buf=wan_skb_put(skb,len); + memcpy(buf,data,len); + + ts=htonl(pkt->rtp_hdr.ts); + ts+=len; + pkt->rtp_hdr.ts = htonl(ts); + + if (wan_skb_len(skb) >= card->wandev.rtp_len || + call_status==WAN_TDM_RTP_CALL_STOP) { + netskb_t *nskb; + u16 seq; + + pkt->rtp_hdr.ts = *timestamp; + + wan_ip_udp_setup(card, + &card->rtp_conf, + chan, + wan_skb_data(skb), + wan_skb_len(skb)-sizeof(wan_rtp_pkt_t)); + + + nskb=wan_skb_clone(skb); + if (nskb) { + nskb->next = nskb->prev = NULL; + nskb->dev = card->wandev.rtp_dev; + nskb->protocol = htons(ETH_P_802_2); + nskb->mac.raw = wan_skb_data(nskb); + nskb->nh.raw = wan_skb_data(nskb); + dev_queue_xmit(nskb); + DEBUG_TEST("%s: RTP(%d) SKB Tx on dev %s \n", + card->devname,chan,nskb->dev->name); + } + + wan_skb_trim(skb,sizeof(wan_rtp_pkt_t)); + + pkt = (wan_rtp_pkt_t*)wan_skb_data(skb); + + seq=htons(pkt->rtp_hdr.seq); + seq++; + pkt->rtp_hdr.seq=htons(seq); + + *timestamp = htonl(ts); + DEBUG_TEST("Chan=%i Seq=%i TS=%i\n",chan,seq,ts); + pkt->rtp_hdr.ts = htonl(ts); + } +} + +static void aft_rtp_tap(void *card_ptr, u8 chan, u8* rx, u8* tx, u32 len) +{ + sdla_t *card = (sdla_t *)card_ptr; + u8 call_status=WAN_TDM_RTP_NO_CHANGE; + wan_rtp_chan_t *rtp_chan; + u32 span; + + if (!card || !rx || !tx ) { + if (WAN_NET_RATELIMIT()) { + DEBUG_EVENT("%s: Internal Error: rtp tap invalid pointers chan %i\n", + __FUNCTION__,chan); + } + return; + } + + if (!card->rtp_conf.rtp_ip || + !card->rtp_conf.rtp_sample || + !card->wandev.rtp_len || + !card->wandev.rtp_dev) { + if (WAN_NET_RATELIMIT()) { + DEBUG_EVENT("%s: RTP Tap Not configured %i\n", + card->devname,chan); + } + return; + } + + if (chan >= 32) { + if (WAN_NET_RATELIMIT()) { + DEBUG_EVENT("%s: Internal Error: rtp tap chan out of range %i\n", + card->devname,chan); + } + return; + } + + span = card->tdmv_conf.span_no-1; + rtp_chan = &card->wandev.rtp_chan[chan]; + + if (wan_test_bit(chan,&card->wandev.rtp_tap_call_map)) { + if (!wan_test_and_set_bit(chan,&card->wandev.rtp_tap_call_status)) { + /* Start of the call */ + call_status=WAN_TDM_RTP_CALL_START; + DEBUG_TEST("%s: CALL Start on ch %i\n", + card->devname,chan); + } + } else { + if (!wan_test_bit(chan,&card->wandev.rtp_tap_call_status)) { + /* Call not up */ + return; + } + wan_clear_bit(chan,&card->wandev.rtp_tap_call_status); + call_status=WAN_TDM_RTP_CALL_STOP; + DEBUG_TEST("%s: CALL Stop on ch %i\n", + card->devname,chan); + } + + + aft_rtp_tap_chan(card, rx, len, &rtp_chan->rx_skb, &rtp_chan->rx_ts, + call_status, (span<<4|(chan+1))); + aft_rtp_tap_chan(card, tx, len, &rtp_chan->tx_skb, &rtp_chan->tx_ts, + call_status, (span<<4|(chan+1))+2000); + +} +#endif + +static int aft_find_master_if_and_dchan(sdla_t *card, int *master_if, u32 active_ch) +{ + int dchan_found=0; + int i; + + if (card->tdmv_conf.dchan) { + if (IS_E1_CARD(card) && !(WAN_FE_FRAME(&card->fe) == WAN_FR_UNFRAMED)) { + card->tdmv_conf.dchan = card->tdmv_conf.dchan << 1; + wan_clear_bit(0,&card->tdmv_conf.dchan); + } + } + + for (i=card->u.aft.num_of_time_slots-1;i>=0;i--){ + if (wan_test_bit(i,&active_ch)){ + + if (wan_test_bit(i,&card->tdmv_conf.dchan)){ + dchan_found=1; + card->u.aft.tdmv_dchan=i; + continue; + } + + /* Find the TOP timeslot. This timeslot will be + * considered MASTER since it is the last timeslot + * to rx data from the T1 line */ + if (*master_if < 0){ + *master_if=i; + } + } + } + + if (card->tdmv_conf.dchan && !dchan_found){ + /* We configured for dchan however, this interface + * was not configued with the DCHAN timeslot. + * It IS now possible that another interface has + * this time slot */ + for (i=card->u.aft.num_of_time_slots-1;i>=0;i--){ + if (wan_test_bit(i,&card->tdmv_conf.dchan)){ + dchan_found=1; + card->u.aft.tdmv_dchan=i; + wan_set_bit(i,&card->u.aft.tdmv_dchan_cfg_on_master); + continue; + } + } + + if (!dchan_found) { + DEBUG_EVENT("%s: Error: TDM DCHAN is out of range 0x%08X\n", + card->devname,card->tdmv_conf.dchan); + return -EINVAL; + } + + /* We have found a DCHAN outside the + Voice active channels */ + } + + return 0; +} + + +static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt) +{ + netskb_t* skb; + netdevice_t* dev; + char* buf; + private_area_t *chan; + + dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); + if (dev == NULL) { + return 1; + } + chan = wan_netif_priv(dev); + if (chan == NULL) { + return 1; + } + + if (chan->common.state != WAN_CONNECTED) { + DEBUG_EVENT("%s: Loop test failed: dev not connected!\n", + card->devname); + return 2; + } + + skb = wan_skb_alloc(wan_udp_pkt->wan_udp_data_len+100); + if (skb == NULL) { + return 3; + } + + switch (chan->common.usedby) { + + case API: + wan_skb_push(skb, sizeof(api_rx_hdr_t)); + break; + + case STACK: + case WANPIPE: + break; + + case TDM_VOICE: + case TDM_VOICE_API: + case TDM_VOICE_DCHAN: + if (card->u.aft.tdmv_dchan) { + break; + } else { + DEBUG_EVENT("%s: Loop test failed: no dchan in TDMV mode!\n", + card->devname); + } + /* Fall into the default case */ + + default: + DEBUG_EVENT("%s: Loop test failed: invalid operation mode!\n", + card->devname); + wan_skb_free(skb); + return 4; + } + + buf = wan_skb_put(skb, wan_udp_pkt->wan_udp_data_len); + memcpy(buf, wan_udp_pkt->wan_udp_data, wan_udp_pkt->wan_udp_data_len); + +#if defined(__LINUX__) + skb->next = skb->prev = NULL; + skb->dev = dev; + skb->protocol = htons(ETH_P_IP); + skb->mac.raw = wan_skb_data(skb); + dev_queue_xmit(skb); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) +# warning "FIXME: Add code for digital loop test" +#endif + return 0; +} + + + +void wanpipe_wake_stack(private_area_t* chan) +{ + WAN_NETIF_WAKE_QUEUE(chan->common.dev); + if (chan->common.usedby == API){ + wan_wakeup_api(chan); + }else if (chan->common.usedby == STACK){ + wanpipe_lip_kick(chan,0); + }else if (chan->common.usedby == TDM_VOICE_DCHAN){ +#ifdef AFT_TDM_API_SUPPORT + if (is_tdm_api(chan,&chan->wp_tdm_api_dev)){ + wanpipe_tdm_api_kick(&chan->wp_tdm_api_dev); + } +#endif + } +} + +/****** End ****************************************************************/ diff --git a/patches/kdrivers/src/net/sdla_aft_te3.c b/patches/kdrivers/src/net/sdla_aft_te3.c index c946094..bdacf5c 100644 --- a/patches/kdrivers/src/net/sdla_aft_te3.c +++ b/patches/kdrivers/src/net/sdla_aft_te3.c @@ -43,7 +43,6 @@ #define DBGSTATS if(0)DEBUG_EVENT - /****** Defines & Macros ****************************************************/ /* Private critical flags */ @@ -107,7 +106,7 @@ enum { #define MAX_AFT_DMA_CHAINS 16 #define MAX_TX_BUF (MAX_AFT_DMA_CHAINS)+1 -#define MAX_RX_BUF ((MAX_AFT_DMA_CHAINS)*8)+1 +#define MAX_RX_BUF ((MAX_AFT_DMA_CHAINS)*4)+1 #define MAX_RX_SCHAIN_BUF (MAX_RX_BUF)*2 @@ -282,15 +281,11 @@ static int if_init (netdevice_t* dev); #endif static int if_open (netdevice_t* dev); static int if_close (netdevice_t* dev); -static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); - - - -static struct net_device_stats* if_stats (netdevice_t* dev); +static int if_do_ioctl(netdevice_t*, struct ifreq*, wan_ioctl_cmd_t); #if defined(__LINUX__) static int if_send (netskb_t* skb, netdevice_t* dev); -static int if_change_mtu(netdevice_t *dev, int new_mtu); +static struct net_device_stats* if_stats (netdevice_t* dev); #else static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct rtentry *rt); #endif @@ -376,8 +371,8 @@ static void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb); static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num); static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb); -static int write_framer(void *pcard,unsigned short framer_off,unsigned short framer_data); -static unsigned int read_framer(void *pcard,unsigned short framer_off); +//static int write_framer(void *pcard,unsigned short framer_off,unsigned short framer_data); +//static unsigned int read_framer(void *pcard,unsigned short framer_off); #if 0 //FIXME to be taken out check with M.F. static void framer_reset(sdla_t *card); @@ -503,9 +498,6 @@ int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) return -EINVAL; } -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); -#endif if (card->adptr_subtype == AFT_SUBTYPE_SHARK) { DEBUG_EVENT("%s: Starting SHARK T3/E3 Adapter!\n", @@ -516,7 +508,7 @@ int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) card->wandev.clocking = conf->clocking; card->wandev.ignore_front_end_status = conf->ignore_front_end_status; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.comm_port = conf->comm_port; card->wandev.udp_port = conf->udp_port; card->wandev.new_if_cnt = 0; @@ -538,14 +530,16 @@ int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) card->fe.write_fe_cpld = write_fe_cpld; // card->fe.read_cpld = read_cpld; - card->fe.write_framer = write_framer; - card->fe.read_framer = read_framer; + card->fe.write_fe_reg = card->hw_iface.fe_write; + card->fe.read_fe_reg = card->hw_iface.fe_read; + //card->fe.write_framer = write_framer; + //card->fe.read_framer = read_framer; // card->wandev.write_front_end_reg = write_front_end_reg; // card->wandev.read_front_end_reg = read_front_end_reg; card->wandev.fe_enable_timer = enable_timer; card->wandev.te_link_state = handle_front_end_state; -//ALEX conf->interface = +//ALEX conf->electrical_interface = // IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; if (card->wandev.comm_port == WANOPT_PRI){ @@ -671,12 +665,12 @@ int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t* dev; volatile private_area_t* chan; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -748,7 +742,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; private_area_t* chan; int err = 0; netskb_t *skb; @@ -776,9 +770,6 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) #ifdef AFT_T3_SINGLE_DMA_CHAIN chan->single_dma_chain=1; #endif - if (conf->single_tx_buf) { - chan->single_dma_chain=1; - } strncpy(chan->if_name, wan_netif_name(dev), WAN_IFNAME_SZ); @@ -932,10 +923,6 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) goto new_if_error; } - if (chan->dma_mtu/2 > aft_rx_copyback) { - aft_rx_copyback=chan->dma_mtu/2; - } - chan->dma_bufs=card->u.xilinx.cfg.dma_per_ch; if (chan->single_dma_chain){ chan->dma_bufs=MAX_RX_SCHAIN_BUF; @@ -1017,7 +1004,6 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) wan_netif_set_priv(dev,chan); #if defined(__LINUX__) dev->init = &if_init; - # ifdef WANPIPE_GENERIC if_init(dev); # endif @@ -1027,9 +1013,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) chan->common.iface.close = &if_close; chan->common.iface.output = &if_send; chan->common.iface.ioctl = &if_do_ioctl; - chan->common.iface.get_stats = &if_stats; chan->common.iface.tx_timeout = &if_tx_timeout; - if (wan_iface.attach){ if (!ifunit(wan_netif_name(dev))){ wan_iface.attach(dev, NULL, chan->common.is_netdev); @@ -1202,7 +1186,6 @@ static int if_init (netdevice_t* dev) dev->watchdog_timeo = 2*HZ; #endif dev->do_ioctl = if_do_ioctl; - dev->change_mtu = if_change_mtu; if (chan->common.usedby == BRIDGE || chan->common.usedby == BRIDGE_NODE){ @@ -1225,6 +1208,8 @@ static int if_init (netdevice_t* dev) dev->type = ARPHRD_PPP; dev->mtu = card->wandev.mtu; dev->hard_header_len = 16; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->addr_len = 0; } @@ -1300,6 +1285,7 @@ static int if_open (netdevice_t* dev) WAN_NETIF_STOP_QUEUE(dev); WAN_NETIF_CARRIER_OFF(dev); + /* If FRONT End is down, it means that the DMA * is disabled. In this case don't try to * reset fifo. Let the enable_data_error_intr() @@ -1518,7 +1504,9 @@ static void if_tx_timeout (netdevice_t *dev) xilinx_tx_fifo_under_recover(card,chan); wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); + if (!chan->single_dma_chain){ + aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); + } } @@ -1676,6 +1664,7 @@ if_send_exit_crit: } +#if defined(__LINUX__) /*============================================================================ * if_stats * @@ -1728,34 +1717,6 @@ static struct net_device_stats* if_stats (netdevice_t* dev) return &chan->if_stats; } - -#if defined(__LINUX__) -static int if_change_mtu(netdevice_t *dev, int new_mtu) -{ - private_area_t* chan= (private_area_t*)wan_netif_priv(dev); - - if (!chan){ - return -ENODEV; - } - - if (!chan->hdlc_eng) { - return -EINVAL; - } - - if (chan->common.usedby == API){ - new_mtu+=sizeof(api_tx_hdr_t); - }else if (chan->common.usedby == STACK){ - new_mtu+=32; - } - - if (new_mtu > chan->dma_mtu) { - return -EINVAL; - } - - dev->mtu = new_mtu; - - return 0; -} #endif /*======================================================================== @@ -1777,7 +1738,8 @@ static int if_change_mtu(netdevice_t *dev, int new_mtu) * wanpipemon debugger * */ -static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +static int +if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t cmd) { private_area_t* chan= (private_area_t*)wan_netif_priv(dev); sdla_t *card; @@ -1897,8 +1859,8 @@ static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) default: #ifndef WANPIPE_GENERIC - DEBUG_EVENT("%s: Command %x not supported!\n", - card->devname,cmd); + DEBUG_IOCTL("%s: Command %x not supported!\n", + card->devname,cmd); return -EOPNOTSUPP; #else if (card->wandev.ioctl){ @@ -2219,58 +2181,6 @@ static void xilinx_dma_rx_complete (sdla_t *card, private_area_t *chan, int wtd) aft_rx_dma_chain_handler(chan,wtd,0); } - -static int aft_check_pci_errors(sdla_t *card, private_area_t *chan, wp_rx_element_t *rx_el) -{ - int pci_err=0; - if (rx_el->reg&RxDMA_HI_DMA_PCI_ERROR_MASK){ - - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_M_ABRT){ - if (WAN_NET_RATELIMIT()) { - DEBUG_EVENT("%s:%s: Rx Error: Abort from Master: pci fatal error!\n", - card->devname,chan->if_name); - } - pci_err=1; - } - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_T_ABRT){ - if (WAN_NET_RATELIMIT()) { - DEBUG_EVENT("%s:%s: Rx Error: Abort from Target: pci fatal error!\n", - card->devname,chan->if_name); - } - pci_err=1; - } - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_DS_TOUT){ - if (WAN_NET_RATELIMIT()) { - DEBUG_EVENT("%s:%s: Rx Error: No 'DeviceSelect' from target: pci fatal error!\n", - card->devname,chan->if_name); - } - pci_err=1; - } - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT){ - if (WAN_NET_RATELIMIT()) { - DEBUG_EVENT("%s:%s: Rx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", - card->devname,chan->if_name); - } - pci_err=1; - } - - if (!pci_err) { - if (WAN_NET_RATELIMIT()) { - DEBUG_EVENT("%s: RXDMA Unknown PCI ERROR = 0x%x\n",chan->if_name,rx_el->reg); - } - } - - - return -1; - } - - - - return 0; -} - - - /*=============================================== * xilinx_rx_post_complete * @@ -2304,17 +2214,34 @@ static void xilinx_rx_post_complete (sdla_t *card, private_area_t *chan, /* Checking Rx DMA Go bit. Has to be '0' */ if (wan_test_bit(RxDMA_HI_DMA_GO_READY_BIT,&rx_el->reg)){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%s: Error: RxDMA Intr: GO bit set on Rx intr\n", + DEBUG_TEST("%s:%s: Error: RxDMA Intr: GO bit set on Rx intr\n", card->devname,chan->if_name); - } chan->if_stats.rx_errors++; chan->errstats.Rx_dma_descr_err++; goto rx_comp_error; } /* Checking Rx DMA PCI error status. Has to be '0's */ - if (aft_check_pci_errors(card,chan,rx_el) != 0) { + if (rx_el->reg&RxDMA_HI_DMA_PCI_ERROR_MASK){ + + if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_M_ABRT){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Master: pci fatal error!\n", + card->devname,chan->if_name); + } + if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_T_ABRT){ + DEBUG_EVENT("%s:%s: Rx Error: Abort from Target: pci fatal error!\n", + card->devname,chan->if_name); + } + if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_DS_TOUT){ + DEBUG_EVENT("%s:%s: Rx Error: No 'DeviceSelect' from target: pci fatal error!\n", + card->devname,chan->if_name); + } + if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT){ + DEBUG_EVENT("%s:%s: Rx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", + card->devname,chan->if_name); + } + + DEBUG_EVENT("%s: RXDMA PCI ERROR = 0x%x\n",chan->if_name,rx_el->reg); chan->errstats.Rx_pci_errors++; chan->if_stats.rx_errors++; goto rx_comp_error; @@ -2519,11 +2446,10 @@ static void wp_bh (unsigned long data) static void wp_bh (void* data, int dummy) #endif { - private_area_t* chan = (private_area_t *)data; - netskb_t *new_skb,*skb; - unsigned char pkt_error; - unsigned long timeout=SYSTEM_TICKS; - int len; + private_area_t *chan = (private_area_t *)data; + netskb_t *new_skb,*skb; + unsigned char pkt_error; + wan_ticks_t timeout=SYSTEM_TICKS; DEBUG_TEST("%s: ------------ BEGIN --------------: %lu\n", __FUNCTION__,SYSTEM_TICKS); @@ -2541,12 +2467,24 @@ static void wp_bh (void* data, int dummy) #if 0 chan->if_stats.rx_errors++; #endif + + if (SYSTEM_TICKS-timeout > 3){ + chan->if_stats.rx_errors++; +#if 0 + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: BH Squeeze!\n",chan->if_name); + } +#endif + wan_skb_queue_head(&chan->wp_rx_complete_list,skb); + break; + } if (chan->common.usedby == API && chan->common.sk == NULL){ DEBUG_TEST("%s: No sock bound to channel rx dropping!\n", chan->if_name); chan->if_stats.rx_dropped++; aft_init_requeue_free_skb(chan, skb); + continue; } @@ -2617,7 +2555,7 @@ static void wp_bh (void* data, int dummy) wan_skb_free(new_skb); continue; } - + }else{ protocol_recv(chan->card,chan,new_skb); } @@ -2629,10 +2567,10 @@ static void wp_bh (void* data, int dummy) } if (SYSTEM_TICKS-timeout > 3){ - //chan->if_stats.rx_errors++; + chan->if_stats.rx_errors++; #if 0 if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: BH Squeeze! %li\n", + DEBUG_EVENT("%s: BH Squeeze! %i\n", chan->if_name,SYSTEM_TICKS-timeout); } #endif @@ -2647,7 +2585,9 @@ static void wp_bh (void* data, int dummy) WAN_TASKLET_END((&chan->common.bh_task)); - +#if 1 + { + int len; if ((len=wan_skb_queue_len(&chan->wp_rx_complete_list))){ DEBUG_TEST("%s: Triggering from bh rx=%i\n",chan->if_name,len); WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); @@ -2655,9 +2595,12 @@ static void wp_bh (void* data, int dummy) DEBUG_TEST("%s: Triggering from bh tx=%i\n",chan->if_name,len); WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); } + } +#endif DEBUG_TEST("%s: ------------ END -----------------: %lu\n", __FUNCTION__,SYSTEM_TICKS); + return; } @@ -2680,6 +2623,9 @@ static int fifo_error_interrupt(sdla_t *card, u32 reg, u32 tx_status, u32 rx_sta card->devname); return 0; } + + DEBUG_TEST("%s: RX FIFO=0x%08X TX FIFO=0x%08X\n", + card->devname,rx_status,tx_status); if (IS_TE3(&card->fe.fe_cfg)){ num_of_logic_ch=1; @@ -2938,7 +2884,6 @@ static WAN_IRQ_RETVAL wp_aft_te3_isr (sdla_t* card) XILINX_DMA_RX_INTR_PENDING_REG, &dma_rx_reg); - DEBUG_TEST("%s: DMA_RX_INTR_REG(0x%X) = 0x%X ActCH=0x%lX\n", card->devname, XILINX_DMA_RX_INTR_PENDING_REG,dma_rx_reg, @@ -3056,7 +3001,10 @@ isr_skb_tx: DEBUG_TEST("%s: Skipping Rx WTD Flags=%d\n", chan->if_name,wan_test_bit(0,&chan->up)); } - aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); + aft_reset_rx_watchdog(card); + if (!chan->single_dma_chain){ + aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); + } } DEBUG_TEST("%s: Rx WatchDog Expired %p!\n", @@ -3275,7 +3223,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); wan_udp_pkt->wan_udp_return_code = 0; break; - + case READ_OPERATIONAL_STATS: wan_udp_pkt->wan_udp_return_code = 0; memcpy(wan_udp_pkt->wan_udp_data,&chan->opstats,sizeof(aft_op_stats_t)); @@ -3346,45 +3294,6 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, } break; } /* end of switch */ - -#if 0 - case READ_OPERATIONAL_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memcpy(wan_udp_pkt->wan_udp_data,&chan->opstats,sizeof(aft_op_stats_t)); - wan_udp_pkt->wan_udp_data_len=sizeof(aft_op_stats_t); - break; - - case FLUSH_OPERATIONAL_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memset(&chan->opstats,0,sizeof(aft_op_stats_t)); - wan_udp_pkt->wan_udp_data_len=0; - break; - - case READ_COMMS_ERROR_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memcpy(wan_udp_pkt->wan_udp_data,&chan->errstats,sizeof(aft_comm_err_stats_t)); - wan_udp_pkt->wan_udp_data_len=sizeof(aft_comm_err_stats_t); - break; - - case FLUSH_COMMS_ERROR_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memset(&chan->errstats,0,sizeof(aft_comm_err_stats_t)); - wan_udp_pkt->wan_udp_data_len=0; - break; - - default: - wan_udp_pkt->wan_udp_data_len = 0; - wan_udp_pkt->wan_udp_return_code = 0xCD; - - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT( - "%s: Warning, Illegal UDP command attempted from network: %x\n", - card->devname,wan_udp_pkt->wan_udp_command); - } - break; - } /* end of switch */ -#endif - } /* end of else */ /* Fill UDP TTL */ @@ -3935,7 +3844,7 @@ static void enable_data_error_intr(sdla_t *card) card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,®); - + aft_enable_rx_watchdog(card,AFT_RX_TIMEOUT); aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); @@ -4031,7 +3940,7 @@ static int update_comms_stats(sdla_t* card) /* TE1 Update T1/E1 alarms */ if (IS_TE3(&card->fe.fe_cfg)) { - WAN_FECALL(&card->wandev, read_alarm, (&card->fe, 0)); + WAN_FECALL(&card->wandev, read_alarm, (&card->fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE)); /* TE1 Update T1/E1 perfomance counters */ WAN_FECALL(&card->wandev, read_pmon, (&card->fe, 0)); } @@ -4075,7 +3984,9 @@ static void xilinx_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) wanpipe_lip_kick(chan,0); } #endif - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); + if (!chan->single_dma_chain){ + aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); + } } static int xilinx_write_ctrl_hdlc(sdla_t *card, u32 timeslot, u8 reg_off, u32 data) @@ -4317,7 +4228,7 @@ static int xilinx_t3_exar_chip_configure(sdla_t *card) card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - WP_DELAY(100); + WP_DELAY(10); /* Disable the chip/hdlc reset condition */ wan_clear_bit(CHIP_RESET_BIT,®); @@ -4384,8 +4295,6 @@ static int xilinx_t3_exar_chip_configure(sdla_t *card) DEBUG_CFG("--- T3 Exar Chip enable/config. -- \n"); card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - - WP_DELAY(100); xilinx_delay(1); #if 0 @@ -4557,6 +4466,15 @@ static int xilinx_t3_exar_dev_configure(sdla_t *card, private_area_t *chan) card->u.xilinx.dev_to_ch_map[0]=(void*)chan; } + /* Setup global DMA parameters */ + if (chan->single_dma_chain){ + card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,®); + reg&=~DMA_CHAIN_TE3_MASK; + reg|=1&DMA_CHAIN_TE3_MASK; + card->hw_iface.bus_write_4(card->hw,XILINX_DMA_CONTROL_REG,reg); + } + + reg=0; if (chan->hdlc_eng){ @@ -4675,6 +4593,9 @@ static void xilinx_t3_exar_transparent_config(sdla_t *card,private_area_t *chan) } +#if 0 +/* Alex +** This functions are moved to sdladrv_fe.c */ #define BIT_DEV_ADDR_CLEAR 0x600 static int write_framer(void *pcard, unsigned short framer_off,unsigned short framer_data) @@ -4689,12 +4610,10 @@ static int write_framer(void *pcard, unsigned short framer_off,unsigned short fr card->hw_iface.bus_write_2(card->hw, 0x46, framer_off); - WP_DELAY(5); card->hw_iface.bus_write_2(card->hw, 0x44, framer_data); - WP_DELAY(5); return 0; } @@ -4709,18 +4628,17 @@ static unsigned int read_framer(void *pcard,unsigned short framer_off) card->hw_iface.bus_write_2(card->hw, 0x46, framer_off); - WP_DELAY(5); card->hw_iface.bus_read_4(card->hw, 0x44, &framer_data); - WP_DELAY(5); DEBUG_TEST("READ FRAMER OFFSET=0x%02X DATA=0x%02X\n", framer_off,framer_data); return framer_data; } +#endif #if 0 static void framer_reset(sdla_t *card) @@ -4909,7 +4827,7 @@ static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int wan_set_bit(TxDMA_HI_DMA_GO_READY_BIT,®); - DEBUG_TX("%s: TXDMA_HI=0x%X DmaDescr=0x%lX len=%i\n", + DEBUG_TEST("%s: TXDMA_HI=0x%X DmaDescr=0x%lX len=%i\n", __FUNCTION__,reg,dma_chain->dma_addr,len); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -5077,6 +4995,24 @@ static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan, netskb_t *skb) } } +#if 0 + if (0){ + netskb_t *nskb=__dev_alloc_skb(wan_skb_len(skb),GFP_DMA|GFP_ATOMIC); + if (!nskb) { + wan_skb_free(skb); + wan_clear_bit(0,&dma_chain->init); + chan->if_stats.tx_errors++; + return -EINVAL; + } else { + unsigned char *buf = wan_skb_put(nskb,wan_skb_len(skb)); + memcpy(buf,wan_skb_data(skb),wan_skb_len(skb)); + wan_skb_free(skb); + skb=nskb; + } + } +#endif + + dma_chain->skb=skb; dma_chain->dma_addr = @@ -5136,7 +5072,7 @@ static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan, netskb_t *skb) if (!wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status)){ aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); } - } + } wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); @@ -5177,7 +5113,7 @@ static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, in card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - dma_descr= (u32)(dma_ch_indx<<4) + XILINX_RxDMA_DESCRIPTOR_HI; + dma_descr=(unsigned long)(dma_ch_indx<<4) + XILINX_RxDMA_DESCRIPTOR_HI; reg =0; @@ -5210,7 +5146,7 @@ static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, in wan_set_bit(RxDMA_HI_DMA_GO_READY_BIT,®); - DEBUG_RX("%s: RXDMA_HI = 0x%X, BusAddr=0x%X DmaDescr=0x%X\n", + DEBUG_TEST("%s: RXDMA_HI = 0x%X, BusAddr=0x%X DmaDescr=0x%X\n", __FUNCTION__,reg,dma_chain->dma_addr,dma_descr); card->hw_iface.bus_write_4(card->hw,dma_descr,reg); @@ -5392,8 +5328,6 @@ static void aft_rx_dma_chain_handler(private_area_t *chan, int wtd, int reset) chan->if_name,__FUNCTION__); return; } - - aft_reset_rx_watchdog(card); if (!wtd){ /* Not watchdog, thus called from an interrupt. @@ -5462,26 +5396,17 @@ static void aft_rx_dma_chain_handler(private_area_t *chan, int wtd, int reset) dma_descr=(dma_chain->index<<4) + XILINX_RxDMA_DESCRIPTOR_HI; card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->reg); - if (aft_check_pci_errors(card,chan,rx_el) != 0) { - chan->errstats.Rx_pci_errors++; - chan->if_stats.rx_errors++; - wan_skb_pull(dma_chain->skb, sizeof(wp_rx_element_t)); - aft_init_requeue_free_skb(chan, dma_chain->skb); - dma_chain->skb=NULL; - } else { + rx_el->pkt_error= dma_chain->pkt_error; + rx_el->dma_addr = dma_chain->dma_addr; - rx_el->pkt_error= dma_chain->pkt_error; - rx_el->dma_addr = dma_chain->dma_addr; + wan_skb_queue_tail(&chan->wp_rx_complete_list,dma_chain->skb); - wan_skb_queue_tail(&chan->wp_rx_complete_list,dma_chain->skb); - - DEBUG_RX("%s: RxInr Pending chain %i Rxlist=%i LO:0x%X HI:0x%X Data=0x%X Len=%i!\n", + DEBUG_RX("%s: RxInr Pending chain %i Rxlist=%i LO:0x%X HI:0x%X Data=0x%X Len=%i!\n", chan->if_name,dma_chain->index, wan_skb_queue_len(&chan->wp_rx_complete_list), rx_el->align,rx_el->reg, (*(unsigned char*)wan_skb_data(dma_chain->skb)), wan_skb_len(dma_chain->skb)); - } dma_chain->skb=NULL; dma_chain->dma_addr=0; @@ -5503,32 +5428,27 @@ static void aft_rx_dma_chain_handler(private_area_t *chan, int wtd, int reset) if (reset){ goto reset_skip_rx_setup; } - - if (!wtd) { - /* Only reload dma on interrupt */ - xilinx_dma_rx(card,chan,cur_dma_ptr); - } + + xilinx_dma_rx(card,chan,cur_dma_ptr); if (wan_skb_queue_len(&chan->wp_rx_complete_list)){ DEBUG_TEST("%s: Rx Queued list triggering\n",chan->if_name); WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); chan->rx_no_data_cnt=0; + }else{ + if (!chan->single_dma_chain){ + if ((chan->rx_no_data_cnt >= 0) && (++chan->rx_no_data_cnt < 3)){ + aft_enable_rx_watchdog(card,AFT_RX_TIMEOUT); + }else{ + /* Enable Rx Interrupt on pending rx descriptor */ + DEBUG_TEST("%s: Setting Max Rx Watchdog Timeout\n", + chan->if_name); + aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); + chan->rx_no_data_cnt=-1; + } + } } -#if 1 - if (!chan->single_dma_chain) { - if ((chan->rx_no_data_cnt >= 0) && (++chan->rx_no_data_cnt < 3)){ - aft_enable_rx_watchdog(card,AFT_RX_TIMEOUT); - }else{ - /* Enable Rx Interrupt on pending rx descriptor */ - DEBUG_TEST("%s: Setting Max Rx Watchdog Timeout\n", - chan->if_name); - aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); - chan->rx_no_data_cnt=-1; - } - } -#endif - reset_skip_rx_setup: wan_clear_bit(RX_HANDLER_BUSY,&chan->dma_status); @@ -5941,11 +5861,15 @@ static void aft_port_task (struct work_struct *work) static void aft_port_task (void * card_ptr, int arg) #endif { -#if defined(__LINUX__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); +# else + sdla_t *card = (sdla_t *)card_ptr; +# endif #else sdla_t *card = (sdla_t *)card_ptr; -#endif +#endif wan_smp_flag_t smp_flags,isr_flags; if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ diff --git a/patches/kdrivers/src/net/sdla_aft_te3.c~ b/patches/kdrivers/src/net/sdla_aft_te3.c~ deleted file mode 100644 index 543bbbd..0000000 --- a/patches/kdrivers/src/net/sdla_aft_te3.c~ +++ /dev/null @@ -1,5908 +0,0 @@ -/***************************************************************************** -* sdla_aft_te3.c WANPIPE(tm) AFT Xilinx Hardware Support -* -* Authors: Nenad Corbic -* -* 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. -* ============================================================================ -* Jan 07, 2003 Nenad Corbic Initial version. -*****************************************************************************/ -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -# include -# include -# include -# include /* Socket Driver common area */ -# include -# include -# if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -# include -# endif -# include -#else -# include -# include -# include -# include -# include -# include /* Socket Driver common area */ -# include -# include -# include -# if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -# include -# endif -# include -#endif - -//#define XILINX_A010 1 - -#define DBGSTATS if(0)DEBUG_EVENT - -/****** Defines & Macros ****************************************************/ - -/* Private critical flags */ -enum { - POLL_CRIT = PRIV_CRIT, - CARD_DOWN -}; - -enum { - LINK_DOWN, - DEVICE_DOWN -}; - -enum { - TX_DMA_BUSY, - TX_HANDLER_BUSY, - TX_INTR_PENDING, - TX_DATA_READY, - - RX_HANDLER_BUSY, - RX_DMA_BUSY, - RX_INTR_PENDING, - RX_DATA_READY, - - RX_WTD_SKIP, -}; - -enum { - AFT_FE_CFG_ERR, - AFT_FE_CFG, - AFT_FE_INTR, - AFT_FE_POLL, - AFT_FE_LED -}; - -#define MAX_IP_ERRORS 10 - -#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) - -#undef DEB_XILINX - -#if 0 -# define AFT_XTEST_DEBUG 1 -#else -# undef AFT_XTEST_DEBUG -#endif - -#if 1 -# define TRUE_FIFO_SIZE 1 -#else -# undef TRUE_FIFO_SIZE -# define HARD_FIFO_CODE 0x01 -#endif - - -#if 0 -#define AFT_T3_SINGLE_DMA_CHAIN 1 -#else -#undef AFT_T3_SINGLE_DMA_CHAIN -#endif - -#define MAX_AFT_DMA_CHAINS 16 -#define MAX_TX_BUF (MAX_AFT_DMA_CHAINS)+1 -#define MAX_RX_BUF ((MAX_AFT_DMA_CHAINS)*4)+1 -#define MAX_RX_SCHAIN_BUF (MAX_RX_BUF)*2 - - -#define AFT_MAX_CHIP_SECURITY_CNT 100 -/* Remove HDLC Address - * 1=Remove Enabled - * 0=Remove Disabled - */ - -static int aft_rx_copyback=1000; - -/******Data Structures*****************************************************/ - -/* This structure is placed in the private data area of the device structure. - * The card structure used to occupy the private area but now the following - * structure will incorporate the card structure along with Protocol specific data - */ - -typedef struct aft_dma_chain -{ - unsigned long init; - u32 dma_addr; - u32 dma_len; - netskb_t *skb; - u32 index; - - u32 dma_descr; - u32 len_align; - u32 reg; - - u8 pkt_error; -}aft_dma_chain_t; - -typedef struct private_area -{ - wanpipe_common_t common; - sdla_t *card; - netdevice_t *dev; - - wan_skb_queue_t wp_tx_free_list; - wan_skb_queue_t wp_tx_pending_list; - wan_skb_queue_t wp_tx_complete_list; - netskb_t *tx_dma_skb; - u8 tx_dma_cnt; - - wan_skb_queue_t wp_rx_free_list; - wan_skb_queue_t wp_rx_complete_list; - - unsigned long time_slot_map; - unsigned char num_of_time_slots; - long logic_ch_num; - - unsigned char hdlc_eng; - unsigned long dma_status; - unsigned char protocol; - unsigned char ignore_modem; - - struct net_device_stats if_stats; - aft_op_stats_t opstats; - aft_comm_err_stats_t errstats; -#if 1 - int tracing_enabled; /* For enabling Tracing */ - unsigned long router_start_time; - unsigned long trace_timeout; - - unsigned char route_status; - unsigned char route_removed; - unsigned long tick_counter; /* For 5s timeout counter */ - unsigned long router_up_time; - - unsigned char mc; /* Mulitcast support on/off */ - unsigned char udp_pkt_src; /* udp packet processing */ - unsigned short timer_int_enabled; - - unsigned char interface_down; - - /* Polling task queue. Each interface - * has its own task queue, which is used - * to defer events from the interrupt */ - wan_taskq_t poll_task; - wan_timer_info_t poll_delay_timer; - - u8 gateway; - u8 true_if_encoding; - - //FIXME: add driver stats as per frame relay! -#endif - -#if defined(__LINUX__) - /* Entry in proc fs per each interface */ - struct proc_dir_entry *dent; -#endif - - unsigned char udp_pkt_data[sizeof(wan_udp_pkt_t)+10]; - atomic_t udp_pkt_len; - - char if_name[WAN_IFNAME_SZ+1]; - - u8 idle_flag; - u16 max_idle_size; - u8 idle_start; - - u8 pkt_error; - u8 rx_fifo_err_cnt; - - int first_time_slot; - - netskb_t *tx_idle_skb; - unsigned char rx_dma; - unsigned char pci_retry; - - unsigned char fifo_size_code; - unsigned char fifo_base_addr; - unsigned char fifo_size; - - int dma_mtu; - - void * prot_ch; - int prot_state; - - wan_trace_t trace_info; - - /* TE3 Specific Dma Chains */ - unsigned char tx_chain_indx,tx_pending_chain_indx; - aft_dma_chain_t tx_dma_chain_table[MAX_AFT_DMA_CHAINS]; - - unsigned char rx_chain_indx, rx_pending_chain_indx; - aft_dma_chain_t rx_dma_chain_table[MAX_AFT_DMA_CHAINS]; - int rx_no_data_cnt; - - unsigned long dma_chain_status; - unsigned long up; - - unsigned char *tx_realign_buf; - unsigned int single_dma_chain; - unsigned int dma_bufs; - -}private_area_t; - -/* Route Status options */ -#define NO_ROUTE 0x00 -#define ADD_ROUTE 0x01 -#define ROUTE_ADDED 0x02 -#define REMOVE_ROUTE 0x03 - -#define WP_WAIT 0 -#define WP_NO_WAIT 1 - -/* variable for keeping track of enabling/disabling FT1 monitor status */ -//static int rCount; - -extern void disable_irq(unsigned int); -extern void enable_irq(unsigned int); - -/**SECTOIN************************************************** - * - * Function Prototypes - * - ***********************************************************/ - -int wp_aft_te3_default_devcfg(sdla_t* card, wandev_conf_t* conf); -int wp_aft_te3_default_ifcfg(sdla_t* card, wanif_conf_t* conf); - -/* WAN link driver entry points. These are called by the WAN router module. */ -static int update (wan_device_t* wandev); -static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf); -static int del_if(wan_device_t *wandev, netdevice_t *dev); - -/* Network device interface */ -#if defined(__LINUX__) -static int if_init (netdevice_t* dev); -#endif -static int if_open (netdevice_t* dev); -static int if_close (netdevice_t* dev); -static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); - -static struct net_device_stats* if_stats (netdevice_t* dev); - -#if defined(__LINUX__) -static int if_send (netskb_t* skb, netdevice_t* dev); -#else -static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct rtentry *rt); -#endif - -static void handle_front_end_state(void* card_id); -static void enable_timer(void* card_id); -static void if_tx_timeout (netdevice_t *dev); - -/* Miscellaneous Functions */ -static void port_set_state (sdla_t *card, int); - -static void disable_comm (sdla_t *card); - -/* Interrupt handlers */ -static WAN_IRQ_RETVAL wp_aft_te3_isr (sdla_t* card); - -/* Bottom half handlers */ -#if defined(__LINUX__) -static void wp_bh (unsigned long); -#else -static void wp_bh (void*, int); -#endif - -/* Miscellaneous functions */ -static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, - private_area_t*, - int local_dev); - -static int xilinx_t3_exar_chip_configure(sdla_t *card); -static int xilinx_t3_exar_dev_configure(sdla_t *card, private_area_t *chan); -static void xilinx_t3_exar_dev_unconfigure(sdla_t *card, private_area_t *chan); -static void xilinx_t3_exar_chip_unconfigure(sdla_t *card); -static void xilinx_t3_exar_transparent_config(sdla_t *card,private_area_t *chan); - -static int xilinx_dma_rx(sdla_t *card, private_area_t *chan, int gcur_ptr); -static void xilinx_dev_enable(sdla_t *card, private_area_t *chan); -static void xilinx_dev_close(sdla_t *card, private_area_t *chan); -static void xilinx_dma_tx_complete (sdla_t *card, private_area_t *chan,int wtd); -static void xilinx_dma_rx_complete (sdla_t *card, private_area_t *chan, int wtd); -static int xilinx_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char); -static void xilinx_init_tx_dma_descr(sdla_t *card, private_area_t *chan); -static int xilinx_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char); -static void xilinx_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb); -static void xilinx_rx_post_complete (sdla_t *card, private_area_t *chan, - netskb_t *skb, - netskb_t **new_skb, - unsigned char *pkt_error); - - - - -#if 0 -//FIXME: Not used check with M.F. if still needed -static unsigned char read_cpld(sdla_t *card, unsigned short cpld_off); -#endif -static int write_cpld(void *pcard, unsigned short cpld_off,unsigned char cpld_data); -static int write_fe_cpld(void *pcard, unsigned short off,unsigned char data); - -static int aft_devel_ioctl(sdla_t *card,struct ifreq *ifr); -static int xilinx_write_bios(sdla_t *card, wan_cmd_api_t *api_cmd); -static int xilinx_write(sdla_t *card, wan_cmd_api_t *api_cmd); -static int xilinx_read(sdla_t *card, wan_cmd_api_t *api_cmd); - -static void front_end_interrupt(sdla_t *card, unsigned long reg); -static void enable_data_error_intr(sdla_t *card); -static void disable_data_error_intr(sdla_t *card, unsigned char); - -static void xilinx_tx_fifo_under_recover (sdla_t *card, private_area_t *chan); - -static int xilinx_write_ctrl_hdlc(sdla_t *card, u32 timeslot, u8 reg_off, u32 data); - -static int set_chan_state(sdla_t* card, netdevice_t* dev, int state); - -static int update_comms_stats(sdla_t* card); - -static int protocol_init (sdla_t*card,netdevice_t *dev, - private_area_t *chan, wanif_conf_t* conf); -static int protocol_stop (sdla_t *card, netdevice_t *dev); -static int protocol_start (sdla_t *card, netdevice_t *dev); -static int protocol_shutdown (sdla_t *card, netdevice_t *dev); -static void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb); - -static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num); -static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb); - -static int write_framer(void *pcard,unsigned short framer_off,unsigned short framer_data); -static unsigned int read_framer(void *pcard,unsigned short framer_off); -#if 0 -//FIXME to be taken out check with M.F. -static void framer_reset(sdla_t *card); -#endif - -static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan,netskb_t *skb); -static void aft_tx_dma_chain_handler(unsigned long data); -static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *); -static void aft_rx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *); -static void aft_index_tx_rx_dma_chains(private_area_t *chan); -static void aft_rx_dma_chain_handler(private_area_t *chan, int wtd, int reset); -#if 0 -//FIXME: Currently not used... -static void aft_dma_te3_set_intr(aft_dma_chain_t *dma_chain, private_area_t *chan); -#endif -static void aft_init_tx_rx_dma_descr(private_area_t *chan); -static void aft_free_rx_complete_list(private_area_t *chan); -static void aft_list_descriptors(private_area_t *chan); -static void aft_free_rx_descriptors(private_area_t *chan); -static void aft_te3_led_ctrl(sdla_t *card, int color, int led_pos, int on); -static void aft_list_tx_descriptors(private_area_t *chan); -static void aft_free_tx_descriptors(private_area_t *chan); - -#if defined(__LINUX__) -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -static void aft_port_task (void * card_ptr); -# else -static void aft_port_task (struct work_struct *work); -# endif -#else -static void aft_port_task (void * card_ptr, int arg); -#endif - -#if 0 -static void aft_fe_intr_ctrl(sdla_t *card, int status); -#endif -static void __aft_fe_intr_ctrl(sdla_t *card, int status); - -static void aft_reset_rx_chain_cnt(private_area_t *chan); -static void aft_reset_tx_chain_cnt(private_area_t *chan); -static void aft_critical_shutdown (sdla_t *card); - -/* Procfs functions */ -static int wan_aft3_get_info(void* pcard, struct seq_file* m, int* stop_cnt); - -/* Function interface between WANPIPE layer and kernel */ -extern wan_iface_t wan_iface; - -static void xilinx_delay(int sec) -{ -#if 0 - unsigned long timeout=SYSTEM_TICKS; - while ((SYSTEM_TICKS-timeout)<(sec*HZ)){ - schedule(); - } -#endif -} - -/**SECTION********************************************************* - * - * Public Functions - * - ******************************************************************/ - -int wp_aft_te3_default_devcfg(sdla_t* card, wandev_conf_t* conf) -{ - conf->config_id = WANCONFIG_AFT_TE3; - conf->u.xilinx.dma_per_ch = MAX_RX_BUF; - conf->u.xilinx.mru = 1500; - return 0; -} - -int wp_aft_te3_default_ifcfg(sdla_t* card, wanif_conf_t* conf) -{ - conf->protocol = WANCONFIG_HDLC; - memcpy(conf->usedby, "WANPIPE", 7); - conf->if_down = 0; - conf->ignore_dcd = WANOPT_NO; - conf->ignore_cts = WANOPT_NO; - conf->hdlc_streaming = WANOPT_NO; - conf->mc = 0; - conf->gateway = 0; - conf->active_ch = ENABLE_ALL_CHANNELS; - - return 0; -} - -/*============================================================================ - * wp_xilinx_init - Cisco HDLC protocol initialization routine. - * - * @card: Wanpipe card pointer - * @conf: User hardware/firmware/general protocol configuration - * pointer. - * - * This routine is called by the main WANPIPE module - * during setup: ROUTER_SETUP ioctl(). - * - * At this point adapter is completely initialized - * and firmware is running. - * o read firmware version (to make sure it's alive) - * o configure adapter - * o initialize protocol-specific fields of the adapter data space. - * - * Return: 0 o.k. - * < 0 failure. - */ - -int wp_aft_te3_init (sdla_t* card, wandev_conf_t* conf) -{ - int err; - - /* Verify configuration ID */ - wan_clear_bit(CARD_DOWN,&card->wandev.critical); - if (card->wandev.config_id != WANCONFIG_AFT_TE3) { - DEBUG_EVENT( "%s: invalid configuration ID %u!\n", - card->devname, card->wandev.config_id); - return -EINVAL; - } - - if (conf == NULL){ - DEBUG_EVENT("%s: Bad configuration structre!\n", - card->devname); - return -EINVAL; - } - -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("%s: Total Mem %d\n",__FUNCTION__,wan_atomic_read(&wan_debug_mem)); -#endif - - if (card->adptr_subtype == AFT_SUBTYPE_SHARK) { - DEBUG_EVENT("%s: Starting SHARK T3/E3 Adapter!\n", - card->devname); - } - - /* Obtain hardware configuration parameters */ - card->wandev.clocking = conf->clocking; - card->wandev.ignore_front_end_status = conf->ignore_front_end_status; - card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; - card->wandev.comm_port = conf->comm_port; - card->wandev.udp_port = conf->udp_port; - card->wandev.new_if_cnt = 0; - wan_atomic_set(&card->wandev.if_cnt,0); - card->u.aft.chip_security_cnt=0; - - memcpy(&card->u.xilinx.cfg,&conf->u.xilinx,sizeof(wan_xilinx_conf_t)); - - card->u.xilinx.cfg.dma_per_ch = MAX_RX_BUF; - - /* TE1 Make special hardware initialization for T1/E1 board */ - if (IS_TE3(&conf->fe_cfg)){ - - memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te3_iface_init(&card->wandev.fe_iface); - card->fe.name = card->devname; - card->fe.card = card; - card->fe.write_cpld = write_cpld; - card->fe.write_fe_cpld = write_fe_cpld; - -// card->fe.read_cpld = read_cpld; - card->fe.write_framer = write_framer; - card->fe.read_framer = read_framer; - -// card->wandev.write_front_end_reg = write_front_end_reg; -// card->wandev.read_front_end_reg = read_front_end_reg; - card->wandev.fe_enable_timer = enable_timer; - card->wandev.te_link_state = handle_front_end_state; -//ALEX conf->interface = -// IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; - - if (card->wandev.comm_port == WANOPT_PRI){ - conf->clocking = WANOPT_EXTERNAL; - } - - }else{ - DEBUG_EVENT("%s: Invalid Front-End media type!!\n", - card->devname); - return -EINVAL; - } - - if (card->wandev.ignore_front_end_status == WANOPT_NO){ - DEBUG_EVENT( - "%s: Enabling front end link monitor\n", - card->devname); - }else{ - DEBUG_EVENT( - "%s: Disabling front end link monitor\n", - card->devname); - } - - /* WARNING: After this point the init function - * must return with 0. The following bind - * functions will cause problems if structures - * below are not initialized */ - - card->wandev.update = &update; - card->wandev.new_if = &new_if; - card->wandev.del_if = &del_if; - card->disable_comm = &disable_comm; - -#ifdef WANPIPE_ENABLE_PROC_FILE_HOOKS - /* Proc fs functions hooks */ - card->wandev.get_config_info = &get_config_info; - card->wandev.get_status_info = &get_status_info; - card->wandev.get_dev_config_info= &get_dev_config_info; - card->wandev.get_if_info = &get_if_info; - card->wandev.set_dev_config = &set_dev_config; - card->wandev.set_if_info = &set_if_info; -#endif - card->wandev.get_info = &wan_aft3_get_info; - - /* Setup Port Bps */ - if(card->wandev.clocking) { - card->wandev.bps = conf->bps; - }else{ - card->wandev.bps = 0; - } - - /* For Primary Port 0 */ - card->wandev.mtu = - (conf->mtu >= MIN_WP_PRI_MTU) ? - wp_min(conf->mtu, MAX_WP_PRI_MTU) : DEFAULT_WP_PRI_MTU; - - - if (!card->u.xilinx.cfg.mru){ - card->u.xilinx.cfg.mru = card->wandev.mtu; - } - - - DEBUG_TEST("%s: Set MTU size to %d!\n", - card->devname, card->wandev.mtu); - - card->hw_iface.getcfg(card->hw, SDLA_BASEADDR, &card->u.xilinx.bar); - - xilinx_delay(1); - port_set_state(card,WAN_DISCONNECTED); - aft_te3_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); - aft_te3_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_OFF); - - WAN_TASKQ_INIT((&card->u.aft.port_task),0,aft_port_task,card); - - card->isr = &wp_aft_te3_isr; - - err=xilinx_t3_exar_chip_configure(card); - if (err){ - return err; - } - - xilinx_delay(1); - - /* Set protocol link state to disconnected, - * After seting the state to DISCONNECTED this - * function must return 0 i.e. success */ - - DEBUG_EVENT( "%s: Init Done.\n",card->devname); - return 0; -} - - - - -/**SECTION************************************************************** - * - * WANPIPE Device Driver Entry Points - * - * *********************************************************************/ - - - -/*============================================================================ - * update - Update wanpipe device status & statistics - * - * @wandev: Wanpipe device pointer - * - * This procedure is called when updating the PROC file system. - * It returns various communications statistics. - * - * cat /proc/net/wanrouter/wanpipe# (where #=1,2,3...) - * - * These statistics are accumulated from 3 - * different locations: - * 1) The 'if_stats' recorded for the device. - * 2) Communication error statistics on the adapter. - * 3) Operational statistics on the adapter. - * - * The board level statistics are read during a timer interrupt. - * Note that we read the error and operational statistics - * during consecitive timer ticks so as to minimize the time - * that we are inside the interrupt handler. - * - */ -static int update (wan_device_t* wandev) -{ - sdla_t* card = wandev->private; - netdevice_t* dev; - volatile private_area_t* chan; - - /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) - return -EFAULT; - - if(wandev->state == WAN_UNCONFIGURED) - return -ENODEV; - - if(wan_test_bit(PERI_CRIT, (void*)&card->wandev.critical)) - return -EAGAIN; - - dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); - if(dev == NULL) - return -ENODEV; - - if((chan=wan_netif_priv(dev)) == NULL) - return -ENODEV; - - if(card->update_comms_stats){ - return -EAGAIN; - } - - DEBUG_TEST("%s: Chain Dma Status=0x%lX, TxCur=%i, TxPend=%i RxCur=%i RxPend=%i\n", - chan->if_name, - chan->dma_chain_status, - chan->tx_chain_indx, - chan->tx_pending_chain_indx, - chan->rx_chain_indx, - chan->rx_pending_chain_indx); - - - update_comms_stats(card); - - return 0; -} - - - -/*============================================================================ - * new_if - Create new logical channel. - * - * &wandev: Wanpipe device pointer - * &dev: Network device pointer - * &conf: User configuration options pointer - * - * This routine is called by the ROUTER_IFNEW ioctl, - * in wanmain.c. The ioctl passes us the user configuration - * options which we use to configure the driver and - * firmware. - * - * This functions main purpose is to allocate the - * private structure for protocol and bind it - * to dev->priv pointer. - * - * Also the dev->init pointer should also be initialized - * to the if_init() function. - * - * Any allocation necessary for the private strucutre - * should be done here, as well as proc/ file initializetion - * for the network interface. - * - * o parse media- and hardware-specific configuration - * o make sure that a new channel can be created - * o allocate resources, if necessary - * o prepare network device structure for registaration. - * o add network interface to the /proc/net/wanrouter - * - * The opposite of this function is del_if() - * - * Return: 0 o.k. - * < 0 failure (channel will not be created) - */ -static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) -{ - sdla_t* card = wandev->private; - private_area_t* chan; - int err = 0; - netskb_t *skb; - - DEBUG_EVENT( "%s: Configuring Interface: %s\n", - card->devname, wan_netif_name(dev)); - - if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)){ - DEBUG_EVENT( "%s: Invalid interface name!\n", - card->devname); - return -EINVAL; - } - - /* allocate and initialize private data */ - chan = wan_malloc(sizeof(private_area_t)); - if(chan == NULL){ - WAN_MEM_ASSERT(card->devname); - return -ENOMEM; - } - memset(chan, 0, sizeof(private_area_t)); - - chan->first_time_slot=-1; - chan->single_dma_chain=0; - -#ifdef AFT_T3_SINGLE_DMA_CHAIN - chan->single_dma_chain=1; -#endif - - strncpy(chan->if_name, wan_netif_name(dev), WAN_IFNAME_SZ); - - chan->card = card; - - wan_skb_queue_init(&chan->wp_tx_free_list); - wan_skb_queue_init(&chan->wp_tx_pending_list); - wan_skb_queue_init(&chan->wp_tx_complete_list); - - wan_skb_queue_init(&chan->wp_rx_free_list); - wan_skb_queue_init(&chan->wp_rx_complete_list); - - wan_trace_info_init(&chan->trace_info,MAX_TRACE_QUEUE); - - /* Initiaize Tx/Rx DMA Chains */ - aft_index_tx_rx_dma_chains(chan); - - /* Initialize the socket binding information - * These hooks are used by the API sockets to - * bind into the network interface */ - - WAN_TASKLET_INIT((&chan->common.bh_task),0,wp_bh,chan); - chan->common.dev = dev; - chan->tracing_enabled = 0; - chan->route_status = NO_ROUTE; - chan->route_removed = 0; - - /* Setup interface as: - * WANPIPE = IP over Protocol (Firmware) - * API = Raw Socket access to Protocol (Firmware) - * BRIDGE = Ethernet over Protocol, no ip info - * BRIDGE_NODE = Ethernet over Protocol, with ip info - */ - if(strcmp(conf->usedby, "WANPIPE") == 0) { - - DEBUG_EVENT( "%s: Running in WANPIPE mode\n", - wandev->name); - chan->common.usedby = WANPIPE; - - /* Option to bring down the interface when - * the link goes down */ - if (conf->if_down){ - wan_set_bit(DYN_OPT_ON,&chan->interface_down); - DEBUG_EVENT( - "%s:%s: Dynamic interface configuration enabled\n", - card->devname,chan->if_name); - } - - if (conf->protocol != WANOPT_NO){ - wan_netif_set_priv(dev,chan); - if ((err=protocol_init(card,dev,chan,conf)) != 0){ - wan_netif_set_priv(dev, chan); - goto new_if_error; - } - - if (conf->ignore_dcd == WANOPT_YES || conf->ignore_cts == WANOPT_YES){ - DEBUG_EVENT( "%s: Ignore modem changes DCD/CTS\n",card->devname); - chan->ignore_modem=1; - }else{ - DEBUG_EVENT( "%s: Restart protocol on modem changes DCD/CTS\n", - card->devname); - } - } - - } else if( strcmp(conf->usedby, "API") == 0) { - chan->common.usedby = API; - DEBUG_EVENT( "%s:%s: Running in API mode\n", - wandev->name,chan->if_name); - wan_reg_api(chan, dev, card->devname); - - }else if (strcmp(conf->usedby, "BRIDGE") == 0) { - chan->common.usedby = BRIDGE; - DEBUG_EVENT( "%s:%s: Running in WANPIPE (BRIDGE) mode.\n", - card->devname,chan->if_name); - - }else if (strcmp(conf->usedby, "BRIDGE_N") == 0) { - chan->common.usedby = BRIDGE_NODE; - DEBUG_EVENT( "%s:%s: Running in WANPIPE (BRIDGE_NODE) mode.\n", - card->devname,chan->if_name); - - }else if (strcmp(conf->usedby, "STACK") == 0) { - chan->common.usedby = STACK; - if (chan->hdlc_eng){ - card->wandev.mtu+=32; - } - DEBUG_EVENT( "%s:%s: Running in Stack mode.\n", - card->devname,chan->if_name); - - - }else{ - DEBUG_EVENT( "%s:%s: Error: Invalid operation mode [WANPIPE|API|BRIDGE|BRIDGE_NODE]\n", - card->devname,chan->if_name); - err=-EINVAL; - goto new_if_error; - } - - xilinx_delay(1); - - chan->hdlc_eng = conf->hdlc_streaming; - - if (!chan->hdlc_eng){ - if (card->wandev.mtu&0x03){ - DEBUG_EVENT("%s:%s: Error, Transparent MTU must be word aligned!\n", - card->devname,chan->if_name); - err = -EINVAL; - goto new_if_error; - } - } - chan->time_slot_map=conf->active_ch; - - err=xilinx_t3_exar_dev_configure(card,chan); - if (err){ - goto new_if_error; - } - - xilinx_delay(1); - - - if (!chan->hdlc_eng){ - unsigned char *buf; - - if (!chan->max_idle_size){ - chan->max_idle_size=card->wandev.mtu; - } - - DEBUG_EVENT("%s:%s: Config for Transparent mode: Idle=%X Len=%u\n", - card->devname,chan->if_name, - chan->idle_flag,chan->max_idle_size); - - chan->idle_flag=0x7E; - - chan->tx_idle_skb = wan_skb_alloc(chan->max_idle_size); - if (!chan->tx_idle_skb){ - err=-ENOMEM; - goto new_if_error; - } - buf=wan_skb_put(chan->tx_idle_skb,chan->max_idle_size); - memset(buf,chan->idle_flag,chan->max_idle_size); - } - - chan->dma_mtu = card->wandev.mtu >= card->u.xilinx.cfg.mru? - card->wandev.mtu:card->u.xilinx.cfg.mru; - - chan->dma_mtu = xilinx_valid_mtu(chan->dma_mtu); - if (!chan->dma_mtu){ - DEBUG_EVENT("%s:%s: Error invalid MTU %i mru %i\n", - card->devname, - chan->if_name, - card->wandev.mtu,card->u.xilinx.cfg.mru); - err= -EINVAL; - goto new_if_error; - } - - chan->dma_bufs=card->u.xilinx.cfg.dma_per_ch; - if (chan->single_dma_chain){ - chan->dma_bufs=MAX_RX_SCHAIN_BUF; - } - - DEBUG_EVENT("%s:%s: Allocating %i dma len=%i Chains=%s\n", - card->devname,chan->if_name, - chan->dma_bufs, - chan->dma_mtu, - chan->single_dma_chain ? "Off":"On"); - - - err=aft_alloc_rx_dma_buff(card, chan, chan->dma_bufs); - if (err){ - goto new_if_error; - } - - /* If gateway option is set, then this interface is the - * default gateway on this system. We must know that information - * in case DYNAMIC interface configuration is enabled. - * - * I.E. If the interface is brought down by the driver, the - * default route will also be removed. Once the interface - * is brought back up, we must know to re-astablish the - * default route. - */ - if ((chan->gateway = conf->gateway) == WANOPT_YES){ - DEBUG_EVENT( "%s: Interface %s is set as a gateway.\n", - card->devname,chan->if_name); - } - - /* Get Multicast Information from the user - * FIXME: This option is not clearly defined - */ - chan->mc = conf->mc; - - - /* The network interface "dev" has been passed as - * an argument from the above layer. We must initialize - * it so it can be registered into the kernel. - * - * The "dev" structure is the link between the kernel - * stack and the wanpipe driver. It contains all - * access hooks that kernel uses to communicate to - * the our driver. - * - * For now, just set the "dev" name to the user - * defined name and initialize: - * dev->if_init : function that will be called - * to further initialize - * dev structure on "ifconfig up" - * - * dev->priv : private structure allocated above - * - */ - -#if 0 - /* Create interface file in proc fs. - * Once the proc file system is created, the new_if() function - * should exit successfuly. - * - * DO NOT place code under this function that can return - * anything else but 0. - */ - err = wanrouter_proc_add_interface(wandev, - &chan->dent, - chan->if_name, - dev); - if (err){ - DEBUG_EVENT( - "%s: can't create /proc/net/router/frmw/%s entry!\n", - card->devname, chan->if_name); - goto new_if_error; - } -#endif - /* Only setup the dev pointer once the new_if function has - * finished successfully. DO NOT place any code below that - * can return an error */ - wan_netif_set_priv(dev,chan); -#if defined(__LINUX__) - dev->init = &if_init; -# ifdef WANPIPE_GENERIC - if_init(dev); -# endif -#else - chan->common.is_netdev = 1; - chan->common.iface.open = &if_open; - chan->common.iface.close = &if_close; - chan->common.iface.output = &if_send; - chan->common.iface.ioctl = &if_do_ioctl; - chan->common.iface.get_stats = &if_stats; - chan->common.iface.tx_timeout = &if_tx_timeout; - if (wan_iface.attach){ - if (!ifunit(wan_netif_name(dev))){ - wan_iface.attach(dev, NULL, chan->common.is_netdev); - } - }else{ - DEBUG_EVENT("%s: Failed to attach network interface %s!\n", - card->devname, wan_netif_name(dev)); - wan_netif_set_priv(dev, NULL); - err = -EINVAL; - goto new_if_error; - } - wan_netif_set_mtu(dev, card->wandev.mtu); -#endif - - /* Increment the number of network interfaces - * configured on this card. - */ - wan_atomic_inc(&card->wandev.if_cnt); - - chan->common.state = WAN_CONNECTING; - - DEBUG_EVENT( "\n"); - - return 0; - -new_if_error: - - while ((skb=wan_skb_dequeue(&chan->wp_tx_free_list)) != NULL){ - wan_skb_free(skb); - } - - while ((skb=wan_skb_dequeue(&chan->wp_rx_free_list)) != NULL){ - wan_skb_free(skb); - } - - WAN_TASKLET_KILL(&chan->common.bh_task); - - if (chan->common.usedby == API){ - wan_unreg_api(chan, card->devname); - } - - if (chan->tx_idle_skb){ - wan_skb_free(chan->tx_idle_skb); - chan->tx_idle_skb=NULL; - } - - wan_free(chan); - - wan_netif_set_priv(dev,NULL); - - return err; -} - -/*============================================================================ - * del_if - Delete logical channel. - * - * @wandev: Wanpipe private device pointer - * @dev: Netowrk interface pointer - * - * This function is called by ROUTER_DELIF ioctl call - * to deallocate the network interface. - * - * The network interface and the private structure are - * about to be deallocated by the upper layer. - * We have to clean and deallocate any allocated memory. - * - * NOTE: DO NOT deallocate dev->priv here! It will be - * done by the upper layer. - * - */ -static int del_if (wan_device_t* wandev, netdevice_t* dev) -{ - private_area_t* chan = wan_netif_priv(dev); - sdla_t* card = chan->card; - netskb_t *skb; - wan_smp_flag_t flags; - - xilinx_t3_exar_dev_unconfigure(card,chan); - - WAN_TASKLET_KILL(&chan->common.bh_task); - - if (chan->common.usedby == API){ - wan_unreg_api(chan, card->devname); - } - - protocol_shutdown(card,dev); - - - wan_spin_lock_irq(&card->wandev.lock,&flags); - - while ((skb=wan_skb_dequeue(&chan->wp_rx_free_list)) != NULL){ - wan_skb_free(skb); - } - - while ((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ - wan_skb_free(skb); - } - - while ((skb=wan_skb_dequeue(&chan->wp_tx_free_list)) != NULL){ - wan_skb_free(skb); - } - - if (chan->tx_realign_buf){ - wan_free(chan->tx_realign_buf); - chan->tx_realign_buf=NULL; - } - - wan_spin_unlock_irq(&card->wandev.lock,&flags); - - /* Delete interface name from proc fs. */ -#if 0 - wanrouter_proc_delete_interface(wandev, chan->if_name); -#endif - - /* Decrement the number of network interfaces - * configured on this card. - */ - wan_atomic_dec(&card->wandev.if_cnt); - - DEBUG_SUB_MEM(sizeof(private_area_t)); - return 0; -} - - -/**SECTION*********************************************************** - * - * KERNEL Device Entry Interfaces - * - ********************************************************************/ - - - -/*============================================================================ - * if_init - Initialize Linux network interface. - * - * @dev: Network interface pointer - * - * During "ifconfig up" the upper layer calls this function - * to initialize dev access pointers. Such as transmit, - * stats and header. - * - * It is called only once for each interface, - * during Linux network interface registration. - * - * Returning anything but zero will fail interface - * registration. - */ -#if defined(__LINUX__) -static int if_init (netdevice_t* dev) -{ - private_area_t* chan = wan_netif_priv(dev); - sdla_t* card = chan->card; - wan_device_t* wandev = &card->wandev; -#ifdef WANPIPE_GENERIC - hdlc_device* hdlc; -#endif - - /* Initialize device driver entry points */ - dev->open = &if_open; - dev->stop = &if_close; -#ifdef WANPIPE_GENERIC - hdlc = dev_to_hdlc(dev); - hdlc->xmit = if_send; -#else - dev->hard_start_xmit = &if_send; -#endif - dev->get_stats = &if_stats; -#if defined(LINUX_2_4)||defined(LINUX_2_6) - dev->tx_timeout = &if_tx_timeout; - dev->watchdog_timeo = 2*HZ; -#endif - dev->do_ioctl = if_do_ioctl; - - if (chan->common.usedby == BRIDGE || - chan->common.usedby == BRIDGE_NODE){ - - /* Setup the interface for Bridging */ - int hw_addr=0; - ether_setup(dev); - - /* Use a random number to generate the MAC address */ - memcpy(dev->dev_addr, "\xFE\xFC\x00\x00\x00\x00", 6); - get_random_bytes(&hw_addr, sizeof(hw_addr)); - *(int *)(dev->dev_addr + 2) += hw_addr; - - }else{ - - if (chan->protocol != WANCONFIG_PPP && - chan->protocol != WANCONFIG_CHDLC){ - dev->flags |= IFF_POINTOPOINT; - dev->flags |= IFF_NOARP; - dev->type = ARPHRD_PPP; - dev->mtu = card->wandev.mtu; - dev->hard_header_len = 16; - dev->addr_len = 0; - } - - if (chan->common.usedby == API){ - dev->mtu = card->wandev.mtu+sizeof(api_tx_hdr_t); - } - - /* Enable Mulitcasting if user selected */ - if (chan->mc == WANOPT_YES){ - dev->flags |= IFF_MULTICAST; - } - - if (chan->true_if_encoding){ - dev->type = ARPHRD_HDLC; /* This breaks the tcpdump */ - }else{ - dev->type = ARPHRD_PPP; - } - } - - /* Initialize hardware parameters */ - dev->irq = wandev->irq; - dev->dma = wandev->dma; - dev->base_addr = wandev->ioport; - card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &dev->mem_start); - card->hw_iface.getcfg(card->hw, SDLA_MEMEND, &dev->mem_end); - - /* Set transmit buffer queue length - * If too low packets will not be retransmitted - * by stack. - */ - dev->tx_queue_len = 100; - - return 0; -} -#endif - -/*============================================================================ - * if_open - Open network interface. - * - * @dev: Network device pointer - * - * On ifconfig up, this function gets called in order - * to initialize and configure the private area. - * Driver should be configured to send and receive data. - * - * This functions starts a timer that will call - * frmw_config() function. This function must be called - * because the IP addresses could have been changed - * for this interface. - * - * Return 0 if O.k. or errno. - */ -static int if_open (netdevice_t* dev) -{ - private_area_t* chan = wan_netif_priv(dev); - sdla_t* card = chan->card; - wan_smp_flag_t flags; - -#if defined(__LINUX__) - /* Only one open per interface is allowed */ - if (open_dev_check(dev)){ - DEBUG_EVENT("%s: Open dev check failed!\n", - wan_netif_name(dev)); - return -EBUSY; - } -#endif - - /* Initialize the router start time. - * Used by wanpipemon debugger to indicate - * how long has the interface been up */ - wan_getcurrenttime(&chan->router_start_time, NULL); - - WAN_NETIF_STOP_QUEUE(dev); - WAN_NETIF_CARRIER_OFF(dev); - - /* If FRONT End is down, it means that the DMA - * is disabled. In this case don't try to - * reset fifo. Let the enable_data_error_intr() - * function do this, after front end has come up */ - - wan_spin_lock_irq(&card->wandev.lock,&flags); - if (card->wandev.state == WAN_CONNECTED){ - DEBUG_TEST("%s: OPEN reseting fifo\n", - wan_netif_name(dev)); - xilinx_init_rx_dev_fifo(card,chan,WP_WAIT); - xilinx_init_tx_dev_fifo(card,chan,WP_WAIT); - xilinx_init_tx_dma_descr(card,chan); - - xilinx_dma_rx(card,chan,-1); - } - - /* Check for transparent HDLC mode */ - if (!chan->hdlc_eng){ - /* The Transparent HDLC engine is - * enabled. The Rx dma has already - * been setup above. Now setup - * TX DMA and enable the HDLC engine */ - - DEBUG_CFG("%s: Transparent Tx Enabled!\n", - wan_netif_name(dev)); - - xilinx_t3_exar_transparent_config(card,chan); - } - - xilinx_dev_enable(card,chan); - wan_set_bit(0,&chan->up); - - if (card->wandev.state == WAN_CONNECTED){ - /* If Front End is connected already set interface - * state to Connected too */ - set_chan_state(card, dev, WAN_CONNECTED); - WAN_NETIF_WAKE_QUEUE(dev); - WAN_NETIF_CARRIER_ON(dev); - if (chan->common.usedby == API){ - wan_wakeup_api(chan); - }else if (chan->common.usedby == STACK){ - wanpipe_lip_kick(chan,0); - } - } - - wan_spin_unlock_irq(&card->wandev.lock,&flags); - - chan->ignore_modem=0x0F; - - /* Increment the module usage count */ - wanpipe_open(card); - - protocol_start(card,dev); - - /* Wait for the front end interrupt - * before enabling the card */ - return 0; -} - -/*============================================================================ - * if_close - Close network interface. - * - * @dev: Network device pointer - * - * On ifconfig down, this function gets called in order - * to cleanup interace private area. - * - * IMPORTANT: - * - * No deallocation or unconfiguration should ever occur in this - * function, because the interface can come back up - * (via ifconfig up). - * - * Furthermore, in dynamic interfacace configuration mode, the - * interface will come up and down to reflect the protocol state. - * - * Any deallocation and cleanup can occur in del_if() - * function. That function is called before the dev interface - * itself is deallocated. - * - * Thus, we should only stop the net queue and decrement - * the wanpipe usage counter via wanpipe_close() function. - */ - -static int if_close (netdevice_t* dev) -{ - private_area_t* chan = wan_netif_priv(dev); - sdla_t* card = chan->card; - wan_smp_flag_t smp_flags; - - wan_clear_bit(0,&chan->up); - - WAN_NETIF_STOP_QUEUE(dev); - -#if defined(LINUX_2_1) - dev->start=0; -#endif - protocol_stop(card,dev); - - chan->common.state = WAN_DISCONNECTED; - - wan_spin_lock_irq(&card->wandev.lock,&smp_flags); - xilinx_dev_close(card,chan); - wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); - - chan->ignore_modem=0x00; - - wanpipe_close(card); - return 0; -} - - -/*============================================================= - * disable_comm - Main shutdown function - * - * @card: Wanpipe device pointer - * - * The command 'wanrouter stop' has been called - * and the whole wanpipe device is going down. - * This is the last function called to disable - * all comunications and deallocate any memory - * that is still allocated. - * - * o Disable communications, turn off interrupts - * o Deallocate memory used, if any - * o Unconfigure TE1 card - */ - -static void disable_comm (sdla_t *card) -{ - wan_smp_flag_t flags; - - /* Unconfiging, only on shutdown */ - if (IS_TE3(&card->fe.fe_cfg)) { - if (card->wandev.fe_iface.unconfig){ - card->wandev.fe_iface.unconfig(&card->fe); - } - } - - wan_spin_lock_irq(&card->wandev.lock,&flags); - - /* Disable DMA ENGINE before we perform - * core reset. Otherwise, we will receive - * rx fifo errors on subsequent resetart. */ - disable_data_error_intr(card,DEVICE_DOWN); - - wan_set_bit(CARD_DOWN,&card->wandev.critical); - - wan_spin_unlock_irq(&card->wandev.lock,&flags); - - WP_DELAY(10); - aft_te3_led_ctrl(card, WAN_AFT_RED, 0,WAN_AFT_ON); - aft_te3_led_ctrl(card, WAN_AFT_GREEN, 0, WAN_AFT_ON); - - xilinx_t3_exar_chip_unconfigure(card); - - return; -} - - - -/*============================================================================ - * if_tx_timeout - * - * Kernel networking stack calls this function in case - * the interface has been stopped for TX_TIMEOUT seconds. - * - * This would occur if we lost TX interrupts or the - * card has stopped working for some reason. - * - * Handle transmit timeout event from netif watchdog - */ -static void if_tx_timeout (netdevice_t *dev) -{ - private_area_t* chan = wan_netif_priv(dev); - sdla_t *card = chan->card; - unsigned int cur_dma_ptr; - u32 reg; - wan_smp_flag_t smp_flags; - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - - ++chan->if_stats.collisions; - - DEBUG_EVENT( "%s: Transmit timed out on %s\n", - card->devname,wan_netif_name(dev)); - -// DEBUG_EVENT("%s: TxStatus=0x%X DMAADDR=0x%lX DMALEN=%i \n", -// chan->if_name, -// chan->dma_status, -// chan->tx_dma_addr, -// chan->tx_dma_len); - - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - cur_dma_ptr=get_current_tx_dma_ptr(reg); - - DEBUG_EVENT("%s: Chain TxIntrPend=%i, TxBusy=%i TxCur=%i, TxPend=%i HwCur=%i TxErr=%li\n", - chan->if_name, - wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status), - wan_test_bit(TX_DMA_BUSY,&chan->dma_status), - chan->tx_chain_indx, - chan->tx_pending_chain_indx, - cur_dma_ptr, - chan->if_stats.tx_fifo_errors); - - /* The Interrupt didn't trigger. - * Clear the interrupt pending flag and - * let watch dog, clean up the tx chain */ - - wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - aft_list_tx_descriptors(chan); - xilinx_tx_fifo_under_recover(card,chan); - wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); - - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); -} - - -/*============================================================================ - * if_send - Send a packet on a network interface. - * - * @dev: Network interface pointer - * @skb: Packet obtained from the stack or API - * that should be sent out the port. - * - * o Mark interface as stopped - * (marks start of the transmission) to indicate - * to the stack that the interface is busy. - * - * o Check link state. - * If link is not up, then drop the packet. - * - * o Copy the tx packet into the protocol tx buffers on - * the adapter. - * - * o If tx successful: - * Free the skb buffer and mark interface as running - * and return 0. - * - * o If tx failed, busy: - * Keep interface marked as busy - * Do not free skb buffer - * Enable Tx interrupt (which will tell the stack - * that interace is not busy) - * Return a non-zero value to tell the stack - * that the tx should be retried. - * - * Return: 0 complete (socket buffer must be freed) - * non-0 packet may be re-transmitted - * - */ -#if defined(__LINUX__) -static int if_send (netskb_t* skb, netdevice_t* dev) -#else -static int if_send(netdevice_t *dev, netskb_t *skb, struct sockaddr *dst,struct rtentry *rt) -#endif -{ - - private_area_t *chan = wan_netif_priv(dev); - sdla_t *card = chan->card; - wan_smp_flag_t smp_flags; - - /* Mark interface as busy. The kernel will not - * attempt to send any more packets until we clear - * this condition */ - - if (skb == NULL){ - /* This should never happen. Just a sanity check. - */ - DEBUG_EVENT( "%s: interface %s got kicked!\n", - card->devname, wan_netif_name(dev)); - - WAN_NETIF_WAKE_QUEUE(dev); - return 0; - } - - /* Non 2.4 kernels used to call if_send() - * after TX_TIMEOUT seconds have passed of interface - * being busy. Same as if_tx_timeout() in 2.4 kernels */ -#if defined(LINUX_2_1) - if (dev->tbusy){ - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - ++chan->if_stats.collisions; - if((SYSTEM_TICKS - chan->tick_counter) < (5 * HZ)) { - return 1; - } - - if_tx_timeout(dev); - } -#endif - - if (chan->common.state != WAN_CONNECTED){ - WAN_NETIF_STOP_QUEUE(dev); - if (WAN_NETIF_CARRIER_OK(dev)){ - DEBUG_EVENT("%s: Critical Error: Carrier on on tx dev down\n", - chan->if_name); - } - wan_netif_set_ticks(dev, SYSTEM_TICKS); - ++chan->if_stats.tx_carrier_errors; - - - return 1; - - } else if (!WAN_NETIF_UP(dev)) { - ++chan->if_stats.tx_carrier_errors; - WAN_NETIF_START_QUEUE(dev); - wan_skb_free(skb); - wan_netif_set_ticks(dev, SYSTEM_TICKS); - return 0; - - }else { - int err=0; - - if (chan->common.usedby == API){ - if (sizeof(api_tx_hdr_t) >= wan_skb_len(skb)){ - wan_skb_free(skb); - ++chan->if_stats.tx_errors; - WAN_NETIF_START_QUEUE(dev); - goto if_send_exit_crit; - } - wan_skb_pull(skb,sizeof(api_tx_hdr_t)); - } - - wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - - err=xilinx_dma_te3_tx(card,chan,skb); - - switch (err){ - - case 0: - WAN_NETIF_START_QUEUE(dev); - wan_netif_set_ticks(dev, SYSTEM_TICKS); - err=0; - break; - - case -EBUSY: - WAN_NETIF_STOP_QUEUE(dev); - err=1; - break; - - default: - - /* The packet was dropped - * by the tx chain handler. - * The tx_dropped stat was updated, - * thus all is left for us is - * to start the interface again. - * This SHOULD NEVER happen */ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: TE3 Failed to send: Should never happend!\n", - chan->if_name); - } - WAN_NETIF_START_QUEUE(dev); - wan_netif_set_ticks(dev, SYSTEM_TICKS); - err=0; - } - wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); - - return err; - } - -if_send_exit_crit: - - return 0; -} - - -/*============================================================================ - * if_stats - * - * Used by /proc/net/dev and ifconfig to obtain interface - * statistics. - * - * Return a pointer to struct net_device_stats. - */ -static struct net_device_stats* if_stats (netdevice_t* dev) -{ - private_area_t* chan; - - if ((chan=wan_netif_priv(dev)) == NULL) - return NULL; - -#if 0 -{ - sdla_t *card; - card=chan->card; - - - u8 *base_addr=card->u.xilinx.rx_dma_ptr; - u8 *base_addr_tx=card->u.xilinx.tx_dma_ptr; - u8 *addr=(u8*)wan_dma_get_vaddr(card,base_addr); - u8 *addrtx=(u8*)wan_dma_get_vaddr(card,base_addr_tx); - u8 *addr1, *addr0; - - addr+=chan->logic_ch_num*card->u.xilinx.dma_mtu_off; - - addr0=addr+0*card->u.xilinx.dma_mtu; - addr1=addr+1*card->u.xilinx.dma_mtu; - - DEBUG_EVENT("%s: Buf 0: 0x%02X 1: 0x%02X Txbuf: 0x%02X RxCompList=%i RxFreeList=%i TxList=%i\n", - wan_netif_name(dev),addr0[0],addr1[0],addrtx[0], - wan_skb_queue_len(&chan->wp_rx_complete_list), - wan_skb_queue_len(&chan->wp_rx_free_list), - wan_skb_queue_len(&chan->wp_tx_pending_list)); -} -#endif - - -#if 0 - DEBUG_EVENT("%s: RxCompList=%i RxFreeList=%i TxList=%i\n", - wan_netif_name(dev), - wan_skb_queue_len(&chan->wp_rx_complete_list), - wan_skb_queue_len(&chan->wp_rx_free_list), - wan_skb_queue_len(&chan->wp_tx_pending_list)); -#endif - - - return &chan->if_stats; -} - - - - -/*======================================================================== - * - * if_do_ioctl - Ioctl handler for fr - * - * @dev: Device subject to ioctl - * @ifr: Interface request block from the user - * @cmd: Command that is being issued - * - * This function handles the ioctls that may be issued by the user - * to control or debug the protocol or hardware . - * - * It does both busy and security checks. - * This function is intended to be wrapped by callers who wish to - * add additional ioctl calls of their own. - * - * Used by: SNMP Mibs - * wanpipemon debugger - * - */ -static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) -{ - private_area_t* chan= (private_area_t*)wan_netif_priv(dev); - sdla_t *card; -#if defined(__LINUX__) - wan_smp_flag_t smp_flags; -#endif - wan_udp_pkt_t *wan_udp_pkt; - int err=0; - - if (!chan){ - return -ENODEV; - } - card=chan->card; - - NET_ADMIN_CHECK(); - - switch(cmd) - { -#if defined(__LINUX__) - case SIOC_WANPIPE_BIND_SK: - if (!ifr){ - err= -EINVAL; - break; - } - - wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - err=wan_bind_api_to_svc(chan,ifr->ifr_data); - chan->if_stats.rx_dropped=0; - wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); - break; - - case SIOC_WANPIPE_UNBIND_SK: - if (!ifr){ - err= -EINVAL; - break; - } - - wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - err=wan_unbind_api_from_svc(chan,ifr->ifr_data); - wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); - - break; - - case SIOC_WANPIPE_CHECK_TX: - case SIOC_ANNEXG_CHECK_TX: - err=0; - break; - - case SIOC_WANPIPE_DEV_STATE: - err = chan->common.state; - break; - - case SIOC_ANNEXG_KICK: - err=0; - break; -#endif - case SIOC_WAN_DEVEL_IOCTL: - err = aft_devel_ioctl(card, ifr); - break; - - case SIOC_AFT_CUSTOMER_ID: - err=0; - break; - - case SIOC_WANPIPE_PIPEMON: - - if (wan_atomic_read(&chan->udp_pkt_len) != 0){ - return -EBUSY; - } - - wan_atomic_set(&chan->udp_pkt_len,MAX_LGTH_UDP_MGNT_PKT); - - /* For performance reasons test the critical - * here before spin lock */ - if (wan_test_bit(0,&card->in_isr)){ - wan_atomic_set(&chan->udp_pkt_len,0); - return -EBUSY; - } - - - wan_udp_pkt=(wan_udp_pkt_t*)chan->udp_pkt_data; - if (WAN_COPY_FROM_USER(&wan_udp_pkt->wan_udp_hdr,ifr->ifr_data,sizeof(wan_udp_hdr_t))){ - wan_atomic_set(&chan->udp_pkt_len,0); - return -EFAULT; - } - - /* We have to check here again because we don't know - * what happened during spin_lock */ - if (wan_test_bit(0,&card->in_isr)) { - DEBUG_EVENT( "%s:%s Pipemon command failed, Driver busy: try again.\n", - card->devname, - wan_netif_name(chan->common.dev)); - wan_atomic_set(&chan->udp_pkt_len,0); - return -EBUSY; - } - - process_udp_mgmt_pkt(card,dev,chan,1); - - /* This area will still be critical to other - * PIPEMON commands due to udp_pkt_len - * thus we can release the irq */ - - if (wan_atomic_read(&chan->udp_pkt_len) > sizeof(wan_udp_pkt_t)){ - DEBUG_EVENT( "%s: Error: Pipemon buf too bit on the way up! %i\n", - card->devname,wan_atomic_read(&chan->udp_pkt_len)); - wan_atomic_set(&chan->udp_pkt_len,0); - return -EINVAL; - } - - if (WAN_COPY_TO_USER(ifr->ifr_data,&wan_udp_pkt->wan_udp_hdr,sizeof(wan_udp_hdr_t))){ - wan_atomic_set(&chan->udp_pkt_len,0); - return -EFAULT; - } - - wan_atomic_set(&chan->udp_pkt_len,0); - return 0; - - default: -#ifndef WANPIPE_GENERIC - DEBUG_EVENT("%s: Command %x not supported!\n", - card->devname,cmd); - return -EOPNOTSUPP; -#else - if (card->wandev.ioctl){ - err = card->wandev.hdlc_ioctl(card, dev, ifr, cmd); - } -#endif - } - - return err; -} - - -/**SECTION********************************************************** - * - * FIRMWARE Specific Interface Functions - * - *******************************************************************/ - - -#define FIFO_RESET_TIMEOUT_CNT 1000 -#define FIFO_RESET_TIMEOUT_US 10 -static int xilinx_init_rx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char wait) -{ - - u32 reg; - u32 dma_descr; - u8 timeout=1; - u16 i; - unsigned int cur_dma_ptr; - - /* Clean RX DMA fifo */ - aft_reset_rx_chain_cnt(chan); - - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - cur_dma_ptr=get_current_rx_dma_ptr(reg); - - dma_descr=(unsigned long)(cur_dma_ptr<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - reg=0; - wan_set_bit(INIT_DMA_FIFO_CMD_BIT,®); - - DEBUG_TEST("%s: Clearing RX Fifo %s DmaDescr=(0x%X) Reg=(0x%X)\n", - __FUNCTION__,chan->if_name, - dma_descr,reg); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - - if (wait == WP_WAIT){ - for(i=0;ihw_iface.bus_read_4(card->hw,dma_descr,®); - if (wan_test_bit(INIT_DMA_FIFO_CMD_BIT,®)){ - WP_DELAY(FIFO_RESET_TIMEOUT_US); - continue; - } - timeout=0; - break; - } - - if (timeout){ - DEBUG_EVENT("%s:%s: Error: Rx fifo reset timedout %u us\n", - card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US); - }else{ - DEBUG_TEST("%s:%s: Rx Fifo Reset Successful\n", - card->devname,chan->if_name); - } - }else{ - timeout=0; - } - - return timeout; -} - -static int xilinx_init_tx_dev_fifo(sdla_t *card, private_area_t *chan, unsigned char wait) -{ - u32 reg; - u32 dma_descr; - u8 timeout=1; - u16 i; - unsigned int cur_dma_ptr; - - aft_reset_tx_chain_cnt(chan); - - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - cur_dma_ptr=get_current_tx_dma_ptr(reg); - - /* Clean TX DMA fifo */ - dma_descr=(unsigned long)(cur_dma_ptr<<4) + XILINX_TxDMA_DESCRIPTOR_HI; - reg=0; - wan_set_bit(INIT_DMA_FIFO_CMD_BIT,®); - - DEBUG_TEST("%s: Clearing TX Fifo %s DmaDescr=(0x%X) Reg=(0x%X)\n", - __FUNCTION__,chan->if_name, - dma_descr,reg); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - - if (wait == WP_WAIT){ - for(i=0;ihw_iface.bus_read_4(card->hw,dma_descr,®); - if (wan_test_bit(INIT_DMA_FIFO_CMD_BIT,®)){ - WP_DELAY(FIFO_RESET_TIMEOUT_US); - continue; - } - timeout=0; - break; - } - - if (timeout){ - DEBUG_EVENT("%s:%s: Error: Tx fifo reset timedout %u us\n", - card->devname,chan->if_name,i*FIFO_RESET_TIMEOUT_US); - }else{ - DEBUG_TEST("%s:%s: Tx Fifo Reset Successful\n", - card->devname,chan->if_name); - } - }else{ - timeout=0; - } - - return timeout; -} - - -static void xilinx_dev_enable(sdla_t *card, private_area_t *chan) -{ - u32 reg; - - DEBUG_TEST("%s: Enabling Global Inter Mask !\n",chan->if_name); - - /* Enable Logic Channel Interrupts for DMA and fifo */ - card->hw_iface.bus_read_4(card->hw, - XILINX_GLOBAL_INTER_MASK, ®); - wan_set_bit(chan->logic_ch_num,®); - - card->hw_iface.bus_write_4(card->hw, - XILINX_GLOBAL_INTER_MASK, reg); - - wan_set_bit(chan->logic_ch_num,&card->u.xilinx.active_ch_map); -} - - - -static void xilinx_dev_close(sdla_t *card, private_area_t *chan) -{ - u32 reg; - - DEBUG_CFG("-- Close Xilinx device. --\n"); - - /* Disable Logic Channel Interrupts for DMA and fifo */ - card->hw_iface.bus_read_4(card->hw, - XILINX_GLOBAL_INTER_MASK, ®); - - wan_clear_bit(chan->logic_ch_num,®); - wan_clear_bit(chan->logic_ch_num,&card->u.xilinx.active_ch_map); - - /* We are masking the chan interrupt. - * Lock to make sure that the interrupt is - * not running */ - card->hw_iface.bus_write_4(card->hw, - XILINX_GLOBAL_INTER_MASK, reg); - - - aft_reset_rx_watchdog(card); - aft_reset_tx_watchdog(card); - - reg=0; - - /* Select an HDLC logic channel for configuration */ - card->hw_iface.bus_read_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG, ®); - - reg&=~HDLC_LOGIC_CH_BIT_MASK; - reg&= HDLC_LCH_TIMESLOT_MASK; /* mask not valid bits */ - - card->hw_iface.bus_write_4(card->hw, - XILINX_TIMESLOT_HDLC_CHAN_REG, - (reg|(chan->logic_ch_num&HDLC_LOGIC_CH_BIT_MASK))); - - - reg=0; - xilinx_write_ctrl_hdlc(card, - chan->first_time_slot, - XILINX_HDLC_CONTROL_REG, - reg); - - /* Initialize DMA descriptors and DMA Chains */ - aft_init_tx_rx_dma_descr(chan); - -} - -/**SECTION************************************************************* - * - * TX Handlers - * - **********************************************************************/ - - -/*=============================================== - * xilinx_dma_tx_complete - * - */ -static void xilinx_dma_tx_complete (sdla_t *card, private_area_t *chan, int wtd) -{ - DEBUG_TEST("%s: Tx interrupt wtd=%d\n",chan->if_name,wtd); - - aft_reset_tx_watchdog(card); - - if (!wtd){ - wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); - } - - aft_tx_dma_chain_handler((unsigned long)chan); - - - if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ - WAN_NETIF_WAKE_QUEUE(chan->common.dev); -#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC - if (chan->common.usedby == API){ - wan_wakeup_api(chan); - }else if (chan->common.usedby == STACK){ - wanpipe_lip_kick(chan,0); - } -#endif - } - - if (!chan->single_dma_chain){ - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); - } - - return; -} - -/*=============================================== - * xilinx_tx_post_complete - * - */ -static void xilinx_tx_post_complete (sdla_t *card, private_area_t *chan, netskb_t *skb) -{ - unsigned long reg = wan_skb_csum(skb); - - if ((wan_test_bit(TxDMA_HI_DMA_GO_READY_BIT,®)) || - (reg & TxDMA_HI_DMA_DATA_LENGTH_MASK) || - (reg&TxDMA_HI_DMA_PCI_ERROR_MASK)){ - - DEBUG_EVENT("%s:%s: Tx DMA Descriptor=0x%lX\n", - card->devname,chan->if_name,reg); - - /* Checking Tx DMA Go bit. Has to be '0' */ - if (wan_test_bit(TxDMA_HI_DMA_GO_READY_BIT,®)){ - DEBUG_TEST("%s:%s: Error: TxDMA Intr: GO bit set on Tx intr\n", - card->devname,chan->if_name); - chan->errstats.Tx_dma_errors++; - } - - if (reg & TxDMA_HI_DMA_DATA_LENGTH_MASK){ - DEBUG_TEST("%s:%s: Error: TxDMA Length not equal 0 \n", - card->devname,chan->if_name); - chan->errstats.Tx_dma_len_nonzero++; - } - - /* Checking Tx DMA PCI error status. Has to be '0's */ - if (reg&TxDMA_HI_DMA_PCI_ERROR_MASK){ - - chan->errstats.Tx_pci_errors++; - - if (reg & TxDMA_HI_DMA_PCI_ERROR_M_ABRT){ - DEBUG_EVENT("%s:%s: Tx Error: Abort from Master: pci fatal error!\n", - card->devname,chan->if_name); - } - if (reg & TxDMA_HI_DMA_PCI_ERROR_T_ABRT){ - DEBUG_EVENT("%s:%s: Tx Error: Abort from Target: pci fatal error!\n", - card->devname,chan->if_name); - } - if (reg & TxDMA_HI_DMA_PCI_ERROR_DS_TOUT){ - DEBUG_EVENT("%s:%s: Tx Warning: PCI Latency Timeout!\n", - card->devname,chan->if_name); - chan->errstats.Tx_pci_latency++; - goto tx_post_ok; - } - if (reg & TxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT){ - DEBUG_EVENT("%s:%s: Tx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", - card->devname,chan->if_name); - } - } - chan->if_stats.tx_errors++; - goto tx_post_exit; - } - -tx_post_ok: - chan->opstats.Data_frames_Tx_count++; - chan->opstats.Data_bytes_Tx_count+=wan_skb_len(skb); - chan->if_stats.tx_packets++; - chan->if_stats.tx_bytes+=wan_skb_len(skb); - - /* Indicate that the first tx frame went - * out on the transparent link */ - wan_set_bit(0,&chan->idle_start); - - wan_capture_trace_packet(card, &chan->trace_info, skb, TRC_OUTGOING_FRM); - -tx_post_exit: - - return; -} - - - -/**SECTION************************************************************* - * - * RX Handlers - * - **********************************************************************/ - -/*=============================================== - * xilinx_dma_rx_complete - * - */ -static void xilinx_dma_rx_complete (sdla_t *card, private_area_t *chan, int wtd) -{ - aft_reset_rx_watchdog(card); - aft_rx_dma_chain_handler(chan,wtd,0); -} - -/*=============================================== - * xilinx_rx_post_complete - * - */ -static void xilinx_rx_post_complete (sdla_t *card, private_area_t *chan, - netskb_t *skb, - netskb_t **new_skb, - unsigned char *pkt_error) -{ - - unsigned int len,data_error = 0; - unsigned char *buf; - -#if 0 - wp_rx_element_t *rx_el=(wp_rx_element_t *)&skb->cb[0]; -#else - wp_rx_element_t *rx_el; - rx_el=(wp_rx_element_t *)wan_skb_data(skb); -#endif - DEBUG_RX("%s:%s: RX HI=0x%X LO=0x%X\n DMA=0x%lX", - __FUNCTION__,chan->if_name,rx_el->reg,rx_el->align,rx_el->dma_addr); - -#if 0 - chan->if_stats.rx_errors++; -#endif - - rx_el->align&=RxDMA_LO_ALIGNMENT_BIT_MASK; - *pkt_error=0; - *new_skb=NULL; - - - /* Checking Rx DMA Go bit. Has to be '0' */ - if (wan_test_bit(RxDMA_HI_DMA_GO_READY_BIT,&rx_el->reg)){ - DEBUG_TEST("%s:%s: Error: RxDMA Intr: GO bit set on Rx intr\n", - card->devname,chan->if_name); - chan->if_stats.rx_errors++; - chan->errstats.Rx_dma_descr_err++; - goto rx_comp_error; - } - - /* Checking Rx DMA PCI error status. Has to be '0's */ - if (rx_el->reg&RxDMA_HI_DMA_PCI_ERROR_MASK){ - - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_M_ABRT){ - DEBUG_EVENT("%s:%s: Rx Error: Abort from Master: pci fatal error!\n", - card->devname,chan->if_name); - } - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_T_ABRT){ - DEBUG_EVENT("%s:%s: Rx Error: Abort from Target: pci fatal error!\n", - card->devname,chan->if_name); - } - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_DS_TOUT){ - DEBUG_EVENT("%s:%s: Rx Error: No 'DeviceSelect' from target: pci fatal error!\n", - card->devname,chan->if_name); - } - if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT){ - DEBUG_EVENT("%s:%s: Rx Error: 'Retry' exceeds maximum (64k): pci fatal error!\n", - card->devname,chan->if_name); - } - - DEBUG_EVENT("%s: RXDMA PCI ERROR = 0x%x\n",chan->if_name,rx_el->reg); - chan->errstats.Rx_pci_errors++; - chan->if_stats.rx_errors++; - goto rx_comp_error; - } - - if (chan->hdlc_eng){ - - /* Checking Rx DMA Frame start bit. (information for api) */ - if (!wan_test_bit(RxDMA_HI_DMA_FRAME_START_BIT,&rx_el->reg)){ - DEBUG_TEST("%s:%s RxDMA Intr: Start flag missing: MTU Mismatch! Reg=0x%X\n", - card->devname,chan->if_name,rx_el->reg); - chan->if_stats.rx_frame_errors++; - chan->opstats.Rx_Data_discard_long_count++; - chan->errstats.Rx_hdlc_corrupiton++; - goto rx_comp_error; - } - - /* Checking Rx DMA Frame end bit. (information for api) */ - if (!wan_test_bit(RxDMA_HI_DMA_FRAME_END_BIT,&rx_el->reg)){ - DEBUG_TEST("%s:%s: RxDMA Intr: End flag missing: MTU Mismatch! Reg=0x%X\n", - card->devname,chan->if_name,rx_el->reg); - chan->if_stats.rx_frame_errors++; - chan->opstats.Rx_Data_discard_long_count++; - chan->errstats.Rx_hdlc_corrupiton++; - goto rx_comp_error; - - } else { /* Check CRC error flag only if this is the end of Frame */ - - if (wan_test_bit(RxDMA_HI_DMA_CRC_ERROR_BIT,&rx_el->reg)){ - DEBUG_TEST("%s:%s: RxDMA Intr: CRC Error! Reg=0x%X Len=%i\n", - card->devname,chan->if_name,rx_el->reg, - (rx_el->reg&RxDMA_HI_DMA_DATA_LENGTH_MASK)>>2); - chan->if_stats.rx_frame_errors++; - chan->opstats.Rx_Data_discard_long_count++; - chan->errstats.Rx_hdlc_corrupiton++; - wan_set_bit(WP_CRC_ERROR_BIT,&rx_el->pkt_error); - data_error = 1; - } - - /* Check if this frame is an abort, if it is - * drop it and continue receiving */ - if (wan_test_bit(RxDMA_HI_DMA_FRAME_ABORT_BIT,&rx_el->reg)){ - DEBUG_TEST("%s:%s: RxDMA Intr: Abort! Reg=0x%X\n", - card->devname,chan->if_name,rx_el->reg); - chan->if_stats.rx_frame_errors++; - chan->opstats.Rx_Data_discard_long_count++; - chan->errstats.Rx_hdlc_corrupiton++; - wan_set_bit(WP_ABORT_ERROR_BIT,&rx_el->pkt_error); - data_error = 1; - } - - if (chan->common.usedby != API && data_error){ - goto rx_comp_error; - } - } - } - - len=rx_el->reg&RxDMA_HI_DMA_DATA_LENGTH_MASK; - - if (chan->hdlc_eng){ - /* In HDLC mode, calculate rx length based - * on alignment value, received from DMA */ - len=((((chan->dma_mtu>>2)-1)-len)<<2) - (~(rx_el->align)&RxDMA_LO_ALIGNMENT_BIT_MASK); - }else{ - /* In Transparent mode, our RX buffer will always be - * aligned to the 32bit (word) boundary, because - * the RX buffers are all of equal length */ - len=(((card->wandev.mtu>>2)-len)<<2) - (~(0x03)&RxDMA_LO_ALIGNMENT_BIT_MASK); - } - - *pkt_error=rx_el->pkt_error; - - /* After a RX FIFO overflow, we must mark max 7 - * subsequent frames since firmware, cannot - * guarantee the contents of the fifo */ - - if (wan_test_bit(WP_FIFO_ERROR_BIT,&rx_el->pkt_error)){ - if (++chan->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES){ - chan->rx_fifo_err_cnt=0; - } - wan_set_bit(WP_FIFO_ERROR_BIT,pkt_error); - }else{ - if (chan->rx_fifo_err_cnt){ - if (++chan->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES){ - chan->rx_fifo_err_cnt=0; - } - wan_set_bit(WP_FIFO_ERROR_BIT,pkt_error); - } - } - - wan_skb_pull(skb, sizeof(wp_rx_element_t)); - - if (len > aft_rx_copyback){ - /* The rx size is big enough, thus - * send this buffer up the stack - * and allocate another one */ - wan_skb_put(skb,len); - *new_skb=skb; - - aft_alloc_rx_dma_buff(card,chan,1); - }else{ - - /* The rx packet is very - * small thus, allocate a new - * buffer and pass it up */ - *new_skb=wan_skb_alloc(len + 20); - if (!*new_skb){ - DEBUG_EVENT("%s:%s: Failed to allocate rx skb pkt (len=%i)!\n", - card->devname,chan->if_name,(len+20)); - chan->if_stats.rx_dropped++; - goto rx_comp_error; - } - - buf=wan_skb_put((*new_skb),len); - memcpy(buf,wan_skb_tail(skb),len); - - aft_init_requeue_free_skb(chan, skb); - } - - return; - -rx_comp_error: - - aft_init_requeue_free_skb(chan, skb); - return; -} - - - -/**SECTION************************************************** - * - * Logic Channel Registration Support and - * Utility funcitons - * - **********************************************************/ - -static int aft_init_requeue_free_skb(private_area_t *chan, netskb_t *skb) -{ - wan_skb_init(skb,16); - wan_skb_trim(skb,0); -#if 0 - memset(&skb->cb[0],0,sizeof(wp_rx_element_t)); -#endif - wan_skb_queue_tail(&chan->wp_rx_free_list,skb); - - return 0; -} - -static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num) -{ - int i; - netskb_t *skb; - - for (i=0;idma_mtu); - if (!skb){ - DEBUG_EVENT("%s: %s no memory\n", - chan->if_name,__FUNCTION__); - return -ENOMEM; - } - wan_skb_queue_tail(&chan->wp_rx_free_list,skb); - } - - return 0; -} - - -/*============================================================================ - * Enable timer interrupt - */ -static void enable_timer (void* card_id) -{ - sdla_t* card = (sdla_t*)card_id; - - DEBUG_TEST("%s: %s Sdla Polling!\n",__FUNCTION__,card->devname); - -#if defined(__LINUX__) - wan_set_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); - WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); -#else - { - wan_smp_flag_t smp_flags, smp_flags1; - card->hw_iface.hw_lock(card->hw,&smp_flags1); - wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - WAN_FECALL(&card->wandev, polling, (&card->fe)); - wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); - card->hw_iface.hw_unlock(card->hw,&smp_flags1); - } -#endif - return; -} - -/**SECTION************************************************** - * - * API Bottom Half Handlers - * - **********************************************************/ - -#if defined(__LINUX__) -static void wp_bh (unsigned long data) -#else -static void wp_bh (void* data, int dummy) -#endif -{ - private_area_t* chan = (private_area_t *)data; - netskb_t *new_skb,*skb; - unsigned char pkt_error; - unsigned long timeout=SYSTEM_TICKS; - - DEBUG_TEST("%s: ------------ BEGIN --------------: %lu\n", - __FUNCTION__,SYSTEM_TICKS); - - if (!wan_test_bit(0,&chan->up)){ - DEBUG_EVENT("%s: wp_bh() chan not up!\n", - chan->if_name); - WAN_TASKLET_END((&chan->common.bh_task)); - return; - } - - - while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ - -#if 0 - chan->if_stats.rx_errors++; -#endif - - if (SYSTEM_TICKS-timeout > 3){ - chan->if_stats.rx_errors++; -#if 0 - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: BH Squeeze!\n",chan->if_name); - } -#endif - wan_skb_queue_head(&chan->wp_rx_complete_list,skb); - break; - } - - if (chan->common.usedby == API && chan->common.sk == NULL){ - DEBUG_TEST("%s: No sock bound to channel rx dropping!\n", - chan->if_name); - chan->if_stats.rx_dropped++; - aft_init_requeue_free_skb(chan, skb); - - continue; - } - - new_skb=NULL; - pkt_error=0; - - /* The post function will take care - * of the skb and new_skb buffer. - * If new_skb buffer exists, driver - * must pass it up the stack, or free it */ - xilinx_rx_post_complete (chan->card, chan, - skb, - &new_skb, - &pkt_error); - if (new_skb){ - - int len=wan_skb_len(new_skb); - - wan_capture_trace_packet(chan->card, &chan->trace_info, - new_skb,TRC_INCOMING_FRM); - - if (chan->common.usedby == API){ -#if defined(__LINUX__) -# ifndef CONFIG_PRODUCT_WANPIPE_GENERIC - - /* Only for API, we insert packet status - * byte to indicate a packet error. Take - * this byte and put it in the api header */ - - if (wan_skb_headroom(new_skb) >= sizeof(api_rx_hdr_t)){ - api_rx_hdr_t *rx_hdr= - (api_rx_hdr_t*)skb_push(new_skb,sizeof(api_rx_hdr_t)); - memset(rx_hdr,0,sizeof(api_rx_hdr_t)); - rx_hdr->error_flag=pkt_error; - }else{ - int hroom=wan_skb_headroom(new_skb); - int rx_sz=sizeof(api_rx_hdr_t); - DEBUG_EVENT("%s: Error Rx pkt headroom %i < %i\n", - chan->if_name, - hroom, - rx_sz); - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - - new_skb->protocol = htons(PVC_PROT); - wan_skb_reset_mac_header(new_skb); - new_skb->dev = chan->common.dev; - new_skb->pkt_type = WAN_PACKET_DATA; -#if 0 - chan->if_stats.rx_frame_errors++; -#endif - if (wan_api_rx(chan,new_skb) != 0){ - DEBUG_TEST("%s: Error: Rx Socket busy!\n", - chan->if_name); - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } -# endif -#endif - - }else if (chan->common.usedby == STACK){ - - if (wanpipe_lip_rx(chan,new_skb) != 0){ - ++chan->if_stats.rx_dropped; - wan_skb_free(new_skb); - continue; - } - - }else{ - protocol_recv(chan->card,chan,new_skb); - } - - chan->opstats.Data_frames_Rx_count++; - chan->opstats.Data_bytes_Rx_count+=len; - chan->if_stats.rx_packets++; - chan->if_stats.rx_bytes+=len; - } - - if (SYSTEM_TICKS-timeout > 3){ - chan->if_stats.rx_errors++; -#if 0 - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: BH Squeeze! %i\n", - chan->if_name,SYSTEM_TICKS-timeout); - } -#endif - break; - } - } - - while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ - xilinx_tx_post_complete (chan->card,chan,skb); - wan_skb_free(skb); - } - - - WAN_TASKLET_END((&chan->common.bh_task)); -#if 1 - { - int len; - if ((len=wan_skb_queue_len(&chan->wp_rx_complete_list))){ - DEBUG_TEST("%s: Triggering from bh rx=%i\n",chan->if_name,len); - WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); - }else if ((len=wan_skb_queue_len(&chan->wp_tx_complete_list))){ - DEBUG_TEST("%s: Triggering from bh tx=%i\n",chan->if_name,len); - WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); - } - } -#endif - - DEBUG_TEST("%s: ------------ END -----------------: %lu\n", - __FUNCTION__,SYSTEM_TICKS); - - return; -} - -/**SECTION************************************************** - * - * Interrupt Support Functions - * - **********************************************************/ - -static int fifo_error_interrupt(sdla_t *card, u32 reg, u32 tx_status, u32 rx_status) -{ - u32 err=0; - u32 i; - private_area_t *chan; - int num_of_logic_ch; - - - if (card->wandev.state != WAN_CONNECTED){ - DEBUG_EVENT("%s: Warning: Ignoring Error Intr: link disc!\n", - card->devname); - return 0; - } - - if (IS_TE3(&card->fe.fe_cfg)){ - num_of_logic_ch=1; - }else{ - num_of_logic_ch=card->u.xilinx.num_of_time_slots; - } - - if (tx_status != 0){ - for (i=0;iu.xilinx.logic_ch_map)){ - - chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[i]; - if (!chan){ - DEBUG_EVENT("Warning: ignoring tx error intr: no dev!\n"); - continue; - } - - if (!wan_test_bit(0,&chan->up)){ - DEBUG_EVENT("%s: Warning: ignoring tx error intr: dev down 0x%X UP=0x%X!\n", - wan_netif_name(chan->common.dev),chan->common.state,chan->ignore_modem); - continue; - } - - if (chan->common.state != WAN_CONNECTED){ - DEBUG_EVENT("%s: Warning: ignoring tx error intr: dev disc!\n", - wan_netif_name(chan->common.dev)); - continue; - } - - if (!chan->hdlc_eng && !wan_test_bit(0,&chan->idle_start)){ - DEBUG_EVENT("%s: Warning: ignoring tx error intr: dev init error!\n", - wan_netif_name(chan->common.dev)); - if (chan->hdlc_eng){ - xilinx_tx_fifo_under_recover(card,chan); - } - continue; - } - DEBUG_TEST("%s:%s: Warning TX Fifo Error on LogicCh=%li Slot=%i!\n", - card->devname,chan->if_name,chan->logic_ch_num,i); - - xilinx_tx_fifo_under_recover(card,chan); - ++chan->if_stats.tx_fifo_errors; - err=-EINVAL; - } - } - } - - - if (rx_status != 0){ - for (i=0;iu.xilinx.logic_ch_map)){ - chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[i]; - if (!chan){ - continue; - } - - if (!wan_test_bit(0,&chan->up)){ - DEBUG_EVENT("%s: Warning: ignoring rx error intr: dev down 0x%X UP=0x%X!\n", - wan_netif_name(chan->common.dev),chan->common.state,chan->ignore_modem); - continue; - } - - if (chan->common.state != WAN_CONNECTED){ - DEBUG_EVENT("%s: Warning: ignoring rx error intr: dev disc!\n", - wan_netif_name(chan->common.dev)); - continue; - } - - DEBUG_TEST("%s:%s: Warning RX Fifo Error on LCh=%li Slot=%i RxCL=%i RxFL=%i RxDMA=%i\n", - card->devname,chan->if_name,chan->logic_ch_num,i, - wan_skb_queue_len(&chan->wp_rx_complete_list), - wan_skb_queue_len(&chan->wp_rx_free_list), - chan->rx_dma); - - ++chan->if_stats.rx_fifo_errors; -#if 0 -{ - unsigned long dma_descr; - unsigned int reg; - dma_descr=(chan->logic_ch_num<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_read_4(card->hw, dma_descr, ®); - DEBUG_EVENT("%s: Hi Descriptor 0x%X\n",chan->if_name,reg); -} -#endif - - wan_set_bit(WP_FIFO_ERROR_BIT, &chan->pkt_error); - - err=-EINVAL; - } - } - } - - return err; -} - - -static void front_end_interrupt(sdla_t *card, unsigned long reg) -{ - /* FIXME: To be filled by ALEX :) */ - DEBUG_TE3("%s: front_end_interrupt!\n",card->devname); - -// wp_debug_func_add(__FUNCTION__); - - if (IS_TE3(&card->fe.fe_cfg)){ - /* FIXME HANDLE T3 Interrupt */ - WAN_FECALL(&card->wandev, isr, (&card->fe)); - }else{ - DEBUG_EVENT("%s: Internal Error (Never should happened)!\n", - card->devname); - } - - handle_front_end_state(card); - return; -} - -/**SECTION*************************************************************** - * - * HARDWARE Interrupt Handlers - * - ***********************************************************************/ - - -/*============================================================================ - * wpfw_isr - * - * Main interrupt service routine. - * Determin the interrupt received and handle it. - * - */ -static WAN_IRQ_RETVAL wp_aft_te3_isr (sdla_t* card) -{ - int i; - u32 reg; - u32 dma_tx_reg,dma_rx_reg,rx_fifo_status=0,tx_fifo_status=0; - private_area_t *chan; - int skip_rx_wtd=0; - WAN_IRQ_RETVAL_DECL(irq_ret); - - if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ - WAN_IRQ_RETURN(irq_ret); - } - - wan_set_bit(0,&card->in_isr); - - /* -----------------2/6/2003 9:02AM------------------ - * Disable all chip Interrupts (offset 0x040) - * -- "Transmit/Receive DMA Engine" interrupt disable - * -- "FiFo/Line Abort Error" interrupt disable - * --------------------------------------------------*/ - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); - - DEBUG_TEST("\n"); - DEBUG_TEST("%s: ISR (0x%X) = 0x%08X \n", - card->devname,XILINX_CHIP_CFG_REG,reg); - - if (wan_test_bit(ENABLE_TE3_FRACTIONAL,®)){ - unsigned int frc_crc; - u32 freg; - - card->hw_iface.bus_read_4(card->hw,TE3_FRACT_ENCAPSULATION_REG, &freg); - frc_crc=get_te3_rx_fract_crc_cnt(freg); - if (frc_crc){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: TE3 Frac CRC Cnt = %i 0x%08X\n", - card->devname, frc_crc,reg); - } - } - } - - if (wan_test_bit(SECURITY_STATUS_FLAG,®)){ - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - if (++card->u.aft.chip_security_cnt > - AFT_MAX_CHIP_SECURITY_CNT){ - -#if 1 - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: Critical: Chip Security Compromised: Disabling Driver (%i)!\n", - card->devname,card->u.aft.chip_security_cnt); - } - card->u.aft.chip_security_cnt=0; - aft_critical_shutdown(card); - goto isr_end; -#else - - DEBUG_EVENT("%s: Critical: Chip Security Compromised: Disabling Driver (%i)!\n", - card->devname,card->u.aft.chip_security_cnt); - DEBUG_EVENT("%s: Please call Sangoma Tech Support (www.sangoma.com)!\n", - card->devname); - - - aft_critical_shutdown(card); - goto isr_end; -#endif - } - }else{ - card->u.aft.chip_security_cnt=0; - } - - /* Note: If interrupts are received without pending - * flags, it usually indicates that the interrupt - * is being shared. (Check 'cat /proc/interrupts') - */ - - if (wan_test_bit(FRONT_END_INTR_ENABLE_BIT,®)){ - if (wan_test_bit(FRONT_END_INTR_FLAG,®)){ - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); -#if defined(__LINUX__) - wan_set_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); - WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); - - __aft_fe_intr_ctrl(card,0); -#else - front_end_interrupt(card,reg); -#endif - } - } - - /* Test Fifo Error Interrupt, - * If set shutdown all interfaces and - * reconfigure */ - if (wan_test_bit(ERROR_INTR_ENABLE_BIT,®)){ - if (wan_test_bit(ERROR_INTR_FLAG,®)){ - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - - card->hw_iface.bus_read_4(card->hw,XILINX_HDLC_TX_INTR_PENDING_REG,&tx_fifo_status); - card->hw_iface.bus_read_4(card->hw,XILINX_HDLC_RX_INTR_PENDING_REG,&rx_fifo_status); - - rx_fifo_status&=card->u.aft.active_ch_map; - tx_fifo_status&=card->u.aft.active_ch_map; - - fifo_error_interrupt(card,reg,tx_fifo_status,rx_fifo_status); - } - } - - /* -----------------2/6/2003 9:37AM------------------ - * Checking for Interrupt source: - * 1. Receive DMA Engine - * 2. Transmit DMA Engine - * 3. Error conditions. - * --------------------------------------------------*/ - if (wan_test_bit(GLOBAL_INTR_ENABLE_BIT,®) && - (wan_test_bit(DMA_INTR_FLAG,®) || rx_fifo_status)){ - - int num_of_logic_ch; - - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - - if (IS_TE3(&card->fe.fe_cfg)){ - num_of_logic_ch=1; - }else{ - num_of_logic_ch=card->u.xilinx.num_of_time_slots; - } - - /* Receive DMA Engine */ - card->hw_iface.bus_read_4(card->hw, - XILINX_DMA_RX_INTR_PENDING_REG, - &dma_rx_reg); - - - DEBUG_TEST("%s: DMA_RX_INTR_REG(0x%X) = 0x%X ActCH=0x%lX\n", - card->devname, - XILINX_DMA_RX_INTR_PENDING_REG,dma_rx_reg, - card->u.xilinx.active_ch_map); - - dma_rx_reg&=card->u.xilinx.active_ch_map; - - if (dma_rx_reg == 0 && rx_fifo_status == 0){ - goto isr_skb_rx; - } - - for (i=0; iu.xilinx.logic_ch_map)){ - - chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[i]; - if (!chan){ - DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%i\n", - card->devname,i); - continue; - } - - if (!wan_test_bit(0,&chan->up)){ - DEBUG_EVENT("%s: Error: Dev not up for Rx logical ch=%i\n", - card->devname,i); - continue; - } - -#if 0 - chan->if_stats.rx_frame_errors++; -#endif - - DEBUG_ISR("%s: RX Interrupt pend. \n", - card->devname); - xilinx_dma_rx_complete(card,chan,0); - skip_rx_wtd=1; - } - } -isr_skb_rx: - - /* Transmit DMA Engine */ - - card->hw_iface.bus_read_4(card->hw, - XILINX_DMA_TX_INTR_PENDING_REG, - &dma_tx_reg); - - dma_tx_reg&=card->u.xilinx.active_ch_map; - - DEBUG_TEST("%s: DMA_TX_INTR_REG(0x%X) = 0x%X, ChMap=0x%lX NumofCh=%i\n", - card->devname, - XILINX_DMA_TX_INTR_PENDING_REG, - dma_tx_reg, - card->u.xilinx.active_ch_map, - num_of_logic_ch); - - if (dma_tx_reg == 0){ - goto isr_skb_tx; - } - - for (i=0; iu.xilinx.logic_ch_map)){ - chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[i]; - if (!chan){ - DEBUG_EVENT("%s: Error: No Dev for Tx logical ch=%i\n", - card->devname,i); - continue; - } - - if (!wan_test_bit(0,&chan->up)){ - DEBUG_EVENT("%s: Error: Dev not up for Tx logical ch=%i\n", - card->devname,i); - continue; - } - - - DEBUG_TEST("---- TX Interrupt pend. --\n"); - xilinx_dma_tx_complete(card,chan,0); - - }else{ - DEBUG_EVENT("Failed Testing for Tx Timeslot %i TxReg=0x%X ChMap=0x%lX\n",i, - dma_tx_reg,card->u.xilinx.logic_ch_map); - } - } - } - -isr_skb_tx: - - DEBUG_ISR("---- ISR SKB TX end.-------------------\n"); - - if (wan_test_bit(AFT_TE3_TX_WDT_INTR_PND,®)){ - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - aft_reset_tx_watchdog(card); - chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[0]; - if (chan && wan_test_bit(0,&chan->up)){ -#if 0 - ++chan->if_stats.tx_dropped; -#endif - xilinx_dma_tx_complete (card,chan,1); - } - DEBUG_TEST("%s: Tx WatchDog Expired!\n",card->devname); - aft_reset_tx_watchdog(card); - } - - if (wan_test_bit(AFT_TE3_RX_WDT_INTR_PND,®)){ - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - aft_reset_rx_watchdog(card); - chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[0]; - if (!skip_rx_wtd && chan && wan_test_bit(0,&chan->up)){ -#if 0 - chan->if_stats.rx_dropped++; -#endif - xilinx_dma_rx_complete (card,chan,1); - }else{ - if (chan){ - DEBUG_TEST("%s: Skipping Rx WTD Flags=%d\n", - chan->if_name,wan_test_bit(0,&chan->up)); - } - aft_reset_rx_watchdog(card); - aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); - } - - DEBUG_TEST("%s: Rx WatchDog Expired %p!\n", - card->devname,chan); - } - - - /* -----------------2/6/2003 10:36AM----------------- - * Finish of the interupt handler - * --------------------------------------------------*/ -isr_end: - DEBUG_ISR("---- ISR end.-------------------\n"); - wan_clear_bit(0,&card->in_isr); - WAN_IRQ_RETURN(irq_ret); -} - - - -/**SECTION*********************************************************** - * - * WANPIPE Debugging Interfaces - * - ********************************************************************/ - - - -/*============================================================================= - * process_udp_mgmt_pkt - * - * Process all "wanpipemon" debugger commands. This function - * performs all debugging tasks: - * - * Line Tracing - * Line/Hardware Statistics - * Protocol Statistics - * - * "wanpipemon" utility is a user-space program that - * is used to debug the WANPIPE product. - * - */ -#if 1 -static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, - private_area_t* chan, int local_dev ) -{ - unsigned short buffer_length; - wan_udp_pkt_t *wan_udp_pkt; - wan_trace_t *trace_info=NULL; - - wan_udp_pkt = (wan_udp_pkt_t *)chan->udp_pkt_data; - - if (wan_atomic_read(&chan->udp_pkt_len) == 0){ - return -ENODEV; - } - - trace_info=&chan->trace_info; - wan_udp_pkt = (wan_udp_pkt_t *)chan->udp_pkt_data; - - { - - netskb_t *skb; - - wan_udp_pkt->wan_udp_opp_flag = 0; - - switch(wan_udp_pkt->wan_udp_command) { - - case READ_CONFIGURATION: - case READ_CODE_VERSION: - wan_udp_pkt->wan_udp_return_code = 0; - wan_udp_pkt->wan_udp_data_len=0; - break; - - - case ENABLE_TRACING: - - wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; - wan_udp_pkt->wan_udp_data_len = 0; - - if (!wan_test_bit(0,&trace_info->tracing_enabled)){ - - trace_info->trace_timeout = SYSTEM_TICKS; - - wan_trace_purge(trace_info); - - if (wan_udp_pkt->wan_udp_data[0] == 0){ - wan_clear_bit(1,&trace_info->tracing_enabled); - DEBUG_UDP("%s: TE3 trace enabled!\n", - card->devname); - }else if (wan_udp_pkt->wan_udp_data[0] == 1){ - wan_clear_bit(2,&trace_info->tracing_enabled); - wan_set_bit(1,&trace_info->tracing_enabled); - DEBUG_UDP("%s: TE3 trace enabled!\n", - card->devname); - }else{ - wan_clear_bit(1,&trace_info->tracing_enabled); - wan_set_bit(2,&trace_info->tracing_enabled); - DEBUG_UDP("%s: TE3 trace enabled!\n", - card->devname); - } - wan_set_bit (0,&trace_info->tracing_enabled); - - }else{ - DEBUG_EVENT("%s: Error: TE3 trace already running!\n", - card->devname); - wan_udp_pkt->wan_udp_return_code = 2; - } - - break; - - case DISABLE_TRACING: - - wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; - - if(wan_test_bit(0,&trace_info->tracing_enabled)) { - - wan_clear_bit(0,&trace_info->tracing_enabled); - wan_clear_bit(1,&trace_info->tracing_enabled); - wan_clear_bit(2,&trace_info->tracing_enabled); - - wan_trace_purge(trace_info); - - DEBUG_UDP("%s: Disabling TE3 trace\n", - card->devname); - - }else{ - /* set return code to line trace already - disabled */ - wan_udp_pkt->wan_udp_return_code = 1; - } - - break; - - case GET_TRACE_INFO: - - if(wan_test_bit(0,&trace_info->tracing_enabled)){ - trace_info->trace_timeout = SYSTEM_TICKS; - }else{ - DEBUG_EVENT("%s: Error TE3 trace not enabled\n", - card->devname); - /* set return code */ - wan_udp_pkt->wan_udp_return_code = 1; - break; - } - - buffer_length = 0; - wan_udp_pkt->wan_udp_atm_num_frames = 0; - wan_udp_pkt->wan_udp_atm_ismoredata = 0; - -#if defined(__FreeBSD__) || defined(__OpenBSD__) - while (wan_skb_queue_len(&trace_info->trace_queue)){ - WAN_IFQ_POLL(&trace_info->trace_queue, skb); - if (skb == NULL){ - DEBUG_EVENT("%s: No more trace packets in trace queue!\n", - card->devname); - break; - } - if ((WAN_MAX_DATA_SIZE - buffer_length) < skb->m_pkthdr.len){ - /* indicate there are more frames on board & exit */ - wan_udp_pkt->wan_udp_atm_ismoredata = 0x01; - break; - } - - m_copydata(skb, - 0, - skb->m_pkthdr.len, - &wan_udp_pkt->wan_udp_data[buffer_length]); - buffer_length += skb->m_pkthdr.len; - WAN_IFQ_DEQUEUE(&trace_info->trace_queue, skb); - if (skb){ - wan_skb_free(skb); - } - wan_udp_pkt->wan_udp_atm_num_frames++; - } -#elif defined(__LINUX__) - while ((skb=skb_dequeue(&trace_info->trace_queue)) != NULL){ - - if((MAX_TRACE_BUFFER - buffer_length) < wan_skb_len(skb)){ - /* indicate there are more frames on board & exit */ - wan_udp_pkt->wan_udp_atm_ismoredata = 0x01; - if (buffer_length != 0){ - wan_skb_queue_head(&trace_info->trace_queue, skb); - }else{ - /* If rx buffer length is greater than the - * whole udp buffer copy only the trace - * header and drop the trace packet */ - - memcpy(&wan_udp_pkt->wan_udp_atm_data[buffer_length], - wan_skb_data(skb), - sizeof(wan_trace_pkt_t)); - - buffer_length = sizeof(wan_trace_pkt_t); - wan_udp_pkt->wan_udp_atm_num_frames++; - wan_skb_free(skb); - } - break; - } - - memcpy(&wan_udp_pkt->wan_udp_atm_data[buffer_length], - wan_skb_data(skb), - wan_skb_len(skb)); - - buffer_length += wan_skb_len(skb); - wan_skb_free(skb); - wan_udp_pkt->wan_udp_atm_num_frames++; - } -#endif - /* set the data length and return code */ - wan_udp_pkt->wan_udp_data_len = buffer_length; - wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK; - break; - - case ROUTER_UP_TIME: - wan_getcurrenttime( &chan->router_up_time, NULL ); - chan->router_up_time -= chan->router_start_time; - *(unsigned long *)&wan_udp_pkt->wan_udp_data = - chan->router_up_time; - wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long); - wan_udp_pkt->wan_udp_return_code = 0; - break; - - case READ_OPERATIONAL_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memcpy(wan_udp_pkt->wan_udp_data,&chan->opstats,sizeof(aft_op_stats_t)); - wan_udp_pkt->wan_udp_data_len=sizeof(aft_op_stats_t); - break; - - case FLUSH_OPERATIONAL_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memset(&chan->opstats,0,sizeof(aft_op_stats_t)); - wan_udp_pkt->wan_udp_data_len=0; - break; - - case READ_COMMS_ERROR_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memcpy(wan_udp_pkt->wan_udp_data,&chan->errstats,sizeof(aft_comm_err_stats_t)); - wan_udp_pkt->wan_udp_data_len=sizeof(aft_comm_err_stats_t); - break; - - case FLUSH_COMMS_ERROR_STATS: - wan_udp_pkt->wan_udp_return_code = 0; - memset(&chan->errstats,0,sizeof(aft_comm_err_stats_t)); - wan_udp_pkt->wan_udp_data_len=0; - break; - - default: - wan_udp_pkt->wan_udp_data_len = 0; - wan_udp_pkt->wan_udp_return_code = 0xCD; - - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT( - "%s: Warning, Illegal UDP command attempted from network: %x\n", - card->devname,wan_udp_pkt->wan_udp_command); - } - break; - } /* end of switch */ - } /* end of else */ - - /* Fill UDP TTL */ - wan_udp_pkt->wan_ip_ttl= card->wandev.ttl; - - wan_udp_pkt->wan_udp_request_reply = UDPMGMT_REPLY; - return 1; - -} -#endif - -/**SECTION************************************************************* - * - * TASK Functions and Triggers - * - **********************************************************************/ - - -/*============================================================================ - * port_set_state - * - * Set PORT state. - * - */ -static void port_set_state (sdla_t *card, int state) -{ - struct wan_dev_le *devle; - netdevice_t *dev; - - if (card->wandev.state != state) - { -#if 0 - switch (state) - { - case WAN_CONNECTED: - DEBUG_EVENT( "%s: Link connected!\n", - card->devname); - break; - - case WAN_CONNECTING: - DEBUG_EVENT( "%s: Link connecting...\n", - card->devname); - break; - - case WAN_DISCONNECTED: - DEBUG_EVENT( "%s: Link disconnected!\n", - card->devname); - break; - } -#endif - card->wandev.state = state; - WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ - dev = WAN_DEVLE2DEV(devle); - if (!dev) continue; - set_chan_state(card, dev, state); - } - } -} - -/*============================================================ - * handle_front_end_state - * - * Front end state indicates the physical medium that - * the Z80 backend connects to. - * - * S514-1/2/3: V32/RS232/FT1 Front End - * Front end state is determined via - * Modem/Status. - * S514-4/5/7/8: 56K/T1/E1 Front End - * Front end state is determined via - * link status interrupt received - * from the front end hardware. - * - * If the front end state handler is enabed by the - * user. The interface state will follow the - * front end state. I.E. If the front end goes down - * the protocol and interface will be declared down. - * - * If the front end state is UP, then the interface - * and protocol will be up ONLY if the protocol is - * also UP. - * - * Therefore, we must have three state variables - * 1. Front End State (card->wandev.front_end_status) - * 2. Protocol State (card->wandev.state) - * 3. Interface State (dev->flags & IFF_UP) - * - */ - -static void handle_front_end_state(void *card_id) -{ - sdla_t *card = (sdla_t*)card_id; - unsigned char status; - - if (card->wandev.ignore_front_end_status == WANOPT_YES){ - return; - } - - WAN_FECALL(&card->wandev, get_fe_status, (&card->fe, &status)); - if (status == FE_CONNECTED){ - if (card->wandev.state != WAN_CONNECTED){ - enable_data_error_intr(card); - port_set_state(card,WAN_CONNECTED); - card->u.xilinx.state_change_exit_isr=1; - wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); - } - } else { - if (card->wandev.state != WAN_DISCONNECTED){ - port_set_state(card,WAN_DISCONNECTED); - disable_data_error_intr(card,LINK_DOWN); - card->u.xilinx.state_change_exit_isr=1; - wan_set_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); - } - } -} - -#if 0 -static unsigned char read_cpld(sdla_t *card, unsigned short cpld_off) -{ - - u16 org_off; - u8 tmp; - - cpld_off &= ~BIT_DEV_ADDR_CLEAR; - cpld_off |= BIT_DEV_ADDR_CPLD; - - /*ALEX: Save the current address. */ - card->hw_iface.bus_read_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - &org_off); - card->hw_iface.bus_write_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - cpld_off); - - card->hw_iface.bus_read_1(card->hw,XILINX_MCPU_INTERFACE, &tmp); - - /*ALEX: Restore original address */ - card->hw_iface.bus_write_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - org_off); - return tmp; - - -} -#endif - -static int write_cpld(void *pcard, unsigned short off,unsigned char data) -{ - sdla_t *card = (sdla_t*)pcard; - u16 org_off; - - off &= ~BIT_DEV_ADDR_CLEAR; - off |= BIT_DEV_ADDR_CPLD; - - /*ALEX: Save the current original address */ - card->hw_iface.bus_read_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - &org_off); - - /* This delay is required to avoid bridge optimization - * (combining two writes together)*/ - WP_DELAY(5); - - card->hw_iface.bus_write_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - off); - - /* This delay is required to avoid bridge optimization - * (combining two writes together)*/ - WP_DELAY(5); - - card->hw_iface.bus_write_1(card->hw, - XILINX_MCPU_INTERFACE, - data); - /*ALEX: Restore the original address */ - card->hw_iface.bus_write_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - org_off); - return 0; -} - - -static int write_fe_cpld(void *pcard, unsigned short off,unsigned char data) -{ - sdla_t *card = (sdla_t*)pcard; - u16 org_off; - - off &= ~AFT3_BIT_DEV_ADDR_EXAR_CLEAR; - off |= AFT3_BIT_DEV_ADDR_EXAR_CPLD; - - /*ALEX: Save the current original address */ - card->hw_iface.bus_read_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - &org_off); - - /* This delay is required to avoid bridge optimization - * (combining two writes together)*/ - WP_DELAY(5); - - card->hw_iface.bus_write_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - off); - - /* This delay is required to avoid bridge optimization - * (combining two writes together)*/ - WP_DELAY(5); - - card->hw_iface.bus_write_1(card->hw, - XILINX_MCPU_INTERFACE, - data); - /*ALEX: Restore the original address */ - card->hw_iface.bus_write_2(card->hw, - XILINX_MCPU_INTERFACE_ADDR, - org_off); - return 0; -} - -#if 0 -static unsigned char write_front_end_reg (void* card1, unsigned short off, unsigned char value) -{ - sdla_t* card = (sdla_t*)card1; - - off &= ~BIT_DEV_ADDR_CLEAR; - card->hw_iface.bus_write_2(card->hw,XILINX_MCPU_INTERFACE_ADDR, off); - /* NC: Mar 25 2004 - * This delays are required to avoid bridge optimization - * (combining two writes together) - */ - WP_DELAY(5); - card->hw_iface.bus_write_1(card->hw,XILINX_MCPU_INTERFACE, value); - WP_DELAY(5); - - return 0; -} - -/*============================================================================ - * Read TE1/56K Front end registers - */ -static unsigned char read_front_end_reg (void* card1, unsigned short off) -{ - sdla_t* card = (sdla_t*)card1; - u8 tmp; - - off &= ~BIT_DEV_ADDR_CLEAR; - card->hw_iface.bus_write_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, off); - card->hw_iface.bus_read_1(card->hw,XILINX_MCPU_INTERFACE, &tmp); - WP_DELAY(5); - - return tmp; -} -#endif - -static int xilinx_read(sdla_t *card, wan_cmd_api_t *api_cmd) -{ - - if (api_cmd->offset <= 0x3C){ - card->hw_iface.pci_read_config_dword(card->hw, - api_cmd->offset, - (u32*)&api_cmd->data[0]); - api_cmd->len=4; - - }else{ - card->hw_iface.peek(card->hw, api_cmd->offset, &api_cmd->data[0], api_cmd->len); - } - -#ifdef DEB_XILINX - DEBUG_EVENT("%s: Reading Bar%i Offset=0x%X Len=%i\n", - card->devname,api_cmd->bar,api_cmd->offset,api_cmd->len); -#endif - - return 0; -} - -static int xilinx_write(sdla_t *card, wan_cmd_api_t *api_cmd) -{ - -#ifdef DEB_XILINX - DEBUG_EVENT("%s: Writting Bar%i Offset=0x%X Len=%i\n", - card->devname, - api_cmd->bar,api_cmd->offset,api_cmd->len); -#endif - -#if 0 - card->hw_iface.poke(card->hw, api_cmd->offset, &api_cmd->data[0], api_cmd->len); -#endif - if (api_cmd->len == 1){ - card->hw_iface.bus_write_1( - card->hw, - api_cmd->offset, - (u8)api_cmd->data[0]); - }else if (api_cmd->len == 2){ - card->hw_iface.bus_write_2( - card->hw, - api_cmd->offset, - *(u16*)&api_cmd->data[0]); - }else if (api_cmd->len == 4){ - card->hw_iface.bus_write_4( - card->hw, - api_cmd->offset, - *(u32*)&api_cmd->data[0]); - }else{ - card->hw_iface.poke( - card->hw, - api_cmd->offset, - &api_cmd->data[0], - api_cmd->len); - } - - return 0; -} - -static int xilinx_write_bios(sdla_t *card, wan_cmd_api_t *api_cmd) -{ -#ifdef DEB_XILINX - DEBUG_EVENT("Setting PCI 0x%X=0x%08lX 0x3C=0x%08X\n", - (card->wandev.S514_cpu_no[0] == SDLA_CPU_A) ? 0x10 : 0x14, - card->u.xilinx.bar,card->wandev.irq); -#endif - card->hw_iface.pci_write_config_dword(card->hw, - (card->wandev.S514_cpu_no[0] == SDLA_CPU_A) ? 0x10 : 0x14, - card->u.xilinx.bar); - card->hw_iface.pci_write_config_dword(card->hw, 0x3C, card->wandev.irq); - card->hw_iface.pci_write_config_dword(card->hw, 0x0C, 0x0000ff00); - - return 0; -} - -static int aft_devel_ioctl(sdla_t *card,struct ifreq *ifr) -{ - wan_cmd_api_t api_cmd; - int err; - - if (!ifr || !ifr->ifr_data){ - DEBUG_EVENT("%s: Error: No ifr or ifr_data\n",__FUNCTION__); - return -EINVAL; - } - - if (WAN_COPY_FROM_USER(&api_cmd,ifr->ifr_data,sizeof(wan_cmd_api_t))){ - return -EFAULT; - } - - switch(api_cmd.cmd){ -#if defined(__LINUX__) - case SDLA_HDLC_READ_REG: -#endif - case SIOC_WAN_READ_REG: - err=xilinx_read(card, &api_cmd); - break; - -#if defined(__LINUX__) - case SDLA_HDLC_WRITE_REG: -#endif - case SIOC_WAN_WRITE_REG: - err=xilinx_write(card, &api_cmd); - break; - -#if defined(__LINUX__) - case SDLA_HDLC_SET_PCI_BIOS: -#endif - case SIOC_WAN_SET_PCI_BIOS: - err=xilinx_write_bios(card, &api_cmd); - break; - } - - if (WAN_COPY_TO_USER(ifr->ifr_data,&api_cmd,sizeof(wan_cmd_api_t))){ - return -EFAULT; - } - return 0; -} - -/*========================================= - * enable_data_error_intr - * - * Description: - * - * Run only after the front end comes - * up from down state. - * - * Clean the DMA Tx/Rx pending interrupts. - * (Ignore since we will reconfigure - * all dma descriptors. DMA controler - * was already disabled on link down) - * - * For all channels clean Tx/Rx Fifo - * - * Enable DMA controler - * (This starts the fifo cleaning - * process) - * - * For all channels reprogram Tx/Rx DMA - * descriptors. - * - * Clean the Tx/Rx Error pending interrupts. - * (Since dma fifo's are now empty) - * - * Enable global DMA and Error interrutps. - * - */ - -static void enable_data_error_intr(sdla_t *card) -{ - struct wan_dev_le *devle; - u32 reg; - netdevice_t *dev; - - DEBUG_TEST("%s: %s() !!!\n", - card->devname,__FUNCTION__); - - - /* Clean Tx/Rx DMA interrupts */ - card->hw_iface.bus_read_4(card->hw, - XILINX_DMA_RX_INTR_PENDING_REG, ®); - card->hw_iface.bus_read_4(card->hw, - XILINX_DMA_TX_INTR_PENDING_REG, ®); - - - /* For all channels clean Tx/Rx fifos */ - WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ - private_area_t *chan; - - dev = WAN_DEVLE2DEV(devle); - if (!dev || !wan_netif_priv(dev)) - continue; - chan = wan_netif_priv(dev); - - if (!wan_test_bit(0,&chan->up)){ - continue; - } - - aft_list_descriptors(chan); - - DEBUG_TEST("%s: 1) Free Used DMA CHAINS %s\n", - card->devname,chan->if_name); - - aft_rx_dma_chain_handler(chan,0,1); - aft_free_rx_complete_list(chan); - - - aft_list_descriptors(chan); - - DEBUG_TEST("%s: 1) Free UNUSED DMA CHAINS %s\n", - card->devname,chan->if_name); - - aft_free_rx_descriptors(chan); - - aft_free_tx_descriptors(chan); - - - DEBUG_TEST("%s: 2) Init interface fifo no wait %s\n", - card->devname,chan->if_name); - - xilinx_init_rx_dev_fifo(card, chan, WP_NO_WAIT); - xilinx_init_tx_dev_fifo(card, chan, WP_NO_WAIT); - - aft_list_descriptors(chan); - } - - - - if (card->fe.fe_cfg.cfg.te3_cfg.fractional){ - card->hw_iface.bus_read_4(card->hw,TE3_FRACT_ENCAPSULATION_REG,®); - - DEBUG_EVENT("%s: Rx Fractional Frame Size = 0x%lX\n", - card->devname, - get_te3_rx_fract_frame_size(reg)); - - /* FIXME: Setup bitrate and tx frame size */ - } - - - /* Enable DMA controler, in order to start the - * fifo cleaning */ - reg=0; - reg|=(AFT_T3_DMA_FIFO_MARK << DMA_FIFO_T3_MARK_BIT_SHIFT); - reg|=(MAX_AFT_DMA_CHAINS-1)&DMA_CHAIN_TE3_MASK; - - wan_set_bit(DMA_RX_ENGINE_ENABLE_BIT,®); - wan_set_bit(DMA_TX_ENGINE_ENABLE_BIT,®); - card->hw_iface.bus_write_4(card->hw,XILINX_DMA_CONTROL_REG,reg); - - /* For all channels clean Tx/Rx fifos */ - WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ - private_area_t *chan; - - dev = WAN_DEVLE2DEV(devle); - if (!dev || !wan_netif_priv(dev)) - continue; - chan = wan_netif_priv(dev); - - if (!wan_test_bit(0,&chan->up)){ - continue; - } - - DEBUG_TEST("%s: 3) Init interface fifo %s\n", - card->devname,chan->if_name); - - xilinx_init_rx_dev_fifo(card, chan, WP_WAIT); - xilinx_init_tx_dev_fifo(card, chan, WP_WAIT); - - DEBUG_TEST("%s: Clearing Fifo and idle_flag %s\n", - card->devname,chan->if_name); - wan_clear_bit(0,&chan->idle_start); - } - - /* For all channels, reprogram Tx/Rx DMA descriptors. - * For Tx also make sure that the BUSY flag is clear - * and previoulsy Tx packet is deallocated */ - - WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ - private_area_t *chan; - - dev = WAN_DEVLE2DEV(devle); - if (!dev || !wan_netif_priv(dev)) - continue; - chan = wan_netif_priv(dev); - - if (!wan_test_bit(0,&chan->up)){ - continue; - } - - DEBUG_TEST("%s: 4) Init interface %s\n", - card->devname,chan->if_name); - - xilinx_dma_rx(card,chan,-1); - - aft_list_descriptors(chan); - - DEBUG_TEST("%s: Clearing Fifo and idle_flag %s\n", - card->devname,chan->if_name); - - } - - /* Clean Tx/Rx Error interrupts, since fifos are now - * empty, and Tx fifo may generate an underrun which - * we want to ignore :) */ - - card->hw_iface.bus_read_4(card->hw, - XILINX_HDLC_RX_INTR_PENDING_REG, ®); - card->hw_iface.bus_read_4(card->hw, - XILINX_HDLC_TX_INTR_PENDING_REG, ®); - - /* Enable Global DMA and Error Interrupts */ - reg=0; - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG,®); - wan_set_bit(GLOBAL_INTR_ENABLE_BIT,®); - wan_set_bit(ERROR_INTR_ENABLE_BIT,®); - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - - - card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,®); - - aft_enable_rx_watchdog(card,AFT_RX_TIMEOUT); - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); - - DEBUG_TEST("%s: END !!! Dma=0x%08X\n", - __FUNCTION__,reg); - -} - -static void disable_data_error_intr(sdla_t *card, unsigned char event) -{ - u32 reg; -#if 0 - private_area_t *chan; - - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG,®); - wan_clear_bit(GLOBAL_INTR_ENABLE_BIT,®); - wan_clear_bit(ERROR_INTR_ENABLE_BIT,®); - wan_clear_bit(FRONT_END_INTR_ENABLE_BIT,®); - wan_clear_bit(ENABLE_TE3_FRACTIONAL,®); - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - - aft_reset_rx_watchdog(card); - aft_reset_tx_watchdog(card); - - chan=(private_area_t*)card->u.xilinx.dev_to_ch_map[0]; - if (chan && wan_test_bit(0,&chan->up)){ - xilinx_dev_close(card,chan); - WAN_NETIF_STOP_QUEUE(chan->common.dev); - WAN_TASKLET_KILL(&chan->common.bh_task); - } - - xilinx_t3_exar_chip_unconfigure(card); - - WP_DELAY(10500); - - xilinx_t3_exar_chip_configure(card); - if (chan && wan_test_bit(0,&chan->up)){ - WP_DELAY(500); - xilinx_t3_exar_dev_configure(card,chan); - WP_DELAY(500); - xilinx_dev_enable(card, chan); - WAN_TASKLET_INIT((&chan->common.bh_task),0,wp_bh,(unsigned long)chan); - } -#endif - - - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG,®); - wan_clear_bit(GLOBAL_INTR_ENABLE_BIT,®); - wan_clear_bit(ERROR_INTR_ENABLE_BIT,®); - if (event==DEVICE_DOWN){ - wan_clear_bit(FRONT_END_INTR_ENABLE_BIT,®); - wan_clear_bit(ENABLE_TE3_FRACTIONAL,®); - } - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - - card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,®); - wan_clear_bit(DMA_RX_ENGINE_ENABLE_BIT,®); - wan_clear_bit(DMA_TX_ENGINE_ENABLE_BIT,®); - card->hw_iface.bus_write_4(card->hw,XILINX_DMA_CONTROL_REG,reg); - - aft_reset_rx_watchdog(card); - aft_reset_tx_watchdog(card); - - if (event==DEVICE_DOWN){ - wan_set_bit(CARD_DOWN,&card->wandev.critical); - } - - - DEBUG_TEST("%s: Event = %s\n",__FUNCTION__, - event==DEVICE_DOWN?"Device Down": "Link Down"); - -} - -static void xilinx_init_tx_dma_descr(sdla_t *card, private_area_t *chan) -{ - unsigned long dma_descr; - unsigned long reg=0; - - dma_descr=(chan->logic_ch_num<<4) + XILINX_TxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_write_4(card->hw,dma_descr, reg); -} - - - -/*============================================================================ - * Update communications error and general packet statistics. - */ -static int update_comms_stats(sdla_t* card) -{ - /* 1. On the first timer interrupt, update T1/E1 alarms - * and PMON counters (only for T1/E1 card) (TE1) - */ - - /* TE1 Update T1/E1 alarms */ - if (IS_TE3(&card->fe.fe_cfg)) { - WAN_FECALL(&card->wandev, read_alarm, (&card->fe, 0)); - /* TE1 Update T1/E1 perfomance counters */ - WAN_FECALL(&card->wandev, read_pmon, (&card->fe, 0)); - } - - return 0; -} - -static void xilinx_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) -{ - -#if 1 - u32 reg; - /* Enable DMA controler, in order to start the - * fifo cleaning */ - card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,®); - wan_clear_bit(DMA_TX_ENGINE_ENABLE_BIT,®); - card->hw_iface.bus_write_4(card->hw,XILINX_DMA_CONTROL_REG,reg); -#endif - -#if 0 - aft_list_tx_descriptors(chan); -#endif - aft_free_tx_descriptors(chan); - -#if 1 - xilinx_init_tx_dev_fifo(card,chan,WP_NO_WAIT); - - card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,®); - wan_set_bit(DMA_TX_ENGINE_ENABLE_BIT,®); - card->hw_iface.bus_write_4(card->hw,XILINX_DMA_CONTROL_REG,reg); - - xilinx_init_tx_dev_fifo(card,chan,WP_WAIT); -#endif - wan_clear_bit(0,&chan->idle_start); - - WAN_NETIF_WAKE_QUEUE(chan->common.dev); -#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC - if (chan->common.usedby == API){ - wan_wakeup_api(chan); - }else if (chan->common.usedby == STACK){ - wanpipe_lip_kick(chan,0); - } -#endif - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); -} - -static int xilinx_write_ctrl_hdlc(sdla_t *card, u32 timeslot, u8 reg_off, u32 data) -{ - /* M.F. for Exar T3 card direct access - * without analize current timeslot */ - - card->hw_iface.bus_write_4(card->hw,reg_off,data); - - return 0; -} - -static int set_chan_state(sdla_t* card, netdevice_t* dev, int state) -{ - private_area_t *chan = wan_netif_priv(dev); - if (!chan || !wan_test_bit(0,&chan->up)) { - return -ENODEV; - } - - chan->common.state = state; - if (state == WAN_CONNECTED){ - wan_clear_bit(0,&chan->idle_start); - WAN_NETIF_CARRIER_ON(dev); - WAN_NETIF_WAKE_QUEUE(dev); - chan->opstats.link_active_count++; - }else{ - WAN_NETIF_CARRIER_OFF(dev); - WAN_NETIF_STOP_QUEUE(dev); - chan->opstats.link_inactive_modem_count++; - } - -#if defined(__LINUX__) -# if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - if (chan->common.usedby == API){ - wan_update_api_state(chan); - } -#endif -#endif - - if (chan->common.usedby == STACK){ - if (state == WAN_CONNECTED){ - wanpipe_lip_connect(chan,0); - }else{ - wanpipe_lip_disconnect(chan,0); - } - } - return 0; -} - - -/**SECTION************************************************************* - * - * Protocol API Support Functions - * - **********************************************************************/ - - -static int protocol_init (sdla_t *card, netdevice_t *dev, - private_area_t *chan, - wanif_conf_t* conf) -{ - - chan->common.protocol = conf->protocol; - - DEBUG_TEST("%s: Protocol init 0x%X PPP=0x0%x FR=0x0%X\n", - wan_netif_name(dev), chan->common.protocol, - WANCONFIG_PPP, - WANCONFIG_FR); - -#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC - - DEBUG_EVENT("%s: AFT Driver doesn't directly support any protocols!\n", - chan->if_name); - return -1; - -#else - if (chan->common.protocol == WANCONFIG_PPP || - chan->common.protocol == WANCONFIG_CHDLC){ - - struct ifreq ifr; - struct if_settings ifsettings; - - wanpipe_generic_register(card, dev, wan_netif_name(dev)); - chan->common.prot_ptr = dev; - - if (chan->common.protocol == WANCONFIG_CHDLC){ - DEBUG_EVENT("%s: Starting Kernel CISCO HDLC protocol\n", - chan->if_name); - ifsettings.type = IF_PROTO_CISCO; - }else{ - DEBUG_EVENT("%s: Starting Kernel Sync PPP protocol\n", - chan->if_name); - ifsettings.type = IF_PROTO_PPP; - - } - ifr.ifr_data = (caddr_t)&ifsettings; - if (wp_lite_set_proto(dev, &ifr)){ - wanpipe_generic_unregister(dev); - return -EINVAL; - } - - }else if (chan->common.protocol == WANCONFIG_GENERIC){ - chan->common.prot_ptr = dev; - - }else{ - DEBUG_EVENT("%s:%s: Unsupported protocol %d\n", - card->devname,chan->if_name,chan->common.protocol); - return -EPROTONOSUPPORT; - } -#endif - - return 0; -} - - -static int protocol_start (sdla_t *card, netdevice_t *dev) -{ - int err=0; - - private_area_t *chan=wan_netif_priv(dev); - - if (!chan) - return 0; - - return err; -} - -static int protocol_stop (sdla_t *card, netdevice_t *dev) -{ - private_area_t *chan=wan_netif_priv(dev); - int err = 0; - - if (!chan) - return 0; - - return err; -} - -static int protocol_shutdown (sdla_t *card, netdevice_t *dev) -{ - private_area_t *chan=wan_netif_priv(dev); - - if (!chan) - return 0; - -#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC - - return 0; -#else - - if (chan->common.protocol == WANCONFIG_PPP || - chan->common.protocol == WANCONFIG_CHDLC){ - - chan->common.prot_ptr = NULL; - wanpipe_generic_unregister(dev); - - }else if (chan->common.protocol == WANCONFIG_GENERIC){ - DEBUG_EVENT("%s:%s Protocol shutdown... \n", - card->devname, chan->if_name); - } -#endif - return 0; -} - -void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb) -{ - -#ifdef CONFIG_PRODUCT_WANPIPE_GENERIC - if (chan->common.protocol == WANCONFIG_PPP || - chan->common.protocol == WANCONFIG_CHDLC){ - wanpipe_generic_input(chan->common.dev, skb); - return 0; - } -#endif - -#if defined(__LINUX__) && defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - if (chan->common.protocol == WANCONFIG_GENERIC){ - skb->protocol = htons(ETH_P_HDLC); - skb->dev = chan->common.dev; - wan_skb_reset_mac_header(skb); - netif_rx(skb); - return 0; - } -#endif - -#if defined(__LINUX__) - skb->protocol = htons(ETH_P_IP); - skb->dev = chan->common.dev; - wan_skb_reset_mac_header(skb); - netif_rx(skb); -#else - DEBUG_EVENT("%s: Action not supported (IP)!\n", - card->devname); - wan_skb_free(skb); -#endif - - return; -} - - -/**SECTION************************************************************* - * - * T3 Exar Config Code - * - **********************************************************************/ - - -/*========================================================= - * xilinx_t3_exar_chip_configure - * - */ - -static int xilinx_t3_exar_chip_configure(sdla_t *card) -{ - u32 reg,tmp; - volatile unsigned char cnt=0; - int err=0; - - DEBUG_CFG("T3 Exar Chip Configuration. -- \n"); - - xilinx_delay(1); - - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); - - /* Enable the chip/hdlc reset condition */ - reg=0; - wan_set_bit(CHIP_RESET_BIT,®); - wan_set_bit(FRONT_END_RESET_BIT,®); - - /* Hardcode the AFT T3/E3 clock source - * to External/Normal */ - if (card->fe.fe_cfg.cfg.te3_cfg.clock == WAN_MASTER_CLK){ - wan_set_bit(AFT_T3_CLOCK_MODE,®); - }else{ - wan_clear_bit(AFT_T3_CLOCK_MODE,®); - } - - DEBUG_CFG("--- T3 Exar Chip Reset. -- \n"); - - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - - WP_DELAY(100); - - /* Disable the chip/hdlc reset condition */ - wan_clear_bit(CHIP_RESET_BIT,®); - wan_clear_bit(FRONT_END_RESET_BIT,®); - - /* Disable ALL chip interrupts */ - wan_clear_bit(GLOBAL_INTR_ENABLE_BIT,®); - wan_clear_bit(ERROR_INTR_ENABLE_BIT,®); - wan_clear_bit(FRONT_END_INTR_ENABLE_BIT,®); - - /* Configure for T3 or E3 front end */ - - if (IS_DS3(&card->fe.fe_cfg)){ - card->u.xilinx.num_of_time_slots=NUM_OF_T1_CHANNELS; - wan_clear_bit(INTERFACE_TYPE_T3_E3_BIT,®); - if (card->fe.fe_cfg.frame == WAN_FR_DS3_Cbit){ - wan_set_bit(INTERFACE_MODE_DS3_C_BIT,®); - }else{ - wan_clear_bit(INTERFACE_MODE_DS3_C_BIT,®); - } - }else if (IS_E3(&card->fe.fe_cfg)){ - card->u.xilinx.num_of_time_slots=NUM_OF_E1_CHANNELS; - wan_set_bit(INTERFACE_TYPE_T3_E3_BIT,®); - if (card->fe.fe_cfg.frame == WAN_FR_E3_G832){ - wan_set_bit(INTERFACE_MODE_E3_G832,®); - }else{ - wan_clear_bit(INTERFACE_MODE_E3_G832,®); - } - }else{ - DEBUG_EVENT("%s: Error: T3 Exar doesn't support non T3/E3 interface!\n", - card->devname); - return -EINVAL; - } - - /* Hardcode the HDLC Conroller to - * HDLC mode. The transparent mode can be - * configured later in new_if() section - * - * HDLC =clear bit - * TRANSPARENT =set bit - * */ - wan_clear_bit(AFT_T3_HDLC_TRANS_MODE,®); - - - /* Enable/Disable TX and RX Fractional - * HDLC */ - - /* FIXME: HAVE A CONFIG OPTION HERE */ - - /* Enable Internal HDLC Encapsulation core */ - if (card->fe.fe_cfg.cfg.te3_cfg.fractional){ - DEBUG_EVENT("%s: BEFORE TE3 FRACT = 0x%X\n", - card->devname, reg); - - wan_set_bit(ENABLE_TE3_FRACTIONAL,®); - - //te3_enable_fractional(®, TE3_FRACT_VENDOR_KENTROX); - DEBUG_EVENT("%s: AFTER TE3 FRACT = 0x%X\n", - card->devname, reg); - }else{ - wan_clear_bit(ENABLE_TE3_FRACTIONAL,®); - } - - DEBUG_CFG("--- T3 Exar Chip enable/config. -- \n"); - - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - - WP_DELAY(100); - - xilinx_delay(1); -#if 0 - framer_reset(card); /* was for A105 proto */ -#endif /* M.F. remove for A300 */ - -#if 0 - write_cpld(card,0x00, 0x00); /* M.F. was 0x01 for A105 proto */ - /* M.F. 0x00 for A300 */ - /* set DS3 interface mode */ - write_cpld(card,0x01, 0x00); /* clear TxAIS bit */ - - // 3. Setup Framer - write_framer(card,0x00, 0x6F); /* DS3 - mode (bit 6)*/ - /* Internal LOS enable (bit 5)*/ - /* Interrupt enabl.reset(bit 3)*/ - /* Frame format M13 (bit 2)*/ - /* TimRef - Mode 3 (code '1X')*/ - write_framer(card,0x01, 0xA2); /* */ -#else - -//FIXME: Alex to put in Exar T3/E3 Configuration - DEBUG_EVENT("%s: Config %s Front End: Clock=%s Type=0x%X\n", - card->devname, - FE_MEDIA_DECODE(&card->fe), - (card->fe.fe_cfg.cfg.te3_cfg.clock == WAN_MASTER_CLK)? - "Master":"Normal", - card->adptr_subtype); - - if (card->wandev.fe_iface.config){ - err = card->wandev.fe_iface.config(&card->fe); - if (err){ - DEBUG_EVENT("%s: Failed %s configuratoin!\n", - card->devname, - FE_MEDIA_DECODE(&card->fe)); - return -EINVAL; - } - }else{ - DEBUG_EVENT("%s: Internal Error (%s:%d)\n", - card->devname, - __FUNCTION__,__LINE__); - return -EINVAL; - } -#endif - for (;;){ - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); - - if (!wan_test_bit(HDLC_CORE_READY_FLAG_BIT,®)){ - /* The HDLC Core is not ready! we have - * an error. */ - if (++cnt > 5){ - err = -EINVAL; - break; - }else{ - WP_DELAY(500); - /* FIXME: we cannot do this while in - * critical area */ - } - }else{ - err=0; - break; - } - } - - xilinx_delay(1); - - if (err != 0){ - DEBUG_EVENT("%s: Error: HDLC Core Not Ready!\n", - card->devname); - - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); - - /* Disable the chip/hdlc reset condition */ - wan_set_bit(CHIP_RESET_BIT,®); - - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - return err; - } else{ - DEBUG_CFG("%s: HDLC Core Ready 0x%08X\n", - card->devname,reg); - } - - xilinx_delay(1); - - /* Setup global DMA parameters */ - reg=0; - reg|=(AFT_T3_DMA_FIFO_MARK << DMA_FIFO_T3_MARK_BIT_SHIFT); - reg|=(MAX_AFT_DMA_CHAINS-1)&DMA_CHAIN_TE3_MASK; - - /* Enable global DMA engine and set to default - * number of active channels. Note: this value will - * change in dev configuration */ - wan_set_bit(DMA_RX_ENGINE_ENABLE_BIT,®); - wan_set_bit(DMA_TX_ENGINE_ENABLE_BIT,®); - - DEBUG_CFG("--- Setup DMA control Reg. -- \n"); - - card->hw_iface.bus_write_4(card->hw,XILINX_DMA_CONTROL_REG,reg); - DEBUG_CFG("--- Tx/Rx global enable. -- \n"); - - xilinx_delay(1); - - reg=0; - card->hw_iface.bus_write_4(card->hw,XILINX_TIMESLOT_HDLC_CHAN_REG,reg); - - /* Clear interrupt pending registers befor first interrupt enable */ - card->hw_iface.bus_read_4(card->hw, XILINX_DMA_RX_INTR_PENDING_REG, &tmp); - card->hw_iface.bus_read_4(card->hw, XILINX_DMA_TX_INTR_PENDING_REG, &tmp); - card->hw_iface.bus_read_4(card->hw, XILINX_HDLC_RX_INTR_PENDING_REG, &tmp); - card->hw_iface.bus_read_4(card->hw, XILINX_HDLC_TX_INTR_PENDING_REG, &tmp); - - card->hw_iface.bus_read_4(card->hw, XILINX_CHIP_CFG_REG, (u32*)®); - - if (wan_test_bit(DMA_INTR_FLAG,®)){ - DEBUG_EVENT("%s: Error: Active DMA Interrupt Pending. !\n", - card->devname); - - reg = 0; - /* Disable the chip/hdlc reset condition */ - wan_set_bit(CHIP_RESET_BIT,®); - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - return err; - } - if (wan_test_bit(ERROR_INTR_FLAG,®)){ - DEBUG_EVENT("%s: Error: Active Error Interrupt Pending. !\n", - card->devname); - - reg = 0; - /* Disable the chip/hdlc reset condition */ - wan_set_bit(CHIP_RESET_BIT,®); - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - return err; - } - - - /* Alawys disable global data and error - * interrupts */ - wan_clear_bit(GLOBAL_INTR_ENABLE_BIT,®); - wan_clear_bit(ERROR_INTR_ENABLE_BIT,®); - -#ifndef AFT_XTEST_DEBUG - /* Always enable the front end interrupt */ - wan_set_bit(FRONT_END_INTR_ENABLE_BIT,®); -#endif - DEBUG_CFG("--- Set Global Interrupts (0x%X)-- \n",reg); - - xilinx_delay(1); - - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - - DEBUG_CFG("--- Set Global Interrupt enabled. -- \n"); - - return err; -} - -static int xilinx_t3_exar_dev_configure(sdla_t *card, private_area_t *chan) -{ - - u32 reg,reg1; - - DEBUG_TEST("-- T3 Exar Dev Configure Xilinx. --\n"); - - - chan->logic_ch_num=0; - chan->first_time_slot=0; - card->u.xilinx.logic_ch_map=0x01; - - if (!card->u.xilinx.dev_to_ch_map[0]){ - card->u.xilinx.dev_to_ch_map[0]=(void*)chan; - } - - reg=0; - - if (chan->hdlc_eng){ - /* HDLC engine is enabled on the above logical channels */ - wan_clear_bit(HDLC_RX_PROT_DISABLE_BIT,®); - wan_clear_bit(HDLC_TX_PROT_DISABLE_BIT,®); - - wan_set_bit(HDLC_TX_CHAN_ENABLE_BIT,®); - - if (card->fe.fe_cfg.cfg.te3_cfg.fractional){ - DEBUG_EVENT("%s: Configuring for Fractional\n",card->devname); - wan_set_bit(HDLC_RX_ADDR_FIELD_DISC_BIT,®); - wan_set_bit(HDLC_TX_ADDR_INSERTION_BIT,®); - }else{ - wan_set_bit(HDLC_RX_ADDR_RECOGN_DIS_BIT,®); - } - - if (card->fe.fe_cfg.cfg.te3_cfg.fcs == 32){ - wan_set_bit(HDLC_TX_FCS_SIZE_BIT,®); - wan_set_bit(HDLC_RX_FCS_SIZE_BIT,®); - } - - DEBUG_EVENT("%s:%s: Config for HDLC mode: FCS=%d\n", - card->devname,chan->if_name, - card->fe.fe_cfg.cfg.te3_cfg.fcs); - }else{ - - /* Transprent Mode */ - - /* Do not start HDLC Core here, because - * we have to setup Tx/Rx DMA buffers first - * The transparent mode, will start - * comms as soon as the HDLC is enabled */ - - } - - /* Select an HDLC Tx channel for configuration */ - reg1=0; - card->hw_iface.bus_write_4(card->hw, AFT_T3_RXTX_ADDR_SELECT_REG, reg1); - - if (card->fe.fe_cfg.cfg.te3_cfg.fractional){ - xilinx_write_ctrl_hdlc(card, - chan->first_time_slot, - XILINX_HDLC_ADDR_REG, - 0xA5A5A5A5); - } - - xilinx_write_ctrl_hdlc(card, - chan->first_time_slot, - XILINX_HDLC_CONTROL_REG, - reg); - - - /* Select an HDLC Rx channel for configuration */ - reg1=1; - card->hw_iface.bus_write_4(card->hw, AFT_T3_RXTX_ADDR_SELECT_REG, reg1); - - if (card->fe.fe_cfg.cfg.te3_cfg.fractional){ - - xilinx_write_ctrl_hdlc(card, - chan->first_time_slot, - XILINX_HDLC_ADDR_REG, - 0xA5A5A5A5); - } - - xilinx_write_ctrl_hdlc(card, - chan->first_time_slot, - XILINX_HDLC_CONTROL_REG, - reg); - - return 0; - -} - -static void xilinx_t3_exar_dev_unconfigure(sdla_t *card, private_area_t *chan) -{ - /* Nothing to do for T3 Exar */ - wan_smp_flag_t flags; - - wan_spin_lock_irq(&card->wandev.lock,&flags); - card->u.xilinx.dev_to_ch_map[0]=NULL; - aft_reset_rx_watchdog(card); - aft_reset_tx_watchdog(card); - wan_spin_unlock_irq(&card->wandev.lock,&flags); - -} - -static void xilinx_t3_exar_chip_unconfigure(sdla_t *card) -{ - - u32 reg=0; - - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); - - /* Enable the chip/hdlc reset condition */ - wan_set_bit(CHIP_RESET_BIT,®); - wan_set_bit(FRONT_END_RESET_BIT,®); - - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); - -} - - -static void xilinx_t3_exar_transparent_config(sdla_t *card,private_area_t *chan) -{ - u32 reg; - - DEBUG_EVENT("%s: Configuring for Transparent mode!\n", - card->devname); - - /* T3/E3 Exar Card */ - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); - /* Enable hdlc transparent mode */ - wan_set_bit(AFT_T3_HDLC_TRANS_MODE,®); - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); -} - - -#define BIT_DEV_ADDR_CLEAR 0x600 - -static int write_framer(void *pcard, unsigned short framer_off,unsigned short framer_data) -{ - sdla_t *card = (sdla_t*)pcard; - - framer_off &= ~BIT_DEV_ADDR_CLEAR; - - DEBUG_TEST("WRITE FRAMER OFFSET=0x%02X DATA=0x%02X\n", - framer_off,framer_data); - - card->hw_iface.bus_write_2(card->hw, - 0x46, - framer_off); - WP_DELAY(5); - - card->hw_iface.bus_write_2(card->hw, - 0x44, - framer_data); - WP_DELAY(5); - return 0; -} - -static unsigned int read_framer(void *pcard,unsigned short framer_off) -{ - sdla_t *card = (sdla_t*)pcard; - unsigned int framer_data; - - framer_off &= ~BIT_DEV_ADDR_CLEAR; - - - card->hw_iface.bus_write_2(card->hw, - 0x46, - framer_off); - WP_DELAY(5); - - card->hw_iface.bus_read_4(card->hw, - 0x44, - &framer_data); - WP_DELAY(5); - - DEBUG_TEST("READ FRAMER OFFSET=0x%02X DATA=0x%02X\n", - framer_off,framer_data); - - return framer_data; -} - -#if 0 -static void framer_reset(sdla_t *card) -{ - int i = 0; - unsigned short j = 0; - - j = (unsigned short)read_cpld(card,0x00); - j = j & 0x00FE; - write_cpld(card,0x00, j); - // delay - for(i=0;i<10;i++); - j = j | 0x0001; - write_cpld(card,0x00, j); -} -#endif - -/**SECTION************************************************************* - * - * TE3 Exar Tx Functions - * DMA Chains - * - **********************************************************************/ - - -/*=============================================== - * aft_tx_dma_chain_handler - * - */ -static void aft_tx_dma_chain_handler(unsigned long data) -{ - private_area_t *chan = (private_area_t *)data; - sdla_t *card = chan->card; - int dma_free=0; - u32 reg,dma_descr; - aft_dma_chain_t *dma_chain; - - if (wan_test_and_set_bit(TX_HANDLER_BUSY,&chan->dma_status)){ - DEBUG_EVENT("%s: SMP Critical in %s\n", - chan->if_name,__FUNCTION__); - return; - } - - dma_chain = &chan->tx_dma_chain_table[chan->tx_pending_chain_indx]; - - for (;;){ - - /* If the current DMA chain is in use,then - * all chains are busy */ - if (!wan_test_bit(0,&dma_chain->init)){ - break; - } - - dma_descr=(chan->tx_pending_chain_indx<<4) + XILINX_TxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_read_4(card->hw,dma_descr,®); - - /* If GO bit is set, then the current DMA chain - * is in process of being transmitted, thus - * all are busy */ - if (wan_test_bit(TxDMA_HI_DMA_GO_READY_BIT,®)){ - break; - } - - DEBUG_TEST("%s: TX DMA Handler Chain %i\n",chan->if_name,dma_chain->index); - - if (dma_chain->skb){ -//NENAD -#if 1 - wan_skb_set_csum(dma_chain->skb, reg); - wan_skb_queue_tail(&chan->wp_tx_complete_list,dma_chain->skb); - dma_chain->skb=NULL; -#else - chan->if_stats.tx_packets++; - chan->if_stats.tx_bytes+=wan_skb_len(dma_chain->skb); -#endif - } - - aft_tx_dma_chain_init(chan,dma_chain); - - if (chan->single_dma_chain){ - break; - } - - if (++chan->tx_pending_chain_indx >= MAX_AFT_DMA_CHAINS){ - chan->tx_pending_chain_indx=0; - } - - dma_chain = &chan->tx_dma_chain_table[chan->tx_pending_chain_indx]; - dma_free=1; - } - - wan_clear_bit(TX_HANDLER_BUSY,&chan->dma_status); - - if (wan_skb_queue_len(&chan->wp_tx_complete_list)){ - WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); - } - - return; -} - -/*=============================================== - * aft_dma_chain_tx - * - */ -static int aft_dma_chain_tx(aft_dma_chain_t *dma_chain,private_area_t *chan, int intr) -{ - -#define dma_descr dma_chain->dma_descr -#define reg dma_chain->reg -#define len dma_chain->dma_len -#define dma_ch_indx dma_chain->index -#define len_align dma_chain->len_align -#define card chan->card - - dma_descr=(dma_ch_indx<<4) + XILINX_TxDMA_DESCRIPTOR_HI; - - DEBUG_TX("%s:%d: chan logic ch=%i chain=%li dma_descr=0x%x set!\n", - __FUNCTION__,__LINE__,chan->logic_ch_num,dma_ch_indx,dma_descr); - - card->hw_iface.bus_read_4(card->hw,dma_descr,®); - - if (wan_test_bit(TxDMA_HI_DMA_GO_READY_BIT,®)){ - DEBUG_EVENT("%s: Error: TxDMA GO Ready bit set on dma (chain=%i) Tx 0x%X\n", - card->devname,dma_ch_indx,reg); - card->hw_iface.bus_write_4(card->hw,dma_descr,0); - return -EBUSY; - } - - dma_descr=(dma_ch_indx<<4) + XILINX_TxDMA_DESCRIPTOR_LO; - - /* Write the pointer of the data packet to the - * DMA address register */ - reg=dma_chain->dma_addr; - - /* Set the 32bit alignment of the data length. - * Used to pad the tx packet to the 32 bit - * boundary */ - reg&=~(TxDMA_LO_ALIGNMENT_BIT_MASK); - reg|=(len&0x03); - - len_align=0; - if (len&0x03){ - len_align=1; - } - - DEBUG_TX("%s: TXDMA_LO=0x%X PhyAddr=0x%X DmaDescr=0x%X\n", - __FUNCTION__,reg,dma_chain->dma_addr,dma_descr); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - - dma_descr=(dma_ch_indx<<4) + XILINX_TxDMA_DESCRIPTOR_HI; - - reg=0; - - reg|=(((len>>2)+len_align)&TxDMA_HI_DMA_DATA_LENGTH_MASK); - - reg|=(chan->fifo_size_code&DMA_FIFO_SIZE_MASK)<fifo_base_addr&DMA_FIFO_BASE_ADDR_MASK)<< - DMA_FIFO_BASE_ADDR_SHIFT; - - - if (chan->single_dma_chain){ - wan_clear_bit(DMA_HI_TE3_NOT_LAST_FRAME_BIT,®); - wan_clear_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); - }else{ - - wan_set_bit(DMA_HI_TE3_NOT_LAST_FRAME_BIT,®); - - if (intr){ - DEBUG_TEST("%s: Setting Interrupt on index=%i\n", - chan->if_name,dma_ch_indx); - wan_clear_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); - }else{ - wan_set_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); - } - } - - if (chan->hdlc_eng){ - /* Only enable the Frame Start/Stop on - * non-transparent hdlc configuration */ - - wan_set_bit(TxDMA_HI_DMA_FRAME_START_BIT,®); - wan_set_bit(TxDMA_HI_DMA_FRAME_END_BIT,®); - } - - wan_set_bit(TxDMA_HI_DMA_GO_READY_BIT,®); - - DEBUG_TX("%s: TXDMA_HI=0x%X DmaDescr=0x%lX len=%i\n", - __FUNCTION__,reg,dma_chain->dma_addr,len); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - -#if 0 - ++chan->if_stats.tx_fifo_errors; -#endif - - return 0; - -#undef dma_descr -#undef reg -#undef len -#undef dma_ch_indx -#undef len_align -#undef card -} - -/*=============================================== - * aft_dma_chain_init - * - */ -static void aft_tx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_chain) -{ - - if (dma_chain->dma_addr){ - chan->card->hw_iface.pci_unmap_dma(chan->card->hw, - dma_chain->dma_addr, - dma_chain->dma_len, - PCI_DMA_TODEVICE); - } - - - if (dma_chain->skb){ - wan_skb_free(dma_chain->skb); - dma_chain->skb=NULL; - } - - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - - wan_clear_bit(0,&dma_chain->init); -} - -static void aft_rx_dma_chain_init(private_area_t *chan, aft_dma_chain_t *dma_chain) -{ - - if (dma_chain->dma_addr){ - chan->card->hw_iface.pci_unmap_dma(chan->card->hw, - dma_chain->dma_addr, - dma_chain->dma_len, - PCI_DMA_FROMDEVICE); - } - - - if (dma_chain->skb){ - aft_init_requeue_free_skb(chan,dma_chain->skb); - dma_chain->skb=NULL; - } - - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - - wan_clear_bit(0,&dma_chain->init); -} - -static int aft_realign_skb_pkt(private_area_t *chan, netskb_t *skb) -{ - unsigned char *data=wan_skb_data(skb); - int len = wan_skb_len(skb); - - if (len > chan->dma_mtu){ - DEBUG_EVENT("%s: Critical error: Tx unalign pkt(%d) > MTU buf(%d)!\n", - chan->if_name,len,chan->dma_mtu); - return -ENOMEM; - } - - if (!chan->tx_realign_buf){ - chan->tx_realign_buf=wan_malloc(chan->dma_mtu); - if (!chan->tx_realign_buf){ - DEBUG_EVENT("%s: Error: Failed to allocate tx memory buf\n", - chan->if_name); - return -ENOMEM; - }else{ - DEBUG_EVENT("%s: AFT Realign buffer allocated Len=%d\n", - chan->if_name,chan->dma_mtu); - - } - } - - memcpy(chan->tx_realign_buf,data,len); - - wan_skb_init(skb,0); - wan_skb_trim(skb,0); - - if (wan_skb_tailroom(skb) < len){ - DEBUG_EVENT("%s: Critical error: Tx unalign pkt tail room(%i) < unalign len(%i)!\n", - chan->if_name,wan_skb_tailroom(skb),len); - - return -ENOMEM; - } - - data=wan_skb_put(skb,len); - - if ((unsigned long)data & 0x03){ - /* At this point pkt should be realigned. If not - * there is something really wrong! */ - return -EINVAL; - } - - memcpy(data,chan->tx_realign_buf,len); - - return 0; -} - - - -/*=============================================== - * xilinx_dma_te3_tx - * - */ -static int xilinx_dma_te3_tx (sdla_t *card,private_area_t *chan, netskb_t *skb) -{ - int err=0, intr=0; - aft_dma_chain_t *dma_chain; - - if (wan_test_and_set_bit(TX_DMA_BUSY,&chan->dma_status)){ - DEBUG_EVENT("%s: SMP Critical in %s\n", - chan->if_name,__FUNCTION__); - - return -EBUSY; - } - - if (chan->tx_chain_indx >= MAX_AFT_DMA_CHAINS){ - DEBUG_EVENT("%s: MAJOR ERROR: TE3 Tx: Dma tx chain = %i\n", - chan->if_name,chan->tx_chain_indx); - if (!chan->single_dma_chain){ - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); - } - return -EBUSY; - } - - dma_chain = &chan->tx_dma_chain_table[chan->tx_chain_indx]; - - aft_reset_tx_watchdog(card); - - /* If the current DMA chain is in use,then - * all chains are busy */ - if (wan_test_and_set_bit(0,&dma_chain->init)){ - wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); - return -EBUSY; - } - - if ((unsigned long)wan_skb_data(skb) & 0x03){ - err=aft_realign_skb_pkt(chan,skb); - if (err){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: Tx Error: Non Aligned packet %p: dropping...\n", - chan->if_name,wan_skb_data(skb)); - } - wan_skb_free(skb); - wan_clear_bit(0,&dma_chain->init); - chan->if_stats.tx_errors++; - return -EINVAL; - } - } - - dma_chain->skb=skb; - - dma_chain->dma_addr = - card->hw_iface.pci_map_dma(card->hw, - wan_skb_data(dma_chain->skb), - wan_skb_len(dma_chain->skb), - PCI_DMA_TODEVICE); - - dma_chain->dma_len = wan_skb_len(dma_chain->skb); - - - DEBUG_TX("%s: DMA Chain %i: Cur=%i Pend=%i Len=%i\n", - chan->if_name,dma_chain->index, - chan->tx_chain_indx,chan->tx_pending_chain_indx, - wan_skb_len(dma_chain->skb)); - - intr=0; - if (!chan->single_dma_chain && - !wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status)){ - int pending_indx=chan->tx_pending_chain_indx; - if (chan->tx_chain_indx >= pending_indx){ - intr = ((MAX_AFT_DMA_CHAINS-(chan->tx_chain_indx - - pending_indx))<=2); - }else{ - intr = ((pending_indx - chan->tx_chain_indx)<=2); - } - - if (intr){ - DEBUG_TEST("%s: Setting tx interrupt on chain=%i\n", - chan->if_name,dma_chain->index); - wan_set_bit(TX_INTR_PENDING,&chan->dma_chain_status); - } - } - - err=aft_dma_chain_tx(dma_chain,chan,intr); - if (err){ - DEBUG_EVENT("%s: Tx dma chain %i overrun error: should never happen!\n", - chan->if_name,dma_chain->index); - aft_tx_dma_chain_init(chan,dma_chain); - chan->if_stats.tx_errors++; - - wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); - return -EINVAL; - } - - - /* We are sure that the packet will - * be bound and transmitted, thus unhook - * it from the protocol stack */ - wan_skb_unlink(skb); - - if (!chan->single_dma_chain){ - if (++chan->tx_chain_indx >= MAX_AFT_DMA_CHAINS){ - chan->tx_chain_indx=0; - } - - if (!wan_test_bit(TX_INTR_PENDING,&chan->dma_chain_status)){ - aft_enable_tx_watchdog(card,AFT_TX_TIMEOUT); - } - } - - wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); - - return 0; -} - - - -/**SECTION************************************************************* - * - * TE3 Exar Rx Functions - * DMA Chains - * - **********************************************************************/ - -static int aft_dma_chain_rx(aft_dma_chain_t *dma_chain, private_area_t *chan, int intr) -{ -#define dma_descr dma_chain->dma_descr -#define reg dma_chain->reg -#define len dma_chain->dma_len -#define dma_ch_indx dma_chain->index -#define len_align dma_chain->len_align -#define card chan->card - - /* Write the pointer of the data packet to the - * DMA address register */ - reg=dma_chain->dma_addr; - - /* Set the 32bit alignment of the data length. - * Since we are setting up for rx, set this value - * to Zero */ - reg&=~(RxDMA_LO_ALIGNMENT_BIT_MASK); - - dma_descr=(dma_ch_indx<<4) + XILINX_RxDMA_DESCRIPTOR_LO; - -// DEBUG_RX("%s: RxDMA_LO = 0x%X, BusAddr=0x%X DmaDescr=0x%X\n", -// __FUNCTION__,reg,bus_addr,dma_descr); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - - dma_descr=(unsigned long)(dma_ch_indx<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - - reg =0; - - if (chan->single_dma_chain){ - wan_clear_bit(DMA_HI_TE3_NOT_LAST_FRAME_BIT,®); - wan_clear_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); - }else{ - - wan_set_bit(DMA_HI_TE3_NOT_LAST_FRAME_BIT,®); - - if (intr){ - DEBUG_TEST("%s: Setting Rx Interrupt on index=%i\n", - chan->if_name,dma_ch_indx); - wan_clear_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); - }else{ - wan_set_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); - } - - } - - if (chan->hdlc_eng){ - reg|=((chan->dma_mtu>>2)-1)&RxDMA_HI_DMA_DATA_LENGTH_MASK; - }else{ - reg|=(card->wandev.mtu>>2)&RxDMA_HI_DMA_DATA_LENGTH_MASK; - } - - reg|=(chan->fifo_size_code&DMA_FIFO_SIZE_MASK)<fifo_base_addr&DMA_FIFO_BASE_ADDR_MASK)<< - DMA_FIFO_BASE_ADDR_SHIFT; - - wan_set_bit(RxDMA_HI_DMA_GO_READY_BIT,®); - - DEBUG_RX("%s: RXDMA_HI = 0x%X, BusAddr=0x%X DmaDescr=0x%X\n", - __FUNCTION__,reg,dma_chain->dma_addr,dma_descr); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - - return 0; - -#undef dma_descr -#undef reg -#undef len -#undef dma_ch_indx -#undef len_align -#undef card -} - -static int xilinx_dma_rx(sdla_t *card, private_area_t *chan, int gcur_ptr) -{ - int err=0, intr=0; - aft_dma_chain_t *dma_chain; - int cur_dma_ptr, i,max_dma_cnt,free_queue_len; - u32 reg; - - if (wan_test_and_set_bit(RX_DMA_BUSY,&chan->dma_status)){ - DEBUG_EVENT("%s: SMP Critical in %s\n", - chan->if_name,__FUNCTION__); - return -EBUSY; - } - - aft_reset_rx_watchdog(card); - - if (chan->single_dma_chain) { - max_dma_cnt=MAX_AFT_DMA_CHAINS; - cur_dma_ptr=0; - free_queue_len=MAX_AFT_DMA_CHAINS; - }else{ - - free_queue_len=wan_skb_queue_len(&chan->wp_rx_free_list); - if (free_queue_len == 0){ - aft_free_rx_complete_list(chan); - free_queue_len=wan_skb_queue_len(&chan->wp_rx_free_list); - if (free_queue_len == 0){ - DEBUG_EVENT("%s: %s() CRITICAL ERROR: No free rx buffers\n", - card->devname,__FUNCTION__); - goto te3_rx_skip; - } - } - - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - cur_dma_ptr=get_current_rx_dma_ptr(reg); - - if (chan->rx_chain_indx >= cur_dma_ptr){ - max_dma_cnt = MAX_AFT_DMA_CHAINS - (chan->rx_chain_indx-cur_dma_ptr); - }else{ - max_dma_cnt = cur_dma_ptr - chan->rx_chain_indx; - } - - if (free_queue_len < max_dma_cnt){ - #if 0 - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: Free List(%d) lower than max dma %d\n", - card->devname, - free_queue_len, - max_dma_cnt); - } - #endif - max_dma_cnt = free_queue_len; - } - - } - - DEBUG_TEST("%s: DMA RX: CBoardPtr=%i Driver=%i MaxDMA=%i\n", - card->devname,cur_dma_ptr,chan->rx_chain_indx,max_dma_cnt); - - for (i=0;irx_dma_chain_table[chan->rx_chain_indx]; - - /* If the current DMA chain is in use,then - * all chains are busy */ - if (wan_test_and_set_bit(0,&dma_chain->init)){ - DEBUG_TEST("%s: Warning: %s():%d dma chain busy %i!\n", - card->devname, __FUNCTION__, __LINE__, - dma_chain->index); - - err=-EBUSY; - break; - } - - dma_chain->skb=wan_skb_dequeue(&chan->wp_rx_free_list); - if (!dma_chain->skb){ - DEBUG_TEST("%s: Warning Rx chain = %i: no free rx bufs (RxComp=%i RxFree=%i)\n", - chan->if_name,dma_chain->index, - wan_skb_queue_len(&chan->wp_rx_complete_list), - wan_skb_queue_len(&chan->wp_rx_free_list)); - wan_clear_bit(0,&dma_chain->init); - err=-EINVAL; - break; - } - - dma_chain->dma_addr = - card->hw_iface.pci_map_dma(card->hw, - wan_skb_tail(dma_chain->skb), - chan->dma_mtu, - PCI_DMA_FROMDEVICE); - - dma_chain->dma_len = chan->dma_mtu; - - intr=0; - if (!wan_test_bit(RX_INTR_PENDING,&chan->dma_chain_status)){ - - free_queue_len--; - - if (free_queue_len <= 2){ - DEBUG_TEST("%s: DBG: Setting intr queue size low\n", - card->devname); - intr=1; - }else{ - if (chan->rx_chain_indx >= cur_dma_ptr){ - intr = ((MAX_AFT_DMA_CHAINS - - (chan->rx_chain_indx-cur_dma_ptr)) <=4); - }else{ - intr = ((cur_dma_ptr - chan->rx_chain_indx)<=4); - } - } - - if (intr){ - DEBUG_TEST("%s: Setting Rx interrupt on chain=%i\n", - chan->if_name,dma_chain->index); - wan_set_bit(RX_INTR_PENDING,&chan->dma_chain_status); - } - } - - DEBUG_TEST("%s: Setting Buffer on Rx Chain = %i Intr=%i\n", - chan->if_name,dma_chain->index, intr); - - err=aft_dma_chain_rx(dma_chain,chan,intr); - if (err){ - DEBUG_EVENT("%s: Rx dma chain %i overrun error: should never happen!\n", - chan->if_name,dma_chain->index); - aft_rx_dma_chain_init(chan,dma_chain); - chan->if_stats.rx_dropped++; - break; - } - - if (chan->single_dma_chain){ - break; - } - - if (++chan->rx_chain_indx >= MAX_AFT_DMA_CHAINS){ - chan->rx_chain_indx=0; - } - } - -te3_rx_skip: - - if (!chan->single_dma_chain){ - aft_enable_rx_watchdog(card,AFT_RX_TIMEOUT); - } - - wan_clear_bit(RX_DMA_BUSY,&chan->dma_status); - - return err; -} - -/*=============================================== - * aft_rx_dma_chain_handler - * - */ -//N1 -static void aft_rx_dma_chain_handler(private_area_t *chan, int wtd, int reset) -{ - sdla_t *card = chan->card; - u32 reg,dma_descr; - wp_rx_element_t *rx_el; - aft_dma_chain_t *dma_chain; - int i,max_dma_cnt, cur_dma_ptr; - - if (wan_test_and_set_bit(RX_HANDLER_BUSY,&chan->dma_status)){ - DEBUG_EVENT("%s: SMP Critical in %s\n", - chan->if_name,__FUNCTION__); - return; - } - - if (!wtd){ - /* Not watchdog, thus called from an interrupt. - * Clear the RX INTR Pending flag */ - wan_clear_bit(RX_INTR_PENDING,&chan->dma_chain_status); - } - - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - cur_dma_ptr=get_current_rx_dma_ptr(reg); - - max_dma_cnt = MAX_AFT_DMA_CHAINS; - - DEBUG_TEST("%s: DMA RX %s: CBoardPtr=%i Driver=%i MaxDMA=%i\n", - card->devname, - wtd?"WTD":"Intr", - cur_dma_ptr, - chan->rx_chain_indx,max_dma_cnt); - - for (i=0;irx_dma_chain_table[chan->rx_pending_chain_indx]; - if (!dma_chain){ - DEBUG_EVENT("%s:%d Assertion Error !!!!\n", - __FUNCTION__,__LINE__); - break; - } - - /* If the current DMA chain is in use,then - * all chains are busy */ - if (!wan_test_bit(0,&dma_chain->init)){ - DEBUG_TEST("%s: Warning (%s) Pending chain %i empty!\n", - chan->if_name,__FUNCTION__,dma_chain->index); - - break; - } - - dma_descr=(dma_chain->index<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_read_4(card->hw,dma_descr,®); - - /* If GO bit is set, then the current DMA chain - * is in process of being transmitted, thus - * all are busy */ - if (wan_test_bit(RxDMA_HI_DMA_GO_READY_BIT,®)){ - DEBUG_TEST("%s: Warning (%s) Pending chain %i Go bit still set!\n", - chan->if_name,__FUNCTION__,dma_chain->index); - break; - } - - card->hw_iface.pci_unmap_dma(card->hw, - dma_chain->dma_addr, - chan->dma_mtu, - PCI_DMA_FROMDEVICE); - - rx_el=(wp_rx_element_t *)wan_skb_push(dma_chain->skb, sizeof(wp_rx_element_t)); - memset(rx_el,0,sizeof(wp_rx_element_t)); - -#if 0 - chan->if_stats.rx_frame_errors++; -#endif - - /* Reading Rx DMA descriptor information */ - dma_descr=(dma_chain->index<<4) + XILINX_RxDMA_DESCRIPTOR_LO; - card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->align); - rx_el->align&=RxDMA_LO_ALIGNMENT_BIT_MASK; - - dma_descr=(dma_chain->index<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_read_4(card->hw,dma_descr, &rx_el->reg); - - rx_el->pkt_error= dma_chain->pkt_error; - rx_el->dma_addr = dma_chain->dma_addr; - - wan_skb_queue_tail(&chan->wp_rx_complete_list,dma_chain->skb); - - DEBUG_RX("%s: RxInr Pending chain %i Rxlist=%i LO:0x%X HI:0x%X Data=0x%X Len=%i!\n", - chan->if_name,dma_chain->index, - wan_skb_queue_len(&chan->wp_rx_complete_list), - rx_el->align,rx_el->reg, - (*(unsigned char*)wan_skb_data(dma_chain->skb)), - wan_skb_len(dma_chain->skb)); - - dma_chain->skb=NULL; - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - dma_chain->pkt_error=0; - wan_clear_bit(0,&dma_chain->init); - - - if (chan->single_dma_chain){ - break; - } - - if (++chan->rx_pending_chain_indx >= MAX_AFT_DMA_CHAINS){ - chan->rx_pending_chain_indx=0; - } - - } - - if (reset){ - goto reset_skip_rx_setup; - } - - xilinx_dma_rx(card,chan,cur_dma_ptr); - - if (wan_skb_queue_len(&chan->wp_rx_complete_list)){ - DEBUG_TEST("%s: Rx Queued list triggering\n",chan->if_name); - WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); - chan->rx_no_data_cnt=0; - }else{ - if (!chan->single_dma_chain){ - if ((chan->rx_no_data_cnt >= 0) && (++chan->rx_no_data_cnt < 3)){ - aft_enable_rx_watchdog(card,AFT_RX_TIMEOUT); - }else{ - /* Enable Rx Interrupt on pending rx descriptor */ - DEBUG_TEST("%s: Setting Max Rx Watchdog Timeout\n", - chan->if_name); - aft_enable_rx_watchdog(card,AFT_MAX_WTD_TIMEOUT); - chan->rx_no_data_cnt=-1; - } - } - } - -reset_skip_rx_setup: - - wan_clear_bit(RX_HANDLER_BUSY,&chan->dma_status); - - - return; -} - -static void aft_index_tx_rx_dma_chains(private_area_t *chan) -{ - int i; - - for (i=0;itx_dma_chain_table[i].index=i; - chan->rx_dma_chain_table[i].index=i; - } -} - - -static void aft_init_tx_rx_dma_descr(private_area_t *chan) -{ - int i; - u32 reg=0; - sdla_t *card=chan->card; - unsigned int tx_dma_descr,rx_dma_descr; - unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; - - if (chan->single_dma_chain){ - dma_cnt=1; - } - - - for (i=0;ihw_iface.bus_write_4(card->hw,tx_dma_descr,reg); - card->hw_iface.bus_write_4(card->hw,rx_dma_descr,reg); - - aft_tx_dma_chain_init(chan,&chan->tx_dma_chain_table[i]); - aft_tx_dma_chain_init(chan,&chan->rx_dma_chain_table[i]); - } -} - -#if 0 -static void aft_dma_te3_set_intr(aft_dma_chain_t *dma_chain, private_area_t *chan) -{ -#define dma_ch_indx dma_chain->index -#define card chan->card - - u32 reg=0; - u32 len; - u32 dma_descr; - - /* If the current DMA chain is in use,then - * all chains are busy */ - if (!wan_test_bit(0,&dma_chain->init)){ - DEBUG_EVENT("%s: (%s) Error: Pending chain %i empty!\n", - chan->if_name,__FUNCTION__,dma_chain->index); - return; - } - - dma_descr=(unsigned long)(dma_ch_indx<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - - card->hw_iface.bus_read_4(card->hw,dma_descr,®); - - /* If GO bit is set, then the current DMA chain - * is in process of being Received, thus - * all are busy */ - if (!wan_test_bit(RxDMA_HI_DMA_GO_READY_BIT,®)){ - DEBUG_EVENT("%s: (%s) Error: Pending chain %i Go bit is not set!\n", - chan->if_name,__FUNCTION__,dma_chain->index); - return; - } - - len=reg&RxDMA_HI_DMA_DATA_LENGTH_MASK; - - DEBUG_TEST("%s: Set Rx Intr on 1st Pending Chain: index=%i Len=%i (dmalen=%i)\n", - chan->if_name,dma_ch_indx,len,dma_chain->dma_len); - - wan_clear_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®); - - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - -#undef dma_ch_indx -#undef card -} -#endif - -/* - * ****************************************************************** - * Proc FS function - */ -static int wan_aft3_get_info(void* pcard, struct seq_file *m, int *stop_cnt) -{ - sdla_t *card = (sdla_t*)pcard; - - m->count = - WAN_FECALL(&card->wandev, update_alarm_info, (&card->fe, m, stop_cnt)); - m->count = - WAN_FECALL(&card->wandev, update_pmon_info, (&card->fe, m, stop_cnt)); - - return m->count; -} - - -static void aft_free_rx_complete_list(private_area_t *chan) -{ - void *skb; - while((skb=wan_skb_dequeue(&chan->wp_rx_complete_list)) != NULL){ - - chan->if_stats.rx_dropped++; - aft_init_requeue_free_skb(chan, skb); - } -} - -static void aft_list_descriptors(private_area_t *chan) -{ -#if 0 - u32 reg,cur_dma_ptr; - sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; - u32 dma_descr; - int i; - - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - cur_dma_ptr=get_current_rx_dma_ptr(reg); - - DEBUG_EVENT("%s: List Descritpors:\n",chan->if_name); - - DEBUG_EVENT("%s: Chain DMA Status=0x%lX, TxCur=%i, TxPend=%i RxCur=%i RxPend=%i HwCur=%i RC=%i RFree=%i\n", - chan->if_name, - chan->dma_chain_status, - chan->tx_chain_indx, - chan->tx_pending_chain_indx, - chan->rx_chain_indx, - chan->rx_pending_chain_indx, - cur_dma_ptr, - wan_skb_queue_len(&chan->wp_rx_complete_list), - wan_skb_queue_len(&chan->wp_rx_free_list)); - - - for (i=0;irx_dma_chain_table[i]; - if (!dma_chain){ - DEBUG_EVENT("%s:%d Assertion Error !!!!\n", - __FUNCTION__,__LINE__); - break; - } - - dma_descr=(dma_chain->index<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_read_4(card->hw,dma_descr,®); - - DEBUG_EVENT("%s: DMA=%i : Init=%li Go=%u Intr=%u Addr=%s Skb=%s\n", - chan->if_name, - dma_chain->index, - dma_chain->init, - wan_test_bit(RxDMA_HI_DMA_GO_READY_BIT,®), - wan_test_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®), - dma_chain->dma_addr?"Yes":"No", - dma_chain->skb?"Yes":"No"); - } -#endif -} - -static void aft_list_tx_descriptors(private_area_t *chan) -{ -#if 1 - u32 reg,cur_dma_ptr,low,dma_ctrl; - sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; - u32 dma_descr; - int i; - - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - cur_dma_ptr=get_current_tx_dma_ptr(reg); - - card->hw_iface.bus_read_4(card->hw,XILINX_DMA_CONTROL_REG,&dma_ctrl); - - DEBUG_EVENT("%s: List TX Descritpors:\n",chan->if_name); - - DEBUG_EVENT("%s: Chain DMA Status=0x%lX, TxCur=%i, TxPend=%i HwCur=%i RP=%i RC=%i RFree=%i Ctrl=0x%X\n", - chan->if_name, - chan->dma_chain_status, - chan->tx_chain_indx, - chan->tx_pending_chain_indx, - cur_dma_ptr, - wan_skb_queue_len(&chan->wp_tx_pending_list), - wan_skb_queue_len(&chan->wp_tx_complete_list), - wan_skb_queue_len(&chan->wp_tx_free_list), - dma_ctrl); - - - for (i=0;itx_dma_chain_table[i]; - if (!dma_chain){ - DEBUG_EVENT("%s:%d Assertion Error !!!!\n", - __FUNCTION__,__LINE__); - break; - } - - dma_descr=(dma_chain->index<<4) + XILINX_TxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_read_4(card->hw,dma_descr,®); - - dma_descr=(dma_chain->index<<4) + XILINX_TxDMA_DESCRIPTOR_LO; - card->hw_iface.bus_read_4(card->hw,dma_descr,&low); - - DEBUG_EVENT("%s: DMA=%i : Init=%lu Go=%u Intr=%u Addr=%s Skb=%s HI=0x%X LO=0x%X\n", - chan->if_name, - dma_chain->index, - dma_chain->init, - wan_test_bit(TxDMA_HI_DMA_GO_READY_BIT,®), - wan_test_bit(DMA_HI_TE3_INTR_DISABLE_BIT,®), - dma_chain->dma_addr?"Yes":"No", - dma_chain->skb?"Yes":"No", - reg,low); - } -#endif -} - - -static void aft_free_rx_descriptors(private_area_t *chan) -{ - u32 reg; - sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; - u32 dma_descr; - int i; - - for (i=0;irx_dma_chain_table[i]; - if (!dma_chain){ - DEBUG_EVENT("%s:%d Assertion Error !!!!\n", - __FUNCTION__,__LINE__); - break; - } - - dma_descr=(dma_chain->index<<4) + XILINX_RxDMA_DESCRIPTOR_HI; - card->hw_iface.bus_read_4(card->hw,dma_descr,®); - - /* If GO bit is set, then the current DMA chain - * is in process of being transmitted, thus - * all are busy */ - reg=0; - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - - aft_rx_dma_chain_init(chan,&chan->rx_dma_chain_table[i]); - - dma_chain->skb=NULL; - dma_chain->dma_addr=0; - dma_chain->dma_len=0; - dma_chain->pkt_error=0; - wan_clear_bit(0,&dma_chain->init); - } - - aft_free_rx_complete_list(chan); - - DEBUG_TEST("%s: Free Rx Bufs (RxComp=%i RxFree=%i)\n", - chan->if_name, - wan_skb_queue_len(&chan->wp_rx_complete_list), - wan_skb_queue_len(&chan->wp_rx_free_list)); - - aft_reset_rx_chain_cnt(chan); -} - -static void aft_reset_rx_chain_cnt(private_area_t *chan) -{ - u32 reg,cur_dma_ptr; - sdla_t *card=chan->card; - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - - if (chan->single_dma_chain){ - set_current_rx_dma_ptr(®,0); - } - - cur_dma_ptr=get_current_rx_dma_ptr(reg); - chan->rx_pending_chain_indx = chan->rx_chain_indx = cur_dma_ptr; - return; -} - -static void aft_reset_tx_chain_cnt(private_area_t *chan) -{ - u32 reg,cur_dma_ptr; - sdla_t *card=chan->card; - card->hw_iface.bus_read_4(card->hw,AFT_TE3_CRNT_DMA_DESC_ADDR_REG,®); - - if (chan->single_dma_chain){ - set_current_tx_dma_ptr(®,0); - cur_dma_ptr=0; - } - - cur_dma_ptr=get_current_tx_dma_ptr(reg); - - chan->tx_pending_chain_indx = chan->tx_chain_indx = cur_dma_ptr; - return; -} - -static void aft_free_tx_descriptors(private_area_t *chan) -{ - u32 reg; - sdla_t *card=chan->card; - aft_dma_chain_t *dma_chain; - u32 dma_descr; - int i; - void *skb; - unsigned int dma_cnt=MAX_AFT_DMA_CHAINS; - - DEBUG_TEST("%s:%s: Tx: Freeing Descripors\n",card->devname,chan->if_name); - - wan_clear_bit(TX_INTR_PENDING,&chan->dma_chain_status); - wan_clear_bit(TX_DMA_BUSY,&chan->dma_status); - - for (i=0;itx_dma_chain_table[i]; - if (!dma_chain){ - DEBUG_EVENT("%s:%d Assertion Error !!!!\n", - __FUNCTION__,__LINE__); - break; - } - - dma_descr=(dma_chain->index<<4) + XILINX_TxDMA_DESCRIPTOR_HI; - reg=0; - card->hw_iface.bus_write_4(card->hw,dma_descr,reg); - - aft_tx_dma_chain_init(chan, dma_chain); - } - - aft_reset_tx_chain_cnt(chan); - - while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ - wan_skb_free(skb); - } -} - - - -static void aft_te3_led_ctrl(sdla_t *card, int color, int led_pos, int on) -{ - u32 reg; - if (card->adptr_subtype == AFT_SUBTYPE_SHARK) { - - switch (color){ - - case WAN_AFT_RED: - if (on){ - wan_clear_bit(0,&card->u.aft.led_ctrl); - wan_clear_bit(2,&card->u.aft.led_ctrl); - }else{ - wan_set_bit(0,&card->u.aft.led_ctrl); - wan_set_bit(2,&card->u.aft.led_ctrl); - } - break; - - case WAN_AFT_GREEN: - if (on){ - wan_clear_bit(1,&card->u.aft.led_ctrl); - wan_clear_bit(3,&card->u.aft.led_ctrl); - }else{ - wan_set_bit(1,&card->u.aft.led_ctrl); - wan_set_bit(3,&card->u.aft.led_ctrl); - } - break; - } - - write_cpld(card,0x00,card->u.aft.led_ctrl); - } else { - card->hw_iface.bus_read_4(card->hw,TE3_LOCAL_CONTROL_STATUS_REG,®); - aft_te3_set_led(color, led_pos, on, ®); - card->hw_iface.bus_write_4(card->hw,TE3_LOCAL_CONTROL_STATUS_REG,reg); - } -} - - -static void __aft_fe_intr_ctrl(sdla_t *card, int status) -{ - u32 reg; - - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG,®); - if (status){ - wan_set_bit(FRONT_END_INTR_ENABLE_BIT,®); - }else{ - wan_clear_bit(FRONT_END_INTR_ENABLE_BIT,®); - } - card->hw_iface.bus_write_4(card->hw,XILINX_CHIP_CFG_REG,reg); -} - -#if 0 -static void aft_fe_intr_ctrl(sdla_t *card, int status) -{ - wan_smp_flag_t smp_flags; - - wan_spin_lock_irq(&card->wandev.lock,&smp_flags); - __aft_fe_intr_ctrl(card, status); - wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); -} -#endif - - -#if defined(__LINUX__) -# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -static void aft_port_task (void * card_ptr) -# else -static void aft_port_task (struct work_struct *work) -# endif -#else -static void aft_port_task (void * card_ptr, int arg) -#endif -{ -#if defined(__LINUX__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) - sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); -#else - sdla_t *card = (sdla_t *)card_ptr; -#endif - wan_smp_flag_t smp_flags,isr_flags; - - if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ - return; - } - - DEBUG_TEST("%s: AFT PORT TASK CMD=0x%X!\n", - card->devname,card->u.aft.port_task_cmd); - - if (wan_test_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd)){ - card->hw_iface.hw_lock(card->hw,&smp_flags); - - wan_spin_lock_irq(&card->wandev.lock,&isr_flags); - __aft_fe_intr_ctrl(card, 0); - front_end_interrupt(card,0); - wan_clear_bit(AFT_FE_INTR,&card->u.aft.port_task_cmd); - __aft_fe_intr_ctrl(card, 1); - wan_spin_unlock_irq(&card->wandev.lock,&isr_flags); - - card->hw_iface.hw_unlock(card->hw,&smp_flags); - } - - if (wan_test_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd)){ - card->hw_iface.hw_lock(card->hw,&smp_flags); - - wan_spin_lock_irq(&card->wandev.lock,&isr_flags); - __aft_fe_intr_ctrl(card, 0); - WAN_FECALL(&card->wandev, polling, (&card->fe)); - wan_clear_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd); - __aft_fe_intr_ctrl(card, 1); - wan_spin_unlock_irq(&card->wandev.lock,&isr_flags); - - card->hw_iface.hw_unlock(card->hw,&smp_flags); - } - - if (wan_test_bit(AFT_FE_LED,&card->u.aft.port_task_cmd)){ - card->hw_iface.hw_lock(card->hw,&smp_flags); - wan_spin_lock_irq(&card->wandev.lock,&isr_flags); - __aft_fe_intr_ctrl(card, 0); - if (card->wandev.state == WAN_CONNECTED){ - aft_te3_led_ctrl(card, WAN_AFT_RED, 0, WAN_AFT_OFF); - aft_te3_led_ctrl(card, WAN_AFT_GREEN, 0,WAN_AFT_ON); - }else{ - aft_te3_led_ctrl(card, WAN_AFT_RED, 0, WAN_AFT_ON); - aft_te3_led_ctrl(card, WAN_AFT_GREEN, 0,WAN_AFT_OFF); - } - wan_clear_bit(AFT_FE_LED,&card->u.aft.port_task_cmd); - __aft_fe_intr_ctrl(card, 1); - wan_spin_unlock_irq(&card->wandev.lock,&isr_flags); - card->hw_iface.hw_unlock(card->hw,&smp_flags); - } - - -} - -static void aft_critical_shutdown (sdla_t *card) -{ - -#ifdef __LINUX__ - printk(KERN_ERR "%s: Error: Card Critically Shutdown!\n", - card->devname); -#else - DEBUG_EVENT("%s: Error: Card Critically Shutdown!\n", - card->devname); -#endif - - - /* Unconfiging, only on shutdown */ - if (IS_TE3(&card->fe.fe_cfg)) { - if (card->wandev.fe_iface.unconfig){ - card->wandev.fe_iface.unconfig(&card->fe); - } - } - - port_set_state(card,WAN_DISCONNECTED); - disable_data_error_intr(card,DEVICE_DOWN); - wan_set_bit(CARD_DOWN,&card->wandev.critical); - - aft_te3_led_ctrl(card, WAN_AFT_RED, 1, WAN_AFT_ON); - aft_te3_led_ctrl(card, WAN_AFT_GREEN, 1,WAN_AFT_OFF); - -} - -#if 0 -static int aft_hdlc_core_ready(sdla_t *card) -{ - u32 reg; - int i,err=1; - - for (i=0;i<5;i++){ - card->hw_iface.bus_read_4(card->hw,XILINX_CHIP_CFG_REG, ®); - - if (!wan_test_bit(HDLC_CORE_READY_FLAG_BIT,®)){ - WP_DELAY(500); - }else{ - err=0; - break; - } - } - - if (err){ - DEBUG_EVENT("%s: Critical Error: HDLC Core not ready!\n", - card->devname); - } - return err; -} -#endif -/****** End ****************************************************************/ diff --git a/patches/kdrivers/src/net/sdla_asyhdlc.c b/patches/kdrivers/src/net/sdla_asyhdlc.c index a848292..e98081f 100644 --- a/patches/kdrivers/src/net/sdla_asyhdlc.c +++ b/patches/kdrivers/src/net/sdla_asyhdlc.c @@ -229,7 +229,7 @@ static int set_asy_config (sdla_t* card); static int asy_comm_enable (sdla_t* card); /* Interrupt handlers */ -static WAN_IRQ_RETVAL wpc_isr (sdla_t* card); +static void wpc_isr (sdla_t* card); static void rx_intr (sdla_t* card); static void timer_intr(sdla_t *); @@ -387,7 +387,7 @@ int wp_asyhdlc_init (sdla_t* card, wandev_conf_t* conf) card->wandev.fe_enable_timer = chdlc_enable_timer; card->wandev.te_link_state = chdlc_handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_CARD(card)) ? WANOPT_V35 : WANOPT_RS232; if (card->u.c.comm_port == WANOPT_PRI){ @@ -460,9 +460,9 @@ int wp_asyhdlc_init (sdla_t* card, wandev_conf_t* conf) card->u.c.update_call_count = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; - if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&& + if ((card->u.c.comm_port == WANOPT_SEC && conf->electrical_interface == WANOPT_V35)&& card->type != SDLA_S514){ printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n", card->devname, PORT(card->u.c.comm_port)); @@ -609,7 +609,7 @@ int wp_asyhdlc_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t *dev; chdlc_private_area_t* chdlc_priv_area; unsigned long smp_flags; @@ -619,7 +619,7 @@ static int update (wan_device_t* wandev) #endif /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -716,7 +716,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; chdlc_private_area_t* chdlc_priv_area; int err = 0; @@ -919,6 +919,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; #if defined(LINUX_2_4)||defined(LINUX_2_6) @@ -1110,6 +1112,9 @@ static void disable_comm (sdla_t *card) /* TE1 - Unconfiging, only on shutdown */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1567,6 +1572,9 @@ static int chdlc_disable_comm_shutdown (sdla_t *card) /* TE1 - Unconfiging, only on shutdown */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1650,7 +1658,7 @@ static int update_comms_stats(sdla_t* card, if (IS_TE1_CARD(card)) { card->wandev.fe_iface.read_alarm(&card->fe, 0); /* TE1 Update T1/E1 perfomance counters */ - card->wandev.fe_iface.read_pmon(&card->fe, 0); + card->wandev.fe_iface.read_pmon(&card->fe); }else if (IS_56K_CARD(card)) { /* 56K Update CSU/DSU alarms */ card->wandev.fe_iface.read_alarm(&card->fe, 1); @@ -1737,7 +1745,7 @@ static unsigned char read_front_end_reg (void* card1, ...) /*============================================================================ * Write to TE1/56K Front end registers */ -static int write_front_end_reg (void* card1, ...) +static unsigned char write_front_end_reg (void* card1, ...) { va_list args; sdla_t *card = (sdla_t*)card1; @@ -1856,22 +1864,19 @@ static void chdlc_bh (unsigned long data) /*============================================================================ * Cisco HDLC interrupt service routine. */ -static WAN_IRQ_RETVAL wpc_isr (sdla_t* card) +static void wpc_isr (sdla_t* card) { netdevice_t* dev; SHARED_MEMORY_INFO_STRUCT flags; int i; - WAN_IRQ_RETVAL_DECL(irq_ret); - - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); /* Check for which port the interrupt has been generated * Since Secondary Port is piggybacking on the Primary * the check must be done here. */ if (!card->hw){ - WAN_IRQ_RETURN(irq_ret); + return; } card->hw_iface.peek(card->hw, card->flags_off, @@ -1887,7 +1892,6 @@ static WAN_IRQ_RETVAL wpc_isr (sdla_t* card) if (!card->tty_opt && !dev && flags.interrupt_info_struct.interrupt_type != COMMAND_COMPLETE_APP_INT_PEND){ - WAN_IRQ_RETURN(irq_ret); goto isr_done; } @@ -1898,7 +1902,6 @@ static WAN_IRQ_RETVAL wpc_isr (sdla_t* card) if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) { printk(KERN_INFO "%s: Chdlc ISR: Critical with PERI_CRIT!\n", card->devname); - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); goto isr_done; } @@ -1910,8 +1913,7 @@ static WAN_IRQ_RETVAL wpc_isr (sdla_t* card) card->devname); card->in_isr = 0; card->hw_iface.poke_byte(card->hw, card->intr_type_off, 0x00); - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - WAN_IRQ_RETURN(irq_ret); + return; } } @@ -1993,9 +1995,7 @@ isr_done: card->in_isr = 0; card->hw_iface.poke_byte(card->hw, card->intr_type_off, 0x00); - - WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED); - WAN_IRQ_RETURN(irq_ret); + return; } /*============================================================================ @@ -2257,7 +2257,7 @@ static int set_asy_config(sdla_t* card) if(card->wandev.clocking) cfg.baud_rate = card->wandev.bps; - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; cfg.modem_config_options = 0; @@ -3000,6 +3000,9 @@ static int config_chdlc (sdla_t *card, netdevice_t *dev) (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -3016,6 +3019,9 @@ static int config_chdlc (sdla_t *card, netdevice_t *dev) card->devname); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -3176,7 +3182,7 @@ static int chdlc_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_atm.c b/patches/kdrivers/src/net/sdla_atm.c index 4ccbe1c..f90e4e2 100644 --- a/patches/kdrivers/src/net/sdla_atm.c +++ b/patches/kdrivers/src/net/sdla_atm.c @@ -14,7 +14,7 @@ * ============================================================================ * Jul 13, 2004 David Rokhvarg Added Idle cell trace. * Sep 12, 2003 Nenad Corbic Fixed the TE1 clock selection, the -* conf->interfaces must be hardcoded, before +* conf->electrical_interfaces must be hardcoded, before * writting the value to the card structure. * Jan 07, 2002 Nenad Corbic Initial version. *****************************************************************************/ @@ -337,7 +337,7 @@ int wp_atm_init (sdla_t* card, wandev_conf_t* conf) if (IS_TE1_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe,&card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -345,7 +345,7 @@ int wp_atm_init (sdla_t* card, wandev_conf_t* conf) card->wandev.fe_enable_timer = enable_timer; card->wandev.te_link_state = handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_CARD(card)) ? WANOPT_V35 : WANOPT_RS232; if (card->wandev.comm_port == WANOPT_PRI){ @@ -355,7 +355,7 @@ int wp_atm_init (sdla_t* card, wandev_conf_t* conf) }else if (IS_56K_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe,&card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -384,7 +384,7 @@ int wp_atm_init (sdla_t* card, wandev_conf_t* conf) card->wandev.clocking = conf->clocking; card->wandev.ignore_front_end_status = conf->ignore_front_end_status; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.comm_port = conf->comm_port; card->wandev.udp_port = conf->udp_port; card->wandev.new_if_cnt = 0; @@ -656,13 +656,13 @@ atm_timer_poll_exit: */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; struct net_device* dev; volatile private_area_t* priv_area; unsigned long timeout; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -751,7 +751,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; private_area_t* priv_area; int err = 0; @@ -971,7 +971,7 @@ new_if_error: static int del_if (wan_device_t* wandev, struct net_device* dev) { private_area_t* priv_area = dev->priv; - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; unsigned long flags; wan_atomic_dec(&card->wandev.if_cnt); @@ -1039,6 +1039,8 @@ static int if_init (struct net_device* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; #if defined(LINUX_2_4)||defined(LINUX_2_6) @@ -1328,7 +1330,7 @@ static int if_send (netskb_t* skb, struct net_device* dev) { private_area_t *chan = dev->priv; sdla_t *card = chan->card; - unsigned long smp_flags=0; + unsigned long smp_flags; int err=0; /* Mark interface as busy. The kernel will not @@ -2065,7 +2067,7 @@ static int set_frmw_config(sdla_t* card) cfg.baud_rate = card->wandev.bps; } - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; /* Automatic DTR/RTS and notify modem status changes */ @@ -3989,7 +3991,7 @@ static int get_dev_config_info(char* buf, char** start, off_t offs, int len, int return cnt; PROC_ADD_INIT(offs, stop_cnt); - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; PROC_ADD_LINE(cnt, (buf, &cnt, len, offs, &stop_cnt, &size, PROC_DEV_SEPARATE)); @@ -4037,7 +4039,7 @@ static int set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; DEBUG_EVENT( "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_bitstrm.c b/patches/kdrivers/src/net/sdla_bitstrm.c index f5b3933..d08ee4e 100644 --- a/patches/kdrivers/src/net/sdla_bitstrm.c +++ b/patches/kdrivers/src/net/sdla_bitstrm.c @@ -32,6 +32,11 @@ #include #include +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG +# include "wanpipe_lapb_kernel.h" +#endif + + /****** Defines & Macros ****************************************************/ @@ -219,6 +224,10 @@ typedef struct bitstrm_private_area unsigned char rbs_on; unsigned char rbs_chan; unsigned char rbs_sig; + + netdevice_t *annexg_dev; + unsigned char label[WAN_IF_LABEL_SZ+1]; + //FIXME: add driver stats as per frame relay! } bitstrm_private_area_t; @@ -284,6 +293,14 @@ static int bstrm_comm_disable (sdla_t *card); static int bstrm_set_FE_config (sdla_t *card); +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG +static int bind_annexg(netdevice_t *dev, netdevice_t *annexg_dev); +static netdevice_t * un_bind_annexg(wan_device_t *wandev, netdevice_t* annexg_dev_name); +static int get_map(wan_device_t*, netdevice_t*, struct seq_file* m, int*); +static void get_active_inactive(wan_device_t *wandev, netdevice_t *dev, + void *wp_stats); +#endif + /* Interrupt handlers */ static WAN_IRQ_RETVAL wpbit_isr (sdla_t* card); static void rx_intr (sdla_t* card); @@ -475,7 +492,7 @@ int wpbit_init (sdla_t* card, wandev_conf_t* conf) if (IS_TE1_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -484,7 +501,7 @@ int wpbit_init (sdla_t* card, wandev_conf_t* conf) card->wandev.fe_enable_timer = bstrm_enable_timer; card->wandev.te_link_state = bstrm_handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_CARD(card)) ? WANOPT_V35 : WANOPT_RS232; if (card->u.b.comm_port == WANOPT_PRI){ @@ -501,7 +518,7 @@ int wpbit_init (sdla_t* card, wandev_conf_t* conf) }else if (IS_56K_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -555,6 +572,15 @@ int wpbit_init (sdla_t* card, wandev_conf_t* conf) card->wandev.new_if = &new_if; card->wandev.del_if = &del_if; card->wandev.udp_port = conf->udp_port; + + +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG + card->wandev.bind_annexg = &bind_annexg; + card->wandev.un_bind_annexg = &un_bind_annexg; + card->wandev.get_map = &get_map; + card->wandev.get_active_inactive= &get_active_inactive; +#endif + card->wandev.new_if_cnt = 0; // Proc fs functions @@ -577,7 +603,7 @@ int wpbit_init (sdla_t* card, wandev_conf_t* conf) card->u.b.update_call_count = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; @@ -877,13 +903,13 @@ int wpbit_init (sdla_t* card, wandev_conf_t* conf) static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t* dev; bitstrm_private_area_t* bstrm_priv_area; //unsigned long smp_flags; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -1011,7 +1037,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { int i; struct sk_buff *skb; - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; bitstrm_private_area_t* bstrm_priv_area; unsigned long smp_flags; int err=0; @@ -1199,6 +1225,17 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) bstrm_priv_area->protocol=0; DEBUG_EVENT( "%s: Running in STACK mode !\n", wandev->name); + +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG + }else if (strcmp(conf->usedby, "ANNEXG") == 0) { + printk(KERN_INFO "%s:%s: Interface running in ANNEXG mode!\n", + wandev->name,bstrm_priv_area->if_name); + bstrm_priv_area->common.usedby=ANNEXG; + + if (strlen(conf->label)){ + strncpy(bstrm_priv_area->label,conf->label,WAN_IF_LABEL_SZ); + } +#endif } else if( strcmp(conf->usedby, "SWITCH") == 0) { bstrm_priv_area->common.usedby=SWITCH; @@ -1398,7 +1435,8 @@ new_if_error: static int del_if (wan_device_t* wandev, netdevice_t* dev) { bitstrm_private_area_t* bstrm_priv_area = dev->priv; - sdla_t *card = wandev->private; + bitstrm_private_area_t* chan = dev->priv; + sdla_t *card = wandev->priv; int i; unsigned long smp_flags; @@ -1406,6 +1444,34 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) return 0; } +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG + if (chan->common.usedby == ANNEXG && chan->annexg_dev){ + netdevice_t *tmp_dev; + int err; + + printk(KERN_INFO "%s: Unregistering Lapb Protocol\n",wandev->name); + + if (!IS_FUNC_CALL(lapb_protocol,lapb_unregister)){ + wan_spin_lock_irq(&wandev->lock, &smp_flags); + chan->annexg_dev = NULL; + wan_spin_unlock_irq(&wandev->lock, &smp_flags); + return 0; + } + + wan_spin_lock_irq(&wandev->lock, &smp_flags); + tmp_dev=chan->annexg_dev; + chan->annexg_dev=NULL; + wan_spin_unlock_irq(&wandev->lock, &smp_flags); + + if ((err=lapb_protocol.lapb_unregister(tmp_dev))){ + wan_spin_lock_irq(&wandev->lock, &smp_flags); + chan->annexg_dev=tmp_dev; + wan_spin_unlock_irq(&wandev->lock, &smp_flags); + return err; + } + } +#endif + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); if (test_bit(0,&card->in_isr)){ @@ -1638,14 +1704,14 @@ static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) DEBUG_DBG("INTERFACE_LEVEL_V35\n"); - card->wandev.interface = WANOPT_V35; + card->wandev.electrical_interface = WANOPT_V35; card->u.b.cfg.rx_complete_length = 720; card->u.b.cfg.max_length_tx_data_block = 720; card->u.b.time_slots = NO_ACTIVE_RX_TIME_SLOTS_T1; }else{ DEBUG_DBG("INTERFACE_LEVEL_RS232\n"); - card->wandev.interface = WANOPT_RS232; + card->wandev.electrical_interface = WANOPT_RS232; //Must be less than original 720, because //default .conf file is for T1. //It is max len which can be pushed into @@ -1654,11 +1720,9 @@ static int if_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) card->u.b.cfg.max_length_tx_data_block = 682;//divisible by 31 card->u.b.time_slots = NO_ACTIVE_RX_TIME_SLOTS_E1; } - if (card->wandev.fe_iface.pre_release){ card->wandev.fe_iface.pre_release(&card->fe); } - if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1989,10 +2053,10 @@ static void disable_comm (sdla_t *card) /* TE1 - Unconfiging */ + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } if (IS_TE1_CARD(card)) { - if (card->wandev.fe_iface.pre_release){ - card->wandev.fe_iface.pre_release(&card->fe); - } if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -2025,7 +2089,14 @@ static void if_tx_timeout (netdevice_t *dev) }else if (chan->common.usedby == STACK){ wanpipe_lip_kick(chan,0); } - +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG + if (chan->common.usedby == ANNEXG && + chan->annexg_dev){ + if (IS_FUNC_CALL(lapb_protocol,lapb_mark_bh)){ + lapb_protocol.lapb_mark_bh(chan->annexg_dev); + } + } +#endif } @@ -2730,6 +2801,13 @@ static void bstrm_tx_bh (unsigned long data) }else if (chan->common.usedby == STACK){ start_net_queue(chan->common.dev); wanpipe_lip_kick(chan,0); +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG + }else if (chan->common.usedby == ANNEXG && + chan->annexg_dev){ + if (IS_FUNC_CALL(lapb_protocol,lapb_mark_bh)){ + lapb_protocol.lapb_mark_bh(chan->annexg_dev); + } +#endif }else if (chan->common.usedby == SWITCH){ start_net_queue(chan->common.dev); }else{ @@ -3246,7 +3324,9 @@ switch_hdlc_send: goto tx_up_skb_recover; } - }else{ +//ANNEXG RECEIVE + + } else{ buf = skb_push(new_skb,sizeof(api_rx_hdr_t)); memset(buf, 0, sizeof(api_rx_hdr_t)); @@ -3623,6 +3703,8 @@ static void calc_tx_crc(bitstrm_private_area_t *chan,unsigned char byte) static void tx_up_decode_pkt(bitstrm_private_area_t *chan) { unsigned char *buf; + sdla_t *card = chan->card; + struct sk_buff *skb = dev_alloc_skb(chan->rx_decode_len+sizeof(api_rx_hdr_t)); if (!skb){ DEBUG_EVENT( "%s: HDLC Tx up: failed to allocate memory!\n", @@ -3634,17 +3716,62 @@ static void tx_up_decode_pkt(bitstrm_private_area_t *chan) if (chan->common.usedby==STACK){ + buf = skb_put(skb,chan->rx_decode_len-2); + memcpy(buf, + chan->rx_decode_buf, + chan->rx_decode_len-2); + if (wanpipe_lip_rx(chan,skb) != 0){ dev_kfree_skb_any(skb); chan->card->wandev.stats.rx_dropped++; chan->ifstats.rx_dropped++; }else{ chan->card->wandev.stats.rx_packets++; - chan->card->wandev.stats.rx_bytes += chan->rx_decode_len; + chan->card->wandev.stats.rx_bytes += chan->rx_decode_len-2; chan->ifstats.rx_packets++; - chan->ifstats.rx_bytes+=chan->rx_decode_len; + chan->ifstats.rx_bytes+=chan->rx_decode_len-2; } +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG + } else if (chan->common.usedby == ANNEXG) { + + if (!chan->annexg_dev) { + dev_kfree_skb_any(skb); + ++card->wandev.stats.rx_dropped; + chan->ifstats.rx_dropped++; + return; + } + + if ((chan->rx_decode_len) <= 2) { + DEBUG_EVENT("%s: Bad Rx Frame Length %i\n", + card->devname,chan->rx_decode_len); + dev_kfree_skb_any(skb); + ++card->wandev.stats.rx_dropped; + chan->ifstats.rx_dropped++; + return; + } + + buf = skb_put(skb,chan->rx_decode_len-2); + memcpy(buf, + chan->rx_decode_buf, + chan->rx_decode_len-2); + + skb->protocol = htons(ETH_P_X25); + skb->dev = chan->annexg_dev; + wan_skb_reset_mac_header(skb); + + if (IS_FUNC_CALL(lapb_protocol,lapb_rx)) { + lapb_protocol.lapb_rx(chan->annexg_dev,skb); + card->wandev.stats.rx_packets++; + card->wandev.stats.rx_bytes += chan->rx_decode_len-2; + chan->ifstats.rx_packets++; + chan->ifstats.rx_bytes+=chan->rx_decode_len-2; + } else { + dev_kfree_skb_any(skb); + ++card->wandev.stats.rx_dropped; + } + +#endif }else if (chan->common.usedby==API || chan->common.usedby==SWITCH){ buf = skb_put(skb,sizeof(api_rx_hdr_t)); @@ -4236,7 +4363,7 @@ static int set_bstrm_config(sdla_t* card) cfg.baud_rate = card->wandev.bps; } - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; cfg.modem_config_options = 0; @@ -4592,7 +4719,7 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, /* Decapsulate pkt and pass it up the protocol stack */ new_skb->protocol = htons(ETH_P_IP); new_skb->dev = dev; - wan_skb_reset_mac_header(new_skb); + wan_skb_reset_mac_header(new_skb); netif_rx(new_skb); } else { @@ -4944,6 +5071,21 @@ static void port_set_state (sdla_t *card, int state) }else{ wanpipe_lip_disconnect(bstrm_priv_area,0); } + +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG + } else if (bstrm_priv_area->common.usedby == ANNEXG && + bstrm_priv_area->annexg_dev){ + if (state == WAN_CONNECTED){ + if (IS_FUNC_CALL(lapb_protocol,lapb_link_up)){ + lapb_protocol.lapb_link_up(bstrm_priv_area->annexg_dev); + } + } else { + if (IS_FUNC_CALL(lapb_protocol,lapb_link_down)){ + lapb_protocol.lapb_link_down(bstrm_priv_area->annexg_dev); + } + } + +#endif }else if (bstrm_priv_area->common.usedby == API){ wan_wakeup_api(bstrm_priv_area); wan_update_api_state(bstrm_priv_area); @@ -5060,6 +5202,7 @@ static int config_bstrm (sdla_t *card) if (card->wandev.fe_iface.post_init){ err=card->wandev.fe_iface.post_init(&card->fe); } + } @@ -5153,10 +5296,10 @@ static int bstrm_get_config_info(void* priv, struct seq_file* m, int* stop_cnt) wan_device_t* wandev = (wan_device_t*)priv; sdla_t* card = NULL; - if (wandev == NULL || wandev->private == NULL) + if (wandev == NULL || wandev->priv == NULL) return 0; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; if (!card->comm_enabled){ DEBUG_EVENT( "DEBUG: Enable communication for Bit Streaming protocol\n"); bstrm_comm_enable (card); @@ -5290,7 +5433,7 @@ static int bstrm_bind_dev_switch (sdla_t *card, bitstrm_private_area_t*chan, cha return 0; } - sw_dev = wan_dev_get_by_name(sw_dev_name); + sw_dev = dev_get_by_name(sw_dev_name); if (!sw_dev){ DEBUG_EVENT( "%s: Device %s waiting for switch device %s\n", card->devname, chan->if_name,sw_dev_name); @@ -5498,6 +5641,8 @@ static int protocol_shutdown (sdla_t *card, netdevice_t *dev) wp_sppp_detach(dev); dev->do_ioctl = NULL; + dev->hard_header = NULL; + dev->rebuild_header = NULL; if (chan->common.prot_ptr){ kfree(chan->common.prot_ptr); @@ -5735,3 +5880,100 @@ static int send_rbs_oob_msg (sdla_t *card, bitstrm_private_area_t *chan) return err; } +#ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG +static int bind_annexg(netdevice_t *dev, netdevice_t *annexg_dev) +{ + unsigned long smp_flags=0; + bitstrm_private_area_t* chan = dev->priv; + sdla_t *card = chan->card; + if (!chan) + return -EINVAL; + + if (chan->common.usedby != ANNEXG) + return -EPROTONOSUPPORT; + + if (chan->annexg_dev) + return -EBUSY; + + spin_lock_irqsave(&card->wandev.lock,smp_flags); + chan->annexg_dev = annexg_dev; + spin_unlock_irqrestore(&card->wandev.lock,smp_flags); + return 0; +} + + +static netdevice_t * un_bind_annexg(wan_device_t *wandev, netdevice_t *annexg_dev) +{ + struct wan_dev_le *devle; + netdevice_t *dev; + unsigned long smp_flags=0; + sdla_t *card = wandev->priv; + + WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ + bitstrm_private_area_t* chan; + + dev = WAN_DEVLE2DEV(devle); + if (dev == NULL || (chan = wan_netif_priv(dev)) == NULL) + continue; + + if (!chan->annexg_dev || chan->common.usedby != ANNEXG) + continue; + + if (chan->annexg_dev == annexg_dev){ + spin_lock_irqsave(&card->wandev.lock,smp_flags); + chan->annexg_dev = NULL; + spin_unlock_irqrestore(&card->wandev.lock,smp_flags); + return dev; + } + } + return NULL; +} + + +static void get_active_inactive(wan_device_t *wandev, netdevice_t *dev, + void *wp_stats_ptr) +{ + bitstrm_private_area_t* chan = dev->priv; + wp_stack_stats_t *wp_stats = (wp_stack_stats_t *)wp_stats_ptr; + + if (chan->common.usedby == ANNEXG && chan->annexg_dev){ + if (IS_FUNC_CALL(lapb_protocol,lapb_get_active_inactive)){ + lapb_protocol.lapb_get_active_inactive(chan->annexg_dev,wp_stats); + } + } + + if (chan->common.state == WAN_CONNECTED){ + wp_stats->fr_active++; + }else{ + wp_stats->fr_inactive++; + } +} + +static int +get_map(wan_device_t *wandev, netdevice_t *dev, struct seq_file* m, int* stop_cnt) +{ + bitstrm_private_area_t* chan = dev->priv; + + if (!(dev->flags&IFF_UP)){ + return m->count; + } + + if (chan->common.usedby == ANNEXG && chan->annexg_dev){ + if (IS_FUNC_CALL(lapb_protocol,lapb_get_map)){ + return lapb_protocol.lapb_get_map(chan->annexg_dev, + m); + } + } + + PROC_ADD_LINE(m, + "%15s:%s:%c:%s:%c\n", + chan->label, + wandev->name,(wandev->state == WAN_CONNECTED) ? '*' : ' ', + dev->name,(chan->common.state == WAN_CONNECTED) ? '*' : ' '); + + return m->count; +} + +#endif + + diff --git a/patches/kdrivers/src/net/sdla_bri.c b/patches/kdrivers/src/net/sdla_bri.c new file mode 100755 index 0000000..201b4d0 --- /dev/null +++ b/patches/kdrivers/src/net/sdla_bri.c @@ -0,0 +1,3356 @@ +/*************************************************************************** + * sdla_bri.c WANPIPE(tm) + * ISDN-BRI support module for "Cologne XHFC-2SU" chip. + * + * Author(s): David Rokhvarg + * + * Copyright: (c) 1984 - 2007 Sangoma Technologies Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * ============================================================================ + * March 12, 2007 David Rokhvarg + * v1.0 Initial version. + * + * February 26, 2008 David Rokhvarg + * v1.1 Imrovements in SU State transition code. + * Implemented T3 and T4 timers. + * + ****************************************************************************** + */ + +/******************************************************************************* +** INCLUDE FILES +*******************************************************************************/ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include /* for 'wanpipe_common_t' used in 'sdla_aft_te1.h'*/ +# include /* for 'private_area_t' */ +#elif (defined __WINDOWS__) +# include +# include +# include +# include +# include +# include +# include +# include +# include /* for 'wanpipe_common_t' used in 'sdla_aft_te1.h'*/ +# include /* for 'private_area_t' */ +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include /* for 'wanpipe_common_t' used in 'sdla_aft_te1.h'*/ +# include /* for 'private_area_t' */ +#endif + +#undef DEBUG_BRI +#define DEBUG_BRI if(0)DEBUG_EVENT + +/* DEBUG macro definitions */ +#define DEBUG_HFC_INIT if(0)DEBUG_EVENT +#define DEBUG_HFC_MODE if(0)DEBUG_EVENT +#define DEBUG_HFC_S0_STATES if(0)DEBUG_EVENT +#define DEBUG_HFC_IRQ if(0)DEBUG_EVENT +#define DEBUG_HFC_SU_IRQ if(0)DEBUG_EVENT + +#define DEBUG_HFC_TX if(0)DEBUG_EVENT +#define DEBUG_TX_DATA if(0)DEBUG_EVENT +#define TX_EXTRA_DBG if(0)DEBUG_EVENT +#define TX_FAST_DBG if(0)DEBUG_EVENT + +#define DEBUG_HFC_RX if(0)DEBUG_EVENT +#define RX_EXTRA_DBG if(0)DEBUG_EVENT +#define DEBUG_RX1 if(0)DEBUG_EVENT +#define DBG_RX_DATA if(0)DEBUG_EVENT + +#define DEBUG_HFC_CLOCK if(0)DEBUG_EVENT + +#define BUILD_MOD_TESTER 0 /* for Production Test */ +#define DBG_MODULE_TESTER if(0)DEBUG_EVENT + +#define NT_STATE_FUNC() if(0)DEBUG_EVENT("%s(): line: %d\n", __FUNCTION__, __LINE__) +#define CLOCK_FUNC() if(0)DEBUG_EVENT("%s(): line: %d\n", __FUNCTION__, __LINE__) + +#define DBG_SPI if(0)DEBUG_EVENT + +#define DEBUG_FE_STATUS if(0)DEBUG_EVENT + +/* Timer interrupt counter - used by activation timer T3 */ +#define HFC_TIMER_COUNTER_T3 2 + +#define FIFO_THRESHOLD_INDEX 1 + +#define LINE_STABILITY_THRESHOLD 3 + +enum { + WAITING_TO_STABILIZE=1, + LINE_STABLE, + LINE_DISCONNECTED +}; + + +#define CHECK_DATA 0 +#if CHECK_DATA +static void dump_chip_SRAM(sdla_fe_t *fe, u8 mod_no, u8 port_no); +static void dump_data(u8 *data, int data_len); +static int check_data(u8 *data, int data_len); +#endif + +/******************************************************************************* +** DEFINES AND MACROS +*******************************************************************************/ +#define REPORT_MOD_NO (mod_no+1) + +static u8 validate_fe_line_no(sdla_fe_t *fe, const char *caller_name) +{ + if ((int32_t)WAN_FE_LINENO(fe) < 0 || WAN_FE_LINENO(fe) > MAX_BRI_LINES){ + DEBUG_EVENT("%s(): %s: ISDN BRI: Invalid FE line number %d (Min=1 Max=%d)\n", + caller_name, fe->name, WAN_FE_LINENO(fe)+1, MAX_BRI_LINES); + return 1; + } + return 0; +} + +static int32_t validate_physical_mod_no(u32 mod_no, const char *caller_name) +{ + if(mod_no % 2){ + DEBUG_EVENT("%s(): Error: mod_no (%d) is not divisible by 2!!\n", + caller_name, mod_no); + return 1; + } + + if(mod_no >= MAX_BRI_LINES){ + DEBUG_EVENT("%s(): Error: mod_no (%d) is greate than maximum of %d!!\n", + caller_name, mod_no, MAX_BRI_LINES - 1); + return 1; + } + return 0; +} + +/* Translate FE_LINENO to physical module number divisible by BRI_MAX_PORTS_PER_CHIP. */ +static u8 fe_line_no_to_physical_mod_no(sdla_fe_t *fe) +{ + u8 mod_no; + + mod_no = WAN_FE_LINENO(fe); + /* get quotient between 0 and 11 (including) */ + mod_no = mod_no / BRI_MAX_PORTS_PER_CHIP; + /* here WAN_FE_LINENO(fe) is translated into an EVEN number between 0 and 22 (including). */ + mod_no *= BRI_MAX_PORTS_PER_CHIP; + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return 0; + } + + return mod_no; +} + +/* Translate FE_LINENO to port number on the module. can be only 0 or 1. */ +static u8 fe_line_no_to_port_no(sdla_fe_t *fe) +{ + return WAN_FE_LINENO(fe) % BRI_MAX_PORTS_PER_CHIP; +} + + +/*******************************************************************************/ +/* Register Write/Read debugging funcitons */ + +/* Enabling/Disabling register debugging */ +#define WAN_DEBUG_BRI_REG 0 + +#if WAN_DEBUG_BRI_REG + +#define HFC_WRITE 1 +#define HFC_READ 2 + +static void decode_reg_r_fifo(__u8 data, __u8 read_or_write_direction); +static void decode_reg_r_slot(__u8 data, __u8 read_or_write_direction); +static void decode_reg_r_su_irqmsk(__u8 data, __u8 read_or_write_direction); +static void decode_reg_r_fifo_md(__u8 data, __u8 read_or_write_direction); +static void decode_reg_r_pcm_md0(__u8 data, __u8 read_or_write_direction); +static void decode_reg_a_sl_cfg(__u8 data, __u8 read_or_write_direction); +static void decode_reg_a_con_hdlc(__u8 data, __u8 read_or_write_direction); +static void decode_reg_a_fifo_sta(__u8 data, __u8 read_or_write_direction); +static void decode_reg_a_su_rd_sta(__u8 data, __u8 read_or_write_direction); +#endif /* WAN_DEBUG_BRI_REG */ +/*******************************************************************************/ + + +/*******************************************************************************/ +/* SPI access functions and dbg macros */ + +static +__u8 _read_xhfc(sdla_fe_t *fe, u32 mod_no, u8 reg, const char *caller_name, int32_t file_lineno); + +static +int32_t _write_xhfc(sdla_fe_t *fe, u32 mod_no, u8 reg, u8 val, + const char *caller_name, int32_t file_lineno); + +/* Read/Write to front-end register */ +#define WRITE_REG(reg,val) _write_xhfc(fe, mod_no, reg, val, __FUNCTION__, __LINE__) +#define READ_REG(reg) _read_xhfc(fe, mod_no, reg, __FUNCTION__, __LINE__) + +/*******************************************************************************/ + + +/******************************************************************************* +** STRUCTURES AND TYPEDEFS +*******************************************************************************/ + + +/******************************************************************************* +** GLOBAL VARIABLES +*******************************************************************************/ +#if !defined(__WINDOWS__) +extern WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head; +#endif + + +/******************************************************************************* +** FUNCTION PROTOTYPES +*******************************************************************************/ +static int32_t bri_global_config(void* pfe); +static int32_t bri_global_unconfig(void* pfe); +static int32_t wp_bri_config(void *pfe); +static int32_t wp_bri_unconfig(void *pfe); +static int32_t wp_bri_post_init(void *pfe); +static int32_t wp_bri_if_config(void *pfe, u32 mod_map, u8); +static int32_t wp_bri_if_unconfig(void *pfe, u32 mod_map, u8); +static int32_t wp_bri_disable_irq(sdla_fe_t *fe, u32 mod_no, u8 port_no); +static void bri_enable_interrupts(sdla_fe_t *fe, u32 mod_no, u8 port_no); +static int32_t wp_bri_intr(sdla_fe_t *); +static int32_t wp_bri_check_intr(sdla_fe_t *); +static int32_t wp_bri_polling(sdla_fe_t*); +static int32_t wp_bri_udp(sdla_fe_t*, void*, u8*); +static u32 wp_bri_active_map(sdla_fe_t* fe, u8 line_no); +static u8 wp_bri_fe_media(sdla_fe_t *fe); +static int32_t wp_bri_set_dtmf(sdla_fe_t*, int32_t, u8); +static int wp_bri_intr_ctrl(sdla_fe_t *fe, int, u_int8_t, u_int8_t, unsigned int); +static int wp_bri_event_ctrl(sdla_fe_t*, wan_event_ctrl_t*); + +static int wp_bri_pre_release(void* pfe); + +static int32_t wp_bri_dchan_tx(sdla_fe_t *fe, void *src_data_buffer, u32 buffer_len); + +static void *wp_bri_dchan_rx(sdla_fe_t *fe, u8 mod_no, u8 port_no); + +static int wp_bri_get_fe_status(sdla_fe_t *fe, unsigned char *status); +static int wp_bri_set_fe_status(sdla_fe_t *fe, unsigned char status); + + +/*******************************************************************************/ +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +static void l1_timer_expire_t3(void* pfe); +static void l1_timer_expire_t4(void* pfe); +#elif defined(__WINDOWS__) +static void l1_timer_expire_t3(IN PKDPC Dpc, void* pfe, void* arg2, void* arg3); +static void l1_timer_expire_t4(IN PKDPC Dpc, void* pfe, void* arg2, void* arg3); +#else +static void l1_timer_expire_t3(unsigned long pfe); +static void l1_timer_expire_t4(unsigned long pfe); +#endif + +static void l1_timer_start_t3(void *pport); +static void l1_timer_stop_t3(void *pport); +static void l1_timer_start_t4(void *pport); +static void l1_timer_stop_t4(void *pport); +/*******************************************************************************/ + +#if defined(AFT_TDM_API_SUPPORT) +static int32_t wp_bri_watchdog(sdla_fe_t *fe); +#endif + +static int32_t wp_bri_spi_bus_reset(sdla_fe_t *fe); +static int32_t reset_chip(sdla_fe_t *fe, u32 mod_no); +static int32_t init_xfhc(sdla_fe_t *fe, u32 mod_no); +static void xhfc_select_fifo(sdla_fe_t *fe, u32 mod_no, u8 fifo); +static void xhfc_waitbusy(sdla_fe_t *fe, u32 mod_no); +static void xhfc_select_pcm_slot(sdla_fe_t *fe, u32 mod_no, u8 slot, u8 direction); +static void xhfc_increment_fifo(sdla_fe_t *fe, u32 mod_no); +static int32_t config_clock_routing(sdla_fe_t *fe, u32 mod_no, u8 master_mode); +static int32_t clock_control(sdla_fe_t *fe, u8 line_state); +static void xhfc_ph_command(sdla_fe_t *fe, bri_xhfc_port_t *port, u_char command); + +static u8 __su_new_state(sdla_fe_t *fe, u32 mod_no, u8 port_no); +static void sdla_bri_set_status(sdla_fe_t* fe, u8 mod_no, u8 port_no, u8 status); + +/* for selecting PCM direction */ +#define XHFC_DIRECTION_TX 0 +#define XHFC_DIRECTION_RX 1 + +#if 0 +static void xhfc_select_xhfc_channel(sdla_fe_t *fe, u32 mod_no, + u8 channel, u8 direction, u8 vrout_bitmap); +#endif + +static int32_t check_f0cl_increment(sdla_fe_t *fe, u8 old_f0cl, u8 new_f0cl, int32_t *diff); + +/******************************************************************************* +** FUNCTION DEFINITIONS +*******************************************************************************/ + + +/*******************************************************************************/ + +static +u8 _read_xhfc(sdla_fe_t *fe, u32 mod_no, u8 reg, const char *caller_name, int32_t file_lineno) +{ + u8 val = READ_BRI_REG(mod_no, reg); + +#if WAN_DEBUG_BRI_REG /* extra heavy debugging for the chip */ + switch(reg) + { + case R_FIFO: + decode_reg_r_fifo(val, HFC_READ); + break; + case R_SLOT: + decode_reg_r_slot(val, HFC_READ); + break; + case R_SU_IRQMSK: + decode_reg_r_su_irqmsk(val, HFC_READ); + break; + case R_FIFO_MD: + decode_reg_r_fifo_md(val, HFC_READ); + break; + case R_PCM_MD0: + decode_reg_r_pcm_md0(val, HFC_READ); + break; + case A_SL_CFG: + decode_reg_a_sl_cfg(val, HFC_READ); + break; + case A_CON_HDLC: + decode_reg_a_con_hdlc(val, HFC_READ); + break; + case A_FIFO_STA: + decode_reg_a_fifo_sta(val, HFC_READ); + break; + case A_SU_RD_STA: + decode_reg_a_su_rd_sta(val, HFC_READ); + break; + default: + ;/* DEBUG_HFC_MODE("HFC_READ: reg decoder unknow reg: 0x%X.\n", reg); */ + } +#endif + + return val; +} + +static +int32_t _write_xhfc(sdla_fe_t *fe, u32 mod_no, u8 reg, u8 val, const char *caller_name, int32_t file_lineno) +{ +#if WAN_DEBUG_BRI_REG /* extra heavy debugging for the chip */ + switch(reg) + { + case R_FIFO: + decode_reg_r_fifo(val, HFC_WRITE); + break; + case R_SLOT: + decode_reg_r_slot(val, HFC_WRITE); + break; + case R_SU_IRQMSK: + decode_reg_r_su_irqmsk(val, HFC_WRITE); + break; + case R_FIFO_MD: + decode_reg_r_fifo_md(val, HFC_WRITE); + break; + case R_PCM_MD0: + decode_reg_r_pcm_md0(val, HFC_WRITE); + break; + case A_SL_CFG: + decode_reg_a_sl_cfg(val, HFC_WRITE); + break; + case A_CON_HDLC: + decode_reg_a_con_hdlc(val, HFC_WRITE); + break; + case A_FIFO_STA: + decode_reg_a_fifo_sta(val, HFC_WRITE); + break; + case A_SU_RD_STA: + decode_reg_a_su_rd_sta(val, HFC_WRITE); + break; + default: + ;/* DEBUG_HFC_MODE("HFC_WRITE: reg decoder unknow reg: 0x%X.\n", reg); */ + } +#endif + return WRITE_BRI_REG(mod_no, reg, val); +} + +#if WAN_DEBUG_BRI_REG /* extra heavy debugging for the chip */ + +static const char* decode_hfc_direction(__u8 read_or_write_direction) +{ + switch(read_or_write_direction) + { + case HFC_WRITE: + return "HFC_WRITE"; + case HFC_READ: + return "HFC_READ"; + default: + return "Unknown HFC direction!!"; + } +} + +static void decode_reg_r_fifo(__u8 data, __u8 read_or_write_direction) +{ + reg_r_fifo r_fifo; + + r_fifo.reg = data; + + DEBUG_HFC_MODE("%s:R_FIFO=0x%02X: v_fifo_dir: 0x%X (%s) v_fifo_num: %d reserved_9: 0x%X v_rev: 0x%X\n", + decode_hfc_direction(read_or_write_direction), + data, + r_fifo.bit.v_fifo_dir, + (r_fifo.bit.v_fifo_dir == XHFC_DIRECTION_TX ? "Tx" : "Rx"), + r_fifo.bit.v_fifo_num, + r_fifo.bit.reserved_9, + r_fifo.bit.v_rev); +} + +static void decode_reg_r_slot(__u8 data, __u8 read_or_write_direction) +{ + reg_r_slot r_slot; + + r_slot.reg = data; + + DEBUG_HFC_MODE("%s:R_SLOT=0x%02X: PCM v_sl_dir: %s, PCM v_sl_num: %d\n", + decode_hfc_direction(read_or_write_direction), + data, + (r_slot.bit.v_sl_dir == XHFC_DIRECTION_TX ? "Tx" : "Rx"), + r_slot.bit.v_sl_num); +} + +static void decode_reg_a_sl_cfg(__u8 data, __u8 read_or_write_direction) +{ + reg_a_sl_cfg a_sl_cfg; + + a_sl_cfg.reg = data; + + DEBUG_HFC_MODE("%s:A_SL_CFG=0x%02X: v_ch_sdir: %s, v_ch_snum: %d, v_rout: %d\n", + decode_hfc_direction(read_or_write_direction), + data, + (a_sl_cfg.bit.v_ch_sdir == XHFC_DIRECTION_TX ? "Tx" : "Rx"), + a_sl_cfg.bit.v_ch_snum, + a_sl_cfg.bit.v_rout); +} + +static void decode_reg_a_con_hdlc(__u8 data, __u8 read_or_write_direction) +{ + reg_a_con_hdlc a_con_hdlc; + + a_con_hdlc.reg = data; + + DEBUG_HFC_MODE("%s:A_CON_HDLC=0x%02X: v_iff: 0x%X, HDLC or TRANSP (v_hdlc_trp): 0x%X, v_fifo_irq: 0x%X, v_data_flow: 0x%X\n", + decode_hfc_direction(read_or_write_direction), + data, + a_con_hdlc.bit.v_iff, + a_con_hdlc.bit.v_hdlc_trp, + a_con_hdlc.bit.v_fifo_irq, + a_con_hdlc.bit.v_data_flow); +} + +static void decode_reg_a_fifo_sta(__u8 data, __u8 read_or_write_direction) +{ + reg_a_fifo_sta a_fifo_sta; + + a_fifo_sta.reg = data; + + DEBUG_HFC_MODE("%s:A_FIFO_STA=0x%02X: v_fifo_err: 0x%X, v_abo_done: 0x%X\n", + decode_hfc_direction(read_or_write_direction), + data, + a_fifo_sta.bit.v_fifo_err, + a_fifo_sta.bit.v_abo_done); +} + +static void decode_reg_a_su_rd_sta(__u8 data, __u8 read_or_write_direction) +{ + reg_a_su_rd_sta a_su_rd_sta; + + a_su_rd_sta.reg = data; + + DEBUG_HFC_MODE( +"%s:A_SU_RD_STA=0x%02X: v_su_sta: 0x%X, v_su_fr_sync: 0x%X, v_su_t2_exp: 0x%X, v_su_info0: 0x%X, v_g2_g3: 0x%X,\n", + decode_hfc_direction(read_or_write_direction), + data, + a_su_rd_sta.bit.v_su_sta, + a_su_rd_sta.bit.v_su_fr_sync, + a_su_rd_sta.bit.v_su_t2_exp, + a_su_rd_sta.bit.v_su_info0, + a_su_rd_sta.bit.v_g2_g3); +} + + +static void decode_reg_r_su_irqmsk(__u8 data, __u8 read_or_write_direction) +{ + reg_r_su_irqmsk r_su_irqmsk; + + r_su_irqmsk.reg = data; + + DEBUG_HFC_MODE("%s:R_SU_IRQMSK=0x%02X: v_su0_irqmsk: 0x%X v_su1_irqmsk: 0x%X v_su2_irqmsk: 0x%X v_su3_irqmsk: 0x%X reserved_29: 0x%X\n", + decode_hfc_direction(read_or_write_direction), + data, + r_su_irqmsk.bit.v_su0_irqmsk, + r_su_irqmsk.bit.v_su1_irqmsk, + r_su_irqmsk.bit.v_su2_irqmsk, + r_su_irqmsk.bit.v_su3_irqmsk, + r_su_irqmsk.bit.reserved_29); +} + +static void decode_reg_r_fifo_md(__u8 data, __u8 read_or_write_direction) +{ + reg_r_fifo_md r_fifo_md; + + r_fifo_md.reg = data; + + DEBUG_HFC_MODE("%s:R_FIFO_MD=0x%02X: v_fifo_md: 0x%X v_df_md: 0x%X v_unidir_md: 0x%X v_unidir_rx: 0x%X reserved_7: 0x%X\n", + decode_hfc_direction(read_or_write_direction), + data, + r_fifo_md.bit.v_fifo_md, + r_fifo_md.bit.v_df_md, + r_fifo_md.bit.v_unidir_md, + r_fifo_md.bit.v_unidir_rx, + r_fifo_md.bit.reserved_7); +} + +static void decode_reg_r_pcm_md0(__u8 data, __u8 read_or_write_direction) +{ + reg_r_pcm_md0 r_pcm_md0; + + r_pcm_md0.reg = data; + + DEBUG_HFC_MODE("%s:R_PCM_MD0=0x%02X: v_pcm_md: 0x%X v_c4_pol: 0x%X v_f0_neg: 0x%X v_f0_len: 0x%X v_pcm_idx: 0x%X\n", + decode_hfc_direction(read_or_write_direction), + data, + r_pcm_md0.bit.v_pcm_md, + r_pcm_md0.bit.v_c4_pol, + r_pcm_md0.bit.v_f0_neg, + r_pcm_md0.bit.v_f0_len, + r_pcm_md0.bit.v_pcm_idx); +} +#endif /* WAN_DEBUG_BRI_REG */ + +/*******************************************************************************/ + +static void xhfc_waitbusy(sdla_fe_t *fe, u32 mod_no) +{ + u32 wait_counter = 0; +#define MAX_XHFC_WAIT_COUNTER 10000 + + do{ + if(!(READ_REG(R_STATUS) & M_BUSY)){ + break; + } + }while(wait_counter++ < MAX_XHFC_WAIT_COUNTER); + + if(wait_counter >= MAX_XHFC_WAIT_COUNTER){ + DEBUG_EVENT("%s: %s() time out!\n", fe->name, __FUNCTION__); + } +} + +static void xhfc_select_fifo(sdla_fe_t *fe, u32 mod_no, u8 fifo) +{ + WRITE_REG(R_FIFO, fifo); + xhfc_waitbusy(fe, mod_no); +} + +static void xhfc_select_pcm_slot(sdla_fe_t *fe, u32 mod_no, u8 slot, u8 direction) +{ + reg_r_slot r_slot; + + memset(&r_slot, 0, sizeof(reg_r_slot)); + + r_slot.bit.v_sl_dir = direction; + r_slot.bit.v_sl_num = slot; + + WRITE_REG(R_SLOT, r_slot.reg); + xhfc_waitbusy(fe, mod_no); +} + +#if 0 +static void xhfc_select_xhfc_channel(sdla_fe_t *fe, u32 mod_no, + u8 channel, u8 direction, u8 vrout_bitmap) +{ + reg_a_sl_cfg a_sl_cfg; + memset(&a_sl_cfg, 0, sizeof(reg_a_sl_cfg)); + + a_sl_cfg.bit.v_ch_sdir = direction; /* 1 bit */ + a_sl_cfg.bit.v_ch_snum = channel; /* 5 bits */ + a_sl_cfg.bit.v_rout = vrout_bitmap; + + WRITE_REG(A_SL_CFG, a_sl_cfg.reg); + xhfc_waitbusy(fe, mod_no); +} +#endif + +static void xhfc_increment_fifo(sdla_fe_t *fe, u32 mod_no) +{ + WRITE_REG(A_INC_RES_FIFO, M_INC_F); + xhfc_waitbusy(fe, mod_no); +} + +static u32 calculate_pcm_timeslot(u32 mod_no, u8 port_no, u8 bchan) +{ + u32 pcm_slot; +#if 0 + DEBUG_HFC_INIT("port_no: %d, bchan: %d\n", port_no, bchan); +#endif + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return 0; + } + + pcm_slot = 2*port_no + bchan; /* 0, 1, 2, 3 */ + pcm_slot *= 2; /* 0, 2, 4, 6 */ + pcm_slot += (4*mod_no); /* mod_no is 0,2,4.... -->0+0, 0+8, 0+16 */ + + return pcm_slot; +} + +static int32_t reset_chip(sdla_fe_t *fe, u32 mod_no) +{ + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + int32_t err = 0; + + + DEBUG_HFC_INIT("%s(): mod_no: %d\n", __FUNCTION__, mod_no); + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return 1; + } + + bri_module = &bri->mod[mod_no]; + + /* read ChipID from Read Only register R_CHIP_ID */ + fe->fe_chip_id = READ_REG(R_CHIP_ID); + switch (fe->fe_chip_id) + { + case CHIP_ID_2SU: + bri_module->num_ports = 2; + bri_module->max_fifo = 8; + bri_module->max_z = 0x7F; + /* set fifo mode 8 tx and 8 rx fifos */ + WRITE_REG( R_FIFO_MD, M1_FIFO_MD * 1); + break; + default: + err = 1; + DEBUG_EVENT("%s: %s(): unknown Chip ID 0x%x!\n", + fe->name, __FUNCTION__, fe->fe_chip_id); + return err; + } + + /* general soft chip reset */ + WRITE_REG(R_CIRM, M_SRES); + WP_DELAY(5); + WRITE_REG(R_CIRM, 0); + /* wait for XHFC init seqeuence to be finished */ + WP_DELAY(1000); + + + return 0; +} + +static int32_t clock_control(sdla_fe_t *fe, u8 line_state) +{ + sdla_t *card = (sdla_t*)fe->card; + u_int32_t reg; + + DEBUG_HFC_CLOCK("%s(): line_state: %d\n", __FUNCTION__, line_state); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),®); + DEBUG_HFC_CLOCK("Original AFT_LINE_CFG_REG: 0x%X\n", reg); + + if (line_state == 1){ + /* The 'Reference' line is connected, enable sync from line interface */ + + if (wan_test_bit(A500_LINE_SYNC_MASTER_BIT, ®)) { + return 0; + } + + DEBUG_HFC_CLOCK("'Reference' line is connected, enable sync from line interface\n"); + wan_set_bit(A500_LINE_SYNC_MASTER_BIT, ®); + } + if (line_state == 0){ + /* The 'Reference' line is DISconnected, disable sync from line interface */ + + if (!wan_test_bit(A500_LINE_SYNC_MASTER_BIT, ®)) { + return 0; + } + + DEBUG_HFC_CLOCK("'Reference' line is disconnected, disable sync from line interface\n"); + wan_clear_bit(A500_LINE_SYNC_MASTER_BIT, ®); + } + + DEBUG_HFC_CLOCK("New AFT_LINE_CFG_REG: 0x%X\n", reg); + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_LINE_CFG_REG),reg); + + return 0; +} + +static int32_t config_clock_routing(sdla_fe_t *fe, u32 mod_no, u8 master_mode) +{ + reg_r_pcm_md0 pcm_md0; + reg_r_pcm_md2 r_pcm_md2; + reg_r_gpio_sel r_gpio_sel; + reg_r_gpio_en0 r_gpio_en0; + + DEBUG_HFC_CLOCK("%s(): mod_no: %d\n", __FUNCTION__, mod_no); + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return 1; + } + + DEBUG_EVENT("%s: Module %d: configuring clock routing (SYNC_O is %s)...\n", + fe->name, REPORT_MOD_NO, (master_mode == WANOPT_YES ? "Enabled" : "Disabled")); + + /************************************************************************/ +#if 0 + { + reg_r_su_sync r_su_sync; + r_su_sync.reg = 0; + if(master_mode == WANOPT_YES){ + CLOCK_FUNC(); + //r_su_sync.bit.v_sync_sel = 0; //000 = source is line interface 0 + //r_su_sync.bit.v_man_sync = 1; + //r_su_sync.bit.v_auto_synci = 1; + }else{ + CLOCK_FUNC(); + + } + WRITE_REG(R_SU_SYNC, r_su_sync.reg); + } +#endif + /************************************************************************/ + r_gpio_sel.reg = 0; + r_gpio_en0.reg = 0; + if(master_mode == WANOPT_YES){ + CLOCK_FUNC(); + /* select 1-st function of pin 16 - SYNC_O. page 315. */ + r_gpio_sel.bit.v_gpio_sel6 = 0; + + /* enable output on pin 16 - page 314.*/ + r_gpio_en0.bit.v_gpio_en6 = 1; + }else{ + CLOCK_FUNC(); + /* if in NORMAL mode, do NOT provide output on 16, + so there is only one clock source - the master. */ + + /* select 2-nd function of pin 16 - GPIO6. page 315.*/ + r_gpio_sel.bit.v_gpio_sel6 = 1; + + /* DISABLE output on pin 16 - page 314. */ + r_gpio_en0.bit.v_gpio_en6 = 0; + } + WRITE_REG(R_GPIO_SEL, r_gpio_sel.reg); + WRITE_REG(R_GPIO_EN0, r_gpio_en0.reg); + + /************************************************************************/ +#if 1 + pcm_md0.reg = 0; + pcm_md0.bit.v_pcm_idx = 0xA; /* get access to R_PCM_MD2 */ + WRITE_REG(R_PCM_MD0, pcm_md0.reg); + + r_pcm_md2.reg = 0; + if(master_mode == WANOPT_YES){ + CLOCK_FUNC(); + r_pcm_md2.bit.v_sync_out1 = 0;/* 0 = SYNC_O is either SYNC_I or the received + synchronization pulse. page 244. */ + }else{ + /* r_pcm_md2.bit.v_sync_out1 = 1;*/ /* 1 = SYNC_O is either 512 kHz from the PLL or + the received multiframe / superframe + synchronization pulse. page 244. */ + } + + r_pcm_md2.bit.v_sync_out2 = 0;/* SYNC_O output selection + 0 = ST/Up receive from the selected line interface + in TE mode (see R_SU_SYNC register for synchronization source selection) + 1 = SYNC_I is connected to SYNC_O. page 244. */ +#if 0 + if(master_mode == WANOPT_NO){ + r_pcm_md2.bit.v_sync_src = 1; /*V_SYNC_SRC PCM PLL synchronization source selection + 0 = line interface (see R_SU_SYNC for further + synchronization configuration) + 1 = SYNC_I input (8 kHz). page 244. + */ + } +#endif + + WRITE_REG(R_PCM_MD2, r_pcm_md2.reg); +#endif + /************************************************************************/ + + return 0; +} + +/****************************************************************************** +* init_xfhc() +* +* Description : Physical module global configuration. Should be done only one +* time per-module. +* Assuming chip was already reset. +* +* Arguments : pfe - pointer to Front End structure. +* mod_no - module number. +* +* Returns : 0 - configred successfully, otherwise non-zero value. +*******************************************************************************/ +static int32_t init_xfhc(sdla_fe_t *fe, u32 mod_no) +{ + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + int32_t err = 0, i, timeout = 0x2000; + + u8 port_no, bchan; + reg_a_su_ctrl0 a_su_ctrl0; + reg_a_su_ctrl1 a_su_ctrl1; + reg_a_su_rd_sta a_su_rd_sta; + reg_r_fifo_thres r_fifo_thres; + + DEBUG_HFC_INIT("%s(): mod_no: %d\n", __FUNCTION__, mod_no); + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return 1; + } + + bri_module = &bri->mod[mod_no]; + + DBG_MODULE_TESTER("read ChipID from Read Only register R_CHIP_ID: must be 0x61\n"); + + /* read ChipID from Read Only register R_CHIP_ID */ + fe->fe_chip_id = READ_REG(R_CHIP_ID); + switch (fe->fe_chip_id) + { + case CHIP_ID_2SU: + DEBUG_EVENT("%s: Detected XHFC-2SU chip.\n", fe->name); + bri_module->num_ports = 2; + bri_module->max_fifo = 8; + bri_module->max_z = 0x7F; + DBG_MODULE_TESTER("configure FIFOs\n"); + /* 01 = 8 FIFOs with 128 bytes for TX and RX each. page 125 */ + WRITE_REG( R_FIFO_MD, M1_FIFO_MD * 1); + break; + default: + err = 1; + DEBUG_EVENT("%s: %s(): unknown Chip ID 0x%x!\n", + fe->name, __FUNCTION__, fe->fe_chip_id); + return err; + } + + a_su_ctrl0.reg = 0; + a_su_ctrl1.reg = 0; + a_su_rd_sta.reg = 0; + + DBG_MODULE_TESTER("general soft chip reset\n"); + /* general soft chip reset */ + WRITE_REG(R_CIRM, M_SRES); + WP_DELAY(5); + WRITE_REG(R_CIRM, 0); + + /* amplitude */ + WRITE_REG(R_PWM_MD, 0x80); + WRITE_REG(R_PWM1, 0x18); + + /* Set FIFO threshold. page 124.*/ + r_fifo_thres.reg = 0; + r_fifo_thres.bit.v_thres_tx = r_fifo_thres.bit.v_thres_rx = FIFO_THRESHOLD_INDEX; + WRITE_REG(R_FIFO_THRES, r_fifo_thres.reg); + + DBG_MODULE_TESTER("wait 1 second for XHFC init seqeuence to be finished\n"); + /* wait for XHFC init seqeuence to be finished */ + WP_DELAY(1000); + + DBG_MODULE_TESTER("read chip 'busy' bit\n"); + while ((READ_REG(R_STATUS) & (M_BUSY | M_PCM_INIT)) && (timeout)){ + CLOCK_FUNC(); + timeout--; + } + + if (!(timeout)) { + DEBUG_EVENT("%s: %s(): Error: chip initialization sequence timeout!\n", + fe->name, __FUNCTION__); + return 1; + } + + + /* PCM: 1. Slave mode 2. PCM64 (4MBit/s data rate). */ + /* slow PCM adjust speed */ + bri_module->pcm_md1.bit.v_pll_adj = 3; + bri_module->pcm_md1.bit.v_pcm_dr = 1; /* dr stands for 'data rate' (64) */ + + WRITE_REG(R_PCM_MD0, bri_module->pcm_md0.reg + 0x90); /* get access to R_PCM_MD1 */ + WRITE_REG(R_PCM_MD1, bri_module->pcm_md1.reg); + + /* After chip reset SYNC_O is set for OUTPUT by default, make sure + SYNC_O is set for INPUT! Otherwise may cause clock conflict. + */ + config_clock_routing(fe, mod_no, WANOPT_NO); + + DEBUG_HFC_INIT("\n%s: configuring B-channels FIFOs...\n", fe->name); + /* configure B channel fifos for ST<->PCM data flow */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) {/* 2 ports */ + DEBUG_HFC_INIT("=========== port_no: %d ========\n", port_no); + for (bchan = 0; bchan < 2; bchan++) { /* 2 B channels on each port_no */ + DEBUG_HFC_INIT("port_no: %d, bchan: %d\n", port_no, bchan); + /* B chan - Tx of port_no */ + xhfc_select_fifo(fe, mod_no, port_no*8 + bchan*2); + /* ST-->PCM, channel enabled */ + WRITE_REG(A_CON_HDLC, 0xde);/* page 83: Tx, Transparent, ST/U-->PCM */ + /* 64kbit/s */ + WRITE_REG(A_SUBCH_CFG, 0); + /* no interrupts */ + WRITE_REG(A_FIFO_CTRL, 0); + + /* B chan - Rx of port_no */ + xhfc_select_fifo(fe, mod_no, port_no*8 + bchan*2 + 1); + /* ST<--PCM, channel enabled */ + WRITE_REG(A_CON_HDLC, 0xde);/* page 83: Rx, Transparent, ST/U<--PCM */ + /* 64kbit/s */ + WRITE_REG(A_SUBCH_CFG, 0); + /* no interrupts */ + WRITE_REG(A_FIFO_CTRL, 0); + } + } + DEBUG_HFC_INIT("\nDone\n"); + + DEBUG_HFC_INIT("\nconfiguring D-channel FIFOs...\n"); + /* configure D channel fifos */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + reg_a_con_hdlc a_con_hdlc; + + a_con_hdlc.reg = 0; + + a_con_hdlc.bit.v_iff = 1;/* InterFrameFill=ones */ + /* Interrupt every 2^n bytes. n = V_FIFO_IRQ+2 in register A_CON_HDLC. p. 137 */ + /*a_con_hdlc.bit.v_fifo_irq = 3;*/ /* 2^(3+2) = 32 bytes an interrupt is generated */ + a_con_hdlc.bit.v_fifo_irq = 4; /* 2^(4+2) = 64 bytes an interrupt is generated */ + + DEBUG_HFC_INIT("=========== port_no: %d ========\n", port_no); + /* D - Tx of port_no */ + xhfc_select_fifo(fe, mod_no, port_no*8 + 4); + /* FIFO-->ST, channel enabled, IFF=ones */ + WRITE_REG(A_CON_HDLC, a_con_hdlc.reg); + /* 16kbit/s */ + WRITE_REG(A_SUBCH_CFG, 2); +#if 0 + /* interrupts at end of frame only */ + WRITE_REG(A_FIFO_CTRL, 1); +#else + /* Interrupts at end of frame AND at fifo threshold. + Will work as 'transmit interrupt'. */ + WRITE_REG(A_FIFO_CTRL, 0x5); +#endif + + /* D - Rx of port_no */ + xhfc_select_fifo(fe, mod_no, port_no*8 + 4 + 1); + /* ST--> FIFO, channel enabled */ + WRITE_REG(A_CON_HDLC, a_con_hdlc.reg); + /* 16kbit/s */ + WRITE_REG(A_SUBCH_CFG, 2); +#if 0 + /* interrupts at end of frame only */ + WRITE_REG(A_FIFO_CTRL, 1); +#else + /* interrupts at end of frame AND at fifo threshold */ + WRITE_REG(A_FIFO_CTRL, 0x5); +#endif + } + DEBUG_HFC_INIT("\nDone\n"); + + DEBUG_HFC_INIT("Configure PCM time slots\n"); + /* Configure PCM time slots. + B-chan data will use PCM64 bus. D-chan data will use SPI. + */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + for (bchan = 0; bchan < 2; bchan++) { + + u_int8_t pcm_slot; + + DEBUG_HFC_INIT("port_no: %d, bchan: %d\n", port_no, bchan); + + if(mod_no >= MAX_BRI_MODULES){ + /* adjust mod_no to be between 0 and 10 (including)*/ + pcm_slot = calculate_pcm_timeslot(mod_no - MAX_BRI_MODULES, port_no, bchan); + /* AFT Line 1 will use odd PCM timeslots */ + pcm_slot += 1; + }else{ + /* AFT Line 0 will use even PCM timeslots */ + pcm_slot = calculate_pcm_timeslot(mod_no, port_no, bchan); + } + + DEBUG_HFC_INIT("selecting TX pcm_slot: %d\n", pcm_slot); + + /*****************************************************************************************/ + /* transmit slot - select direction TX */ + xhfc_select_pcm_slot(fe, mod_no, pcm_slot, XHFC_DIRECTION_TX); + + /* Connect time slot with channel and pin. + PCM data output on pin STIO2 (+0x40 swap pins) + 0x80+0x40==0xC0==11000000 -> v_rout==0x3 -> "output buffer for STIO2 enabled" page 257. + 0*8 + 0*2 = 0 --> HFC channel 0. + + Assign HFC channel (from 0 to 15) to the selected PCM slot. + */ + WRITE_REG(A_SL_CFG,0x80+0x40+port_no*8+bchan*2); /* assign HFC channel (from 0 to 15) + to the selected PCM slot. */ + + /*****************************************************************************************/ + /* receive slot - select direction RX */ + DEBUG_HFC_INIT("selecting RX pcm_slot: %d\n", pcm_slot); + + xhfc_select_pcm_slot(fe, mod_no, pcm_slot, XHFC_DIRECTION_RX); + + /* Connect time slot with channel and pin. + PCM data input from pin STIO1 (+0x40 swap pins). + Assign HFC channel (from 0 to 15) to the selected PCM slot. + */ + WRITE_REG(A_SL_CFG,0x80+0x40+port_no*8+bchan*2+1);/* assign HFC channel (from 0 to 15) + to the selected PCM slot. */ + }/* for (bchan = 0; bchan < 2; bchan++) */ + }/* for (port_no = 0; port_no < bri_module->num_ports; port_no++) */ + + DBG_MODULE_TESTER("configure ST ports\n"); + /* configure ST ports */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + u8 old_f0cl, new_f0cl; + int32_t f0cl_diff; + + DEBUG_HFC_INIT("%s(): configurig ST port_no: %d\n", __FUNCTION__, port_no); + + WRITE_REG(R_SU_SEL, port_no); + + switch(bri_module->type) + { + case MOD_TYPE_TE: + WRITE_REG(A_SU_CLK_DLY, CLK_DLY_TE); + + /* TE, ST B1+B2 tx enabled, end of pulse control enabled */ + WRITE_REG(A_SU_CTRL0, 0x43); + break; + + case MOD_TYPE_NT: + WRITE_REG(A_SU_CLK_DLY, CLK_DLY_NT); + + /* NT, ST B1+B2 tx enabled, end of pulse control enabled */ + a_su_ctrl0.bit.v_b1_tx_en = 1; + a_su_ctrl0.bit.v_b2_tx_en = 1; + a_su_ctrl0.bit.v_su_md = 1; + WRITE_REG(A_SU_CTRL0, a_su_ctrl0.reg); + break; + } + + /* reset default. TE and NT */ + WRITE_REG(A_SU_CTRL1, 0x0); + + switch(bri_module->type) + { + case MOD_TYPE_NT: + /* enables automatic transition G2->G3 */ + WRITE_REG(A_SU_CTRL1, M_G2_G3_EN); + break; + } + + /* ST B1+B2 rx enabled */ + WRITE_REG(A_SU_CTRL2, 0x3); + + /* end of pulse control for layer 1 compliance */ + WRITE_REG(A_ST_CTRL3, 0xf8); + + /* WRITE_REG(R_SU_SEL, port_no); */ +#if BUILD_MOD_TESTER + DBG_MODULE_TESTER("Activate ST port_no state machines (NT only!!)\n"); + /* try to activate port_no */ + switch(bri_module->type) + { + case MOD_TYPE_TE: + /*WRITE_REG(A_SU_WR_STA, STA_ACTIVATE);*/ + break; + case MOD_TYPE_NT: + WRITE_REG(A_SU_WR_STA, STA_ACTIVATE | M_SU_SET_G2_G3); + break; + } +#endif + DBG_MODULE_TESTER("poll R_F0_CNTL to make sure PCM is connected\n"); + + /* poll R_F0_CNTL to make sure PCM is connected */ + for (i = 0; i < 10; i++) { + + DBG_MODULE_TESTER("get current R_F0_CNTL\n"); + + old_f0cl=READ_REG(R_F0_CNTL); + DBG_MODULE_TESTER("wait for 10ms - f0cl should be incremented by 80 (+- 10 is ok)\n"); + /* wait for 10ms - f0cl should be incremented by 80 (+- 10 is ok) */ + WP_MDELAY(10); + + DBG_MODULE_TESTER("get the R_F0_CNTL after the wait\n"); + new_f0cl=READ_REG(R_F0_CNTL); + + if(check_f0cl_increment(fe, old_f0cl, new_f0cl, &f0cl_diff)){ + return 1; + } + } + + DEBUG_EVENT("%s: Module: %d, PCM 125us pulse ok. (f0cl diff: %d)\n", + fe->name, REPORT_MOD_NO + port_no, f0cl_diff); + + }/* for (port_no = 0; port_no < bri_module->num_ports; port_no++) */ + + /* init line interfaces state machines (in software only!) */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + + bri_module->port[port_no].idx = port_no; + bri_module->port[port_no].hw = bri_module; + + /*wan_set_bit(HFC_L1_ACTIVATING, &bri_module->port[port_no].l1_flags);*/ + + }/* for (port_no = 0; port_no < bri_module->num_ports; port_no++) */ + +#if BUILD_MOD_TESTER + /* for debugging only - read line status */ + WP_MDELAY(300); + + DBG_MODULE_TESTER("read line status - Connected/Disconnected\n"); + /* read line status - Connected/Disconnected */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + + DBG_MODULE_TESTER("select port_no %d\n", port_no); + WRITE_REG(R_SU_SEL, port_no); + + /* poll line status register for around 5ms */ + for (i = 0; i < 5; i++) { + u8 line_status; + + DBG_MODULE_TESTER("read ST line status for port_no %d\n", port_no); + /* read ST line status*/ + a_su_rd_sta.reg = line_status = READ_REG(A_SU_RD_STA); + + if(bri_module->type == MOD_TYPE_TE){ + DEBUG_HFC_S0_STATES("%d: TE: force F7 - pt:%d line status: 0x%02x, v_su_fr_sync: %d\n", + i, port_no, line_status, a_su_rd_sta.bit.v_su_fr_sync); + }else{ + DEBUG_HFC_S0_STATES("%d: NT: force G3 - pt:%d line status: 0x%02x, v_su_fr_sync: %d\n", + i, port_no, line_status, a_su_rd_sta.bit.v_su_fr_sync); + } + + DBG_MODULE_TESTER("a_su_rd_sta.bit.v_su_fr_sync: %d (0-Disconnected, 1-Connected)\n", a_su_rd_sta.bit.v_su_fr_sync); + + WP_MDELAY(200); + } + } +#endif + DBG_MODULE_TESTER("%s(): finished\n", __FUNCTION__); + + return 0; +} + +static int32_t check_f0cl_increment(sdla_fe_t *fe, u8 old_f0cl, u8 new_f0cl, int32_t *diff) +{ + *diff = new_f0cl - old_f0cl; + if(*diff < 0){ + *diff = 255 - old_f0cl; + *diff += new_f0cl; + } + + /* should be between 70 and 90 over 10ms time */ + if(*diff > 90 || *diff < 70){ + DEBUG_EVENT("%s: PCM ERROR 125us pulse not counting!! f0cl diff: %d\n", + fe->name, *diff); + return 1; + } + + DBG_MODULE_TESTER("f0cl diff: %d\n", *diff); + return 0; +} + +typedef enum _DCHAN_RC{ + DCHAN_STATUS_BUSY = 1, + DCHAN_STATUS_COMPLETE, + DCHAN_STATUS_INCOMPLETE, + DCHAN_STATUS_EMPTY +}DCHAN_RC; + +#define TX_EMPTY_FIFO 1 + +static int xhfc_write_fifo_dchan(sdla_fe_t *fe, u8 mod_no, + wp_bri_module_t *bri_module, bri_xhfc_port_t *port, + u8 *free_space) +{ + u8 *buf = NULL; + int *len = NULL, + *idx = NULL; + u8 fcnt, tcnt, i; + u8 free; + u8 f1, f2; + reg_a_fifo_sta fstat; + u8 *data; + u8 rc; + sdla_t *card = (sdla_t*)fe->card; + private_area_t *chan=NULL; + int fifo_usage; + + buf = port->dtxbuf; /* data buffer */ + len = &port->bytes2transmit; /* hdlc packet len */ + idx = &port->dtx_indx; /* already transmitted */ + + DEBUG_HFC_TX("%s(): *len: %d\n", __FUNCTION__, *len); + + /* select the D-channel TX fifo */ + xhfc_select_fifo(fe, mod_no, (port->idx*8+4)); + + fstat.reg = READ_REG(A_FIFO_STA); + if (fstat.reg) WRITE_REG( A_INC_RES_FIFO, 8); + + free = (bri_module->max_z - (READ_REG( A_USAGE))); + *free_space = free; + + TX_FAST_DBG("%s(): Line:%d: free: %d\n", __FUNCTION__, __LINE__, free); + + tcnt = ((free >= (*len - *idx)) ? (*len - *idx) : free); + + f1 = READ_REG( A_F1); + f2 = READ_REG( A_F2); + fcnt = 0x07 - ((f1 - f2) & 0x07); /* free frame count in tx fifo */ + + TX_FAST_DBG("%s(): free: %d, fcnt: %d, tcnt: %d\n", __FUNCTION__, free, fcnt, tcnt); + + TX_EXTRA_DBG("%s(): START: usage: 0x%X, z1: 0x%X z2: 0x%X f1: 0x%X: f2:0x%X f0c:0x%X\n", + __FUNCTION__, READ_REG( A_USAGE),READ_REG( A_Z1),READ_REG( A_Z2),f1,f2,READ_REG( R_F0_CNTL)); + + if (free && fcnt && tcnt) { + data = buf + *idx; + *idx += tcnt; + + TX_EXTRA_DBG("%s(): tcnt: %d, *idx: %d, fstat.reg: 0x%X, fstat.bit.v_fifo_err: %d\n", + __FUNCTION__, tcnt, *idx, fstat.reg, fstat.bit.v_fifo_err); + + /* write data to FIFO */ + i=0; + while (iu.aft.dev_to_ch_map[BRI_DCHAN_LOGIC_CHAN]; + if (chan) { + *len = 0; + *idx = 0; + TX_FAST_DBG("%s(): calling wanpipe_wake_stack()\n", __FUNCTION__); + wanpipe_wake_stack(chan); + } +#endif + + }else{ + xhfc_select_fifo(fe, mod_no, (port->idx*8+4));/* addition ?? */ + + DEBUG_HFC_TX("%s(): transmitted a part of frame.\n", __FUNCTION__); + rc = DCHAN_STATUS_INCOMPLETE; + } + }else{ + DEBUG_HFC_TX("%s(): NO free space in tx fifo!!\n", __FUNCTION__); + rc = DCHAN_STATUS_BUSY; /* there is NO free space in tx fifo */ + } + + TX_EXTRA_DBG("%s(): END: eof usage: 0x%X, z1: 0x%X z2: 0x%X f1: 0x%X: f2:0x%X f0c:0x%X\n", + __FUNCTION__, + READ_REG(A_USAGE), READ_REG( A_Z1), READ_REG(A_Z2),f1,f2,READ_REG( R_F0_CNTL)); + +#if TX_EMPTY_FIFO + chan=(private_area_t*)card->u.aft.dev_to_ch_map[BRI_DCHAN_LOGIC_CHAN]; + + /* make sure FIFO is empty before notifying the kernel about free TX space */ + fifo_usage = READ_REG(A_USAGE); + TX_FAST_DBG("%s(): chan: 0x%p, TX FIFO usage: %d\n", __FUNCTION__, chan, fifo_usage); + + if (chan) { + if(fifo_usage == 0){ + /* FIFO is empty */ + /*WP_DELAY(10000);*/ + *len = 0; + *idx = 0; + + TX_FAST_DBG("%s(): calling wanpipe_wake_stack()\n", __FUNCTION__); + wanpipe_wake_stack(chan); + } + } +#endif + + DEBUG_HFC_TX("%s(): returning: %d.\n", __FUNCTION__, rc); + return rc; +} + +/* +Transmit D channel frames. +Transmitting fifo data requires running PCM clocks with signal at C4IO and F0IO. +*/ +static int32_t wp_bri_dchan_tx(sdla_fe_t *fe, void *src_data_buffer, u32 buffer_len) +{ + u8 mod_no, port_no, rc; + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + bri_xhfc_port_t *port_ptr; + u8 free_space; + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + + DEBUG_TX_DATA("%lu: %s(): Module: %d, port_no: %d. fe->name: %s blen=%i\n", + jiffies, __FUNCTION__, mod_no, port_no, fe->name, buffer_len); + +#if BUILD_MOD_TESTER + { + u32 i; + u8 *tmp = (u8*)src_data_buffer; + + DEBUG_TX_DATA("TX data:\n"); + + for(i = 0; i < buffer_len; i++) { + _DEBUG_EVENT("%02x ", tmp[i]); + if(i && ((i % 20) == 0)){ + DEBUG_EVENT("\n"); + } + } + DEBUG_EVENT("\n"); + } +#endif + + bri_module = &bri->mod[mod_no]; + port_ptr = &bri_module->port[port_no]; + + DEBUG_HFC_S0_STATES("%s(): fe->fe_status: %i \n", __FUNCTION__, fe->fe_status); + + if(src_data_buffer == NULL){ + /* Caller is interested in tx buffer space, + return how many bytes is still left to transmit */ + return port_ptr->bytes2transmit; + } + + if(MAX_DFRAME_LEN_L1 <= buffer_len){ + DEBUG_EVENT("%s: %s(): Tx data length %d exceeds maximum of %d bytes!\n", + fe->name, __FUNCTION__, buffer_len, MAX_DFRAME_LEN_L1); + return -EINVAL; + } + + if(port_ptr->bytes2transmit){ + /* still transmitting previous frame */ + return -EBUSY; + } +/* + { + int ind; + u8 * u8_src_data_buffer = (u8*)src_data_buffer; + + for(ind = 0; ind < buffer_len; ind++){ + if(u8_src_data_buffer[ind] != ind){ + DEBUG_RX1("tx: u8_src_data_buffer[0x%x] is: 0x%x != 0x%x!!\n", + ind, u8_src_data_buffer[ind], ind); + } + } + } +*/ + + memcpy(port_ptr->dtxbuf, src_data_buffer, buffer_len); + port_ptr->bytes2transmit = buffer_len; + + rc = xhfc_write_fifo_dchan(fe, mod_no, bri_module, port_ptr, &free_space); + + /* The frame was accepted for transmission. Return ZERO even if the frame + will be actually transmitted in parts!!! + */ + return 0; +} + +#if CHECK_DATA +static void dump_chip_SRAM(sdla_fe_t *fe, u8 mod_no, u8 port_no) +{ + u8 db; + u16 a; + /* + XHFC dump of internal RAM + + the dump shows content of internal array registers + Z and F counters and other internal variables + + please select address range for D channel that shows the errors + + 128 bytes address range for receive buffer of channel 5, D rx port_no 0 + */ + /* wrong offset + u16 start_addr = 0x580; + u16 end_addr = 0x600; + */ + u16 start_addr = 0x280; + u16 end_addr = 0x300; + +/* + 128 bytes address range for receive buffer of channel 13, D rx port_no 1 + u16 start_addr = 0xd80; + u16 end_addr = 0xe00; +*/ + for (a = start_addr; a < end_addr; a++) + { + WRITE_REG(R_RAM_ADDR, (a & 0xff)); + WRITE_REG(R_RAM_CTRL, ((a >> 8) & 0xff)); + db=READ_REG(R_RAM_DATA); + + /* dummy read to add some delay */ + /*db=READ_REG(R_INT_DATA); + db=READ_REG(R_INT_DATA);*/ + + if((a % 16) == 0){ + _DEBUG_EVENT("\n %04x",a); + } + _DEBUG_EVENT(" %02x",db); + } + DBG_RX_DATA("\n"); +} + +static int check_data(u8 *data, int data_len) +{ + int i, rc = 0; + + /*DBG_RX_DATA("%s(): data_len: %d\n", __FUNCTION__, data_len);*/ + + for(i = 0; i < data_len; i++){ + if(data[i] == 0xFF){ + rc = 1; + break; + } + } + return rc; +} + +static void dump_data(u8 *data, int data_len) +{ + int i; + + DBG_RX_DATA("%s(): data_len: %d\n", __FUNCTION__, data_len); + + for(i = 0; i < data_len; i++){ + if((i%16) == 0){ + _DEBUG_EVENT("\n %04X", i); + } + + _DEBUG_EVENT(" %02X", data[i]); + + if (i == (data_len - 4)){ + printk (" -"); + } + } + _DEBUG_EVENT("\n"); +} +#endif/* CHECK_DATA */ + +static int xhfc_read_fifo_dchan(sdla_fe_t *fe, u8 mod_no, + wp_bri_module_t *bri_module, bri_xhfc_port_t *port, int *rx_data_len) +{ + u8 *buf = port->drxbuf; + int *idx = &port->drx_indx; + u8 *data; /* pointer for new data */ + u8 rcnt, i; + u8 f1=0, f2=0, z1=0, z2=0; + + /* select D-RX fifo */ + xhfc_select_fifo(fe, mod_no, (port->idx * 8) + 5); + + /* hdlc rcnt */ + f1 = READ_REG( A_F1); + f2 = READ_REG( A_F2); + z1 = READ_REG( A_Z1); + z2 = READ_REG( A_Z2); + + rcnt = (z1 - z2) & bri_module->max_z; + if (f1 != f2) + rcnt++; + + /* debug message of F and Z counters */ + RX_EXTRA_DBG("%s(): START: usage: 0x%X, z1: 0x%X z2: 0x%X f1: 0x%X: f2:0x%X f0c:0x%X\n", + __FUNCTION__, + READ_REG(A_USAGE), READ_REG( A_Z1), READ_REG(A_Z2),f1,f2,READ_REG( R_F0_CNTL)); + + if (rcnt > 0) { + data = buf + *idx; + *idx += rcnt; + if(*idx >= MAX_DFRAME_LEN_L1){ + if (0 && WAN_NET_RATELIMIT()) { + DEBUG_EVENT("%s: %s(): frame in mod_no %d, port_no %d > maximum size of %d bytes!\n", + fe->name, __FUNCTION__, mod_no, port->idx, MAX_DFRAME_LEN_L1); + } + *idx = 0; + *rx_data_len = 0; + return DCHAN_STATUS_EMPTY; + } + + DEBUG_HFC_RX("rcnt: %d\n", rcnt); + /* read data from FIFO */ + i=0; + while (i < rcnt) { + *(data+i) = READ_REG(A_FIFO_DATA); + i++; + } + + /* hdlc frame termination */ + if (f1 != f2) { + xhfc_increment_fifo(fe, mod_no); + /* check minimum frame size */ + if (*idx < 4) { + if (0 && WAN_NET_RATELIMIT()) { + DEBUG_EVENT("%s: %s(): frame in mod_no %d, port_no %d < minimum size of 4 bytes!\n", + fe->name, __FUNCTION__, mod_no, port->idx); + } + *idx = 0; + *rx_data_len = 0; + return DCHAN_STATUS_EMPTY; + } + + /* check crc */ + if (buf[(*idx) - 1]) { + if (0 && WAN_NET_RATELIMIT()) { + DEBUG_EVENT("%s: %s(): CRC-error in frame in mod_no %d, port_no %d!\n", + fe->name, __FUNCTION__, mod_no, port->idx); + } + *idx = 0; + *rx_data_len = 0; + return DCHAN_STATUS_EMPTY; + } + + /* D-Channel debug to syslog */ + DBG_RX_DATA("%lu:D-RX len(%02i):\n", jiffies, (*idx)); +#if 0 + i = 0; + while(i < (*idx)){ + printk("%02x ", buf[i++]); + if (i == (*idx - 3)){ + printk ("- "); + } + } + printk("\n"); +#endif + *rx_data_len = *idx - 3;/* discard CRC and STATUS - 3 bytes */ + /* STATUS is the last byte of a frame in the fifo + which is used to check if CRC is correct or not. + + After the ending flag of a frame the XHFC-2SU checks the HDLC CRC checksum. + If it is correct one byte with all �0�s is inserted behind + the CRC data in the FIFO named STAT (see Fig. 4.2). This last byte of a frame in the FIFO is different + from all �0�s if there is no correct CRC field at the end of the frame. + If the STAT value is 0xFF, the HDLC frame ended with at least 8 bits �1�s. This is similar to an abort + HDLC frame condition. + The ending flag of a HDLC frame can also be the starting flag of the next frame. + page 122. + */ +#if CHECK_DATA + if(check_data(port->drxbuf, *rx_data_len)){ + dump_chip_SRAM(fe, mod_no, port->idx); + dump_chip_SRAM(fe, mod_no, port->idx); + reset_chip(fe, mod_no); + dump_data(port->drxbuf, *idx); + } +#endif + *idx = 0; + + RX_EXTRA_DBG("%s(): END: eof usage: 0x%X, z1: 0x%X z2: 0x%X f1: 0x%X: f2:0x%X f0c:0x%X\n", + __FUNCTION__, + READ_REG(A_USAGE), READ_REG( A_Z1), READ_REG(A_Z2),f1,f2,READ_REG( R_F0_CNTL)); + + DEBUG_HFC_RX("%s(): finished receiving a frame.\n", __FUNCTION__); + return DCHAN_STATUS_COMPLETE; + }else{ + + RX_EXTRA_DBG("%s(): END: eof usage: 0x%X, z1: 0x%X z2: 0x%X f1: 0x%X: f2:0x%X f0c:0x%X\n", + __FUNCTION__, + READ_REG(A_USAGE), READ_REG( A_Z1), READ_REG(A_Z2),f1,f2,READ_REG( R_F0_CNTL)); + + DEBUG_HFC_RX("%s(): received a part of frame.\n", __FUNCTION__); + return DCHAN_STATUS_INCOMPLETE; + } + }else{ + + RX_EXTRA_DBG("%s(): END: eof usage: 0x%X, z1: 0x%X z2: 0x%X f1: 0x%X: f2:0x%X f0c:0x%X\n", + __FUNCTION__, + READ_REG(A_USAGE), READ_REG( A_Z1), READ_REG(A_Z2),f1,f2,READ_REG( R_F0_CNTL)); + + DEBUG_HFC_RX("%s(): RX FIFO is empty!\n", __FUNCTION__); + return DCHAN_STATUS_EMPTY; + } +} + + +static void *wp_bri_dchan_rx(sdla_fe_t *fe, u8 mod_no, u8 port_no) +{ + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + bri_xhfc_port_t *port_ptr; + netskb_t *skb; + u8 *skb_data_area; + int rc, rx_data_len = 0; + + /* Note: D channel is slow (less than 2 bytes / ms!!) */ + DEBUG_HFC_RX("%s(): line: %d, mod_no: %d port_no: %d\n", __FUNCTION__, __LINE__, mod_no, port_no); + + bri_module = &bri->mod[mod_no]; + port_ptr = &bri_module->port[port_no]; + + rc = xhfc_read_fifo_dchan(fe, mod_no, bri_module, port_ptr, &rx_data_len); + + skb = NULL; + if((rc == DCHAN_STATUS_COMPLETE) && (rx_data_len < MAX_DFRAME_LEN_L1) && (rx_data_len > 0)){ + /**************************/ + skb = wan_skb_alloc(rx_data_len); + if(skb == NULL){ + return NULL; + } + + skb_data_area = wan_skb_put(skb, rx_data_len); + memcpy(skb_data_area, port_ptr->drxbuf, rx_data_len); +#if 0 + { + int ind; + for(ind = 0; ind < rx_data_len; ind++){ + if(skb_data_area[ind] != ind){ + DEBUG_RX1("rx: skb_data_area[0x%x] is: 0x%x != 0x%x!!\n", + ind, skb_data_area[ind], ind); + } + } + } +#endif + } + + return skb; +} + + +/****************************************************************************** +** wp_bri_iface_init) - +** +** OK +*/ +int32_t wp_bri_iface_init(void *pfe_iface) +{ + sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)pfe_iface; + + BRI_FUNC(); + fe_iface->global_config = &bri_global_config; /* not used in remora */ + fe_iface->global_unconfig = &bri_global_unconfig; /* not used in remora */ + + fe_iface->config = &wp_bri_config; + fe_iface->unconfig = &wp_bri_unconfig; + + fe_iface->pre_release = &wp_bri_pre_release; + + fe_iface->post_init = &wp_bri_post_init; + + fe_iface->if_config = &wp_bri_if_config; + fe_iface->if_unconfig = &wp_bri_if_unconfig; + + fe_iface->active_map = &wp_bri_active_map; + + fe_iface->set_fe_status = &wp_bri_set_fe_status; + fe_iface->get_fe_status = &wp_bri_get_fe_status; + + fe_iface->isr = &wp_bri_intr; + /* fe_iface->disable_irq = &wp_bri_disable_irq; */ + fe_iface->check_isr = &wp_bri_check_intr; + + fe_iface->polling = &wp_bri_polling; + fe_iface->process_udp = &wp_bri_udp; + fe_iface->get_fe_media = &wp_bri_fe_media; + + fe_iface->set_dtmf = &wp_bri_set_dtmf; + fe_iface->intr_ctrl = &wp_bri_intr_ctrl; + fe_iface->event_ctrl = &wp_bri_event_ctrl; + + fe_iface->isdn_bri_dchan_tx = &wp_bri_dchan_tx; +#if 0 + fe_iface->isdn_bri_dchan_rx = &wp_bri_dchan_rx; +#endif + +#if defined(AFT_TDM_API_SUPPORT) + fe_iface->watchdog = &wp_bri_watchdog; +#endif + + return 0; +} + +/* Should be done only ONCE per card. */ +static int32_t wp_bri_spi_bus_reset(sdla_fe_t *fe) +{ + sdla_t *card = (sdla_t*)fe->card; + + BRI_FUNC(); + + DEBUG_EVENT("%s: Executing SPI bus reset....\n", fe->name); + + card->hw_iface.bus_write_4( card->hw, + SPI_INTERFACE_REG, + MOD_SPI_RESET); + WP_DELAY(1000); + card->hw_iface.bus_write_4( card->hw, + SPI_INTERFACE_REG, + 0x00000000); + WP_DELAY(1000); + return 0; +} + +/****************************************************************************** +* scan_modules() +* +* Description : Scan for installed modules. +* +* Arguments : pfe - pointer to Front End structure. +* +* Returns : number of discovered modules. +*******************************************************************************/ +static int32_t scan_modules(sdla_fe_t *fe, u_int8_t rm_no) +{ + u_int8_t mod_no = 0x3; /* to read remora status register ALWAYS put 0x3 into mod_addr. */ + u_int8_t value, ind, mod_counter = 0; + u_int8_t mod_no_index; /* index in the array of ALL modules (NOT lines) on ALL remoras. From 0 to 11 */ + + /* format of remora status register: + bit 0 == 1 - module 1 active (exist) + bit 1 - type of module 1 (0 - NT, 1 - TE) + + bit 2 == 1 - module 2 active (exist) + bit 3 - type of module 1 (0 - NT, 1 - TE) + + bit 4 == 1 - module 3 active (exist) + bit 5 - type of module 1 (0 - NT, 1 - TE) + + bit 6,7 - has to be zeros for active remora. if non-zero, remora does not exist. + */ + + value = fe->read_fe_reg(fe->card, + mod_no, + MOD_TYPE_NONE, + rm_no, + 0); + +#define MODULE1 0 +#define MODULE2 2 +#define MODULE3 4 + + DEBUG_BRI_INIT("remora number: %d, remora status register: 0x%02X\n", rm_no, value); + + if(((value >> 7) & 0x01) || ((value >> 8) & 0x01)){ + DEBUG_EVENT("%s: Remora number %d does not exist.\n", fe->name, rm_no); + return 0; + }else{ + DEBUG_EVENT("%s: Remora number %d exist.\n", fe->name, rm_no); + } + + for(ind = 0; ind < 6; ind++){ + + switch(ind){ + + case MODULE1: + case MODULE2: + case MODULE3: + DEBUG_BRI_INIT("module Number on REMORA (0-2): %d\n", ind / 2); + + /* 0-11, all (even and odd) numbers */ + mod_no_index = rm_no * MAX_BRI_MODULES_PER_REMORA + ind / 2; + DEBUG_BRI_INIT("mod_no_index on CARD (should be 0-11): %d\n", mod_no_index); + + /* 0-23, only even numbers */ + mod_no_index = mod_no_index * 2; + DEBUG_BRI_INIT("mod_no_index (line number) on CARD (should be 0-23): %d\n", mod_no_index); + + if(mod_no_index >= MAX_BRI_LINES){ + DEBUG_EVENT("%s: Error: Module %d/%d exceeds maximum (%d)\n", + fe->name, mod_no_index, mod_no_index, MAX_BRI_LINES); + return 0; + } + + if((value >> ind) & 0x01){ + + mod_counter++; + + if((value >> (ind + 1)) & 0x01){ + + DEBUG_BRI_INIT("%s: Module %d type is: TE\n", + fe->name, mod_no_index); + + fe->bri_param.mod[mod_no_index].type = MOD_TYPE_TE; + + fe->bri_param.mod[mod_no_index].port[PORT_0].mode |= PORT_MODE_TE; + fe->bri_param.mod[mod_no_index].port[PORT_1].mode |= PORT_MODE_TE; + + }else{ + DEBUG_BRI_INIT("%s: Module %d type is: NT\n", + fe->name, mod_no_index); + + fe->bri_param.mod[mod_no_index].type = MOD_TYPE_NT; + + fe->bri_param.mod[mod_no_index].port[PORT_0].mode |= PORT_MODE_NT; + fe->bri_param.mod[mod_no_index].port[PORT_1].mode |= PORT_MODE_NT; + } + + /*Copy information from (even numbered) 'mod_no_index' to + (odd numbered) 'mod_no_index + 1' because for each module there are two lines.*/ + memcpy(&fe->bri_param.mod[mod_no_index + 1], &fe->bri_param.mod[mod_no_index], + sizeof(wp_bri_module_t)); + }else{ + DEBUG_BRI_INIT("%s: Module %d is not installed\n", + fe->name, mod_no_index); + } + DEBUG_BRI_INIT("=================================\n\n"); + break; + }/* switch() */ + }/* for() */ + + return mod_counter; +} + +/****************************************************************************** +* scan_remoras_and_modules() +* +* Description : Scan for installed Remoras and modules. +* +* Arguments : pfe - pointer to Front End structure. +* +* Returns : 0 - configred successfully, otherwise non-zero value. +*******************************************************************************/ +static int32_t scan_remoras_and_modules(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + int32_t rm_no, modules_counter = 0; + + BRI_FUNC(); + + for(rm_no = 0; rm_no < MAX_BRI_REMORAS; rm_no++){ + + modules_counter += scan_modules(fe, rm_no); + } + + if(modules_counter == 0){ + DEBUG_EVENT("%s: Error: modules counter is zero!\n", fe->name); + return 1; + }else{ + DEBUG_EVENT("%s: Total number of modules: %d.\n", fe->name, modules_counter); + return 0; + } +} + +/****************************************************************************** +* bri_global_config() +* +* Description : Global configuration for Sangoma BRI board. +* +* Notes : 1. This routine runs only ONCE for a physical 'base' CARD, +* not for 'additional' cards. +* 2. reset card's SPI. +* 3. Scan for installed Remoras and modules. +* +* Arguments : pfe - pointer to Front End structure. +* +* Returns : 0 - configred successfully, otherwise non-zero value. +*******************************************************************************/ +static int32_t bri_global_config(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + BRI_FUNC(); + + DEBUG_EVENT("%s: %s Global Front End configuration\n", + fe->name, FE_MEDIA_DECODE(fe)); + + return 0; +} + +/******************************************************************************* +* bri_global_unconfig() +* +* Description : Global un-configuration for Sangoma BRI board. +* Note: This routne runs only ONCE for a physical card. +* +* Arguments : +* +* Returns : 0 +*******************************************************************************/ +static int32_t bri_global_unconfig(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + BRI_FUNC(); + + DEBUG_EVENT("%s: %s Global Front End unconfiguration!\n", + fe->name, FE_MEDIA_DECODE(fe)); + + return 0; +} + + +/* + ****************************************************************************** + * wp_bri_pre_release() + * + * Description: BRI pre release function (not locked routines) + * Arguments: + * Returns: + ****************************************************************************** + */ +static int wp_bri_pre_release(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + wp_bri_module_t *bri_module; + sdla_bri_param_t *bri = &fe->bri_param; + u8 mod_no, port_no; + bri_xhfc_port_t *port_ptr; + + DEBUG_EVENT("%s: Running post initialization...\n", fe->name); + + if(validate_fe_line_no(fe, __FUNCTION__)){ + return 1; + } + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port_no: %i\n", __FUNCTION__, mod_no, port_no); + + bri_module = &bri->mod[mod_no]; + + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + port_ptr = &bri_module->port[port_no]; + + wan_del_timer(&port_ptr->t3_timer); + wan_del_timer(&port_ptr->t4_timer); + }/* for (port_no = 0; port_no < bri_module->num_ports; port_no++) */ + + return 0; +} + +/****************************************************************************** +* wp_bri_config() - initialise the XHFC ISDN Chip. +* +* Description : Configure the PHYSICAL module ONE time. +* On each module 2 lines will be configured +* in exactly the same way. +* +* Arguments : pfe - pointer to Front End structure. +* +* Returns : 0 - configred successfully, otherwise non-zero value. +*******************************************************************************/ +static int32_t wp_bri_config(void *pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + sdla_t *card = (sdla_t*)fe->card; + u8 mod_no, port_no, mod_cnt = 0; + /*sdlahw_t* hw = (sdlahw_t*)card->hw;*/ + int32_t err = 0, aft_line_no = 0; + u16 physical_module_config_counter; + u32 physical_card_config_counter; + wp_bri_module_t *bri_module; + sdla_bri_param_t *bri = &fe->bri_param; + + BRI_FUNC(); + + DEBUG_EVENT("%s: %s: Line %d Front End configuration\n", + fe->name, FE_MEDIA_DECODE(fe), WAN_FE_LINENO(fe) + 1); + + if(validate_fe_line_no(fe, __FUNCTION__)){ + return 1; + } + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + + DEBUG_EVENT("%s(): mod_no: %i, port_no: %i\n", __FUNCTION__, mod_no, port_no); + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + fe->bri_param.max_fe_channels = MAX_TIMESLOTS; + fe->bri_param.module_map[0] = fe->bri_param.module_map[1] = 0; + + bri_module = &bri->mod[mod_no]; + + card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &physical_card_config_counter); + if(physical_card_config_counter == 1){ + /* Per-card initialization. Important to do only ONCE.*/ + wp_bri_spi_bus_reset(fe); + } + + if(scan_remoras_and_modules(fe)){ + return 1; + } + +#if BUILD_MOD_TESTER + /* for Production Test nothing else should be done */ + return 0; +#endif + + /*Event lock */ + WAN_LIST_INIT(&fe->event); + /* wan_spin_lock_init(&fe->lock, "wp_bri_lock"); FIXME: 'lock' is not there, but what is there? */ + + card->hw_iface.getcfg(card->hw, SDLA_HWPORTREG, &physical_module_config_counter); + + /* configuration is in 'card' copy to 'interface' */ + fe->bri_param.is_clock_master = card->fe.fe_cfg.cfg.bri.clock_mode; + + if(fe->bri_param.is_clock_master == WANOPT_YES){ + + u32 recovery_clock_flag; + + card->hw_iface.getcfg(card->hw, SDLA_RECOVERY_CLOCK_FLAG, &recovery_clock_flag); + if (recovery_clock_flag){ + DEBUG_EVENT("%s: Error: Multiple Interfaces configured for LINE clocking!\n", + fe->name); + DEBUG_EVENT("%s: Please select only a single device as the LINE clock source\n", + fe->name); + return 1; + } + + if (fe->bri_param.mod[mod_no].type != MOD_TYPE_TE){ + DEBUG_EVENT("%s: Error: NT module does not support LINE clock recovery mode!\n", + fe->name); + return 1; + } + } + + bri_module->fe = fe; + + switch(fe->bri_param.mod[mod_no].type) + { + case MOD_TYPE_TE: + case MOD_TYPE_NT: + if(physical_module_config_counter == 1){ + + if((err = reset_chip(fe, mod_no))){ + return err; + } + + if((err = init_xfhc(fe, mod_no))){ + return err; + } + }else{ + bri_module->num_ports = BRI_MAX_PORTS_PER_CHIP; + bri_module->max_fifo = 8; + bri_module->max_z = 0x7F; + + /* init line interfaces state machines (in software only!) */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + + bri_module->port[port_no].idx = port_no; + bri_module->port[port_no].hw = bri_module; + + }/* for (port_no = 0; port_no < bri_module->num_ports; port_no++) */ + } + break; + + default: + DEBUG_EVENT("%s(): %s: Warning: Module %d (AFT Line: %d): Not Installed.\n", + __FUNCTION__, fe->name, REPORT_MOD_NO, aft_line_no); + break; + } + + /**************************************************************************/ + /* Set active modules (channels) bitmap for all installed LOGICAL modules */ + +#define BCHAN_BITMAP 0x3 /* each BRI line has 2 b-channels --> 2 bits */ + + if(mod_no < (MAX_BRI_LINES / 2)){ + /* 1-st aft line has timeslots 0-23 */ + aft_line_no = 0; + }else{ + /* 2-nd aft line has timeslots 24-47 */ + aft_line_no = 1; + } + + fe->bri_param.mod[mod_no].mod_no = mod_no; + + switch(fe->bri_param.mod[mod_no].type) + { + case MOD_TYPE_TE: + case MOD_TYPE_NT: + fe->bri_param.module_map[aft_line_no] |= (BCHAN_BITMAP << (mod_no*2)); + + DEBUG_EVENT("%s: Module %d (AFT Line: %d): Installed -- %s. Timeslots map: 0x%08X\n", + fe->name, REPORT_MOD_NO, aft_line_no, + WP_BRI_DECODE_MOD_TYPE(fe->bri_param.mod[mod_no].type), + (BCHAN_BITMAP << (mod_no*2))); + mod_cnt++; + break; + + default: + DEBUG_EVENT("%s(): %s: Warning: Module %d (AFT Line: %d): Not Installed.\n", + __FUNCTION__, fe->name, REPORT_MOD_NO, aft_line_no); + break; + } + + /*******************************************************/ + /* Enable interrupts on the installed PHYSICAL module. */ + switch(fe->bri_param.mod[mod_no].type) + { + case MOD_TYPE_TE: + case MOD_TYPE_NT: + if(physical_module_config_counter == 1){ +/* DAVIDR-consider moving call bri_enable_interrupts() to wp_bri_post_init() */ + bri_enable_interrupts(fe, mod_no, port_no); + }else{ + DEBUG_HFC_INIT("%s(): the other port_no is ALREADY running, interrupts are enabled.\n", + __FUNCTION__); + } + break; + default: + DEBUG_EVENT("%s(): %s: Warning: Module %d (AFT Line: %d): Not Installed.\n", + __FUNCTION__, fe->name, REPORT_MOD_NO, aft_line_no); + break; + } + + /******************************************************/ + /*------------------ CLOCK RECOVERY ------------------*/ + if(physical_card_config_counter == 1){ + /* Per-card initialization. Important to do only ONCE.*/ + u32 i; + + /* ALL modules MUST have GPIO6 function switched + from the default 'output' to 'input'. + Otherwise there will be a clock conflict! + */ + for(i = 0; i < MAX_BRI_LINES; i += BRI_MAX_PORTS_PER_CHIP){ + + switch(fe->bri_param.mod[i].type) + { + case MOD_TYPE_TE: + case MOD_TYPE_NT: + config_clock_routing(fe, i, WANOPT_NO); + break; + default: + continue; + }/* switch() */ + }/* for() */ + }/* if() */ + /*----------- END OF CLOCK RECOVERY ------------------*/ + /******************************************************/ + + if(fe->bri_param.is_clock_master == WANOPT_YES){ + u32 recovery_clock_flag = 1; + card->hw_iface.setcfg(card->hw, SDLA_RECOVERY_CLOCK_FLAG, &recovery_clock_flag); + } + return 0; +} + +/****************************************************************************** +** wp_bri_unconfig() - +** +** OK +*/ +static int32_t wp_bri_unconfig(void *pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + u8 mod_no, port_no; + u16 physical_module_config_counter; + sdla_t *card = (sdla_t*)fe->card; + + if(validate_fe_line_no(fe, __FUNCTION__)){ + return 1; + } + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + + DEBUG_HFC_INIT("%s(): mod_no: %d, port_no: %d\n", __FUNCTION__, mod_no, port_no); + + DEBUG_EVENT("%s: Unconfiguring BRI Front End...\n", fe->name); + + card->hw_iface.getcfg(card->hw, SDLA_HWPORTREG, &physical_module_config_counter); + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + + /******************************************************************/ + switch(fe->bri_param.mod[mod_no].type) + { + case MOD_TYPE_TE: + case MOD_TYPE_NT: + if(fe->bri_param.mod[mod_no].type == MOD_TYPE_TE && + fe->bri_param.is_clock_master == WANOPT_YES){ + /* master port_no is shutting down - switch all modules to internal card's clock */ + clock_control(fe, 0); + } + + config_clock_routing(fe, mod_no, WANOPT_NO); + + if(physical_module_config_counter == 1){ + wp_bri_disable_irq(fe, mod_no, port_no); + }else{ + DEBUG_HFC_INIT("%s(): the other port_no is still running, leave interrupts enabled.\n", + __FUNCTION__); + } + break; + default: + /* for missing (not installed) modules - do nothing */ + DEBUG_EVENT("%s(): %s: Warining: unknown module type!\n", + __FUNCTION__, fe->name); + break; + } + /******************************************************************/ + + if(fe->bri_param.is_clock_master == WANOPT_YES){ + u32 recovery_clock_flag = 0; + card->hw_iface.setcfg(card->hw, SDLA_RECOVERY_CLOCK_FLAG, &recovery_clock_flag); + } + + return 0; +} + +/****************************************************************************** +** wp_bri_post_init() - +** +** OK +*/ +static int32_t wp_bri_post_init(void *pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + wp_bri_module_t *bri_module; + sdla_bri_param_t *bri = &fe->bri_param; + u8 mod_no, port_no; + bri_xhfc_port_t *port_ptr; + + DEBUG_EVENT("%s: Running post initialization...\n", fe->name); + + if(validate_fe_line_no(fe, __FUNCTION__)){ + return 1; + } + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port_no: %i\n", __FUNCTION__, mod_no, port_no); + + bri_module = &bri->mod[mod_no]; + + /* */ + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + port_ptr = &bri_module->port[port_no]; + + wan_init_timer(&port_ptr->t3_timer, l1_timer_expire_t3, (wan_timer_arg_t)port_ptr); + wan_init_timer(&port_ptr->t4_timer, l1_timer_expire_t4, (wan_timer_arg_t)port_ptr); + }/* for (port_no = 0; port_no < bri_module->num_ports; port_no++) */ + +#if 1 + { + wan_smp_flag_t smp_flags1; + sdla_t *card = (sdla_t*)fe->card; + + /* Try to activate the port_no - if cable is in, line will get activated. + If no cable, the application will have to call wp_bri_set_fe_status() + to get line activated. */ + card->hw_iface.hw_lock(card->hw,&smp_flags1); + wp_bri_set_fe_status(fe, WAN_FE_CONNECTED); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + } +#endif + return 0; +} + + +/** + * l1_timer_start_t3 + */ +static void l1_timer_start_t3(void *pport) +{ + bri_xhfc_port_t *port_ptr = (bri_xhfc_port_t*)pport; + wp_bri_module_t *bri_module = port_ptr->hw; + u8 mod_no = bri_module->mod_no; + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port number: %i\n", __FUNCTION__, mod_no, port_ptr->idx); + + if(!wan_test_and_set_bit(T3_TIMER_ACTIVE, &port_ptr->timer_flags)){ + + DEBUG_HFC_S0_STATES("Starting T3 timer...\n"); + +#if defined(__WINDOWS__) + /* delay is in MS, so it can be used directly by wan_add_timer() */ + wan_add_timer(&port_ptr->t3_timer, XHFC_TIMER_T3); +#else + wan_add_timer(&port_ptr->t3_timer, (XHFC_TIMER_T3 * HZ) / 1000); +#endif + } +} + +/** + * l1_timer_stop_t3 + */ +static void l1_timer_stop_t3(void *pport) +{ + bri_xhfc_port_t *port_ptr = (bri_xhfc_port_t*)pport; + wp_bri_module_t *bri_module = port_ptr->hw; + u8 mod_no = bri_module->mod_no; + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port number: %i\n", __FUNCTION__, mod_no, port_ptr->idx); + DEBUG_HFC_S0_STATES("Stopping T3 timer...\n"); + + wan_clear_bit(T3_TIMER_ACTIVE, &port_ptr->timer_flags); + wan_clear_bit(HFC_L1_ACTIVATING, &port_ptr->l1_flags); + wan_del_timer(&port_ptr->t3_timer); +} + + +/* + ****************************************************************************** + * l1_timer_expire_t3() + * + * Description: called when timer t3 expires. + * Activation failed, force clean L1 deactivation. + * Arguments: + * Returns: + ****************************************************************************** + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +static void l1_timer_expire_t3(void* pport) +#elif defined(__WINDOWS__) +static void l1_timer_expire_t3(IN PKDPC Dpc, void* pport, void* arg2, void* arg3) +#else +static void l1_timer_expire_t3(unsigned long pport) +#endif +{ + bri_xhfc_port_t *port_ptr = (bri_xhfc_port_t*)pport; + wp_bri_module_t *bri_module = port_ptr->hw; + u8 mod_no = bri_module->mod_no; + sdla_fe_t *fe = (sdla_fe_t*)bri_module->fe; + sdla_t *card = (sdla_t*)fe->card; + wan_smp_flag_t smp_flags1; + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port number: %i\n", __FUNCTION__, mod_no, port_ptr->idx); + + wan_clear_bit(T3_TIMER_ACTIVE, &port_ptr->timer_flags); + + wan_clear_bit(HFC_L1_ACTIVATING, &port_ptr->l1_flags); + card->hw_iface.hw_lock(card->hw,&smp_flags1); + xhfc_ph_command(fe, port_ptr, HFC_L1_FORCE_DEACTIVATE_TE); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); +} + + +/** + * l1_timer_start_t4 + */ +static void l1_timer_start_t4(void *pport) +{ + bri_xhfc_port_t *port_ptr = (bri_xhfc_port_t*)pport; + wp_bri_module_t *bri_module = port_ptr->hw; + u8 mod_no = bri_module->mod_no; + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port number: %i\n", __FUNCTION__, mod_no, port_ptr->idx); + + if(!wan_test_and_set_bit(T4_TIMER_ACTIVE, &port_ptr->timer_flags)){ + + DEBUG_HFC_S0_STATES("Starting T4 timer...\n"); + + wan_set_bit(HFC_L1_DEACTTIMER, &port_ptr->l1_flags); + +#if defined(__WINDOWS__) + /* delay is in MS, so it can be used directly by wan_add_timer() */ + wan_add_timer(&port_ptr->t4_timer, XHFC_TIMER_T4); +#else + wan_add_timer(&port_ptr->t4_timer, (XHFC_TIMER_T4 * HZ) / 1000); +#endif + } +} + +/** + * l1_timer_stop_t4 + */ +static void l1_timer_stop_t4(void *pport) +{ + bri_xhfc_port_t *port_ptr = (bri_xhfc_port_t*)pport; + wp_bri_module_t *bri_module = port_ptr->hw; + u8 mod_no = bri_module->mod_no; + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port number: %i\n", __FUNCTION__, mod_no, port_ptr->idx); + DEBUG_HFC_S0_STATES("Stopping T4 timer...\n"); + + wan_clear_bit(T4_TIMER_ACTIVE, &port_ptr->timer_flags); + wan_clear_bit(HFC_L1_DEACTTIMER, &port_ptr->l1_flags); + wan_del_timer(&port_ptr->t4_timer); +} + + +/* + ****************************************************************************** + * l1_timer_expire_t4() + * + * Description: l1_timer_expire_t4 - called when timer t4 expires. + * Send (PH_DEACTIVATE | INDICATION) to upper layer. + * + * Arguments: + * Returns: + ****************************************************************************** + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +static void l1_timer_expire_t4(void* pport) +#elif defined(__WINDOWS__) +static void l1_timer_expire_t4(IN PKDPC Dpc, void* pport, void* arg2, void* arg3) +#else +static void l1_timer_expire_t4(unsigned long pport) +#endif +{ + bri_xhfc_port_t *port_ptr = (bri_xhfc_port_t*)pport; + wp_bri_module_t *bri_module = port_ptr->hw; + u8 mod_no = bri_module->mod_no; + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port number: %i\n", __FUNCTION__, mod_no, port_ptr->idx); + + wan_clear_bit(T4_TIMER_ACTIVE, &port_ptr->timer_flags); + wan_clear_bit(HFC_L1_DEACTTIMER, &port_ptr->l1_flags); +} + +/****************************************************************************** +** wp_bri_if_config() - +** +** OK +*/ +static int32_t wp_bri_if_config(void *pfe, u32 mod_map, u8 usedby) +{ + BRI_FUNC(); + return 0; +} + + +/****************************************************************************** +** wp_bri_if_unconfig() - +** +** OK +*/ +static int32_t wp_bri_if_unconfig(void *pfe, u32 mod_map, u8 usedby) +{ + BRI_FUNC(); + return 0; +} + + +/******************************************************************************* +* bri_enable_interrupts() +* +* Description: Enable BRI interrupts - start interrupt and set interrupt mask. +* +* Arguments: +* +* Returns: +*******************************************************************************/ +static void bri_enable_interrupts(sdla_fe_t *fe, u32 mod_no, u8 port_no) +{ + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + reg_r_ti_wd r_ti_wd; + reg_r_misc_irqmsk r_misc_irqmsk; + reg_r_irq_ctrl r_irq_ctrl; + + BRI_FUNC(); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return; + } + + DEBUG_EVENT("%s: Module: %d: Enabling %s Interrupts \n", + fe->name, REPORT_MOD_NO, + FE_MEDIA_DECODE(fe)); + + bri_module = &bri->mod[mod_no]; + + WRITE_REG(R_SU_IRQMSK, 0); + + r_ti_wd.reg = 0x0; + /* Configure Timer Interrupt - every 2.048 seconds (page 289, 297). + Used for SU port_no state monitoring with 'HFC_TIMER_COUNTER_T3'. + */ + r_ti_wd.bit.v_ev_ts = 0xD; + /* Watch Dog interrupt not used */ + r_ti_wd.bit.v_wd_ts = 0x0; + WRITE_REG(R_TI_WD, r_ti_wd.reg); + + r_misc_irqmsk.reg = 0; +#if !BUILD_MOD_TESTER + r_misc_irqmsk.bit.v_ti_irqmsk = 1;/* Enable (one) / Disable (zero) timer interrupts */ +#endif + WRITE_REG( R_MISC_IRQMSK, r_misc_irqmsk.reg); + + /* clear all pending interrupts bits */ + READ_REG( R_MISC_IRQ); + READ_REG( R_SU_IRQ); + READ_REG( R_FIFO_BL0_IRQ); + READ_REG( R_FIFO_BL1_IRQ); + READ_REG( R_FIFO_BL2_IRQ); + READ_REG( R_FIFO_BL3_IRQ); + +#if 1 + { + reg_r_su_irqmsk r_su_irqmsk; + + /* unmask FE interrupt for all ports */ + r_su_irqmsk.reg = 0; + r_su_irqmsk.bit.v_su0_irqmsk = 1; + r_su_irqmsk.bit.v_su1_irqmsk = 1; + WRITE_REG( R_SU_IRQMSK, r_su_irqmsk.reg); + } +#endif + + /* enable global (all) interrupts */ + r_irq_ctrl.reg = 0; + r_irq_ctrl.bit.v_glob_irq_en = 1; + r_irq_ctrl.bit.v_fifo_irq_en = 1; + WRITE_REG( R_IRQ_CTRL, r_irq_ctrl.reg); +} + +/****************************************************************************** +** wp_bri_disable_irq() - disable all interrupts by disabling M_GLOB_IRQ_EN +** +** OK +*/ +static int32_t wp_bri_disable_irq(sdla_fe_t *fe, u32 mod_no, u8 port_no) +{ + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + reg_r_su_irqmsk r_su_irqmsk; + reg_r_irq_ctrl r_irq_ctrl; + + BRI_FUNC(); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return 1; + } + + DEBUG_EVENT("%s: Module: %d: Disabling %s Interrupts \n", + fe->name, REPORT_MOD_NO, + FE_MEDIA_DECODE(fe)); + + bri_module = &bri->mod[mod_no]; + + /* disable FE interrupt for the port */ + r_su_irqmsk.reg = 0; + WRITE_REG( R_SU_IRQMSK, r_su_irqmsk.reg); + +/* + if (!wan_test_bit(WP_RM_CONFIGURED,(void*)&fe->bri_param.critical)){ + return -EINVAL; + } +*/ + + /* disable global (all) other interrupts */ + r_irq_ctrl.reg = 0; + WRITE_REG( R_IRQ_CTRL, 0); + + return 0; +} + +static u32 wp_bri_active_map(sdla_fe_t* fe, u8 line_no) +{ + BRI_FUNC(); + + if(line_no >= 2){ + DEBUG_EVENT("%s: %s(): Error: Line number %d is out of range!\n", + fe->name, __FUNCTION__, line_no); + return 0; + } + + DEBUG_EVENT("%s: ACTIVE MAP Port=%i Returning 0x%08X\n", + fe->name, + WAN_FE_LINENO(fe), + 0x03 << (WAN_FE_LINENO(fe)%MAX_BRI_MODULES)*2); + + return 0x03 << (WAN_FE_LINENO(fe)%MAX_BRI_MODULES)*2; +} + +/****************************************************************************** +* wp_bri_fe_status() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +static u8 wp_bri_fe_media(sdla_fe_t *fe) +{ + BRI_FUNC(); + return fe->fe_cfg.media; +} + +/****************************************************************************** +* wp_bri_set_dtmf() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +static int32_t wp_bri_set_dtmf(sdla_fe_t *fe, int32_t mod_no, u8 val) +{ + BRI_FUNC(); +#if 0 + + if (mod_no > MAX_REMORA_MODULES){ + DEBUG_EVENT("%s: Module %d: Module number out of range!\n", + fe->name, mod_no); + return -EINVAL; + } + if (!wan_test_bit(mod_no-1, &fe->bri_param.module_map)){ + DEBUG_EVENT("%s: Module %d: Not configures yet!\n", + fe->name, mod_no); + return -EINVAL; + } + +#endif + return -EINVAL; +} + +#if 0 + +/******************************************************************************* +* sdla_bri_timer() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +static void wp_bri_timer(void* pfe) +#elif defined(__WINDOWS__) +static void wp_bri_timer(IN PKDPC Dpc, void* pfe, void* arg2, void* arg3) +#else +static void wp_bri_timer(void *pfe) +#endif +{ + BRI_FUNC(); + return; +} + +/******************************************************************************* +* wp_bri_enable_timer() +* +* Description: Enable software timer interrupt in delay ms. +* Arguments: +* Returns: +*******************************************************************************/ +static void wp_bri_enable_timer(sdla_fe_t* fe, u8 mod_no, u8 cmd, u32 delay) +{ + BRI_FUNC(); + return; +} + +static int32_t wp_bri_regdump(sdla_fe_t* fe, u8 *data) +{ + BRI_FUNC(); + return 0; +} + +#endif /* if 0*/ + +static int32_t wp_bri_polling(sdla_fe_t* fe) +{ + BRI_FUNC(); + return 0; +} + +/******************************************************************************* +* wp_bri_udp() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +static int32_t wp_bri_udp(sdla_fe_t *fe, void* p_udp_cmd, u8* data) +{ + int32_t err = -EINVAL; + + BRI_FUNC(); +#if 0 + wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; + + switch(udp_cmd->wan_cmd_command){ + case WAN_FE_REGDUMP: + err = wp_bri_regdump(fe, data); + if (err){ + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + udp_cmd->wan_cmd_data_len = (u16)err; + } + break; + + default: + udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; + udp_cmd->wan_cmd_data_len = 0; + break; + } +#endif + return err; +} + +/****************************************************************************** +* wp_bri_get_fe_status() +* +* Description : Get current FE line state - is it Connected or Disconnected +* +* Arguments : fe - pointer to Front End structure. +* status - pointer to location where the FE line state will +* be stored. +* +* Returns : always zero. +*******************************************************************************/ +static int wp_bri_get_fe_status(sdla_fe_t *fe, unsigned char *status) +{ + *status = fe->fe_status; + return 0; +} + +/****************************************************************************** +* wp_bri_set_fe_status() +* +* Description : Set FE line state to Connected or Disconnected. +* In BRI this means Activate or Deactivate the line. +* +* Arguments : fe - pointer to Front End structure. +* new_status - the new FE line state. +* +* Returns : 0 - success. +* 1 - failure. +*******************************************************************************/ +static int wp_bri_set_fe_status(sdla_fe_t *fe, unsigned char new_status) +{ + u8 mod_no, port_no; + int rc = 0; + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + bri_xhfc_port_t *port_ptr; + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + + DEBUG_FE_STATUS("%s(): Module: %d, port_no: %d. fe->name: %s, new status: %d (%s)\n", + __FUNCTION__, mod_no, port_no, fe->name, new_status, FE_STATUS_DECODE(new_status)); + + bri_module = &bri->mod[mod_no]; + port_ptr = &bri_module->port[port_no]; + + switch(new_status) + { + case WAN_FE_CONNECTED: + DEBUG_HFC_S0_STATES("l2->l1 -- ACTIVATE REQUEST\n"); + + if (port_ptr->mode & PORT_MODE_TE) { + if (wan_test_bit(HFC_L1_ACTIVATED, &port_ptr->l1_flags)) { + /* The line is already in active. Confirm to L2 that line is connected. */ + DEBUG_HFC_S0_STATES("l1->l2 -- ACTIVATE CONFIRM\n"); + sdla_bri_set_status(fe, mod_no, port_no, FE_CONNECTED); + } else { + + wan_test_and_set_bit(HFC_L1_ACTIVATING, &port_ptr->l1_flags); + + xhfc_ph_command(fe, port_ptr, HFC_L1_ACTIVATE_TE); + l1_timer_start_t3(port_ptr); + } + } else { + xhfc_ph_command(fe, port_ptr, HFC_L1_ACTIVATE_NT); + } + break; + + case WAN_FE_DISCONNECTED: + DEBUG_HFC_S0_STATES("l2->l1 -- DEACTIVATE REQUEST\n"); + + if (port_ptr->mode & PORT_MODE_TE) { + /* no deact request in TE mode ! */ + DEBUG_EVENT("%s(): %s: Error: 'deactivate' request is invalid for TE!\n", + __FUNCTION__, fe->name); + rc = 1; + } else { + xhfc_ph_command(fe, port_ptr, HFC_L1_DEACTIVATE_NT); + } + break; + + default: + DEBUG_EVENT("%s(): %s: Error: invalid new status '%d' (%s) requested!\n", + __FUNCTION__, fe->name, new_status, FE_STATUS_DECODE(new_status)); + rc = 1; + break; + } + + return rc; +} + + +/****************************************************************************** +* wp_bri_event_ctrl() +* +* Description: Enable/Disable event types +* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) +* Returns: +******************************************************************************/ +static int wp_bri_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) +{ + int err = 0; + + BRI_FUNC(); + + WAN_ASSERT(ectrl == NULL); + + return err; +} + +#if defined(AFT_TDM_API_SUPPORT) +/****************************************************************************** +* wp_bri_watchdog() +* +* Description: +* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) +* Returns: +******************************************************************************/ +static int32_t wp_bri_watchdog(sdla_fe_t *fe) +{ + int32_t mod_no; + + BRI_FUNC(); + + return 0; +} +#endif + +/****************************************************************************** +* wp_bri_intr_ctrl() +* +* Description: Enable/Disable extra interrupt types +* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) +* Returns: +******************************************************************************/ +static int wp_bri_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t type, u_int8_t mode, unsigned int ts_map) +{ + int32_t err = 0; + + BRI_FUNC(); + + return err; + +} + +/****************************************************/ +/* Physical S/U commands to control Line Interface */ +/****************************************************/ +static void xhfc_ph_command(sdla_fe_t *fe, bri_xhfc_port_t *port, u_char command) +{ + wp_bri_module_t *bri_module = port->hw; + u8 mod_no = bri_module->mod_no; + + DEBUG_HFC_S0_STATES("%s()\n", __FUNCTION__); + + switch (command) + { + case HFC_L1_ACTIVATE_TE: + DEBUG_HFC_S0_STATES("HFC_L1_ACTIVATE_TE port(%i)\n", port->idx); + + WRITE_REG(R_SU_SEL, port->idx); + WRITE_REG(A_SU_WR_STA, STA_ACTIVATE); + break; + + case HFC_L1_FORCE_DEACTIVATE_TE: + DEBUG_HFC_S0_STATES("HFC_L1_FORCE_DEACTIVATE_TE port(%i)\n", port->idx); + + WRITE_REG(R_SU_SEL, port->idx); + WRITE_REG(A_SU_WR_STA, STA_DEACTIVATE); + break; + + case HFC_L1_ACTIVATE_NT: + DEBUG_HFC_S0_STATES("HFC_L1_ACTIVATE_NT port(%i)\n", port->idx); + + WRITE_REG(R_SU_SEL, port->idx); + WRITE_REG(A_SU_WR_STA, STA_ACTIVATE | M_SU_SET_G2_G3); + break; + + case HFC_L1_DEACTIVATE_NT: + DEBUG_HFC_S0_STATES("HFC_L1_DEACTIVATE_NT port(%i)\n", port->idx); + + WRITE_REG(R_SU_SEL, port->idx); + WRITE_REG(A_SU_WR_STA, STA_DEACTIVATE); + break; + default: + DEBUG_HFC_S0_STATES("Invalid command: %i !\n", command); + break; + } +} + +/****************************************************************************** +* sdla_bri_set_status() +* +* Description: set line status to 'connected' or 'disconnected' and indicate +* line state change to upper layer. +* Arguments: fe, mod_no, port_no, new line status +* Returns: nothing +******************************************************************************/ +static void sdla_bri_set_status(sdla_fe_t* fe, u8 mod_no, u8 port_no, u8 new_status) +{ + sdla_t *card = (sdla_t*)fe->card; + + BRI_FUNC(); + + DEBUG_HFC_S0_STATES("%s(): new_status: %i, old status: %i\n", + __FUNCTION__, new_status, fe->fe_status); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return; + } + + if (new_status == fe->fe_status){ + return; + } + + fe->fe_status = new_status; + + if (new_status == FE_CONNECTED){ + DEBUG_EVENT("%s: %s Module: %d connected!\n", + fe->name, + FE_MEDIA_DECODE(fe), REPORT_MOD_NO + port_no); + + if (card->wandev.te_report_alarms){ + card->wandev.te_report_alarms(card, 0); + } + + }else{ + DEBUG_EVENT("%s: %s Module: %d disconnected!\n", + fe->name, + FE_MEDIA_DECODE(fe), REPORT_MOD_NO + port_no); + + if (card->wandev.te_report_alarms){ + card->wandev.te_report_alarms(card, 1); + } + + if(fe->bri_param.is_clock_master == WANOPT_YES){ + config_clock_routing(fe, mod_no, WANOPT_NO); + clock_control(fe, 0); + } + } + + return; +} + + +/****************************************************************************** +* su_new_state() +* +* Description: handle SU port state interrupt on a physical module +* +* SU port state interrupt notes: +* 1. Chip automatically goes into inactive state if: +* 1.1 line is disconnected +* 1.2 line is deactivated +* +* 2. Because of (1) user application will have to activate the line, +* wait for the line to get 'connected' for about 1 second and if +* after 1 second line is not getting 'connected', it means line is +* actually disconnected and NOT simply deactivated. +* +* Arguments: fe, mod_no +* +* Returns: nothing +******************************************************************************/ +static void su_new_state(sdla_fe_t *fe, u32 mod_no, u8 port_no) +{ + bri_xhfc_port_t *port; + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + u8 connected = 0; + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return; + } + + bri_module = &bri->mod[mod_no]; + port = &bri_module->port[port_no]; + + connected = __su_new_state(fe, mod_no, port_no); + if(connected == 1){ + sdla_bri_set_status(fe, mod_no, port_no, FE_CONNECTED); + + port->clock_routing_state = WAITING_TO_STABILIZE; + port->clock_routing_counter = 0; + + }else{ + sdla_bri_set_status(fe, mod_no, port_no, FE_DISCONNECTED); + + port->clock_routing_state = LINE_DISCONNECTED; + port->clock_routing_counter = 0; + } +} + + +static u8 __su_new_state(sdla_fe_t *fe, u32 mod_no, u8 port_no) +{ + bri_xhfc_port_t *port; + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + u8 connected = 0; + + BRI_FUNC(); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return connected; + } + + bri_module = &bri->mod[mod_no]; + port = &bri_module->port[port_no]; + + DEBUG_HFC_S0_STATES("%s(): mod_no: %i, port number: %i\n", __FUNCTION__, mod_no, port->idx); + + if (port->mode & PORT_MODE_TE) { + DEBUG_HFC_S0_STATES("TE F%d\n", port->l1_state); + + if ((port->l1_state <= 3) || (port->l1_state >= 7)){ + l1_timer_stop_t3(port); + } + + switch (port->l1_state) + { + case (3): + if (wan_test_and_clear_bit(HFC_L1_ACTIVATED, &port->l1_flags)){ + l1_timer_start_t4(port); + } + return connected; + + case (7): + l1_timer_stop_t4(port); + connected = 1; + + if (wan_test_and_clear_bit(HFC_L1_ACTIVATING, &port->l1_flags)) { + DEBUG_HFC_S0_STATES("l1->l2 -- ACTIVATE CONFIRM\n"); + + wan_set_bit(HFC_L1_ACTIVATED, &port->l1_flags); + + } else { + if (!(wan_test_and_set_bit(HFC_L1_ACTIVATED, &port->l1_flags))) { + DEBUG_HFC_S0_STATES("l1->l2 -- ACTIVATE INDICATION\n"); + } else { + /* L1 was already activated (e.g. F8->F7) */ + return connected; + } + } + break; + + case (8): + l1_timer_stop_t4(port); + return connected; + + default: + return connected; + } + + } else if (port->mode & PORT_MODE_NT) { + + DEBUG_HFC_S0_STATES("NT G%d\n", port->l1_state); + + switch (port->l1_state) + { + case (1): + port->nt_timer = 0; + port->mode &= ~NT_TIMER; + + DEBUG_HFC_S0_STATES("l1->l2 (PH_DEACTIVATE | INDICATION)\n"); + break; + case (2): + if (port->nt_timer < 0) { + port->nt_timer = 0; + port->mode &= ~NT_TIMER; + xhfc_ph_command(fe, port, HFC_L1_DEACTIVATE_NT); + } else { + port->nt_timer = NT_T1_COUNT; + port->mode |= NT_TIMER; + + WRITE_REG(R_SU_SEL, port->idx); + WRITE_REG(A_SU_WR_STA, M_SU_SET_G2_G3); + } + return connected; + case (3): + port->nt_timer = 0; + port->mode &= ~NT_TIMER; + + DEBUG_HFC_S0_STATES("l1->l2 -- ACTIVATE INDICATION\n"); + connected = 1; + break; + case (4): + port->nt_timer = 0; + port->mode &= ~NT_TIMER; + return connected; + default: + break; + } + } + + return connected; +} + +/****************************************************************************** +* get_FE_ptr_for_port() +* +* Description : get pointer to FE structure belonging to a 'port_no' on +* module 'mod_no'. +* Allows to handle FE interrupt of ALL ports on the SAME +* physical module. +* Note: the returned pointer is NOT the same as the pointer +* in 'wp_bri_module_t->fe' because this function returns +* 'fe' related to the 'card'. +* +* Arguments : fe, mod_no, port_no +* +* Returns : fe pointer - found FE for the 'port_no'. +* NULL - FE for the 'port_no' not found (it means port_no +* is not used). +* +******************************************************************************/ +sdla_fe_t *get_FE_ptr_for_port(sdla_fe_t *original_fe, u8 mod_no, u8 port_no) +{ + sdla_t *card = (sdla_t*)original_fe->card; + sdla_t *tmp_card; + void **card_list; + + BRI_FUNC(); + + DEBUG_HFC_IRQ("%s(): mod: %d, port_no: %d (sum: %d)\n", + __FUNCTION__, mod_no, port_no, mod_no + port_no); + + card_list=__sdla_get_ptr_isr_array(card->hw); +/* +{ + int i; + for(i = 0; i < SDLA_MAX_PORTS; i++){ + DEBUG_HFC_IRQ("card_list[%d]: 0x%p\n", i, card_list[i]); + } +} +*/ + tmp_card=(sdla_t*)card_list[mod_no + port_no]; + + DEBUG_HFC_IRQ("%s(): card_list ptr: 0x%p\n", __FUNCTION__, card_list); + DEBUG_HFC_IRQ("%s(): card ptr: 0x%p, tmp_card ptr: 0x%p\n", __FUNCTION__, card, tmp_card); + + if (!tmp_card){ + return NULL; + } + + DEBUG_HFC_IRQ("%s(): %s\n", __FUNCTION__, tmp_card->devname); + + return &tmp_card->fe; +} + +/****************************************************************************** +* xhfc_interrupt() +* +* Description : handle interrupt on a PHYSICAL module +* +* Arguments : fe, mod_no +* +* Returns : 1 - interrupt recognized and handled +* 0 - interrupt not recognized (not generated by this module) +* +******************************************************************************/ +static int32_t xhfc_interrupt(sdla_fe_t *fe, u8 mod_no) +{ + sdla_fe_t *new_fe; + int32_t fifo_irq = 0, i; + sdla_bri_param_t *bri = &fe->bri_param; + wp_bri_module_t *bri_module; + u8 port_no; + reg_a_su_rd_sta new_su_state; + reg_r_su_irq r_su_irq; + reg_r_misc_irq r_misc_irq; + + BRI_FUNC(); + + if(validate_physical_mod_no(mod_no, __FUNCTION__)){ + return 0; + } + + bri_module = &bri->mod[mod_no]; + + /*DEBUG_HFC_SU_IRQ("%s(%lu): %s: mod_no: %d\n", __FUNCTION__, jiffies, fe->name, mod_no);*/ + + /* clear SU state interrupt */ + r_su_irq.reg = READ_REG(R_SU_IRQ); + + /* clear 'misc' interrupts such as timer interrupt */ + r_misc_irq.reg = READ_REG(R_MISC_IRQ); + + /***************************************************************************/ + fifo_irq = 0; + for (port_no = 0; port_no < bri_module->num_ports; port_no++) { + + DBG_MODULE_TESTER("get fifo IRQ state for port_no %d\n", port_no); + + /* get fifo IRQ states in bundle */ + fifo_irq |= (READ_REG(R_FIFO_BL0_IRQ + port_no) << (port_no * 8)); + + DBG_MODULE_TESTER("fifo_irq: 0x%X\n", fifo_irq); + } + + /***************************************************************************/ + for (i = 0; i < bri_module->num_ports; i++) { + + /****************************************************************/ + new_fe = get_FE_ptr_for_port(fe, mod_no, i); + DEBUG_HFC_IRQ("%s(): fe ptr: 0x%p\n", __FUNCTION__, fe); + if(new_fe == NULL){ + /* 'port_no' is not used by any 'wanpipe' */ + continue; + } + fe = new_fe; + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + /****************************************************************/ + + if(r_misc_irq.reg & M_TI_IRQ){ + sdla_bri_param_t *su_bri = &fe->bri_param; + wp_bri_module_t *su_bri_module = &su_bri->mod[mod_no]; + bri_xhfc_port_t *port_ptr = &su_bri_module->port[port_no]; + + //DEBUG_HFC_SU_IRQ("Timer IRQ\n"); + if(fe->bri_param.is_clock_master == WANOPT_YES && + port_ptr->clock_routing_state == WAITING_TO_STABILIZE){ + + port_ptr->clock_routing_counter++; + DEBUG_HFC_CLOCK("clock_routing_counter: %d\n", port_ptr->clock_routing_counter); + + if(port_ptr->clock_routing_counter == LINE_STABILITY_THRESHOLD){ + port_ptr->clock_routing_state = LINE_STABLE; + } + + if(port_ptr->clock_routing_state == LINE_STABLE){ + config_clock_routing(fe, mod_no, WANOPT_YES); + clock_control(fe, 1); + } + } + } + + /****************************************************************/ + + /* select the port on the chip */ + WRITE_REG(R_SU_SEL, port_no); + new_su_state.reg = READ_REG(A_SU_RD_STA); + + /*DEBUG_HFC_SU_IRQ("%s(): SU State: sta:%X, v_su_fr_sync: %i, v_su_info0: %i, v_g2_g3: %i\n", __FUNCTION__, + new_su_state.bit.v_su_sta, new_su_state.bit.v_su_fr_sync, + new_su_state.bit.v_su_info0, new_su_state.bit.v_g2_g3);*/ + + if((r_su_irq.reg & (1 << port_no))){ + sdla_bri_param_t *su_bri = &fe->bri_param; + wp_bri_module_t *su_bri_module = &su_bri->mod[mod_no]; + bri_xhfc_port_t *port_ptr = &su_bri_module->port[port_no]; + + DEBUG_HFC_S0_STATES("%s():SU IRQ:%lu: %s: SU State: 0x%X, v_su_fr_sync: %d, v_su_info0: %d, v_g2_g3: %d\n", + __FUNCTION__, jiffies, + (port_ptr->mode & PORT_MODE_NT) ? "NT: G" : "TE: F", + new_su_state.bit.v_su_sta, new_su_state.bit.v_su_fr_sync, + new_su_state.bit.v_su_info0, new_su_state.bit.v_g2_g3); + + if (new_su_state.bit.v_su_sta != port_ptr->l1_state) { + port_ptr->l1_state = new_su_state.bit.v_su_sta; + /* Handle S/U state change. */ + su_new_state(fe, mod_no, port_no); + } + + }/* if(r_misc_irq.reg & M_TI_IRQ || (r_su_irq.reg & (1 << port_no))) */ + + if(bri_module->port[port_no].bytes2transmit){ + u8 free_space; + + TX_FAST_DBG("%s(): port_no: %d, bytes2transmit: %d, dtx_indx: %d\n", + __FUNCTION__, port_no, bri_module->port[port_no].bytes2transmit, + bri_module->port[port_no].dtx_indx); + + xhfc_write_fifo_dchan(fe, mod_no, bri_module, &bri_module->port[port_no], &free_space); + } + + /* receive D-Channel Data */ + if (fifo_irq & (1 << (port_no*8+5)) ) { + netskb_t *skb = NULL; + DBG_MODULE_TESTER("There is receive D-Channel Data for port_no %d\n", port_no); + + skb = wp_bri_dchan_rx(fe, mod_no, port_no); + if(skb != NULL){ + sdla_t *card = (sdla_t*)fe->card; + private_area_t *chan; + + DEBUG_HFC_IRQ("%s(): Module: %d, port_no: %d.\n", __FUNCTION__, mod_no, port_no); + chan=(private_area_t*)card->u.aft.dev_to_ch_map[BRI_DCHAN_LOGIC_CHAN]; + + DEBUG_HFC_IRQ("%s(): chan ptr: 0x%p\n", __FUNCTION__, chan); + if (!chan){ + DEBUG_EVENT("%s: Error: No Dev for Rx logical ch=%d\n", + card->devname, BRI_DCHAN_LOGIC_CHAN); + break; + } + + wan_skb_queue_tail(&chan->wp_rx_bri_dchan_complete_list, skb); + WAN_TASKLET_SCHEDULE((&chan->common.bh_task)); + } + + }/* if ( fifo_irq & (1 << (port_no*8+5)) ) */ + }/* for (port_no = 0; port_no < bri_module->num_ports; port_no++) */ + /***************************************************************************/ + + return 1; +} + +static int32_t wp_bri_check_intr(sdla_fe_t *fe) +{ + /* must return 1! */ + return 1; +} + +static int32_t wp_bri_intr(sdla_fe_t *fe) +{ + u8 mod_no, port_no; + int32_t interrupt_serviced = 0; + + BRI_FUNC(); + + mod_no = fe_line_no_to_physical_mod_no(fe); + port_no = fe_line_no_to_port_no(fe); + + switch(fe->bri_param.mod[mod_no].type) + { + case MOD_TYPE_TE: + case MOD_TYPE_NT: + if(xhfc_interrupt(fe, mod_no)){ + /* at least one module generated an interrupt */ + interrupt_serviced = 1; + } + break; + default: + /* for missing (not installed) modules - do nothing */ + break; + } + + return interrupt_serviced; +} + + + diff --git a/patches/kdrivers/src/net/sdla_bri_tdmv.c b/patches/kdrivers/src/net/sdla_bri_tdmv.c new file mode 100755 index 0000000..2f3ac92 --- /dev/null +++ b/patches/kdrivers/src/net/sdla_bri_tdmv.c @@ -0,0 +1,1302 @@ +/*************************************************************************** + * sdla_bri_tdmv.c WANPIPE(tm) Multiprotocol WAN Link Driver. + * AFT BRI support. + * + * Author: David Rokhvarg + * + * Copyright: (c) 1984-2007 Sangoma Technologies Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * ============================================================================ + * June 5, 2007 David Rokhvarg Initial version. + ****************************************************************************** + */ + +/******************************************************************************* +** INCLUDE FILES +*******************************************************************************/ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +# include +# include +# include + +# include +# include +# include +#endif + +/******************************************************************************* +** DEFINES AND MACROS +*******************************************************************************/ + +#define DEBUG_TDMV_BRI if(0)DEBUG_EVENT + +#define REG_SHADOW +#define REG_WRITE_SHADOW +#undef PULSE_DIALING + +/* flags bits */ +#define WP_TDMV_REGISTER 1 /*0x01*/ +#define WP_TDMV_RUNNING 2 /*0x02*/ +#define WP_TDMV_UP 3 /*0x04*/ + +#define IS_TDMV_RUNNING(wr) wan_test_bit(WP_TDMV_RUNNING, &(wr)->flags) +#define IS_TDMV_UP(wr) wan_test_bit(WP_TDMV_UP, &(wr)->flags) +#define IS_TDMV_UP_RUNNING(wr) (IS_TDMV_UP(wr) && IS_TDMV_RUNNING(wr)) + +/******************************************************************************* +** STRUCTURES AND TYPEDEFS +*******************************************************************************/ +typedef struct { + int ready; + int offhook; + int lastpol; + int polarity; + int polaritydebounce; + int battery; + int battdebounce; + int ringdebounce; + int nobatttimer; + int wasringing; + + int echotune; /* echo tune */ + struct wan_rm_echo_coefs echoregs; /* echo tune */ +} tdmv_fxo_t; + +typedef struct { + int ready; + int lasttxhook; + int lasttxhook_update; + int lastrxhook; + int oldrxhook; + int debouncehook; + int debounce; + int palarms; + int ohttimer; +} tdmv_fxs_t; + +typedef struct wp_tdmv_bri_ { + void *card; + char *devname; + int num; + int flags; + wan_spinlock_t lock; + wan_spinlock_t tx_rx_lock; + union { + tdmv_fxo_t fxo; + tdmv_fxs_t fxs; + } mod[MAX_BRI_LINES]; + + int spanno; + struct zt_span span; + struct zt_chan chans[MAX_BRI_LINES]; + unsigned long reg_module_map; /* Registered modules */ + + u32 timeslot_map; + + /* Global configuration */ + + u32 intcount; + int pollcount; + unsigned char ec_chunk1[31][ZT_CHUNKSIZE]; + unsigned char ec_chunk2[31][ZT_CHUNKSIZE]; + int usecount; + u16 max_timeslots; /* up to MAX_BRI_LINES */ + int max_rxtx_len; + int channelized; + unsigned long echo_off_map; + int rxsig_state[MAX_BRI_LINES]; + int txsig_state[MAX_BRI_LINES]; /* not used */ + + u_int8_t dtmfsupport; + unsigned int dtmfactive; + unsigned int dtmfmask; + unsigned int dtmfmutemask; + + /* BRI D-chan */ + unsigned int dchan; + netdevice_t *dchan_dev; + +} wp_tdmv_bri_t; + +/******************************************************************************* +** GLOBAL VARIABLES +*******************************************************************************/ +static int wp_remora_no = 0; +extern WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head; +//static int battdebounce = DEFAULT_BATT_DEBOUNCE; +//static int battthresh = DEFAULT_BATT_THRESH; + +/******************************************************************************* +** FUNCTION PROTOTYPES +*******************************************************************************/ +static int wp_tdmv_bri_check_mtu(void* pcard, unsigned long timeslot_map, int *mtu); +static int wp_tdmv_bri_create(void* pcard, wan_tdmv_conf_t *tdmv_conf); +static int wp_tdmv_bri_remove(void* pcard); + +static int wp_tdmv_bri_reg( + void *pcard, + wan_tdmv_if_conf_t *tdmv_conf, + unsigned int active_ch, + u8 ec_enable, + netdevice_t *dev); +static int wp_tdmv_bri_unreg(void* pcard, unsigned long ts_map); +static int wp_tdmv_bri_software_init(wan_tdmv_t *wan_tdmv); +static int wp_tdmv_bri_state(void* pcard, int state); +static int wp_tdmv_bri_running(void* pcard); +static int wp_tdmv_bri_is_rbsbits(wan_tdmv_t *wan_tdmv); +static int wp_tdmv_bri_rx_tx_span(void *pcard); +static int wp_tdmv_bri_rx_chan(wan_tdmv_t*, int,unsigned char*,unsigned char*); +static int wp_tdmv_bri_ec_span(void *pcard); + +static void wp_tdmv_bri_dtmf (void* card_id, wan_event_t *event); + +extern int wp_init_proslic(sdla_fe_t *fe, int mod_no, int fast, int sane); +extern int wp_init_voicedaa(sdla_fe_t *fe, int mod_no, int fast, int sane); + +static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len); +static int wp_tdmv_rx_dchan(wan_tdmv_t*, int, unsigned char*, unsigned int); + +static int wp_tdmv_span_buf_rotate(void *pcard, u32, unsigned long); + +static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm); + +/******************************************************************************* +** FUNCTION DEFINITIONS +*******************************************************************************/ + +static int +#if defined(__FreeBSD__) || defined(__OpenBSD__) +wp_bri_zap_ioctl(struct zt_chan *chan, unsigned int cmd, caddr_t data) +#else +wp_bri_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) +#endif +{ + wp_tdmv_bri_t *wp = NULL; + int err = -ENOTTY; + + DEBUG_TDMV_BRI("%s(): line: %d\n", __FUNCTION__, __LINE__); + + switch(cmd) + { +#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) + case ZT_DCHAN_TX: + + DEBUG_TDMV_BRI("chan: 0x%p\n", chan); + + if(chan){ + DEBUG_TDMV_BRI("chan->pvt: 0x%p\n", chan->pvt); + } + + WAN_ASSERT(chan == NULL || chan->pvt == NULL); + wp = chan->pvt; + + if (wp->dchan_dev && wp->dchan_dev->hard_start_xmit){ + wp_tdmv_tx_dchan(chan, (int)data); + err=0; + }else{ + DEBUG_TDMV_BRI("%s(): line: %d\n", __FUNCTION__, __LINE__); + + DEBUG_TDMV_BRI("wp->dchan_dev: 0x%p\n", wp->dchan_dev); + if(wp->dchan_dev){ + DEBUG_TDMV_BRI("wp->dchan_dev->hard_start_xmit: 0x%p\n", + wp->dchan_dev->hard_start_xmit); + } + err=-EOPNOTSUPP; + } + break; + +#endif + + default: + DEBUG_EVENT("%s(): uknown cmd!\n", __FUNCTION__); + err = -ENOTTY; + break; + } + return err; +} + + +static int wp_bri_zap_open(struct zt_chan *chan) +{ + wp_tdmv_bri_t *wr = NULL; + + BRI_FUNC(); + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wr = chan->pvt; + wr->usecount++; + wan_set_bit(WP_TDMV_RUNNING, &wr->flags); + DEBUG_EVENT("%s: Open (usecount=%d, channo=%d, chanpos=%d)...\n", + wr->devname, + wr->usecount, + chan->channo, + chan->chanpos); + return 0; +} + +static int wp_bri_zap_close(struct zt_chan *chan) +{ + sdla_t *card = NULL; + wp_tdmv_bri_t* wr = NULL; + sdla_fe_t *fe = NULL; + + BRI_FUNC(); + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wr = chan->pvt; + card = wr->card; + fe = &card->fe; + wr->usecount--; + wan_clear_bit(WP_TDMV_RUNNING, &wr->flags); + + return 0; +} + +static int wp_bri_zap_watchdog(struct zt_span *span, int event) +{ + BRI_FUNC(); + +#if 0 + printk("TDM: Restarting DMA\n"); + wctdm_restart_dma(span->pvt); +#endif + return 0; +} + +/****************************************************************************** +** wp_remora_zap_hwec() - +** +** OK +*/ +static int wp_bri_zap_hwec(struct zt_chan *chan, int enable) +{ + wp_tdmv_bri_t *wr = NULL; + sdla_t *card = NULL; + int fe_chan = chan->chanpos; + int err = -ENODEV; + sdla_fe_t *fe = NULL; + + BRI_FUNC(); + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wr = chan->pvt; + WAN_ASSERT2(wr->card == NULL, -ENODEV); + card = wr->card; + fe = &card->fe; + + if (card->wandev.ec_enable){ + DEBUG_EVENT("[TDMV_BRI]: %s: %s(): channel %d\n", + wr->devname, __FUNCTION__, fe_chan); + + if(fe_chan == 1 || fe_chan == 2){ + err = card->wandev.ec_enable(card, enable, fe_chan); + }else{ + DEBUG_EVENT("[TDMV_BRI]: %s: %s(): Warning: invalid fe_channel %d!!\n", + wr->devname, __FUNCTION__, fe_chan); + err = 0; + } + }else{ + DEBUG_EVENT("[TDMV_BRI]: %s: %s(): card->wandev.ec_enable == NULL!!!!!!\n", + wr->devname, __FUNCTION__); + } + return err; +} + + +/****************************************************************************** +** wp_tdmv_rbsbits_poll() - +** +** DONE +*/ +static int wp_tdmv_rbsbits_poll(wan_tdmv_t *wan_tdmv, void *card1) +{ + wp_tdmv_bri_t *wp = NULL; + + BRI_FUNC(); + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + return 0; +} + + +/****************************************************************************** +** wp_tdmv_bri_init() - +** +** OK +*/ +int wp_tdmv_bri_init(wan_tdmv_iface_t *iface) +{ + BRI_FUNC(); + + WAN_ASSERT(iface == NULL); + + memset(iface, 0, sizeof(wan_tdmv_iface_t)); + iface->check_mtu = wp_tdmv_bri_check_mtu; + iface->create = wp_tdmv_bri_create; + iface->remove = wp_tdmv_bri_remove; + iface->reg = wp_tdmv_bri_reg; + iface->unreg = wp_tdmv_bri_unreg; + iface->software_init = wp_tdmv_bri_software_init; + iface->state = wp_tdmv_bri_state; + iface->running = wp_tdmv_bri_running; + iface->is_rbsbits = wp_tdmv_bri_is_rbsbits; + iface->rx_tx_span = wp_tdmv_bri_rx_tx_span; + iface->rx_chan = wp_tdmv_bri_rx_chan; + iface->ec_span = wp_tdmv_bri_ec_span; + + iface->rbsbits_poll = wp_tdmv_rbsbits_poll; //????? + + iface->rx_dchan = wp_tdmv_rx_dchan; + + iface->buf_rotate = wp_tdmv_span_buf_rotate; + return 0; +} + + +static int wp_tdmv_bri_software_init(wan_tdmv_t *wan_tdmv) +{ + sdla_t *card = NULL; + sdla_fe_t *fe = NULL; + wp_tdmv_bri_t *wr = wan_tdmv->sc; + int x = 0, num = 0; + + BRI_FUNC(); + + WAN_ASSERT(wr == NULL); + WAN_ASSERT(wr->card == NULL); + card = wr->card; + fe = &card->fe; + + if (wan_test_bit(WP_TDMV_REGISTER, &wr->flags)){ + + WP_DELAY(1000); + DEBUG_EVENT( + "%s: Wanpipe device is already registered to Zaptel span # %d!\n", + wr->devname, wr->span.spanno); + return 0; + } + + /* Zapata stuff */ + sprintf(wr->span.name, "WPBRI/%d", wr->num); + sprintf(wr->span.desc, "wrtdm Board %d", wr->num + 1); + switch(fe->fe_cfg.tdmv_law){ + case WAN_TDMV_ALAW: + DEBUG_EVENT( + "%s: ALAW override parameter detected. Device will be operating in ALAW\n", + wr->devname); + wr->span.deflaw = ZT_LAW_ALAW; + break; + case WAN_TDMV_MULAW: + wr->span.deflaw = ZT_LAW_MULAW; + break; + } + +wr->span.deflaw = ZT_LAW_ALAW;//FIXME: hardcoded + + wr->dtmfsupport = card->u.aft.tdmv_hw_dtmf; + + for (x = 0; x < MAX_BRI_TIMESLOTS; x++) { + + sprintf(wr->chans[x].name, "WPBRI/%d/%d", wr->num, x); + + wr->chans[x].sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | + ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_FXOLS | + ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | + ZT_SIG_SF; + switch(x) + { + case 0: + case 1: + DEBUG_EVENT("%s: Port %d Configure B-chan %d for voice (%s, type %s)!\n", + wr->devname, + WAN_FE_LINENO(fe) + 1, + x + 1, + wr->chans[x].name, + WP_BRI_DECODE_MOD_TYPE(fe->bri_param.mod[WAN_FE_LINENO(fe)].type)); + break; + + case 2: + DEBUG_EVENT("%s: Port %d Configure BRI D-chan (%s, type %s)!\n", + wr->devname, + WAN_FE_LINENO(fe) + 1, + wr->chans[x].name, + WP_BRI_DECODE_MOD_TYPE(fe->bri_param.mod[WAN_FE_LINENO(fe)].type));/* fe->bri_param.mod[2], there is no [2] */ + break; + }/* switch() */ + + wr->chans[x].chanpos = x+1; + wr->chans[x].pvt = wr; + num++; + + //wr->rxsig_state[x] = ZT_RXSIG_INITIAL; + }/* for() */ + + wr->span.pvt = wr; + wr->span.chans = wr->chans; + wr->span.channels = MAX_BRI_TIMESLOTS;/* this is the number of b-chans (2) and the d-chan on one BRI line. */; + wr->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_CCS; /* <--- this is really BS */ + + wr->span.open = wp_bri_zap_open; + wr->span.close = wp_bri_zap_close; + + //wr->span.flags = ZT_FLAG_RBS; + + wr->span.ioctl = wp_bri_zap_ioctl; + wr->span.watchdog = wp_bri_zap_watchdog; + /* Set this pointer only if card has hw echo canceller module */ + if (card->wandev.ec_dev){ + wr->span.echocan = wp_bri_zap_hwec; + } +#if defined(__LINUX__) + init_waitqueue_head(&wr->span.maintq); +#endif + + WP_DELAY(1000); + + if (zt_register(&wr->span, 0)) { + + BRI_FUNC(); + DEBUG_EVENT("%s: Unable to register span with zaptel\n", + wr->devname); + + WP_DELAY(1000); + return -EINVAL; + } + + if (wr->span.spanno != wr->spanno +1){ + DEBUG_EVENT("\n"); + DEBUG_EVENT("WARNING: Span number %d is already used by another device!\n", + wr->spanno + 1); + DEBUG_EVENT(" Possible cause: Another TDM driver already loaded!\n"); + DEBUG_EVENT(" Solution: Unload wanpipe and check currently\n"); + DEBUG_EVENT(" used spans in /proc/zaptel directory.\n"); + DEBUG_EVENT(" Reconfiguring device %s to new span number # %d\n", + wr->devname,wr->span.spanno); + DEBUG_EVENT("\n"); + wr->spanno = wr->span.spanno-1; + }else{ + DEBUG_EVENT("%s: Wanpipe device is registered to Zaptel span # %d!\n", + wr->devname, wr->span.spanno); + } + wp_tdmv_bri_check_mtu(card, wr->reg_module_map, &wr->max_rxtx_len); + wan_set_bit(WP_TDMV_REGISTER, &wr->flags); + + /* Initialize Callback event function pointers */ + if (wr->dtmfsupport == WANOPT_YES){ + DEBUG_EVENT("ADBG> Updating event callback dtmf\n"); + card->wandev.event_callback.dtmf = wp_tdmv_bri_dtmf; + } + + WP_DELAY(1000); + + wr->span.alarms = ZT_ALARM_NONE;//FIXME: report real line state, also report alarms on line connect/disconnect. + zt_alarm_notify(&wr->span); + + return 0; +} + +/****************************************************************************** +** wp_tdmv_release() - +** +** OK +*/ +static void wp_tdmv_release(wp_tdmv_bri_t *wr) +{ + BRI_FUNC(); + + WAN_ASSERT1(wr == NULL); + if (wan_test_bit(WP_TDMV_REGISTER, &wr->flags)){ + DEBUG_EVENT("%s: Unregister WAN FXS/FXO device from Zaptel!\n", + wr->devname); + wan_clear_bit(WP_TDMV_REGISTER, &wr->flags); + zt_unregister(&wr->span); + wan_clear_bit(WP_TDMV_REGISTER, &wr->flags); + } + wan_free(wr); + return; +} + + +static wp_tdmv_bri_t *wan_remora_search(sdla_t * card) +{ + BRI_FUNC(); + + return NULL; +} + +/****************************************************************************** +** wp_tdmv_bri_check_mtu() - +** +** OK +*/ +static int wp_tdmv_bri_check_mtu(void* pcard, unsigned long timeslot_map, int *mtu) +{ + BRI_FUNC(); + + *mtu = ZT_CHUNKSIZE; + return 0; + +} + +/****************************************************************************** +** wp_tdmv_bri_create() - +*tdmv_* +** OK +*/ +static int wp_tdmv_bri_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) +{ + sdla_t *card = (sdla_t*)pcard; + wp_tdmv_bri_t *wr = NULL; + wan_tdmv_t *tmp = NULL; + + BRI_FUNC(); + + WAN_ASSERT(card == NULL); + WAN_ASSERT(tdmv_conf->span_no == 0); + + wr = wan_remora_search(card); + if (wr){ + DEBUG_EVENT("%s: AFT remora card already configured!\n", + card->devname); + return -EINVAL; + } + + memset(&card->wan_tdmv, 0x0, sizeof(wan_tdmv_t)); + /* We are forcing to register wanpipe devices at the same sequence + * that it defines in /etc/zaptel.conf */ + WAN_LIST_FOREACH(tmp, &wan_tdmv_head, next){ + if (tmp->spanno == tdmv_conf->span_no){ + DEBUG_EVENT("%s: Registering device with an incorrect span number!\n", + card->devname); + DEBUG_EVENT("%s: Another wanpipe device already configured to span #%d!\n", + card->devname, tdmv_conf->span_no); + return -EINVAL; + } + if (!WAN_LIST_NEXT(tmp, next)){ + break; + } + } + + memset(&card->wan_tdmv, 0x0, sizeof(wan_tdmv_t)); + card->wan_tdmv.max_timeslots = card->fe.bri_param.max_fe_channels; + card->wan_tdmv.spanno = tdmv_conf->span_no; + card->wandev.te_report_alarms = wp_tdmv_report_alarms; + + wr = wan_malloc(sizeof(wp_tdmv_bri_t)); + if (wr == NULL){ + return -ENOMEM; + } + memset(wr, 0x0, sizeof(wp_tdmv_bri_t)); + card->wan_tdmv.sc = wr; + wr->spanno = tdmv_conf->span_no-1; + wr->num = wp_remora_no++; + wr->card = card; + wr->devname = card->devname; + wr->max_timeslots = card->fe.bri_param.max_fe_channels; + wr->max_rxtx_len = 0; + wan_spin_lock_init(&wr->lock, "wan_britdmv_lock"); + wan_spin_lock_init(&wr->tx_rx_lock, "wan_britdmv_txrx_lock"); + + /* BRI signalling is selected with hw HDLC (dchan is not 0) */ + wr->dchan = 3;/* MUST be 3! */ + + if (tmp){ + WAN_LIST_INSERT_AFTER(tmp, &card->wan_tdmv, next); + }else{ + WAN_LIST_INSERT_HEAD(&wan_tdmv_head, &card->wan_tdmv, next); + } + return 0; +} + + +/****************************************************************************** +** wp_tdmv_bri_reg() - calculate 'channo' based on 'activ_ch' for the +** interface. +** +** +** Returns: 0-31 - Return TDM Voice channel number. +** -EINVAL - otherwise +** OK +*/ +static int wp_tdmv_bri_reg( + void *pcard, + wan_tdmv_if_conf_t *tdmv_conf, + unsigned int active_ch, + u8 ec_enable, + netdevice_t *dev) +{ + sdla_t *card = (sdla_t*)pcard; + sdla_fe_t *fe = &card->fe; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + int i, channo = 0; + + BRI_FUNC(); + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + + DEBUG_BRI("%s(): FE line no: %d, active_ch: 0x%X\n", + __FUNCTION__, WAN_FE_LINENO(fe), active_ch); + + if(WAN_FE_LINENO(fe) >= MAX_BRI_LINES){ + DEBUG_EVENT( + "%s: %s(): Error: invalid FE line number (%d)!\n", + card->devname, __FUNCTION__, WAN_FE_LINENO(fe)); + return -EINVAL; + } + + if (wan_test_bit(WP_TDMV_REGISTER, &wr->flags)){ + DEBUG_EVENT( + "%s: Error: Master device has already been configured!\n", + card->devname); + return -EINVAL; + } + + DEBUG_BRI("%s(): wr->max_timeslots: %d\n", __FUNCTION__, wr->max_timeslots); + + /* The Zaptel Channel Number for BRI must be adjusted based on + the module number to start from 0 */ + active_ch = active_ch>>(WAN_FE_LINENO(fe)*2); + + for(i = 0; i < wr->max_timeslots; i++){ + if (wan_test_bit(i, &active_ch)){ + if (tdmv_conf->tdmv_echo_off){ + wan_set_bit(i, &wr->echo_off_map); + } + channo = i; + break; + } + } + + DEBUG_BRI("1 %s(): channo: %d, wr->timeslot_map: 0x%X\n", + __FUNCTION__, channo, wr->timeslot_map); + + if(channo > 2){ + DEBUG_EVENT( + "%s: Error: TDMV iface %s failed to configure for channo %d! Must be between 0 and 2 (including).\n", + card->devname, + wan_netif_name(dev), + channo); + return -EINVAL; + } + + /* for BRI only bits 0 and 1 can be set! */ + wan_set_bit(channo, &wr->timeslot_map); + + if (i == wr->max_timeslots){ + DEBUG_EVENT("%s: Error: TDMV iface %s failed to configure for 0x%08X timeslots!\n", + card->devname, + wan_netif_name(dev), + active_ch); + return -EINVAL; + } + + DEBUG_EVENT("%s: Registering TDMV to %s module %d!\n", + card->devname, + WP_BRI_DECODE_MOD_TYPE(fe->bri_param.mod[WAN_FE_LINENO(fe)].type), + WAN_FE_LINENO(fe) + 1); + + wan_set_bit(channo, &wr->reg_module_map); + + if (tdmv_conf->tdmv_echo_off){ + DEBUG_EVENT("%s: TDMV Echo Ctrl:Off\n", + wr->devname); + } + memset(wr->chans[channo].sreadchunk, WAN_TDMV_IDLE_FLAG, ZT_CHUNKSIZE); + memset(wr->chans[channo].swritechunk, WAN_TDMV_IDLE_FLAG, ZT_CHUNKSIZE); + wr->chans[channo].readchunk = wr->chans[channo].sreadchunk; + wr->chans[channo].writechunk = wr->chans[channo].swritechunk; + wr->channelized = WAN_TRUE; + + wp_tdmv_bri_check_mtu(card, active_ch, &wr->max_rxtx_len); + + DEBUG_BRI("%s(): card->u.aft.tdmv_dchan: %d, channo: %d, wr->dchan: %d\n", + __FUNCTION__, card->u.aft.tdmv_dchan, channo, wr->dchan); + + if(wr->dchan != 3){ + DEBUG_EVENT("%s:%s: Error: 'dchan' (%d) not equal 3!\n", + card->devname, wan_netif_name(dev), wr->dchan); + return -EINVAL; + } + + if((channo + 1) == wr->dchan){ /* 3 */ + DEBUG_BRI("%s(): registering BRI D-chan 'dev' pointer\n", __FUNCTION__); + wr->dchan_dev = dev; + card->u.aft.tdmv_dchan = BRI_DCHAN_LOGIC_CHAN; + } + + return channo; +} + +/****************************************************************************** +** wp_tdmv_unreg() - +** +** OK +*/ +static int wp_tdmv_bri_unreg(void* pcard, unsigned long ts_map) +{ + sdla_t *card = (sdla_t*)pcard; + sdla_fe_t *fe = &card->fe; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + int channo = 0; + + BRI_FUNC(); + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + for(channo = 0; channo < wr->max_timeslots; channo++){ + if (wan_test_bit(channo, &wr->reg_module_map)){ + DEBUG_EVENT( + "%s: Unregistering TDMV %s iface from module %d!\n", + card->devname, + WP_BRI_DECODE_MOD_TYPE(fe->bri_param.mod[0].type), + channo+1); + wan_clear_bit(channo, &wr->reg_module_map); + wan_clear_bit(channo, &wr->echo_off_map); + memset(wr->chans[channo].sreadchunk, + WAN_TDMV_IDLE_FLAG, + ZT_CHUNKSIZE); + memset(wr->chans[channo].swritechunk, + WAN_TDMV_IDLE_FLAG, + ZT_CHUNKSIZE); + wr->chans[channo].readchunk = + wr->chans[channo].sreadchunk; + wr->chans[channo].writechunk = + wr->chans[channo].swritechunk; + } + } + return 0; +} + + +/****************************************************************************** +** wp_tdmv_remove() - +** +** OK +*/ +static int wp_tdmv_bri_remove(void* pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + + BRI_FUNC(); + + if (!card->wan_tdmv.sc){ + return 0; + } + + wr = wan_tdmv->sc; + /* Release span, possibly delayed */ + if (wr && wr->reg_module_map){ + DEBUG_EVENT( + "%s: Some interfaces are not unregistered (%08lX)!\n", + card->devname, + wr->reg_module_map); + return -EINVAL; + } + if (wr && wr->usecount){ + DEBUG_EVENT("%s: ERROR: Wanpipe is still used by Asterisk!\n", + card->devname); + return -EINVAL; + } + + if (wr){ + wan_clear_bit(WP_TDMV_RUNNING, &wr->flags); + wan_clear_bit(WP_TDMV_UP, &wr->flags); + wan_tdmv->sc = NULL; + card->wandev.te_report_alarms = NULL; + WAN_LIST_REMOVE(wan_tdmv, next); + wp_tdmv_release(wr); + }else{ + wan_tdmv->sc = NULL; + } + return 0; +} + +static int wp_tdmv_span_buf_rotate(void *pcard, u32 buf_sz, unsigned long mask) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wp = NULL; + int x; + unsigned int rx_offset, tx_offset; + void *ptr; + + WAN_ASSERT(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + rx_offset = buf_sz * card->u.aft.tdm_rx_dma_toggle; + tx_offset = buf_sz * card->u.aft.tdm_tx_dma_toggle; + +#define BRI_NUM_OF_BCHANNELS 2 + for (x = 0; x < BRI_NUM_OF_BCHANNELS; x ++) { + /*for (x = 0; x < 32; x ++) {*/ + if (wan_test_bit(x,&wp->timeslot_map)) { + + wan_spin_lock(&wp->chans[x].lock); + + ptr=(void*)((((unsigned long)wp->chans[x].readchunk) & ~(mask)) + rx_offset); + wp->chans[x].readchunk = ptr; + ptr=(void*)((((unsigned long)wp->chans[x].writechunk) & ~(mask)) + tx_offset); + wp->chans[x].writechunk = ptr; + + wan_spin_unlock(&wp->chans[x].lock); + +#if defined(__LINUX__) + prefetch(wp->chans[x].readchunk); + prefetch(wp->chans[x].writechunk); +#endif + + if (card->wandev.rtp_len && card->wandev.rtp_tap) { + card->wandev.rtp_tap(card,x, + wp->chans[x].readchunk, + wp->chans[x].writechunk, + ZT_CHUNKSIZE); + } + } + } + + return 0; +} + +static int wp_tdmv_bri_state(void* pcard, int state) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + + BRI_FUNC(); + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = (wp_tdmv_bri_t*)wan_tdmv->sc; + + switch(state){ + case WAN_CONNECTED: + DEBUG_TDMV("%s: TDMV Remora state is CONNECTED!\n", + wr->devname); + wan_set_bit(WP_TDMV_UP, &wr->flags); + break; + + case WAN_DISCONNECTED: + DEBUG_TDMV("%s: TDMV Remora state is DISCONNECTED!\n", + wr->devname); + wan_clear_bit(WP_TDMV_UP, &wr->flags); + break; + } + return 0; +} + +/****************************************************************************** +** wp_tdmv_running() - +** +** OK +*/ +static int wp_tdmv_bri_running(void* pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + + BRI_FUNC(); + + wr = wan_tdmv->sc; + if (wr && wr->usecount){ + DEBUG_EVENT("%s: WARNING: Wanpipe is still used by Asterisk!\n", + card->devname); + return -EINVAL; + } + return 0; +} + +/****************************************************************************** +** wp_tdmv_bri_is_rbsbits() - +** +** OK +*/ +static int wp_tdmv_bri_is_rbsbits(wan_tdmv_t *wan_tdmv) +{ + return 0; +} + +/****************************************************************************** +** wp_tdmv_rx_chan() - +** +** OK +*/ +static int wp_tdmv_bri_rx_chan(wan_tdmv_t *wan_tdmv, int channo, + unsigned char *rxbuf, + unsigned char *txbuf) +{ + wp_tdmv_bri_t *wr = wan_tdmv->sc; +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + wan_tdmv_rxtx_pwr_t *pwr_rxtx = NULL; +#endif + + //DEBUG_TDMV_BRI("channo: %d\n", channo); + + //return 0; + + WAN_ASSERT2(wr == NULL, -EINVAL); + WAN_ASSERT2(channo < 0, -EINVAL); + WAN_ASSERT2(channo > 31, -EINVAL); + + if (!IS_TDMV_UP(wr)){ + return -EINVAL; + } + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + pwr_rxtx = &wan_tdmv->chan_pwr[channo]; +#endif + +#if 0 +DEBUG_EVENT("Module %d: RX: %02X %02X %02X %02X %02X %02X %02X %02X\n", + channo, + rxbuf[0], + rxbuf[1], + rxbuf[2], + rxbuf[3], + rxbuf[4], + rxbuf[5], + rxbuf[6], + rxbuf[7] + ); +#endif + wr->chans[channo].readchunk = rxbuf; + wr->chans[channo].writechunk = txbuf; + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + wp_tdmv_echo_check(wan_tdmv, &wr->chans[channo], channo); +#endif + + if (!wan_test_bit(channo, &wr->echo_off_map)){ +/*Echo spike starts at 25bytes*/ +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + if(pwr_rxtx->current_state != ECHO_ABSENT){ +#endif +#if 0 +/* Echo spike starts at 16 bytes */ + + zt_ec_chunk( + &wr->chans[channo], + wr->chans[channo].readchunk, + wr->chans[channo].writechunk); +#endif + +#if 1 +/*Echo spike starts at 9 bytes*/ + zt_ec_chunk( + &wr->chans[channo], + wr->chans[channo].readchunk, + wr->ec_chunk1[channo]); + memcpy( + wr->ec_chunk1[channo], + wr->chans[channo].writechunk, + ZT_CHUNKSIZE); +#endif + +#if 0 +/*Echo spike starts at bytes*/ + zt_ec_chunk( + &wr->chans[channo], + wr->chans[channo].readchunk, + wr->ec_chunk1[channo]); + memcpy( + wr->ec_chunk1[channo], + wr->ec_chunk2[channo], + ZT_CHUNKSIZE); + + memcpy( + wr->ec_chunk2[channo], + wr->chans[channo].writechunk, + ZT_CHUNKSIZE); +#endif + +#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER + } /*if(pwr_rxtx->current_state != ECHO_ABSENT) */ +#endif + } /* if (!wan_test_bit(channo, &wr->echo_off_map)) */ + + return 0; +} + +static int wp_tdmv_bri_rx_tx_span(void *pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + + /*BRI_FUNC();*/ + + WAN_ASSERT(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + wr->intcount++; + + zt_receive(&wr->span); + zt_transmit(&wr->span); + + return 0; +} + +static int wp_tdmv_bri_ec_span(void *pcard) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + + //BRI_FUNC(); + + WAN_ASSERT(wan_tdmv->sc == NULL); + + wr = wan_tdmv->sc; + + zt_ec_span(&wr->span); + + return 0; + +} + +static void wp_tdmv_bri_dtmf (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wr = NULL; + + BRI_FUNC(); + + WAN_ASSERT1(wan_tdmv->sc == NULL); + wr = wan_tdmv->sc; + + if (event->type == WAN_EVENT_EC_DTMF){ + DEBUG_EVENT("%s: Received DTMF Event at TDM BRI (%d:%c:%s:%s)!\n", + card->devname, + event->channel, + event->digit, + (event->dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", + (event->dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP"); + }else if (event->type == WAN_EVENT_RM_DTMF){ + DEBUG_EVENT("%s: Received DTMF Event at TDM BRI (%d:%c)!\n", + card->devname, + event->channel, + event->digit); + } + + if (!(wr->dtmfmask & (1 << (event->channel-1)))){ + DEBUG_EVENT("%s: DTMF is not enabled for the channel %d\n", + card->devname, + event->channel); + return; + } + if (event->dtmf_type == WAN_EC_TONE_PRESENT){ + wr->dtmfactive |= (1 << event->channel); + zt_qevent_lock( + &wr->span.chans[event->channel-1], + (ZT_EVENT_DTMFDOWN | event->digit)); + }else{ + wr->dtmfactive &= ~(1 << event->channel); + zt_qevent_lock( + &wr->span.chans[event->channel-1], + (ZT_EVENT_DTMFUP | event->digit)); + } + return; +} + +static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len) +{ + wp_tdmv_bri_t *wp = NULL; + netskb_t *skb = NULL; + wan_smp_flag_t smp_flags; + unsigned char *data = NULL; + int err = 0; + + WAN_ASSERT2(chan == NULL, -ENODEV); + WAN_ASSERT2(chan->pvt == NULL, -ENODEV); + wp = chan->pvt; + WAN_ASSERT(wp->dchan_dev == NULL); + + if (len <= 2){ + return -EINVAL; + } + len -= 2; /* Remove checksum */ + skb = wan_skb_alloc(len+1); + if (skb == NULL){ + return -ENOMEM; + } + data = wan_skb_put(skb, len); + wan_spin_lock_irq(&chan->lock, &smp_flags); + memcpy(data, chan->writebuf[chan->inwritebuf], len); + wan_spin_unlock_irq(&chan->lock, &smp_flags); +#if 0 + { + int i; + DEBUG_EVENT("%s: TX DCHAN len: %d\n", chan->name, len); + /* + for(i = 0; i < len; i++){ + _DEBUG_EVENT("%02X ", data[i]); + } + _DEBUG_EVENT("\n"); + */ + } +#endif + if (skb){ + err = wp->dchan_dev->hard_start_xmit(skb, wp->dchan_dev); + if (err){ + wan_skb_free(skb); + } + } + + return err; +} + +/****************************************************************************** +** wp_tdmv_rx_dchan() - +** +** OK +*/ +static int wp_tdmv_rx_dchan(wan_tdmv_t *wan_tdmv, int channo, + unsigned char *rxbuf, unsigned int len) +{ + wp_tdmv_bri_t *wp = wan_tdmv->sc; + struct zt_chan *chan = NULL, *ms = NULL; + wan_smp_flag_t smp_flags; + unsigned char *buf = NULL; + int oldbuf; + int i, left; + + DEBUG_TDMV("%s(): channo: %d, wp->dchan: %d, len: %d\n", __FUNCTION__, channo, wp->dchan, len); + + WAN_ASSERT(wp == NULL); + WAN_ASSERT(channo != wp->dchan-1); + chan = &wp->chans[wp->dchan-1]; + WAN_ASSERT(chan == NULL || chan->master == NULL); + ms = chan->master; + + BRI_FUNC(); + + if (!IS_TDMV_UP(wp)){ + DEBUG_TDMV("%s: Asterisk is not running!\n", + wp->devname); + return -EINVAL; + } + if (!(ms->flags & ZT_FLAG_HDLC)){ + DEBUG_TDMV("%s: ERROR: %s not defined as D-CHAN! Or received HDLC data before 'ztcfg' was run.\n", + wp->devname, ms->name); + return -EINVAL; + } + + if (ms->inreadbuf < 0){ + return -EINVAL; + } + + if (ms->inreadbuf >= ZT_MAX_NUM_BUFS){ + DEBUG_EVENT("%s: RX buffer (%s) is out of range (%d-%d)!\n", + wp->devname, ms->name, ms->inreadbuf,ZT_MAX_NUM_BUFS); + return -EINVAL; + } + + /* FIXME wan_spin_lock_irqsave(&wp->tx_rx_lock, smp_flags); */ + wan_spin_lock_irq(&chan->lock, &smp_flags); + buf = ms->readbuf[ms->inreadbuf]; + left = ms->blocksize - ms->readidx[ms->inreadbuf]; + if (len + 2 > left) { + DEBUG_EVENT("%s: ERROR: Not ehough space for RX HDLC packet (%d:%d)!\n", + wp->devname, len+2, left); + wan_spin_unlock_irq(&chan->lock, &smp_flags); + return -EINVAL; + } + for(i = 0; i < len; i++){ + buf[ms->readidx[ms->inreadbuf]++] = rxbuf[i]; + } + /* Add extra 2 bytes for checksum */ + buf[ms->readidx[ms->inreadbuf]++] = 0x00; + buf[ms->readidx[ms->inreadbuf]++] = 0x00; + + oldbuf = ms->inreadbuf; + ms->readn[ms->inreadbuf] = ms->readidx[ms->inreadbuf]; + ms->inreadbuf = (ms->inreadbuf + 1) % ms->numbufs; + if (ms->inreadbuf == ms->outreadbuf) { + /* Whoops, we're full, and have no where else + to store into at the moment. We'll drop it + until there's a buffer available */ + ms->inreadbuf = -1; + /* Enable the receiver in case they've got POLICY_WHEN_FULL */ + ms->rxdisable = 0; + } + if (ms->outreadbuf < 0) { /* start out buffer if not already */ + ms->outreadbuf = oldbuf; + } + /* FIXME wan_spin_unlock_irq(&wp->tx_rx_lock, &smp_flags); */ + wan_spin_unlock_irq(&chan->lock, &smp_flags); + if (!ms->rxdisable) { /* if receiver enabled */ + DEBUG_TDMV("%s: HDLC block is ready!\n", + wp->devname); + /* Notify a blocked reader that there is data available + to be read, unless we're waiting for it to be full */ +#if defined(__LINUX__) + wake_up_interruptible(&ms->readbufq); + wake_up_interruptible(&ms->sel); + if (ms->iomask & ZT_IOMUX_READ) + wake_up_interruptible(&ms->eventbufq); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) + wakeup(&ms->readbufq); + wakeup(&ms->sel); + if (ms->iomask & ZT_IOMUX_READ) + wakeup(&ms->eventbufq); + +#endif + } + return 0; +} + + +/****************************************************************************** +** wp_tdmv_report_alarms() - +** +** DONE +*/ +static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm) +{ + sdla_t *card = (sdla_t*)pcard; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_bri_t *wp = wan_tdmv->sc; + + /* The sc pointer can be NULL, on shutdown. In this + * case don't generate error, just get out */ + if (!wp){ + return; + } + + if(te_alarm == 0){ + wp->span.alarms = ZT_ALARM_NONE; + }else{ + wp->span.alarms = ZT_ALARM_RED; + } + zt_alarm_notify(&wp->span); + return; +} diff --git a/patches/kdrivers/src/net/sdla_bsc.c b/patches/kdrivers/src/net/sdla_bsc.c index ef22e90..033a61c 100644 --- a/patches/kdrivers/src/net/sdla_bsc.c +++ b/patches/kdrivers/src/net/sdla_bsc.c @@ -282,7 +282,7 @@ int wpbsc_init (sdla_t* card, wandev_conf_t* conf) card->wandev.new_if_cnt = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; card->wandev.mtu = cfg.max_data_frame_size; @@ -320,12 +320,12 @@ int wpbsc_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t* dev; volatile bscmp_private_area_t* bscmp_priv_area; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -360,7 +360,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; bscmp_private_area_t* bscmp_priv_area; @@ -431,6 +431,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; dev->do_ioctl = &if_ioctl; diff --git a/patches/kdrivers/src/net/sdla_bscstrm.c b/patches/kdrivers/src/net/sdla_bscstrm.c index 1d60715..07f85ce 100644 --- a/patches/kdrivers/src/net/sdla_bscstrm.c +++ b/patches/kdrivers/src/net/sdla_bscstrm.c @@ -262,7 +262,7 @@ int wp_bscstrm_init (sdla_t* card, wandev_conf_t* conf) card->wandev.new_if_cnt = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; card->wandev.mtu = 1000; @@ -292,7 +292,7 @@ int wp_bscstrm_init (sdla_t* card, wandev_conf_t* conf) printk(KERN_INFO "%s: Bisync Streaming Config: \n",card->devname); printk(KERN_INFO "%s: Comm Port = %s\n", card->devname,card->wandev.comm_port==0?"PRI":"SEC"); - printk(KERN_INFO "%s: Baud Rate = %u\n", + printk(KERN_INFO "%s: Baud Rate = %lu\n", card->devname,card->wandev.bscstrm_cfg.baud_rate); printk(KERN_INFO "%s: Adapter Frequency = %lu\n", card->devname,card->wandev.bscstrm_cfg.adapter_frequency); @@ -353,12 +353,12 @@ int wp_bscstrm_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t* dev; volatile bscstrm_private_area_t* bscstrm_priv_area; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -398,7 +398,7 @@ static void bscstrm_bh (unsigned long data) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; bscstrm_private_area_t* bscstrm_priv_area; @@ -489,6 +489,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; dev->do_ioctl = &if_ioctl; diff --git a/patches/kdrivers/src/net/sdla_chdlc.c b/patches/kdrivers/src/net/sdla_chdlc.c index d89cd95..45a9c57 100644 --- a/patches/kdrivers/src/net/sdla_chdlc.c +++ b/patches/kdrivers/src/net/sdla_chdlc.c @@ -452,7 +452,7 @@ int wpc_init (sdla_t* card, wandev_conf_t* conf) if (IS_TE1_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -460,7 +460,7 @@ int wpc_init (sdla_t* card, wandev_conf_t* conf) card->wandev.fe_enable_timer = chdlc_enable_timer; card->wandev.te_link_state = chdlc_handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_CARD(card)) ? WANOPT_V35 : WANOPT_RS232; if (card->u.c.comm_port == WANOPT_PRI){ @@ -470,7 +470,7 @@ int wpc_init (sdla_t* card, wandev_conf_t* conf) }else if (IS_56K_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -538,9 +538,9 @@ int wpc_init (sdla_t* card, wandev_conf_t* conf) card->u.c.update_call_count = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; - if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&& + if ((card->u.c.comm_port == WANOPT_SEC && conf->electrical_interface == WANOPT_V35)&& card->type != SDLA_S514){ printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n", card->devname, PORT(card->u.c.comm_port)); @@ -749,7 +749,7 @@ int wpc_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t *dev; chdlc_private_area_t* chdlc_priv_area; unsigned long smp_flags; @@ -759,7 +759,7 @@ static int update (wan_device_t* wandev) #endif /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -856,7 +856,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; chdlc_private_area_t* chdlc_priv_area; int err = 0; @@ -1189,6 +1189,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; #if defined(LINUX_2_4)||defined(LINUX_2_6) @@ -1393,7 +1395,6 @@ static void disable_comm (sdla_t *card) if (card->wandev.fe_iface.pre_release){ card->wandev.fe_iface.pre_release(&card->fe); } - if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1907,7 +1908,6 @@ static int chdlc_disable_comm_shutdown (sdla_t *card) if (card->wandev.fe_iface.pre_release){ card->wandev.fe_iface.pre_release(&card->fe); } - if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -2536,7 +2536,7 @@ static void rx_intr (sdla_t* card) api_rx_hdr->usec=tv.tv_usec; skb->protocol = htons(WP_PVC_PROT); - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); skb->dev = dev; skb->pkt_type = WAN_PACKET_DATA; @@ -2553,7 +2553,7 @@ static void rx_intr (sdla_t* card) if (chdlc_priv_area->annexg_dev){ skb->protocol = htons(ETH_P_X25); skb->dev = chdlc_priv_area->annexg_dev; - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); if (wan_api_enqueue_skb(chdlc_priv_area,skb) < 0){ wan_skb_free(skb); @@ -2597,7 +2597,7 @@ static void rx_intr (sdla_t* card) skb->protocol = htons(ETH_P_IP); skb->dev = dev; - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); netif_rx(skb); } @@ -2683,7 +2683,7 @@ static int set_chdlc_config(sdla_t* card) cfg.baud_rate = card->wandev.bps; } - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; @@ -2768,21 +2768,6 @@ static int chdlc_calibrate_baud (sdla_t *card) { wan_mbox_t* mb = &card->wan_mbox; int err; - int enable_again=0; - sdla_t *tmp_card=NULL; - - if (card->wandev.connection == WANOPT_SWITCHED && - card->wandev.clocking == WANOPT_EXTERNAL && - card->next) { - tmp_card=card->next; - if (tmp_card->wandev.connection == WANOPT_SWITCHED && - tmp_card->wandev.clocking == WANOPT_EXTERNAL && - tmp_card->u.c.comm_enabled ) { - DEBUG_EVENT("%s: Next comm enabled -> disabling!\n",tmp_card->devname); - chdlc_comm_disable (tmp_card); - enable_again=1; - } - } mb->wan_data_len = 0; mb->wan_command = START_BAUD_CALIBRATION; @@ -2791,16 +2776,9 @@ static int chdlc_calibrate_baud (sdla_t *card) if (err != COMMAND_OK) chdlc_error (card, err, mb); - - if (enable_again && tmp_card) { - DEBUG_EVENT("%s: Next comm enabled -> re-enabling!\n",tmp_card->devname); - chdlc_comm_enable (tmp_card); - } - return err; } - static int chdlc_read_baud_calibration (sdla_t *card) { wan_mbox_t* mb = &card->wan_mbox; @@ -2867,7 +2845,7 @@ static int set_asy_config(sdla_t* card) if(card->wandev.clocking) cfg.baud_rate = card->wandev.bps; - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; cfg.modem_config_options = 0; @@ -3964,7 +3942,7 @@ dflt_1: /* Decapsulate pkt and pass it up the protocol stack */ new_skb->protocol = htons(ETH_P_IP); new_skb->dev = dev; - wan_skb_reset_mac_header(new_skb); + wan_skb_reset_mac_header(new_skb); netif_rx(new_skb); } else { @@ -4264,7 +4242,6 @@ static int config_chdlc (sdla_t *card, netdevice_t *dev) if (card->wandev.fe_iface.post_init){ err=card->wandev.fe_iface.post_init(&card->fe); } - } @@ -4970,7 +4947,7 @@ static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len) if (net_ratelimit()){ printk(KERN_INFO "%s: Received packet size too big: %i bytes, Max: %i!\n", - card->devname,len,TTY_CHDLC_MAX_MTU); + card->devname,len,TTY_FLIPBUF_SIZE); } return; } @@ -4981,11 +4958,11 @@ static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len) } #endif #else - if ((tty->flip.count+len) >= TTY_CHDLC_MAX_MTU){ + if ((tty->flip.count+len) >= TTY_FLIPBUF_SIZE){ if (net_ratelimit()){ printk(KERN_INFO "%s: Received packet size too big: %i bytes, Max: %i!\n", - card->devname,len,TTY_CHDLC_MAX_MTU); + card->devname,len,TTY_FLIPBUF_SIZE); } return; } @@ -5054,7 +5031,7 @@ static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len) if (net_ratelimit()){ printk(KERN_INFO "%s: Received packet size too big: %i bytes, Max: %i!\n", - card->devname,len,TTY_CHDLC_MAX_MTU); + card->devname,len,TTY_FLIPBUF_SIZE); } return; } @@ -5149,6 +5126,9 @@ static int config_tty (sdla_t *card) (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -5165,6 +5145,9 @@ static int config_tty (sdla_t *card) card->devname); return -EINVAL; } + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -5828,7 +5811,7 @@ static int chdlc_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_ec.c b/patches/kdrivers/src/net/sdla_ec.c index 92a2e99..8caf63b 100644 --- a/patches/kdrivers/src/net/sdla_ec.c +++ b/patches/kdrivers/src/net/sdla_ec.c @@ -29,8 +29,6 @@ # if defined(WAN_OCT6100_DAEMON) # include # endif -#elif (defined __WINDOWS__) -# include #else # include # include @@ -338,6 +336,9 @@ static int wan_ec_action(void *pcard, int enable, int channel) ec->ec_channels_no--; } } + }else{ + DEBUG_HWEC("[HWEC]: %s: %s(): card->wandev.hwec_enable == NULL!\n", + card->devname, __FUNCTION__); } return err; } diff --git a/patches/kdrivers/src/net/sdla_ec_dev.c b/patches/kdrivers/src/net/sdla_ec_dev.c index 0c5d77f..c7b5837 100644 --- a/patches/kdrivers/src/net/sdla_ec_dev.c +++ b/patches/kdrivers/src/net/sdla_ec_dev.c @@ -117,7 +117,7 @@ static int wp_ecdev_reg_globals(void) { int err; - wan_spin_lock_init(&wp_ecdev_hash_lock); + wan_spin_lock_init(&wp_ecdev_hash_lock, "wan_ecdev_lock"); memset(wp_ecdev_hash,0,sizeof(wp_ecdev_hash)); DEBUG_EVENT("%s: Registering Wanpipe ECDEV Device!\n",__FUNCTION__); diff --git a/patches/kdrivers/src/net/sdla_edac.c b/patches/kdrivers/src/net/sdla_edac.c index 189cc74..9f48958 100644 --- a/patches/kdrivers/src/net/sdla_edac.c +++ b/patches/kdrivers/src/net/sdla_edac.c @@ -30,8 +30,6 @@ # include # include -#elif (defined __WINDOWS__) -# include #else #if 0 diff --git a/patches/kdrivers/src/net/sdla_edu.c b/patches/kdrivers/src/net/sdla_edu.c index 930f223..fcc8cdb 100644 --- a/patches/kdrivers/src/net/sdla_edu.c +++ b/patches/kdrivers/src/net/sdla_edu.c @@ -180,7 +180,7 @@ int wpedu_init (sdla_t* card, wandev_conf_t* conf) }else{ card->wandev.mtu = conf->mtu; } - card->wandev.interface = 0; + card->wandev.electrical_interface = 0; card->wandev.clocking = 0; port_num = card->u.c.comm_port; @@ -230,7 +230,7 @@ int wpedu_init (sdla_t* card, wandev_conf_t* conf) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; edu_private_area_t* edu_private_area; int err = 0; @@ -372,6 +372,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; #if defined(LINUX_2_4)||defined(LINUX_2_6) @@ -809,8 +811,8 @@ static void DoIoctl(sdla_t *card) //The flag is set to one before an application will load the card. //No application will be able to reload the card until the flag is reset by //SDLA_CMD_DEREGISTER. - if(card->wandev.interface == 0) - { card->wandev.interface = 1; + if(card->wandev.electrical_interface == 0) + { card->wandev.electrical_interface = 1; ioctl_cmd->return_code = 0; }else { //indicate failure to the caller @@ -821,7 +823,7 @@ static void DoIoctl(sdla_t *card) case SDLA_CMD_DEREGISTER: DEBUG_IOCTL("SDLA_CMD_DEREGISTER\n"); - card->wandev.interface = 0; + card->wandev.electrical_interface = 0; ioctl_cmd->return_code = 0; break; diff --git a/patches/kdrivers/src/net/sdla_fr.c b/patches/kdrivers/src/net/sdla_fr.c index 3be681a..7ccb401 100644 --- a/patches/kdrivers/src/net/sdla_fr.c +++ b/patches/kdrivers/src/net/sdla_fr.c @@ -319,7 +319,9 @@ typedef struct fr_channel #define TMR_INT_ENABLED_UPDATE_DLCI 0x40 #define TMR_INT_ENABLED_TE 0x80 + #pragma pack(1) + typedef struct dlci_status { unsigned short dlci ; @@ -341,6 +343,7 @@ typedef struct fr_dlci_interface unsigned short packet_length ; unsigned char reserved ; } fr_dlci_interface_t; + #pragma pack() extern void disable_irq(unsigned int); @@ -568,7 +571,7 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) if (IS_TE1_MEDIA(&conf->fe_cfg)) { memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -576,14 +579,14 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) card->wandev.fe_enable_timer = fr_enable_timer; card->wandev.te_link_state = fr_handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_FEMEDIA(&card->fe)) ? WANOPT_V35 : WANOPT_RS232; conf->clocking = WANOPT_EXTERNAL; }else if (IS_56K_MEDIA(&conf->fe_cfg)) { memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -714,7 +717,7 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) if (conf->clocking == WANOPT_INTERNAL) u.cfg.port |= 0x0001; - if (conf->interface == WANOPT_RS232) + if (conf->electrical_interface == WANOPT_RS232) u.cfg.port |= 0x0002; if (conf->u.fr.t391) @@ -766,7 +769,7 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) card->wandev.mtu = conf->mtu; card->wandev.bps = conf->bps; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; card->wandev.station = conf->u.fr.station; card->poll = NULL; @@ -846,10 +849,10 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) (IS_T1_CARD(card))?"T1":"E1"); return -EIO; } + /* Run rest of initialization not from lock */ if (card->wandev.fe_iface.post_init){ err=card->wandev.fe_iface.post_init(&card->fe); } - }else if (IS_56K_CARD(card)) { int err = -EINVAL; @@ -864,6 +867,7 @@ int wpf_init(sdla_t *card, wandev_conf_t *conf) card->devname); return -EIO; } + /* Run rest of initialization not from lock */ if (card->wandev.fe_iface.post_init){ err=card->wandev.fe_iface.post_init(&card->fe); } @@ -947,13 +951,13 @@ static int update (wan_device_t* wandev) unsigned long smp_flags; /* sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL)) + if ((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if (wandev->state == WAN_UNCONFIGURED) return -ENODEV; - card = wandev->private; + card = wandev->priv; if (test_and_set_bit(0,&card->update_comms_stats)){ return -EBUSY; @@ -1020,7 +1024,7 @@ static int update (wan_device_t* wandev) static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; fr_channel_t* chan; int dlci = 0; int err = 0; @@ -1360,7 +1364,7 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) { fr_channel_t* chan = dev->priv; unsigned long smp_flags; - sdla_t *card=wandev->private; + sdla_t *card=wandev->priv; /* Delete interface name from proc fs. */ wanrouter_proc_delete_interface(wandev, chan->name); @@ -1434,7 +1438,6 @@ static void disable_comm (sdla_t *card) if (card->wandev.fe_iface.pre_release){ card->wandev.fe_iface.pre_release(&card->fe); } - if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1459,6 +1462,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; #if defined(LINUX_2_4) || defined(LINUX_2_6) @@ -6237,7 +6242,7 @@ static int fr_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_ft1.c b/patches/kdrivers/src/net/sdla_ft1.c index 0008a5d..e370675 100644 --- a/patches/kdrivers/src/net/sdla_ft1.c +++ b/patches/kdrivers/src/net/sdla_ft1.c @@ -204,7 +204,7 @@ int wpft1_init (sdla_t* card, wandev_conf_t* conf) card->u.c.update_call_count = 0; card->wandev.ttl = 0x7F; - card->wandev.interface = 0; + card->wandev.electrical_interface = 0; card->wandev.clocking = 0; diff --git a/patches/kdrivers/src/net/sdla_mp_fr.c b/patches/kdrivers/src/net/sdla_mp_fr.c index 062f8ec..104da38 100644 --- a/patches/kdrivers/src/net/sdla_mp_fr.c +++ b/patches/kdrivers/src/net/sdla_mp_fr.c @@ -434,7 +434,7 @@ int wp_hdlc_fr_init (sdla_t* card, wandev_conf_t* conf) #ifdef TE1_56_CARD_SUPPORT memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -442,7 +442,7 @@ int wp_hdlc_fr_init (sdla_t* card, wandev_conf_t* conf) card->wandev.fe_enable_timer = hdlc_enable_timer; card->wandev.te_link_state = fr_handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_CARD(card)) ? WANOPT_V35 : WANOPT_RS232; if (card->u.c.comm_port == WANOPT_PRI){ @@ -456,7 +456,7 @@ int wp_hdlc_fr_init (sdla_t* card, wandev_conf_t* conf) #ifdef TE1_56_CARD_SUPPORT memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe,&card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -541,11 +541,11 @@ int wp_hdlc_fr_init (sdla_t* card, wandev_conf_t* conf) card->u.c.update_call_count = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; /* The secondary port on S508 card can only have RS232 interface */ - if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&& + if ((card->u.c.comm_port == WANOPT_SEC && conf->electrical_interface == WANOPT_V35)&& card->type != SDLA_S514){ printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n", card->devname, PORT(card->u.c.comm_port)); @@ -750,7 +750,7 @@ int wp_hdlc_fr_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; unsigned long smp_flags; #if 0 SHARED_MEMORY_INFO_STRUCT *flags; @@ -759,7 +759,7 @@ static int update (wan_device_t* wandev) /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -828,7 +828,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; fr_private_area_t* chan; int err = 0; unsigned short dlci=0; @@ -983,7 +983,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) static int del_if (wan_device_t* wandev, netdevice_t* dev) { fr_private_area_t *chan = dev->priv; - sdla_t *card = wandev->private; + sdla_t *card = wandev->priv; fr_prot_t *fr_prot = FR_PROT_AREA(card); unsigned long smp_flags; @@ -1067,6 +1067,9 @@ static void disable_comm (sdla_t *card) #ifdef TE1_56_CARD_SUPPORT /* TE1 - Unconfiging */ if (IS_TE1_CARD(card)) { + if (card->wandev.fe_iface.pre_release){ + card->wandev.fe_iface.pre_release(&card->fe); + } if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1107,6 +1110,7 @@ static int if_init (netdevice_t* dev) #endif dev->do_ioctl = if_do_ioctl; + dev->hard_header = NULL; dev->hard_header_len = 0; dev->addr_len = 2; *(u16*)dev->dev_addr = htons(chan->dlci); @@ -1344,7 +1348,7 @@ static int if_send (struct sk_buff* skb, netdevice_t* dev) fr_private_area_t *chan = dev->priv; sdla_t *card = chan->card; //int udp_type = 0; - unsigned long smp_flags=0; + unsigned long smp_flags; int err=0; #if defined(LINUX_2_4)||defined(LINUX_2_6) @@ -2376,7 +2380,7 @@ static int set_hdlc_config(sdla_t* card) if(card->wandev.clocking) cfg.baud_rate = card->wandev.bps; - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; cfg.modem_config_options = 0; @@ -3579,6 +3583,10 @@ static int config_hdlc (sdla_t *card) (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; } + /* Run rest of initialization not from lock */ + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } @@ -3595,6 +3603,10 @@ static int config_hdlc (sdla_t *card) card->devname); return -EINVAL; } + /* Run rest of initialization not from lock */ + if (card->wandev.fe_iface.post_init){ + err=card->wandev.fe_iface.post_init(&card->fe); + } } #endif @@ -3723,7 +3735,7 @@ static int fr_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); @@ -5028,7 +5040,7 @@ static netdevice_t * un_bind_annexg(wan_device_t *wandev, netdevice_t *annexg_de struct wan_dev_le *devle; netdevice_t *dev; unsigned long smp_flags=0; - sdla_t *card = wandev->private; + sdla_t *card = wandev->priv; WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ fr_channel_t *chan; diff --git a/patches/kdrivers/src/net/sdla_pos.c b/patches/kdrivers/src/net/sdla_pos.c index a3bb7db..cb39ada 100644 --- a/patches/kdrivers/src/net/sdla_pos.c +++ b/patches/kdrivers/src/net/sdla_pos.c @@ -190,7 +190,7 @@ int wp_pos_init (sdla_t* card, wandev_conf_t* conf) card->wandev.clocking = conf->clocking; card->wandev.ignore_front_end_status = conf->ignore_front_end_status; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.comm_port = conf->comm_port; card->wandev.udp_port = conf->udp_port; card->wandev.new_if_cnt = 0; @@ -273,14 +273,14 @@ int wp_pos_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; struct net_device* dev; volatile private_area_t* priv_area; DEBUG_EVENT("%s: %d\n",__FUNCTION__, __LINE__); /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -343,7 +343,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; private_area_t* priv_area; DEBUG_EVENT("%s: %d\n",__FUNCTION__, __LINE__); @@ -486,6 +486,8 @@ static int if_init (struct net_device* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; dev->do_ioctl = if_do_ioctl; diff --git a/patches/kdrivers/src/net/sdla_ppp.c b/patches/kdrivers/src/net/sdla_ppp.c index 06aa85a..fbf46e5 100644 --- a/patches/kdrivers/src/net/sdla_ppp.c +++ b/patches/kdrivers/src/net/sdla_ppp.c @@ -439,7 +439,7 @@ int wpp_init(sdla_t *card, wandev_conf_t *conf) if (IS_TE1_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -447,14 +447,14 @@ int wpp_init(sdla_t *card, wandev_conf_t *conf) card->wandev.fe_enable_timer = ppp_enable_timer; card->wandev.te_link_state = ppp_handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_CARD(card)) ? WANOPT_V35 : WANOPT_RS232; conf->clocking = WANOPT_EXTERNAL; }else if (IS_56K_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -496,7 +496,7 @@ int wpp_init(sdla_t *card, wandev_conf_t *conf) wp_min(conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU; card->wandev.bps = conf->bps; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; card->isr = &wpp_isr; card->poll = NULL; @@ -570,13 +570,13 @@ int wpp_init(sdla_t *card, wandev_conf_t *conf) */ static int update(wan_device_t *wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t *dev; volatile ppp_private_area_t *ppp_priv_area; unsigned long smp_flags; /* sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL)) + if ((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if (wandev->state == WAN_UNCONFIGURED) @@ -655,7 +655,7 @@ static int update(wan_device_t *wandev) */ static int new_if(wan_device_t *wandev, netdevice_t *dev, wanif_conf_t *conf) { - sdla_t *card = wandev->private; + sdla_t *card = wandev->priv; ppp_private_area_t *ppp_priv_area; int err = 0; @@ -868,7 +868,6 @@ static void disable_comm (sdla_t *card) if (card->wandev.fe_iface.pre_release){ card->wandev.fe_iface.pre_release(&card->fe); } - if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -894,6 +893,8 @@ static int if_init(netdevice_t *dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; #if defined(LINUX_2_4)||defined(LINUX_2_6) @@ -2792,7 +2793,7 @@ static int config508(netdevice_t *dev, sdla_t *card) if (card->wandev.clocking) cfg.line_speed = card->wandev.bps; - if (card->wandev.interface == WANOPT_RS232) + if (card->wandev.electrical_interface == WANOPT_RS232) cfg.conf_flags |= INTERFACE_LEVEL_RS232; @@ -3405,7 +3406,7 @@ udp_dflt_cmd: stack */ new_skb->protocol = ppp_priv_area->protocol; new_skb->dev = dev; - wan_skb_reset_mac_header(new_skb); + wan_skb_reset_mac_header(new_skb); netif_rx(new_skb); @@ -3819,6 +3820,7 @@ static int config_ppp (sdla_t *card) (IS_T1_CARD(card))?"T1":"E1"); return 0; } + /* Run rest of initialization not from lock */ if (card->wandev.fe_iface.post_init){ err=card->wandev.fe_iface.post_init(&card->fe); } @@ -3836,6 +3838,7 @@ static int config_ppp (sdla_t *card) card->devname); return 0; } + /* Run rest of initialization not from lock */ if (card->wandev.fe_iface.post_init){ err=card->wandev.fe_iface.post_init(&card->fe); } @@ -4236,7 +4239,7 @@ static int ppp_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_remora.c b/patches/kdrivers/src/net/sdla_remora.c index 73ef7fd..df81aad 100644 --- a/patches/kdrivers/src/net/sdla_remora.c +++ b/patches/kdrivers/src/net/sdla_remora.c @@ -16,7 +16,7 @@ ****************************************************************************** */ -/******************************************************************************* +/****************************************************************************** ** INCLUDE FILES *******************************************************************************/ #if defined(__FreeBSD__) || defined(__OpenBSD__) @@ -31,9 +31,9 @@ # include #elif (defined __WINDOWS__) # include -# include # include # include +# include #else # include # include @@ -45,24 +45,39 @@ # include #endif +#if !defined(__WINDOWS__) +#if 1 +#define AFT_FUNC_DEBUG() +#else +#define AFT_FUNC_DEBUG() DEBUG_EVENT("%s:%d\n",__FUNCTION__,__LINE__) +#endif +#endif /******************************************************************************* ** DEFINES AND MACROS *******************************************************************************/ +#undef WAN_REMORA_AUTO_CALIBRATE + #if 1 # define AFT_TDM_API_SUPPORT #else # undef AFT_TDM_API_SUPPORT #endif +#if 1 +# define AFT_API_SUPPORT +#else +# undef AFT_API_SUPPORT +#endif + #if 0 # define AFT_RM_INTR_SUPPORT #else # undef AFT_RM_INTR_SUPPORT #endif -#define AUDIO_RINGCHECK +#undef AUDIO_RINGCHECK #if 1 /* Current A200 designs (without interrupts) */ @@ -79,7 +94,7 @@ #define WP_RM_CONFIGURED 0x03 #define WP_RM_TIMER_EVENT_PENDING 0x04 -#define WP_RM_POLL_TIMER 1000 +#define WP_RM_POLL_TIMER 100 #define WP_RM_POLL_EVENT_TIMER 10 #define WP_RM_POLL_TONE_TIMER 5000 #define WP_RM_POLL_RING_TIMER 10000 @@ -89,8 +104,6 @@ enum { WP_RM_POLL_TONE_RING, WP_RM_POLL_TONE_CONGESTION, WP_RM_POLL_TONE_DONE, - //WP_RM_POLL_RING, - //WP_RM_POLL_RING_STOP, WP_RM_POLL_TDMV, WP_RM_POLL_EVENT, WP_RM_POLL_INIT, @@ -106,9 +119,42 @@ enum { WP_RM_POLL_TXSIG_ONHOOK, WP_RM_POLL_ONHOOKTRANSFER, WP_RM_POLL_SETPOLARITY, - WP_RM_POLL_RING_DETECT + WP_RM_POLL_RING_DETECT, + WP_RM_POLL_READ, + WP_RM_POLL_WRITE, + WP_RM_POLL_RXSIG_OFFHOOK, + WP_RM_POLL_RXSIG_ONHOOK }; +#define WP_RM_POLL_DECODE(type) \ + ((type) == WP_RM_POLL_TONE_DIAL) ? "Tone (dial)": \ + ((type) == WP_RM_POLL_TONE_BUSY) ? "Tone (busy)": \ + ((type) == WP_RM_POLL_TONE_RING) ? "Tone (ring)": \ + ((type) == WP_RM_POLL_TONE_CONGESTION) ? "Tone (congestion)": \ + ((type) == WP_RM_POLL_TONE_DONE) ? "Tone (done)": \ + ((type) == WP_RM_POLL_TDMV) ? "TDMV": \ + ((type) == WP_RM_POLL_EVENT) ? "RM-Event": \ + ((type) == WP_RM_POLL_INIT) ? "Init": \ + ((type) == WP_RM_POLL_POWER) ? "Power": \ + ((type) == WP_RM_POLL_LC) ? "Loop closure": \ + ((type) == WP_RM_POLL_RING_TRIP) ? "Ring Trip": \ + ((type) == WP_RM_POLL_DTMF) ? "DTMF": \ + ((type) == WP_RM_POLL_RING) ? "Ring": \ + ((type) == WP_RM_POLL_TONE) ? "Tone": \ + ((type) == WP_RM_POLL_TXSIG_KEWL) ? "TX Sig KEWL": \ + ((type) == WP_RM_POLL_TXSIG_START) ? "TX Sig Start": \ + ((type) == WP_RM_POLL_TXSIG_OFFHOOK) ? "TX Sig Off-hook": \ + ((type) == WP_RM_POLL_TXSIG_ONHOOK) ? "TX Sig On-hook": \ + ((type) == WP_RM_POLL_ONHOOKTRANSFER) ? "On-hook transfer": \ + ((type) == WP_RM_POLL_SETPOLARITY) ? "Set polarity": \ + ((type) == WP_RM_POLL_RING_DETECT) ? "Ring Detect": \ + ((type) == WP_RM_POLL_READ) ? "FE Read": \ + ((type) == WP_RM_POLL_WRITE) ? "FE Write":"Unknown RM poll event" \ + ((type) == WP_RM_POLL_RXSIG_OFFHOOK) ? "RX Sig Off-hook": \ + ((type) == WP_RM_POLL_RXSIG_ONHOOK) ? "RX Sig On-hook": \ + "Unknown RM poll event" + + /* tone_struct DialTone ** OSC1= 350 Hz OSC2= 440 Hz .0975 Volts -18 dBm */ #define DIALTONE_IR13 0x7b30 @@ -332,7 +378,6 @@ static struct fxo_mode { { "USA", 0, 0, 0, 0, 0, 0x3, 0, 0, }, { "YEMEN", 0, 0, 0, 0, 0, 0x3, 0, 0, }, }; - static int acim2tiss[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3 }; /******************************************************************************* @@ -345,7 +390,7 @@ static int acim2tiss[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0 #if !defined(__WINDOWS__) extern WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head; #endif -static int battdebounce = DEFAULT_BATT_DEBOUNCE; +static int battdebounce = 64; //DEFAULT_BATT_DEBOUNCE; static int battthresh = DEFAULT_BATT_THRESH; /******************************************************************************* @@ -357,6 +402,7 @@ int wp_init_voicedaa(sdla_fe_t *fe, int mod_no, int fast, int sane); static int wp_remora_config(void *pfe); static int wp_remora_unconfig(void *pfe); static int wp_remora_post_init(void *pfe); +static int wp_remora_pre_release(void* pfe); static int wp_remora_if_config(void *pfe, u32 mod_map, u8); static int wp_remora_if_unconfig(void *pfe, u32 mod_map, u8); static int wp_remora_disable_irq(void *pfe); @@ -364,7 +410,7 @@ static int wp_remora_intr(sdla_fe_t *); static int wp_remora_check_intr(sdla_fe_t *); static int wp_remora_polling(sdla_fe_t*); static int wp_remora_udp(sdla_fe_t*, void*, unsigned char*); -static unsigned int wp_remora_active_map(sdla_fe_t* fe); +static unsigned int wp_remora_active_map(sdla_fe_t* fe, unsigned char); static unsigned char wp_remora_fe_media(sdla_fe_t *fe); static int wp_remora_set_dtmf(sdla_fe_t*, int, unsigned char); static int wp_remora_intr_ctrl(sdla_fe_t*, int, u_int8_t, u_int8_t, unsigned int); @@ -403,7 +449,7 @@ static void wait_just_a_bit(int foo, int fast) #if defined(__FreeBSD__) || defined(__OpenBSD__) WP_SCHEDULE(foo, "A200"); #else - unsigned long start_ticks; + wan_ticks_t start_ticks; start_ticks = SYSTEM_TICKS + foo; while(SYSTEM_TICKS < start_ticks){ WP_DELAY(100); @@ -427,6 +473,17 @@ static void wp_remora_reset_spi(sdla_fe_t *fe) SPI_INTERFACE_REG, 0x00000000); WP_DELAY(1000); + +#if 0 +{ + unsigned int value; + + /* Enable Slow speed SPI */ + card->hw_iface.bus_read_4(card->hw, 0x40, &data); + data |= 0x00000020; + card->hw_iface.bus_write_4(card->hw, 0x40, data); +} +#endif return; } @@ -434,7 +491,8 @@ static void wp_remora_reset_spi(sdla_fe_t *fe) static int wp_proslic_setreg_indirect(sdla_fe_t *fe, int mod_no, unsigned char address, unsigned short data) { - + DEBUG_REG("%s: Indirect Register %d = %X\n", + fe->name, address, data); WRITE_RM_REG(mod_no, IDA_LO,(unsigned char)(data & 0xFF)); WRITE_RM_REG(mod_no, IDA_HI,(unsigned char)((data & 0xFF00)>>8)); WRITE_RM_REG(mod_no, IAA,address); @@ -458,10 +516,12 @@ static int wp_proslic_init_indirect_regs(sdla_fe_t *fe, int mod_no) { unsigned char i; + DEBUG_CFG("%s: Initializing Indirect Registers...\n", fe->name); for (i=0; iname); return 0; } @@ -472,6 +532,7 @@ static int wp_proslic_verify_indirect_regs(sdla_fe_t *fe, int mod_no) unsigned short i, initial; int j; + DEBUG_CFG("%s: Verifing Indirect Registers...\n", fe->name); for (i=0; iname, mod_no, + fe->name, mod_no+1, i); return -1; } @@ -489,7 +550,7 @@ static int wp_proslic_verify_indirect_regs(sdla_fe_t *fe, int mod_no) if ( j != initial && indirect_regs[i].altaddr != 255){ DEBUG_EVENT( "%s: Module %d: Internal Error: iReg=%s (%X) Value=%X (%X)\n", - fe->name, mod_no, + fe->name, mod_no+1, indirect_regs[i].name, indirect_regs[i].address, j, initial); @@ -500,51 +561,50 @@ static int wp_proslic_verify_indirect_regs(sdla_fe_t *fe, int mod_no) if (!passed) { DEBUG_EVENT( "%s: Module %d: Init Indirect Registers UNSUCCESSFULLY.\n", - fe->name, mod_no); + fe->name, mod_no+1); return -1; } + DEBUG_CFG("%s: Verifing Indirect Registers...Done!\n", fe->name); return 0; } - +/****************************************************************************** +** wp_remora_chain_enable() - +** +** OK +*/ static int wp_remora_chain_enable(sdla_fe_t *fe) { int mod_no; unsigned char byte; - for(mod_no = 0;mod_no < MAX_REMORA_MODULES; mod_no += 2){ + for(mod_no = 0;mod_no < MAX_REMORA_MODULES; mod_no ++){ if (fe->rm_param.mod[mod_no].type == MOD_TYPE_NONE){ byte = READ_RM_FXS_REG(mod_no, 0, 0); byte &= 0x0F; if (byte == 0x05){ - DEBUG_RM("%s: Module %d/%d FXS\n", - fe->name, mod_no,mod_no+1); + DEBUG_RM("%s: Module %d FXS\n", + fe->name, mod_no+1); fe->rm_param.mod[mod_no].type = MOD_TYPE_FXS; - fe->rm_param.mod[mod_no+1].type = - MOD_TYPE_FXS; }else if (byte == 0x00){ - DEBUG_RM("%s: Module %d/%d TEST\n", - fe->name, mod_no,mod_no+1); + DEBUG_RM("%s: Module %d TEST\n", + fe->name, mod_no+1); fe->rm_param.mod[mod_no].type = MOD_TYPE_TEST; - fe->rm_param.mod[mod_no+1].type = - MOD_TYPE_TEST; } } } /* Reset SPI interface */ wp_remora_reset_spi(fe); - for(mod_no = 0;mod_no < MAX_REMORA_MODULES; mod_no += 2){ + for(mod_no = 0;mod_no < MAX_REMORA_MODULES; mod_no ++){ if (fe->rm_param.mod[mod_no].type == MOD_TYPE_NONE){ byte = READ_RM_FXO_REG(mod_no,1,2); if (byte == 0x03){ - DEBUG_RM("%s: Module %d/%d FXO\n", - fe->name, mod_no,mod_no+1); + DEBUG_RM("%s: Module %d FXO\n", + fe->name, mod_no+1); fe->rm_param.mod[mod_no].type = MOD_TYPE_FXO; - fe->rm_param.mod[mod_no+1].type = - MOD_TYPE_FXO; } } } @@ -553,14 +613,14 @@ static int wp_remora_chain_enable(sdla_fe_t *fe) wp_remora_reset_spi(fe); /* Now enable chain mode for only FXS modules (FXO by default chain) */ - for(mod_no = 0;mod_no < MAX_REMORA_MODULES; mod_no += 2){ - if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ + for(mod_no = 0;mod_no < MAX_REMORA_MODULES; mod_no ++){ + if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS && mod_no % 2 == 0){ WRITE_RM_FXS_REG(mod_no,0,0,0xC0); byte = READ_RM_FXS_REG(mod_no, 1, 0); if ((byte & 0x80) != 0x80){ DEBUG_RM( "%s: Module %d: Failed to enable chain (%02X)!\n", - fe->name, mod_no, byte); + fe->name, mod_no+1, byte); return -EINVAL; } }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ @@ -568,24 +628,17 @@ static int wp_remora_chain_enable(sdla_fe_t *fe) if (byte != 0x03){ /* Should never happened */ fe->rm_param.mod[mod_no].type = MOD_TYPE_NONE; - fe->rm_param.mod[mod_no+1].type = MOD_TYPE_NONE; continue; } }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_TEST){ /* Test module or nothing */ continue; - }else{ - DEBUG_RM( - "%s: Module %d: Failed to detect FXO/FXS module!\n", - fe->name, mod_no); - continue; } DEBUG_RM( - "%s: Module %d/%d %s (chain)\n", - fe->name, mod_no,mod_no+1, + "%s: Module %d %s (chain)\n", + fe->name, mod_no+1, WP_REMORA_DECODE_TYPE(fe->rm_param.mod[mod_no].type)); fe->rm_param.mod[mod_no].chain = MOD_CHAIN_ENABLED; - fe->rm_param.mod[mod_no+1].chain= MOD_CHAIN_ENABLED; } return 0; } @@ -598,7 +651,7 @@ static int wp_init_proslic_insane(sdla_fe_t *fe, int mod_no) if ((value & 0x30) >> 4){ DEBUG_RM("%s: Proslic on module %d is not a Si3210 (%02X)!\n", fe->name, - mod_no, + mod_no+1, value); return -1; } @@ -618,7 +671,7 @@ static int wp_init_proslic_insane(sdla_fe_t *fe, int mod_no) if (value != 0x2) { DEBUG_EVENT( "%s: Proslic on module %d insane (1) %d should be 2!\n", - fe->name, mod_no, value); + fe->name, mod_no+1, value); return -1; } @@ -626,7 +679,7 @@ static int wp_init_proslic_insane(sdla_fe_t *fe, int mod_no) if (value != 0x0) { DEBUG_EVENT( "%s: Proslic on modyle %d insane (2) %d should be 0!\n", - fe->name, mod_no, value); + fe->name, mod_no+1, value); return -1; } @@ -634,7 +687,7 @@ static int wp_init_proslic_insane(sdla_fe_t *fe, int mod_no) if (value != 0x33) { DEBUG_EVENT( "%s: Proslic on module %d insane (3) %02X should be 0x33\n", - fe->name, mod_no, value); + fe->name, mod_no+1, value); return -1; } WRITE_RM_REG(mod_no, 30, 0); @@ -644,10 +697,11 @@ static int wp_init_proslic_insane(sdla_fe_t *fe, int mod_no) static int wp_powerup_proslic(sdla_fe_t *fe, int mod_no, int fast) { wp_remora_fxs_t *fxs; - unsigned long start_ticks; + wan_ticks_t start_ticks; int loopcurrent = 20, lim; unsigned char vbat; + DEBUG_CFG("%s: PowerUp SLIC initialization...\n", fe->name); fxs = &fe->rm_param.mod[mod_no].u.fxs; /* set the period of the DC-DC converter to 1/64 kHz START OUT SLOW*/ WRITE_RM_REG(mod_no, 92, 0xf5); @@ -673,7 +727,7 @@ static int wp_powerup_proslic(sdla_fe_t *fe, int mod_no, int fast) "%s: Module %d: Failed to powerup within %d ms (%dV : %dV)!\n", fe->name, mod_no+1, - (int)(((SYSTEM_TICKS - start_ticks) * 1000 / HZ)), + (u_int32_t)(((SYSTEM_TICKS - start_ticks) * 1000 / HZ)), (vbat * 375)/1000, (0xc0 * 375)/1000); DEBUG_EVENT( "%s: Module %d: Did you remember to plug in the power cable?\n", @@ -718,14 +772,16 @@ static int wp_powerup_proslic(sdla_fe_t *fe, int mod_no, int fast) } wait_just_a_bit(HZ/10, fast); } + DEBUG_CFG("%s: PowerUp SLIC initialization...Done!\n", fe->name); return 0; } static int wp_proslic_powerleak_test(sdla_fe_t *fe, int mod_no, int fast) { - unsigned long start_ticks; + wan_ticks_t start_ticks; unsigned char vbat; + DEBUG_CFG("%s: PowerLeak ProSLIC testing...\n", fe->name); /* powerleak */ WRITE_RM_REG(mod_no, 64, 0); WRITE_RM_REG(mod_no, 14, 0x10); @@ -739,7 +795,7 @@ static int wp_proslic_powerleak_test(sdla_fe_t *fe, int mod_no, int fast) fe->name, mod_no+1, 376 * vbat / 1000, vbat, - (int)((SYSTEM_TICKS - start_ticks) * 1000 / HZ)); + (u_int32_t)((SYSTEM_TICKS - start_ticks) * 1000 / HZ)); return -1; } DEBUG_RM("%s: Module %d: Post-leakage voltage: %d volts\n", @@ -747,13 +803,16 @@ static int wp_proslic_powerleak_test(sdla_fe_t *fe, int mod_no, int fast) mod_no+1, 376 * vbat / 1000); + DEBUG_CFG("%s: PowerLeak ProSLIC testing...Done!\n", fe->name); return 0; } +#if defined(WAN_REMORA_AUTO_CALIBRATE) static int wp_proslic_calibrate(sdla_fe_t *fe, int mod_no, int fast) { - volatile unsigned long start_ticks; + volatile wan_ticks_t start_ticks; + DEBUG_CFG("%s: ProSLIC calibration...\n", fe->name); /* perform all calibration */ WRITE_RM_REG(mod_no, 97, 0x1f); /* start */ @@ -769,14 +828,16 @@ static int wp_proslic_calibrate(sdla_fe_t *fe, int mod_no, int fast) } wait_just_a_bit(HZ/10, fast); } + DEBUG_CFG("%s: ProSLIC calibration...Done!\n", fe->name); return 0; } - +#else static int wp_proslic_manual_calibrate(sdla_fe_t *fe, int mod_no, int fast) { - volatile unsigned long start_ticks; + volatile wan_ticks_t start_ticks; int i=0; + DEBUG_CFG("%s: ProSLIC manual calibration...\n", fe->name); WRITE_RM_REG(mod_no, 21, 0x00); WRITE_RM_REG(mod_no, 22, 0x00); WRITE_RM_REG(mod_no, 23, 0x00); @@ -799,12 +860,12 @@ static int wp_proslic_manual_calibrate(sdla_fe_t *fe, int mod_no, int fast) } wait_just_a_bit(HZ/10, fast); - wp_proslic_setreg_indirect(fe, mod_no, 88, 0x0); - wp_proslic_setreg_indirect(fe, mod_no, 89, 0x0); - wp_proslic_setreg_indirect(fe, mod_no, 90, 0x0); - wp_proslic_setreg_indirect(fe, mod_no, 91, 0x0); - wp_proslic_setreg_indirect(fe, mod_no, 92, 0x0); - wp_proslic_setreg_indirect(fe, mod_no, 93, 0x0); + wp_proslic_setreg_indirect(fe, mod_no, 88, 0x00); + wp_proslic_setreg_indirect(fe, mod_no, 89, 0x00); + wp_proslic_setreg_indirect(fe, mod_no, 90, 0x00); + wp_proslic_setreg_indirect(fe, mod_no, 91, 0x00); + wp_proslic_setreg_indirect(fe, mod_no, 92, 0x00); + wp_proslic_setreg_indirect(fe, mod_no, 93, 0x00); /* Step 16 */ /* Insert manual calibration for sangoma Si3210 */ @@ -843,8 +904,10 @@ static int wp_proslic_manual_calibrate(sdla_fe_t *fe, int mod_no, int fast) while(READ_RM_REG(mod_no, 96) != 0){ if ((SYSTEM_TICKS - start_ticks) > 400){ DEBUG_EVENT( - "%s: Module %d: Timeout on SLIC calibration (%ld:%ld!\n", - fe->name, mod_no+1,start_ticks,SYSTEM_TICKS); + "%s: Module %d: Timeout on SLIC calibration (%ld:%ld)!\n", + fe->name, mod_no+1, + (unsigned long)start_ticks, + (unsigned long)SYSTEM_TICKS); return -1; } wait_just_a_bit(HZ/10, fast); @@ -852,9 +915,10 @@ static int wp_proslic_manual_calibrate(sdla_fe_t *fe, int mod_no, int fast) DEBUG_RM("%s: Module %d: Calibration is done\n", fe->name, mod_no+1); /*READ_RM_REG(mod_no, 96);*/ - + DEBUG_CFG("%s: ProSLIC manual calibration...Done!\n", fe->name); return 0; } +#endif /* static */ int wp_init_proslic(sdla_fe_t *fe, int mod_no, int fast, int sane) @@ -870,6 +934,7 @@ int wp_init_proslic(sdla_fe_t *fe, int mod_no, int fast, int sane) fe->rm_param.mod[mod_no].u.fxs.idletxhookstate = 1; } + DEBUG_CFG("%s: Start ProSLIC configuration...\n", fe->name); /* Step 8 */ if (!sane && wp_init_proslic_insane(fe, mod_no)){ return -2; @@ -936,13 +1001,15 @@ int wp_init_proslic(sdla_fe_t *fe, int mod_no, int fast, int sane) /* Step 13 */ WRITE_RM_REG(mod_no, 64, 0); - //if (wp_proslic_calibrate(fe, mod_no, fast)){ - // return -1; - //} +#if defined(WAN_REMORA_AUTO_CALIBRATE) + if (wp_proslic_calibrate(fe, mod_no, fast)){ + return -1; + } +#else if (wp_proslic_manual_calibrate(fe, mod_no, fast)){ return -1; } - +#endif /* Perform DC-DC calibration */ WRITE_RM_REG(mod_no, 93, 0x99); wait_just_a_bit(10, fast); @@ -1003,17 +1070,17 @@ int wp_init_proslic(sdla_fe_t *fe, int mod_no, int fast, int sane) WRITE_RM_REG(mod_no, 73, 0x04); if (!strcmp(fxo_modes[fe->fe_cfg.cfg.remora.opermode].name, "AUSTRALIA")) { - value = acim2tiss[fxo_modes[fe->fe_cfg.cfg.remora.opermode].acim]; + value = (unsigned char)acim2tiss[fxo_modes[fe->fe_cfg.cfg.remora.opermode].acim]; WRITE_RM_REG(mod_no, 10, 0x8 | value); if (fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_osc){ wp_proslic_setreg_indirect( fe, mod_no, 20, - fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_osc); + (unsigned char)fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_osc); } if (fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_x){ wp_proslic_setreg_indirect( fe, mod_no, 21, - fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_x); + (unsigned char)fxo_modes[fe->fe_cfg.cfg.remora.opermode].ring_x); } } @@ -1046,12 +1113,44 @@ int wp_init_proslic(sdla_fe_t *fe, int mod_no, int fast, int sane) } }else{ if (!strcmp(fxo_modes[fe->fe_cfg.cfg.remora.opermode].name, "AUSTRALIA")) { - WRITE_RM_REG(mod_no, 74, 0x3f); - if (wp_proslic_setreg_indirect(fe, mod_no, 21, 0x1d1)){ - return -1; - } - DEBUG_EVENT("%s: Module %d: Boosting ringer (89V peak)\n", + if (fe->fe_cfg.cfg.remora.fxs_ringampl){ + u16 ringx=0x00; + u8 vbath = 0x00; + switch(fe->fe_cfg.cfg.remora.fxs_ringampl){ + case 47: ringx = 0x163; vbath = 0x31; break; + case 45: ringx = 0x154; vbath = 0x2f; break; + case 40: ringx = 0x12e; vbath = 0x2b; break; + case 35: ringx = 0x108; vbath = 0x26; break; + case 30: ringx = 0xe2; vbath = 0x21; break; + case 25: ringx = 0xbc; vbath = 0x1d; break; + case 20: ringx = 0x97; vbath = 0x1b; break; + case 15: ringx = 0x71; vbath = 0x13; break; + case 10: ringx = 0x4b; vbath = 0x0e; break; + } + if (ringx && vbath){ + DEBUG_EVENT( + "%s: Module %d: Ringing Amplitude %d (RNGX:%04X VBATH:%02X)\n", + fe->name,mod_no+1, fe->fe_cfg.cfg.remora.fxs_ringampl, ringx, vbath); + WRITE_RM_REG(mod_no, 74, vbath); + if (wp_proslic_setreg_indirect(fe, mod_no, 21, ringx)){ + DEBUG_EVENT( + "%s: Module %d: Failed to set RingX value!\n", + fe->name, mod_no+1); + } + + }else{ + DEBUG_EVENT( + "%s: Module %d: Invalid Ringing Amplitude value %d\n", + fe->name, mod_no+1, fe->fe_cfg.cfg.remora.fxs_ringampl); + } + }else{ + WRITE_RM_REG(mod_no, 74, 0x3f); + if (wp_proslic_setreg_indirect(fe, mod_no, 21, 0x1d1)){ + return -1; + } + DEBUG_EVENT("%s: Module %d: Boosting ringer (89V peak)\n", fe->name, mod_no+1); + } } else if (fe->fe_cfg.cfg.remora.fxs_lowpower == WANOPT_YES){ if (wp_proslic_setreg_indirect(fe, mod_no, 21, 0x108)){ return -1; @@ -1162,6 +1261,7 @@ int wp_init_proslic(sdla_fe_t *fe, int mod_no, int fast, int sane) fe->name, mod_no+1, READ_RM_REG(mod_no, 82)*375/1000, READ_RM_REG(mod_no, 83)*375/1000); + DEBUG_CFG("%s: Start ProSLIC configuration...Done!\n", fe->name); return 0; } @@ -1175,7 +1275,7 @@ static int wp_voicedaa_insane(sdla_fe_t *fe, int mod_no) byte = READ_RM_REG(mod_no, 11); DEBUG_TEST("%s: Module %d: VoiceDAA System: %02x\n", fe->name, - mod_no, + mod_no+1, byte & 0xf); return 0; } @@ -1183,8 +1283,8 @@ static int wp_voicedaa_insane(sdla_fe_t *fe, int mod_no) int wp_init_voicedaa(sdla_fe_t *fe, int mod_no, int fast, int sane) { - unsigned char reg16=0, reg26=0, reg30=0, reg31=0; - unsigned long start_ticks; + unsigned char reg16=0, reg26=0, reg30=0, reg31=0; + wan_ticks_t start_ticks; if (!sane && wp_voicedaa_insane(fe, mod_no)){ return -2; @@ -1254,12 +1354,12 @@ int wp_init_voicedaa(sdla_fe_t *fe, int mod_no, int fast, int sane) DEBUG_EVENT( "%s: Module %d: VoiceDAA did not bring up ISO link properly!\n", fe->name, - mod_no); + mod_no+1); return -1; } DEBUG_TEST("%s: Module %d: ISO-Cap is now up, line side: %02x rev %02x\n", fe->name, - mod_no, + mod_no+1, READ_RM_REG(mod_no, 11) >> 4, (READ_RM_REG(mod_no, 13) >> 2) & 0xf); } else { @@ -1273,6 +1373,7 @@ int wp_init_voicedaa(sdla_fe_t *fe, int mod_no, int fast, int sane) WRITE_RM_REG(mod_no, 2, 0x87/*0x84*/); fe->rm_param.mod[mod_no].u.fxo.imask = 0xFF; #else + WRITE_RM_REG(mod_no, 2, 0x04 | 0x03); /* Ring detect mode (begin/end) */ fe->rm_param.mod[mod_no].u.fxo.imask = 0x00; #endif @@ -1325,7 +1426,7 @@ int wp_init_voicedaa(sdla_fe_t *fe, int mod_no, int fast, int sane) if (!strcmp(fxo_modes[fe->fe_cfg.cfg.remora.opermode].name, "NEWZEALAND")) { DEBUG_EVENT("%s: Module %d: Adjusting gain\n", fe->name, - mod_no); + mod_no+1); WRITE_RM_REG(mod_no, 38, 0x7); } @@ -1338,29 +1439,39 @@ int wp_init_voicedaa(sdla_fe_t *fe, int mod_no, int fast, int sane) ** ** OK */ -int wp_remora_iface_init(void *pfe_iface) +int wp_remora_iface_init(void *p_fe, void *pfe_iface) { + sdla_fe_t *fe = (sdla_fe_t*)p_fe; sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)pfe_iface; fe_iface->config = &wp_remora_config; fe_iface->unconfig = &wp_remora_unconfig; + fe_iface->post_init = &wp_remora_post_init; + fe_iface->if_config = &wp_remora_if_config; fe_iface->if_unconfig = &wp_remora_if_unconfig; + fe_iface->pre_release = &wp_remora_pre_release; fe_iface->active_map = &wp_remora_active_map; + fe_iface->isr = &wp_remora_intr; fe_iface->disable_irq = &wp_remora_disable_irq; fe_iface->check_isr = &wp_remora_check_intr; + fe_iface->polling = &wp_remora_polling; fe_iface->process_udp = &wp_remora_udp; fe_iface->get_fe_media = &wp_remora_fe_media; + fe_iface->set_dtmf = &wp_remora_set_dtmf; fe_iface->intr_ctrl = &wp_remora_intr_ctrl; + fe_iface->event_ctrl = &wp_remora_event_ctrl; -#if defined(AFT_TDM_API_SUPPORT) +#if defined(AFT_TDM_API_SUPPORT) || defined(AFT_API_SUPPORT) fe_iface->watchdog = &wp_remora_watchdog; #endif + WAN_LIST_INIT(&fe->event); + wan_spin_lock_irq_init(&fe->lockirq, "wan_rm_lock"); return 0; } @@ -1419,10 +1530,6 @@ static int wp_remora_config(void *pfe) fe->rm_param.module_map = 0; fe->rm_param.intcount = 0; fe->rm_param.last_watchdog = SYSTEM_TICKS; - /*Event lock */ - WAN_LIST_INIT(&fe->event); - wan_spin_lock_init(&fe->lock); - if (wp_remora_opermode(fe)){ return -EINVAL; } @@ -1447,19 +1554,10 @@ retry_cfg: if (!(err = wp_init_proslic(fe, mod_no, 0, sane))){ DEBUG_EVENT( "%s: Module %d: Installed -- Auto FXS!\n", - fe->name, - mod_no); + fe->name, mod_no+1); wan_set_bit(mod_no, &fe->rm_param.module_map); fe->rm_param.mod[mod_no].u.fxs.oldrxhook = 1; /* default (off-hook) */ mod_cnt++; -#if 0 - }else{ - DEBUG_EVENT( - "%s: Module %d: FXS failed!\n", - fe->name, - mod_no); - err_cnt++; -#endif } break; @@ -1468,56 +1566,48 @@ retry_cfg: if (!err){ DEBUG_EVENT( "%s: Module %d: Installed -- Auto FXO (%s mode)!\n", - fe->name, - mod_no, + fe->name, mod_no+1, fxo_modes[fe->fe_cfg.cfg.remora.opermode].name); wan_set_bit(mod_no, &fe->rm_param.module_map); mod_cnt++; -#if 0 - }else{ - DEBUG_EVENT( - "%s: Module %d: FXO failed!\n", - fe->name, - mod_no); - err_cnt++; -#endif } break; case MOD_TYPE_TEST: DEBUG_EVENT( "%s: Module %d: Installed -- FXS/FXO tester!\n", - fe->name, - mod_no); + fe->name, mod_no+1); wan_set_bit(mod_no, &fe->rm_param.module_map); + ((sdla_t*)fe->card)->fe_no_intr = 0x1; mod_cnt++; break; default: DEBUG_TDMV("%s: Module %d: Not Installed!\n", - fe->name, - mod_no); + fe->name, mod_no+1); break; } if (err/* && !sane*/){ - sane = 1; - if (retry++ < 10) goto retry_cfg; + if (!sane/*retry++ < 10*/){ + sane = 1; + DEBUG_EVENT("%s: Module %d: Retry configuration...\n", + fe->name, mod_no+1); + goto retry_cfg; + } DEBUG_EVENT("%s: Module %d: %s failed!\n", - fe->name, - mod_no, + fe->name, mod_no+1, WP_REMORA_DECODE_TYPE(fe->rm_param.mod[mod_no].type)); err_cnt++; - }else{ -#if defined(__WINDOWS__) - //FIXME: should be fixed for linux too? - //if not reset to zero, initialization will fail even - //if "retry_cfg" was SUCCESSFUL!! - err_cnt = 0; -#endif } } - if (err_cnt){ - DEBUG_EVENT("%s: %d FXO/FXS module(s) are failed to initialize!\n", +#if 0 + /* NC REMOVED IT TEMPORARILY */ + if (err_cnt && fe->fe_cfg.cfg.remora.relaxcfg != WANOPT_YES){ +#else + if (err_cnt) { +#endif + DEBUG_EVENT( + "%s: %d FXO/FXS module(s) are failed to initialize!\n", fe->name, err_cnt); return -EINVAL; } @@ -1527,9 +1617,15 @@ retry_cfg: #endif if (mod_cnt == 0){ - DEBUG_EVENT("%s: No FXO/FXS modules are found!\n", + if (err_cnt){ + DEBUG_EVENT( + "ERROR: %s: Configuration is failed for all FXO/FXS modules!\n", fe->name); - // return -EINVAL; + }else{ + DEBUG_EVENT("ERROR: %s: No FXO/FXS modules are found!\n", + fe->name); + } + return -EINVAL; } /* Initialize and start T1/E1 timer */ wan_set_bit(WP_RM_TIMER_KILL,(void*)&fe->rm_param.critical); @@ -1574,8 +1670,6 @@ retry_cfg: static int wp_remora_unconfig(void *pfe) { sdla_fe_t *fe = (sdla_fe_t*)pfe; - sdla_fe_timer_event_t *fe_event; - wan_smp_flag_t smp_flags; int mod_no; DEBUG_EVENT("%s: Unconfiguring FXS/FXO Front End...\n", @@ -1586,6 +1680,32 @@ static int wp_remora_unconfig(void *pfe) /* Clear and Kill TE timer poll command */ wan_clear_bit(WP_RM_CONFIGURED,(void*)&fe->rm_param.critical); + + for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no++){ + if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { + wan_clear_bit(mod_no, &fe->rm_param.module_map); + } + } + return 0; +} + +/* + ****************************************************************************** + * sdla_te_pre_release() + * + * Description: T1/E1 pre release routines (not locked). + * Arguments: + * Returns: + ****************************************************************************** + */ +static int wp_remora_pre_release(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + sdla_fe_timer_event_t *fe_event = NULL; + wan_smp_flag_t smp_flags; + int empty = 0; + + /* Kill TE timer poll command */ wan_set_bit(WP_RM_TIMER_KILL,(void*)&fe->rm_param.critical); if (wan_test_bit(WP_RM_TIMER_RUNNING,(void*)&fe->rm_param.critical)){ @@ -1593,19 +1713,20 @@ static int wp_remora_unconfig(void *pfe) } wan_clear_bit(WP_RM_TIMER_RUNNING,(void*)&fe->rm_param.critical); - wan_spin_lock_irq(&fe->lock,&smp_flags); - while(!WAN_LIST_EMPTY(&fe->event)){ - fe_event = WAN_LIST_FIRST(&fe->event); - WAN_LIST_REMOVE(fe_event, next); - if (fe_event) wan_free(fe_event); - } - wan_spin_unlock_irq(&fe->lock,&smp_flags); - - for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no++){ - if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { - wan_clear_bit(mod_no, &fe->rm_param.module_map); + do{ + wan_spin_lock_irq(&fe->lockirq,&smp_flags); + if (!WAN_LIST_EMPTY(&fe->event)){ + fe_event = WAN_LIST_FIRST(&fe->event); + WAN_LIST_REMOVE(fe_event, next); + }else{ + empty = 1; } - } + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); + /* Free should be called not from spin_lock_irq (windows) !!!! */ + if (fe_event) wan_free(fe_event); + fe_event = NULL; + }while(!empty); + return 0; } @@ -1718,7 +1839,7 @@ static int wp_remora_disable_irq(void *pfe) return 0; } -static unsigned int wp_remora_active_map(sdla_fe_t* fe) +static unsigned int wp_remora_active_map(sdla_fe_t* fe, unsigned char not_used) { return fe->rm_param.module_map; } @@ -1749,12 +1870,12 @@ static int wp_remora_set_dtmf(sdla_fe_t *fe, int mod_no, unsigned char val) if (mod_no > MAX_REMORA_MODULES){ DEBUG_EVENT("%s: Module %d: Module number out of range!\n", - fe->name, mod_no); + fe->name, mod_no+1); return -EINVAL; } if (!wan_test_bit(mod_no-1, &fe->rm_param.module_map)){ DEBUG_EVENT("%s: Module %d: Not configures yet!\n", - fe->name, mod_no); + fe->name, mod_no+1); return -EINVAL; } @@ -1784,7 +1905,7 @@ static void wp_remora_timer(unsigned long pfe) wan_smp_flag_t smp_flags; int empty = 1; - DEBUG_RM("%s: RM timer!\n", fe->name); + DEBUG_TEST("%s: RM timer!\n", fe->name); if (wan_test_bit(WP_RM_TIMER_KILL,(void*)&fe->rm_param.critical)){ wan_clear_bit(WP_RM_TIMER_RUNNING,(void*)&fe->rm_param.critical); @@ -1799,9 +1920,9 @@ static void wp_remora_timer(unsigned long pfe) wan_clear_bit(WP_RM_TIMER_RUNNING,(void*)&fe->rm_param.critical); /* Enable hardware interrupt for TE1 */ - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); empty = WAN_LIST_EMPTY(&fe->event); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); if (!empty){ if (wan_test_and_set_bit(WP_RM_TIMER_EVENT_PENDING,(void*)&fe->rm_param.critical)){ @@ -1814,7 +1935,7 @@ static void wp_remora_timer(unsigned long pfe) wp_remora_polling(fe); } }else{ - sdla_rm_add_timer(fe, 1000); + sdla_rm_add_timer(fe, WP_RM_POLL_TIMER); } return; } @@ -1832,7 +1953,7 @@ static int sdla_rm_add_timer(sdla_fe_t* fe, unsigned long delay) { int err; - DEBUG_RM("%s: Add new RM timer!\n", fe->name); + DEBUG_TEST("%s: Add new RM timer!\n", fe->name); err = wan_add_timer(&fe->timer, delay * HZ / 1000); if (err){ /* Failed to add timer */ @@ -1843,19 +1964,26 @@ static int sdla_rm_add_timer(sdla_fe_t* fe, unsigned long delay) } +/****************************************************************************** +** wp_remora_polling() +** +** Description: +** Arguments: +** Returns: +******************************************************************************/ static int wp_remora_polling(sdla_fe_t* fe) { -#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) - int err = 0; -#endif sdla_t *card = (sdla_t*)fe->card; + int err = 0; + sdla_fe_timer_event_t *fe_event; + wan_event_t event; wan_smp_flag_t smp_flags; int pending = 0, mod_no = 0; u8 imask; - WAN_ASSERT(fe->write_fe_reg == NULL); - WAN_ASSERT(fe->read_fe_reg == NULL); + WAN_ASSERT_RC(fe->write_fe_reg == NULL,0); + WAN_ASSERT_RC(fe->read_fe_reg == NULL, 0); #if 0 DEBUG_EVENT("%s: %s:%d: ---------------START ----------------------\n", @@ -1864,28 +1992,33 @@ static int wp_remora_polling(sdla_fe_t* fe) DEBUG_EVENT("%s: %s:%d: ---------------STOP ----------------------\n", fe->name, __FUNCTION__,__LINE__); #endif - - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); if (WAN_LIST_EMPTY(&fe->event)){ wan_clear_bit(WP_RM_TIMER_EVENT_PENDING,(void*)&fe->rm_param.critical); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); DEBUG_EVENT("%s: WARNING: No FE events in a queue!\n", fe->name); - sdla_rm_add_timer(fe, HZ); - return 0; +// sdla_rm_add_timer(fe, HZ); +// return 0; + return HZ; } fe_event = WAN_LIST_FIRST(&fe->event); WAN_LIST_REMOVE(fe_event, next); - wan_spin_unlock_irq(&fe->lock,&smp_flags); - + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); +#if defined(__WINDOWS__) + /* FIXME: Try to make common code for all OS */ + /* poll is NOT locked outside! */ wan_spin_lock_irq(&card->wandev.lock,&smp_flags); +#endif mod_no = fe_event->rm_event.mod_no; - DEBUG_RM("%s: Module %d: RM Polling State=%s Cmd=0x%X!\n", - fe->name, mod_no, + DEBUG_RM("[RM] %s: Module %d: RM Polling State=%s Cmd=%s(%X) Mode=%s!\n", + fe->name, mod_no+1, fe->fe_status==FE_CONNECTED?"Con":"Disconn", - fe_event->type); + WP_RM_POLL_DECODE(fe_event->type), fe_event->type, + WAN_EVENT_MODE_DECODE(fe_event->mode)); + switch(fe_event->type){ case WP_RM_POLL_POWER: @@ -1953,10 +2086,10 @@ static int wp_remora_polling(sdla_fe_t* fe) break; case WP_RM_POLL_TONE: if (fe_event->mode == WAN_EVENT_ENABLE){ - DEBUG_EVENT("%s: Module %d: %s %s events (%d)!\n", - fe->name, mod_no, + DEBUG_RM("%s: Module %d: %s %s events (%d)!\n", + fe->name, mod_no+1, WAN_EVENT_MODE_DECODE(fe_event->mode), - WAN_EVENT_TYPE_DECODE(fe_event->type), + WP_RM_POLL_DECODE(fe_event->type), fe_event->rm_event.tone); switch(fe_event->rm_event.tone){ case WAN_EVENT_TONE_DIAL: @@ -1987,7 +2120,7 @@ static int wp_remora_polling(sdla_fe_t* fe) case WP_RM_POLL_TXSIG_START: if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ DEBUG_RM("%s: Module %d: txsig START.\n", - fe->name, mod_no); + fe->name, mod_no+1); fe->rm_param.mod[mod_no].u.fxs.lasttxhook = 4; WRITE_RM_REG(mod_no, 64, fe->rm_param.mod[mod_no].u.fxs.lasttxhook); @@ -2068,10 +2201,13 @@ static int wp_remora_polling(sdla_fe_t* fe) /* Can't change polarity while ringing or when open */ if ((fe->rm_param.mod[mod_no].u.fxs.lasttxhook == 0x04) || (fe->rm_param.mod[mod_no].u.fxs.lasttxhook == 0x00)){ -#if defined(__WINDOWS__) +#if 0 /*defined(__WINDOWS__)*/ //done with the event, reset the pointer. fe->rm_param.mod[mod_no].current_control_event_ptr = NULL; + + wan_spin_lock_irq(&card->wandev.lock,&smp_flags); card->event_control_running = 0; + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); #endif break; } @@ -2086,24 +2222,26 @@ static int wp_remora_polling(sdla_fe_t* fe) break; case WP_RM_POLL_RING_DETECT: - imask = READ_RM_REG(mod_no, 3); - if (fe_event->mode == WAN_EVENT_ENABLE){ - imask |= 0x80; - wan_set_bit(WAN_RM_EVENT_RING_DETECT, - &fe->rm_param.mod[mod_no].events); - }else{ - imask &= ~0x80; - wan_clear_bit(WAN_RM_EVENT_RING_DETECT, - &fe->rm_param.mod[mod_no].events); + if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ + imask = READ_RM_REG(mod_no, 3); + if (fe_event->mode == WAN_EVENT_ENABLE){ + imask |= 0x80; + wan_set_bit(WAN_RM_EVENT_RING_DETECT, + &fe->rm_param.mod[mod_no].events); + }else{ + imask &= ~0x80; + wan_clear_bit(WAN_RM_EVENT_RING_DETECT, + &fe->rm_param.mod[mod_no].events); + } + WRITE_RM_REG(mod_no, 3, imask); } - WRITE_RM_REG(mod_no, 3, imask); break; #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE) case WP_RM_POLL_TDMV: #if defined(__WINDOWS__) //FIXME: implement - TDM_FUNC_DBG + TDM_FUNC_DBG(); #else WAN_TDMV_CALL(polling, (card), err); #endif @@ -2112,15 +2250,51 @@ static int wp_remora_polling(sdla_fe_t* fe) case WP_RM_POLL_INIT: wp_init_proslic(fe, fe_event->rm_event.mod_no, 1, 1); break; + case WP_RM_POLL_READ: + fe->rm_param.reg_dbg_value = READ_RM_REG(mod_no,fe_event->rm_event.reg); + fe->rm_param.reg_dbg_ready = 1; + DEBUG_RM("%s: Module %d: Reading %s register: Reg[%d]=%02X\n", + fe->name, mod_no+1, + WP_REMORA_DECODE_TYPE(fe->rm_param.mod[mod_no].type), + fe_event->rm_event.reg, + fe->rm_param.reg_dbg_value); + break; + case WP_RM_POLL_WRITE: + DEBUG_RM("%s: Module %d: Writting %s register: Reg[%d]=%02X\n", + fe->name, mod_no+1, + WP_REMORA_DECODE_TYPE(fe->rm_param.mod[mod_no].type), + fe_event->rm_event.reg, + fe_event->rm_event.value); + WRITE_RM_REG(mod_no, fe_event->rm_event.reg, fe_event->rm_event.value); + break; + case WP_RM_POLL_RXSIG_ONHOOK: + event.type = WAN_EVENT_RM_LC; + event.channel = mod_no+1; + event.rxhook = WAN_EVENT_RXHOOK_ON; + if (card->wandev.event_callback.hook){ + card->wandev.event_callback.hook(card, &event); + } + break; + case WP_RM_POLL_RXSIG_OFFHOOK: + event.type = WAN_EVENT_RM_LC; + event.channel = mod_no+1; + event.rxhook = WAN_EVENT_RXHOOK_OFF; + if (card->wandev.event_callback.hook){ + card->wandev.event_callback.hook(card, &event); + } + break; default: DEBUG_EVENT("ERROR: %s: Invalid poll event type %X!\n", fe->name, fe_event->type); break; } - wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); - #if defined(__WINDOWS__) + /* poll is NOT locked outside! */ + wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); +#endif + +#if 0/*defined(__WINDOWS__)*/ //done with the event, reset the pointer. fe->rm_param.mod[mod_no].current_control_event_ptr = NULL; @@ -2139,11 +2313,13 @@ static int wp_remora_polling(sdla_fe_t* fe) /* Add fe timer */ fe_event = WAN_LIST_FIRST(&fe->event); if (fe_event){ - sdla_rm_add_timer(fe, fe_event->delay); +// sdla_rm_add_timer(fe, fe_event->delay); + return fe_event->delay; }else{ - sdla_rm_add_timer(fe, HZ); +// sdla_rm_add_timer(fe, WP_RM_POLL_TIMER); } - return 0; +// return 0; + return WP_RM_POLL_TIMER; } /* @@ -2185,26 +2361,92 @@ sdla_rm_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *fe_event) DEBUG_EVENT("%s: %s:%d: ---------------STOP ----------------------\n", fe->name, __FUNCTION__,__LINE__); #endif - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); if (WAN_LIST_EMPTY(&fe->event)){ WAN_LIST_INSERT_HEAD(&fe->event, event, next); }else{ +#if defined(__WINDOWS__) + /* only one event allowed at a time */ + DEBUG_RM("%s: returning EBUSY\n", + fe->name); + wan_spin_unlock_irq(&fe->lockirq, &smp_flags); + return EBUSY; +#else sdla_fe_timer_event_t *tmp; WAN_LIST_FOREACH(tmp, &fe->event, next){ if (!WAN_LIST_NEXT(tmp, next)) break; } if (tmp == NULL){ DEBUG_EVENT("%s: Internal Error!!!\n", fe->name); - wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_spin_unlock_irq(&fe->lockirq, &smp_flags); return -EINVAL; } WAN_LIST_INSERT_AFTER(tmp, event, next); +#endif } - wan_spin_unlock_irq(&fe->lock, &smp_flags); + wan_spin_unlock_irq(&fe->lockirq, &smp_flags); return 0; } +/****************************************************************************** +* wp_remora_event_verification() +* +* Description: +* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) +* Returns: +******************************************************************************/ +static int +wp_remora_event_verification(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) +{ + int mod_no = ectrl->mod_no-1; + /* Event verification */ + if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ + switch(ectrl->type){ + case WAN_EVENT_RM_POWER: + case WAN_EVENT_RM_LC: + case WAN_EVENT_RM_DTMF: + case WAN_EVENT_RM_RING_TRIP: + case WAN_EVENT_RM_RING: + case WAN_EVENT_RM_TONE: + case WAN_EVENT_RM_TXSIG_KEWL: + case WAN_EVENT_RM_TXSIG_START: + case WAN_EVENT_RM_TXSIG_OFFHOOK: + case WAN_EVENT_RM_TXSIG_ONHOOK: + case WAN_EVENT_RM_ONHOOKTRANSFER: + case WAN_EVENT_RM_SETPOLARITY: + break; + default: + DEBUG_EVENT( + "%s: Module %d: Remora RING Event is only valid for FXS module (%X)\n", + fe->name,mod_no+1, + ectrl->type); + return -EINVAL; + } + }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ + switch(ectrl->type){ + case WAN_EVENT_RM_RING_DETECT: + case WAN_EVENT_RM_TXSIG_START: + case WAN_EVENT_RM_TXSIG_OFFHOOK: + case WAN_EVENT_RM_TXSIG_ONHOOK: + break; + default: + DEBUG_EVENT( + "%s: Module %d: Remora RING Event is only valid for FXO module(%X)\n", + fe->name,mod_no+1, + ectrl->type); + return -EINVAL; + } + }else{ + DEBUG_EVENT( + "%s: Module %d: Unknown Module type %X\n", + fe->name,mod_no+1, + fe->rm_param.mod[mod_no].type); + return -EINVAL; + } + + return 0; +} /****************************************************************************** * wp_remora_event_ctrl() * @@ -2216,14 +2458,13 @@ static int wp_remora_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) { sdla_fe_timer_event_t fe_event; - int mod_no, err = 0; + int mod_no = ectrl->mod_no-1, err = 0; WAN_ASSERT(ectrl == NULL); - mod_no = ectrl->mod_no; - - if (mod_no >= MAX_REMORA_MODULES){ + + if (mod_no+1 > MAX_REMORA_MODULES){ DEBUG_EVENT("%s: Module %d: Module number is out of range!\n", - fe->name, mod_no); + fe->name, mod_no+1); return -EINVAL; } if (!wan_test_bit(mod_no, &fe->rm_param.module_map)) { @@ -2232,12 +2473,18 @@ wp_remora_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) return -EINVAL; } - DEBUG_RM("%s: Module %d: Scheduling %s event type!\n", - fe->name, mod_no, - WAN_EVENT_TYPE_DECODE(ectrl->type)); + if (wp_remora_event_verification(fe, ectrl)){ + return -EINVAL; + } + + DEBUG_RM("%s: Module %d: Scheduling %s event (%s:%X)!\n", + fe->name, mod_no+1, + WAN_EVENT_TYPE_DECODE(ectrl->type), + WAN_EVENT_MODE_DECODE(ectrl->mode), ectrl->mode); fe_event.mode = ectrl->mode; - fe_event.rm_event.mod_no= ectrl->mod_no; + fe_event.rm_event.mod_no= mod_no; + fe_event.delay = WP_RM_POLL_TIMER; switch(ectrl->type){ case WAN_EVENT_RM_POWER: fe_event.type = WP_RM_POLL_POWER; @@ -2245,15 +2492,18 @@ wp_remora_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) case WAN_EVENT_RM_LC: fe_event.type = WP_RM_POLL_LC; break; - case WAN_EVENT_RM_RING_TRIP: - fe_event.type = WP_RM_POLL_RING_TRIP; - break; case WAN_EVENT_RM_DTMF: fe_event.type = WP_RM_POLL_DTMF; break; + case WAN_EVENT_RM_RING_TRIP: + fe_event.type = WP_RM_POLL_RING_TRIP; + break; case WAN_EVENT_RM_RING: fe_event.type = WP_RM_POLL_RING; break; + case WAN_EVENT_RM_RING_DETECT: + fe_event.type = WP_RM_POLL_RING_DETECT; + break; case WAN_EVENT_RM_TONE: fe_event.type = WP_RM_POLL_TONE; fe_event.rm_event.tone = ectrl->tone; @@ -2277,16 +2527,7 @@ wp_remora_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) case WAN_EVENT_RM_SETPOLARITY: fe_event.type = WP_RM_POLL_SETPOLARITY; break; - case WAN_EVENT_RM_RING_DETECT: - fe_event.type = WP_RM_POLL_RING_DETECT; - break; - default: - DEBUG_EVENT("%s: Module %d: Invalid wan event type %X\n", - fe->name,mod_no, - ectrl->type); - return -EINVAL; - } - + } err = sdla_rm_add_event(fe, &fe_event); return err; } @@ -2294,8 +2535,8 @@ wp_remora_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) static int wp_remora_dialtone(sdla_fe_t *fe, int mod_no) { - DEBUG_EVENT("%s: Module %d: Enable Dial tone\n", - fe->name, mod_no); + DEBUG_RM("%s: Module %d: Enable Dial tone\n", + fe->name, mod_no+1); wp_proslic_setreg_indirect(fe, mod_no, 13,DIALTONE_IR13); wp_proslic_setreg_indirect(fe, mod_no, 14,DIALTONE_IR14); wp_proslic_setreg_indirect(fe, mod_no, 16,DIALTONE_IR16); @@ -2318,8 +2559,8 @@ static int wp_remora_dialtone(sdla_fe_t *fe, int mod_no) static int wp_remora_busytone(sdla_fe_t *fe, int mod_no) { - DEBUG_EVENT("%s: Module %d: Enable Busy tone\n", - fe->name, mod_no); + DEBUG_RM("%s: Module %d: Enable Busy tone\n", + fe->name, mod_no+1); wp_proslic_setreg_indirect(fe, mod_no, 13,BUSYTONE_IR13); wp_proslic_setreg_indirect(fe, mod_no, 14,BUSYTONE_IR14); wp_proslic_setreg_indirect(fe, mod_no, 16,BUSYTONE_IR16); @@ -2342,8 +2583,8 @@ static int wp_remora_busytone(sdla_fe_t *fe, int mod_no) static int wp_remora_ringtone(sdla_fe_t *fe, int mod_no) { - DEBUG_EVENT("%s: Module %d: Enable Ring tone\n", - fe->name, mod_no); + DEBUG_RM("%s: Module %d: Enable Ring tone\n", + fe->name, mod_no+1); wp_proslic_setreg_indirect(fe, mod_no, 13,RINGBACKTONE_IR13); wp_proslic_setreg_indirect(fe, mod_no, 14,RINGBACKTONE_IR14); wp_proslic_setreg_indirect(fe, mod_no, 16,RINGBACKTONE_IR16); @@ -2366,8 +2607,8 @@ static int wp_remora_ringtone(sdla_fe_t *fe, int mod_no) static int wp_remora_congestiontone(sdla_fe_t *fe, int mod_no) { - DEBUG_EVENT("%s: Module %d: Enable Congestion tone\n", - fe->name, mod_no); + DEBUG_RM("%s: Module %d: Enable Congestion tone\n", + fe->name, mod_no+1); wp_proslic_setreg_indirect(fe, mod_no, 13,CONGESTIONTONE_IR13); wp_proslic_setreg_indirect(fe, mod_no, 14,CONGESTIONTONE_IR14); wp_proslic_setreg_indirect(fe, mod_no, 16,CONGESTIONTONE_IR16); @@ -2469,27 +2710,42 @@ static int wp_remora_stats_voltage(sdla_fe_t* fe, unsigned char *data) */ static int wp_remora_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) { - wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; - sdla_fe_debug_t *fe_debug; - int err = -EINVAL; + wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; + sdla_fe_debug_t *fe_debug; + sdla_fe_timer_event_t event; + int err = -EINVAL; + memset(&event, 0, sizeof(sdla_fe_timer_event_t)); switch(udp_cmd->wan_cmd_command){ -#if 0 -/* FIXME: Update wanpipemon to use API ioctl call */ case WAN_FE_TONES: - fe->rm_param.timer_mod_no = data[0]; - wp_remora_enable_timer(fe, WP_RM_POLL_TONE_DIAL, WP_RM_POLL_TIMER); + event.type = WP_RM_POLL_TONE; + event.rm_event.mod_no = data[0]; + if (data[1]){ + event.mode = WAN_EVENT_ENABLE; + }else{ + event.mode = WAN_EVENT_DISABLE; + } + event.rm_event.tone = WAN_EVENT_TONE_DIAL; + event.delay = WP_RM_POLL_TIMER; + sdla_rm_add_event(fe, &event); udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = 0; break; case WAN_FE_RING: - fe->rm_param.timer_mod_no = data[0]; - wp_remora_enable_timer(fe, WP_RM_POLL_RING, WP_RM_POLL_TIMER); + event.type = WP_RM_POLL_RING; + event.mode = WAN_EVENT_ENABLE; + + event.rm_event.mod_no = data[0]; + if (data[1]){ + event.mode = WAN_EVENT_ENABLE; + }else{ + event.mode = WAN_EVENT_DISABLE; + } + event.delay = WP_RM_POLL_TIMER; + sdla_rm_add_event(fe, &event); udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = 0; break; -#endif + case WAN_FE_REGDUMP: err = wp_remora_regdump(fe, data); if (err){ @@ -2500,33 +2756,6 @@ static int wp_remora_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) case WAN_FE_STATS: err = wp_remora_stats_voltage(fe, data); -#if 0 - /* verify TIP/RING voltage */ - if (!fast){ - WRITE_RM_REG(mod_no, 8, 0x2); - wait_just_a_bit(HZ, fast); - start_ticks = SYSTEM_TICKS; - while(READ_RM_REG(mod_no, 81) < 0x75){ - if ((SYSTEM_TICKS - start_ticks) > HZ*10){ - break; - } - wait_just_a_bit(HZ, fast); - } - wait_just_a_bit(HZ, fast); - if (READ_RM_REG(mod_no, 81) < 0x75){ - if (sane){ - DEBUG_EVENT( - "%s: Module %d: TIP/RING is too low on FXS %d!\n", - fe->name, - mod_no, - READ_RM_REG(mod_no, 81) * 375 / 1000); - } - WRITE_RM_REG(mod_no, 8, 0x0); - return -1; - } - WRITE_RM_REG(mod_no, 8, 0x0); - } -#endif if (err){ udp_cmd->wan_cmd_return_code = WAN_CMD_OK; udp_cmd->wan_cmd_data_len = (unsigned short)err; @@ -2535,13 +2764,45 @@ static int wp_remora_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) case WAN_FE_SET_DEBUG_MODE: fe_debug = (sdla_fe_debug_t*)&data[0]; -#if 0 switch(fe_debug->type){ - case WAN_FE_DEBUG_VOLTAGE: - /* FIXME: Add code */ + case WAN_FE_DEBUG_REG: + if (fe->rm_param.reg_dbg_busy){ + if (fe_debug->fe_debug_reg.read == 2 && fe->rm_param.reg_dbg_ready){ + /* Poll the register value */ + fe_debug->fe_debug_reg.value = fe->rm_param.reg_dbg_value; + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + fe->rm_param.reg_dbg_busy = 0; + } + break; + } + event.type = (fe_debug->fe_debug_reg.read) ? + WP_RM_POLL_READ : WP_RM_POLL_WRITE; + event.rm_event.mod_no = fe_debug->mod_no; + event.rm_event.reg = (u_int16_t)fe_debug->fe_debug_reg.reg; + event.rm_event.value = fe_debug->fe_debug_reg.value; + event.delay = WP_RM_POLL_TIMER; + if (fe_debug->fe_debug_reg.read){ + fe->rm_param.reg_dbg_busy = 1; + fe->rm_param.reg_dbg_ready = 0; + } + sdla_rm_add_event(fe, &event); + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + break; + + case WAN_FE_DEBUG_HOOK: + event.type = (fe_debug->fe_debug_hook.offhook) ? + WP_RM_POLL_RXSIG_OFFHOOK: + WP_RM_POLL_RXSIG_ONHOOK; + event.rm_event.mod_no = fe_debug->mod_no; + sdla_rm_add_event(fe, &event); + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + break; + + default: + udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; + udp_cmd->wan_cmd_data_len = 0; break; } -#endif break; default: @@ -2564,7 +2825,7 @@ static int wp_init_proslic_recheck_sanity(sdla_fe_t *fe, int mod_no) sdla_fe_timer_event_t event; DEBUG_EVENT( "%s: Module %d: Ouch, part reset, quickly restoring reality\n", - fe->name, mod_no); + fe->name, mod_no+1); event.type = WP_RM_POLL_INIT; event.delay = WP_RM_POLL_TIMER; event.rm_event.mod_no = mod_no; @@ -2592,9 +2853,12 @@ static int wp_init_proslic_recheck_sanity(sdla_fe_t *fe, int mod_no) return 0; } -#if defined(AFT_TDM_API_SUPPORT) +#if defined(AFT_TDM_API_SUPPORT) || defined(AFT_API_SUPPORT) static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) { +//#undef DEBUG_RM +//#define DEBUG_RM DEBUG_EVENT + sdla_t *card = NULL; wan_event_t event; #ifndef AUDIO_RINGCHECK @@ -2626,11 +2890,12 @@ static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) } if (poopy) return; + #ifndef AUDIO_RINGCHECK if (!fe->rm_param.mod[mod_no].u.fxo.offhook) { res = READ_RM_REG(mod_no, 5); if ((res & 0x60) && fe->rm_param.mod[mod_no].u.fxo.battery) { - fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 16); + fe->rm_param.mod[mod_no].u.fxo.ringdebounce += (WP_RM_CHUNKSIZE * 4); if (fe->rm_param.mod[mod_no].u.fxo.ringdebounce >= WP_RM_CHUNKSIZE * 64) { if (!fe->rm_param.mod[mod_no].u.fxo.wasringing) { fe->rm_param.mod[mod_no].u.fxo.wasringing = 1; @@ -2648,7 +2913,7 @@ static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) fe->rm_param.mod[mod_no].u.fxo.ringdebounce = WP_RM_CHUNKSIZE * 64; } } else { - fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 4; + fe->rm_param.mod[mod_no].u.fxo.ringdebounce -= WP_RM_CHUNKSIZE * 2; if (fe->rm_param.mod[mod_no].u.fxo.ringdebounce <= 0) { if (fe->rm_param.mod[mod_no].u.fxo.wasringing) { fe->rm_param.mod[mod_no].u.fxo.wasringing = 0; @@ -2700,6 +2965,9 @@ static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) #endif } #else + DEBUG_RM("%s: Module %d: On-Hook status!\n", + fe->name, + mod_no + 1); event.type = WAN_EVENT_RM_LC; event.channel = mod_no+1; event.rxhook = WAN_EVENT_RXHOOK_ON; @@ -2710,7 +2978,9 @@ static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) fe->rm_param.mod[mod_no].u.fxo.battdebounce = battdebounce; } else if (!fe->rm_param.mod[mod_no].u.fxo.battery) fe->rm_param.mod[mod_no].u.fxo.battdebounce = battdebounce; + } else if (abs(b) > battthresh) { + if (!fe->rm_param.mod[mod_no].u.fxo.battery && !fe->rm_param.mod[mod_no].u.fxo.battdebounce) { DEBUG_RM("%s: Module %d: BATTERY (%s)!\n", @@ -2771,12 +3041,11 @@ static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) if (fe->rm_param.mod[mod_no].u.fxo.lastpol != fe->rm_param.mod[mod_no].u.fxo.polarity) { DEBUG_RM( - "%s: Module %d: %lu Polarity reversed (%d -> %d)\n", - fe->name, - mod_no + 1, - SYSTEM_TICKS, + "%s: Module %d: Polarity reversed (%d -> %d) (%ul)\n", + fe->name, mod_no + 1, fe->rm_param.mod[mod_no].u.fxo.polarity, - fe->rm_param.mod[mod_no].u.fxo.lastpol); + fe->rm_param.mod[mod_no].u.fxo.lastpol, + (unsigned int)SYSTEM_TICKS); if (fe->rm_param.mod[mod_no].u.fxo.polarity){ /* FIXME: Add revers polarity event */ } @@ -2786,6 +3055,8 @@ static void wp_remora_voicedaa_check_hook(sdla_fe_t *fe, int mod_no) } } return; +//#undef DEBUG_RM +//#define DEBUG_RM DEBUG_TEST } #endif @@ -2866,7 +3137,7 @@ static void wp_remora_proslic_check_hook(sdla_fe_t *fe, int mod_no) #endif #endif -#if defined(AFT_TDM_API_SUPPORT) +#if defined(AFT_TDM_API_SUPPORT) || defined(AFT_API_SUPPORT) /****************************************************************************** * wp_remora_watchdog() * @@ -2877,11 +3148,7 @@ static void wp_remora_proslic_check_hook(sdla_fe_t *fe, int mod_no) static int wp_remora_watchdog(sdla_fe_t *fe) { int mod_no; - - if (SYSTEM_TICKS - fe->rm_param.last_watchdog < WP_RM_WATCHDOG_TIMEOUT) { - return 0; - } - fe->rm_param.last_watchdog = SYSTEM_TICKS; + for (mod_no = 0; mod_no < fe->rm_param.max_fe_channels; mod_no++) { if (!wan_test_bit(mod_no, &fe->rm_param.module_map)) { @@ -2950,9 +3217,14 @@ static int wp_remora_watchdog(sdla_fe_t *fe) wp_remora_voicedaa_check_hook(fe, mod_no); } } + #if defined(AFT_RM_VIRTUAL_INTR_SUPPORT) - if (wp_remora_check_intr(fe)){ - wp_remora_intr(fe); + if (SYSTEM_TICKS - fe->rm_param.last_watchdog > WP_RM_WATCHDOG_TIMEOUT) { + fe->rm_param.last_watchdog = SYSTEM_TICKS; + + if (wp_remora_check_intr(fe)){ + wp_remora_intr(fe); + } } #endif @@ -2975,17 +3247,18 @@ wp_remora_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t type, u_int8_t mode, uns if (mod_no >= MAX_REMORA_MODULES){ DEBUG_EVENT( "%s: Module %d: Module number is out of range!\n", - fe->name, mod_no); + fe->name, mod_no+1); return -EINVAL; } if (!wan_test_bit(mod_no, &fe->rm_param.module_map)) { DEBUG_EVENT("%s: Module %d: Unconfigured module!\n", - fe->name, mod_no); + fe->name, mod_no+1); return -EINVAL; } if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ - if (type & WAN_RM_INTR_GLOBAL){ + switch(type){ + case WAN_RM_INTR_GLOBAL: if (mode == WAN_FE_INTR_ENABLE){ WRITE_RM_REG(mod_no, 21, fe->rm_param.mod[mod_no].u.fxs.imask1); WRITE_RM_REG(mod_no, 22, fe->rm_param.mod[mod_no].u.fxs.imask2); @@ -2995,16 +3268,30 @@ wp_remora_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t type, u_int8_t mode, uns WRITE_RM_REG(mod_no, 22, 0x00); WRITE_RM_REG(mod_no, 23, 0x00); } + break; + default: + DEBUG_EVENT( + "%s: Module %d: Unsupported FXS interrupt type (%X)!\n", + fe->name, mod_no+1, type); + err = -EINVAL; + break; } }else if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXO){ - - if (type & WAN_RM_INTR_GLOBAL){ + switch(type){ + case WAN_RM_INTR_GLOBAL: if (mode == WAN_FE_INTR_ENABLE){ WRITE_RM_REG(mod_no, 3, fe->rm_param.mod[mod_no].u.fxo.imask); }else{ WRITE_RM_REG(mod_no, 3, 0x00); } + break; + default: + DEBUG_EVENT( + "%s: Module %d: Unsupported FXO interrupt type (%X)!\n", + fe->name, mod_no+1, type); + err = -EINVAL; + break; } } return err; @@ -3025,7 +3312,7 @@ static int wp_remora_check_intr_fxs(sdla_fe_t *fe, int mod_no) int err = 0; DEBUG_EVENT( "%s: Module %d: Oops, part reset, quickly restoring reality\n", - fe->name, mod_no); + fe->name, mod_no+1); #if 0 wp_init_proslic(fe, mod_no, 1, 1); #else @@ -3050,7 +3337,6 @@ static int wp_remora_check_intr_fxo(sdla_fe_t *fe, int mod_no) u_int8_t status; status = READ_RM_REG(mod_no, 4); - return (status) ? 1 : 0; } @@ -3059,8 +3345,6 @@ static int wp_remora_check_intr(sdla_fe_t *fe) int mod_no = 0, pending = 0; fe->rm_param.intcount++; - //mod_no = fe->rm_param.intcount % MAX_REMORA_MODULES; - for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no++){ if (wan_test_bit(mod_no, &fe->rm_param.module_map)) { if (fe->rm_param.mod[mod_no].type == MOD_TYPE_FXS){ @@ -3137,8 +3421,6 @@ static int wp_remora_intr_fxs(sdla_fe_t *fe, int mod_no) WAN_ASSERT(fe->card == NULL); card = fe->card; - DEBUG_TDMAPI("mod_no: %d\n", mod_no); - stat1 = READ_RM_REG(mod_no, 18); if (stat1){ /* Ack interrupts for now */ @@ -3152,7 +3434,7 @@ static int wp_remora_intr_fxs(sdla_fe_t *fe, int mod_no) if (stat2 & 0x02){ DEBUG_RM( "%s: Module %d: LCIP interrupt pending!\n", - fe->name, mod_no); + fe->name, mod_no+1); #if 0 if (card->wandev.fe_notify_iface.hook_state){ card->wandev.fe_notify_iface.hook_state( @@ -3164,13 +3446,13 @@ static int wp_remora_intr_fxs(sdla_fe_t *fe, int mod_no) if (status & 0x01){ DEBUG_RM( "RM: %s: Module %d: Off-hook status!\n", - fe->name, mod_no); + fe->name, mod_no+1); fe->rm_param.mod[mod_no].u.fxs.oldrxhook = 1; event.rxhook = WAN_EVENT_RXHOOK_OFF; }else/* if (fe->rm_param.mod[mod_no].u.fxs.oldrxhook)*/{ DEBUG_RM( "RM: %s: Module %d: On-hook status!\n", - fe->name, mod_no); + fe->name, mod_no+1); fe->rm_param.mod[mod_no].u.fxs.oldrxhook = 0; event.rxhook = WAN_EVENT_RXHOOK_ON; } @@ -3183,7 +3465,7 @@ static int wp_remora_intr_fxs(sdla_fe_t *fe, int mod_no) if (stat2 & 0x01){ DEBUG_RM( "%s: Module %d: Ring TRIP interrupt pending!\n", - fe->name, mod_no); + fe->name, mod_no+1); #if 0 if (card->wandev.fe_notify_iface.hook_state){ card->wandev.fe_notify_iface.hook_state( @@ -3201,27 +3483,51 @@ static int wp_remora_intr_fxs(sdla_fe_t *fe, int mod_no) if (status & 0x02){ DEBUG_RM( "%s: Module %d: Ring Trip detect occured!\n", - fe->name, mod_no); - event.rxhook = WAN_EVENT_RING_TRIP_PRESENT; + fe->name, mod_no+1); + event.ring_mode = WAN_EVENT_RING_TRIP_PRESENT; }else{ DEBUG_RM( "%s: Module %d: Ring Trip detect not occured!\n", - fe->name, mod_no); - event.rxhook = WAN_EVENT_RING_TRIP_STOP; + fe->name, mod_no+1); + event.ring_mode = WAN_EVENT_RING_TRIP_STOP; } if (card->wandev.event_callback.ringtrip){ card->wandev.event_callback.ringtrip(card, &event); } } + if (stat2 & 0x80) { + DEBUG_EVENT("%s: Module %d: Power Alarm Q6!\n", + fe->name, mod_no+1); + } + if (stat2 & 0x40) { + DEBUG_EVENT("%s: Module %d: Power Alarm Q5!\n", + fe->name, mod_no+1); + } + if (stat2 & 0x20) { + DEBUG_EVENT("%s: Module %d: Power Alarm Q4!\n", + fe->name, mod_no+1); + } + if (stat2 & 0x10) { + DEBUG_EVENT("%s: Module %d: Power Alarm Q3!\n", + fe->name, mod_no+1); + } + if (stat2 & 0x08) { + DEBUG_EVENT("%s: Module %d: Power Alarm Q2!\n", + fe->name, mod_no+1); + } + if (stat2 & 0x04) { + DEBUG_EVENT("%s: Module %d: Power Alarm Q1!\n", + fe->name, mod_no+1); + } DEBUG_RM( "%s: Module %d: Reg[64]=%02X Reg[68]=%02X\n", - fe->name, mod_no, + fe->name, mod_no+1, READ_RM_REG(mod_no,64), status); WRITE_RM_REG(mod_no, 19, stat2); }else{ #if defined(__WINDOWS__) - TDM_FUNC_DBG + TDM_FUNC_DBG(); #endif } @@ -3257,27 +3563,33 @@ static int wp_remora_intr_fxo(sdla_fe_t *fe, int mod_no) fe->name, mod_no+1); fe->rm_param.mod[mod_no].u.fxo.ring_detect = 0; event.ring_mode = WAN_EVENT_RING_STOP; - }else{ + } else { DEBUG_RM( "%s: Module %d: Beginning of ring burst\n", fe->name, mod_no+1); fe->rm_param.mod[mod_no].u.fxo.ring_detect = 1; event.ring_mode = WAN_EVENT_RING_PRESENT; } - }else{ + } else { DEBUG_RM( "%s: Module %d: Beginning of ring burst\n", fe->name, mod_no+1); fe->rm_param.mod[mod_no].u.fxo.ring_detect = 1; event.ring_mode = WAN_EVENT_RING_PRESENT; } +#ifdef AUDIO_RINGCHECK +/* If audio ringcheck is enabled, we use this code + * if disabled we use the check_hook code. + * Right now we use the check_hook code because + * this code does not have debounce */ if (card->wandev.event_callback.ringdetect){ card->wandev.event_callback.ringdetect(card, &event); - } - }else if (status){ - DEBUG_RM( - "%s: Module %d: Receive interrupt %02X!\n", - fe->name, mod_no+1, status); + } +#endif + } + if (status & 0x01){ + DEBUG_RM("%s: Module %d: Polarity reversed!\n", + fe->name, mod_no+1); } WRITE_RM_REG(mod_no, 4, 0x00); diff --git a/patches/kdrivers/src/net/sdla_remora_tdmv.c b/patches/kdrivers/src/net/sdla_remora_tdmv.c index f1ab4bd..e555af1 100644 --- a/patches/kdrivers/src/net/sdla_remora_tdmv.c +++ b/patches/kdrivers/src/net/sdla_remora_tdmv.c @@ -25,15 +25,15 @@ # include # include # include +# include # include # include -#elif (defined __WINDOWS__) -# include #else # include # include # include # include +# include # include #endif @@ -42,6 +42,7 @@ *******************************************************************************/ #define REG_SHADOW #define REG_WRITE_SHADOW +#define NEW_PULSE_DIALING #undef PULSE_DIALING #if 0 @@ -115,8 +116,8 @@ typedef struct wp_tdmv_remora_ { char *devname; int num; int flags; - wan_spinlock_t lock; - wan_spinlock_t tx_rx_lock; + wan_spinlock_t lockirq; + wan_spinlock_t tx_rx_lockirq; union { tdmv_fxo_t fxo; tdmv_fxs_t fxs; @@ -146,11 +147,9 @@ typedef struct wp_tdmv_remora_ { int channelized; unsigned char hwec; unsigned long echo_off_map; - int rxsig_state[MAX_REMORA_MODULES]; - int txsig_state[MAX_REMORA_MODULES]; /* not used */ - int battdebounce; - int battthresh; + int battdebounce; /* global for FXO */ + int battthresh; /* global for FXO */ u_int8_t dtmfsupport; unsigned int dtmfactive; @@ -202,6 +201,7 @@ wp_remora_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) wp_tdmv_remora_t *wr = chan->pvt; sdla_t *card = NULL; sdla_fe_t *fe = NULL; + wan_event_ctrl_t *event_ctrl = NULL; int x, err; WAN_ASSERT(wr->card == NULL); @@ -276,7 +276,7 @@ wp_remora_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) wr->mod[chan->chanpos-1].fxo.echotune = 1; #else DEBUG_EVENT("%s: Module %d: Setting echo registers: \n", - fe->name, chan->chanpos-1); + wr->devname, chan->chanpos-1); /* Set the ACIM register */ WRITE_RM_REG(chan->chanpos - 1, 30, echoregs.acim); @@ -291,7 +291,7 @@ wp_remora_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) WRITE_RM_REG(chan->chanpos - 1, 52, echoregs.coef8); DEBUG_EVENT("%s: Module %d: Set echo registers successfully\n", - fe->name, chan->chanpos-1); + wr->devname, chan->chanpos-1); #endif break; } else { @@ -300,33 +300,49 @@ wp_remora_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) } break; - case ZT_TONEDETECT: - err = WAN_COPY_FROM_USER(&x, (int*)data, sizeof(int)); - /*err = get_user(x, (int *)data);*/ - if (err) return -EFAULT; -#if 0 + if (WAN_COPY_FROM_USER(&x, (int*)data, sizeof(int))){ + return -EFAULT; + } - if (!wc->vpm) - return -ENOSYS; -#endif - if (wr->dtmfsupport != WANOPT_YES){ + if (wr->dtmfsupport != WANOPT_YES || card->wandev.ec_dev == NULL){ return -ENOSYS; } - DEBUG_EVENT("%s: Hardware Tone Event detection (%s:%s)!\n", - fe->name, - (x & ZT_TONEDETECT_ON) ? "ON" : "OFF", + DEBUG_TDMV("[TDMV_RM]: %s: HW Tone Detection %s on channel %d (%s)!\n", + wr->devname, + (x & ZT_TONEDETECT_ON) ? "ON" : "OFF", chan->chanpos - 1, (x & ZT_TONEDETECT_MUTE) ? "Mute ON" : "Mute OFF"); - if (x & ZT_TONEDETECT_ON) + if (x & ZT_TONEDETECT_ON){ wr->dtmfmask |= (1 << (chan->chanpos - 1)); - else + }else{ wr->dtmfmask &= ~(1 << (chan->chanpos - 1)); - if (x & ZT_TONEDETECT_MUTE) + } + if (x & ZT_TONEDETECT_MUTE){ wr->dtmfmutemask |= (1 << (chan->chanpos - 1)); - else + }else{ wr->dtmfmutemask &= ~(1 << (chan->chanpos - 1)); + } + +#if defined(CONFIG_WANPIPE_HWEC) + event_ctrl = wan_malloc(sizeof(wan_event_ctrl_t)); + if (event_ctrl==NULL){ + DEBUG_EVENT( + "%s: Failed to allocate memory for event ctrl!\n", + wr->devname); + return -EFAULT; + } + event_ctrl->type = WAN_EVENT_EC_CHAN_MODIFY; + event_ctrl->channel = chan->chanpos-1; + event_ctrl->mode = (x & ZT_TONEDETECT_MUTE) ? WAN_EVENT_ENABLE : WAN_EVENT_DISABLE; + if (wanpipe_ec_event_ctrl(card->wandev.ec_dev, card, event_ctrl)){ + wan_free(event_ctrl); + } + err = 0; +#else + err = -EINVAL; +#endif break; default: @@ -490,7 +506,7 @@ static int wp_remora_zap_hwec(struct zt_chan *chan, int enable) { wp_tdmv_remora_t *wr = NULL; sdla_t *card = NULL; - int channel = chan->chanpos; + int fe_chan = chan->chanpos; int err = -ENODEV; WAN_ASSERT2(chan == NULL, -ENODEV); @@ -506,7 +522,7 @@ static int wp_remora_zap_hwec(struct zt_chan *chan, int enable) * asterisk. In persist mode off asterisk * controls hardware echo cancellation */ if (card->hwec_conf.persist_disable) { - err = card->wandev.ec_enable(card, enable, channel-1); + err = card->wandev.ec_enable(card, enable, fe_chan); } else { err = 0; } @@ -558,7 +574,7 @@ static void wp_tdmv_remora_proslic_recheck_sanity(wp_tdmv_remora_t *wr, int mod_ if (res) { DEBUG_EVENT( "%s: Module %d: Ouch, part reset, quickly restoring reality\n", - wr->devname, mod_no); + wr->devname, mod_no+1); wp_init_proslic(fe, mod_no, 1, 1); } else { if (wr->mod[mod_no].fxs.palarms++ < MAX_ALARMS) { @@ -599,7 +615,7 @@ wp_tdmv_remora_voicedaa_recheck_sanity(wp_tdmv_remora_t *wr, int mod_no) if (!res) { DEBUG_EVENT( "%s: Module %d: Ouch, part reset, quickly restoring reality\n", - wr->devname, mod_no); + wr->devname, mod_no+1); wp_init_voicedaa(fe, mod_no, 1, 1); } return; @@ -655,7 +671,6 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) if (wr->mod[mod_no].fxo.ringdebounce >= ZT_CHUNKSIZE * 64) { if (!wr->mod[mod_no].fxo.wasringing) { wr->mod[mod_no].fxo.wasringing = 1; - wr->rxsig_state[mod_no] = ZT_RXSIG_RING; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_RING); DEBUG_TDMV("%s: Module %d: RING on span %d!\n", wr->devname, @@ -669,7 +684,6 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) if (wr->mod[mod_no].fxo.ringdebounce <= 0) { if (wr->mod[mod_no].fxo.wasringing) { wr->mod[mod_no].fxo.wasringing = 0; - wr->rxsig_state[mod_no] = ZT_RXSIG_OFFHOOK; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); DEBUG_TDMV("%s: Module %d: NO RING on span %d!\n", wr->devname, @@ -700,7 +714,8 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) wr->mod[mod_no].fxo.nobatttimer++; #if 0 if (wr->mod[mod_no].fxo.battery) - printk("Battery loss: %d (%d debounce)\n", b, wr->mod[mod_no].fxo.battdebounce); + printk("Battery loss: %d (%d debounce)\n", + b, wr->mod[mod_no].fxo.battdebounce); #endif if (wr->mod[mod_no].fxo.battery && !wr->mod[mod_no].fxo.battdebounce) { DEBUG_TDMV( @@ -712,7 +727,6 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) #ifdef JAPAN if ((!wr->mod[mod_no].fxo.ohdebounce) && wr->mod[mod_no].fxo.offhook) { - wr->rxsig_state[mod_no] = ZT_RXSIG_ONHOOK; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_ONHOOK); DEBUG_TDMV( "%s: Module %d: Signalled On Hook span %d\n", @@ -745,7 +759,6 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) #ifdef ZERO_BATT_RING if (wr->mod[mod_no].fxo.onhook) { wr->mod[mod_no].fxo.onhook = 0; - wr->rxsig_state[mod_no] = ZT_RXSIG_OFFHOOK; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); DEBUG_TDMV( "%s: Module %d: Signalled Off Hook span %d\n", @@ -754,13 +767,12 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) wr->span.spanno); } #else + zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); DEBUG_TDMV( "%s: Module %d: Signalled Off Hook span %d\n", wr->devname, mod_no + 1, wr->span.spanno); - wr->rxsig_state[mod_no] = ZT_RXSIG_OFFHOOK; - zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); #endif wr->mod[mod_no].fxo.battery = 1; wr->mod[mod_no].fxo.nobatttimer = 0; @@ -784,6 +796,7 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) /* It's something else... */ wr->mod[mod_no].fxo.battdebounce = wr->battdebounce; } + if (wr->mod[mod_no].fxo.battdebounce) wr->mod[mod_no].fxo.battdebounce--; if (wr->mod[mod_no].fxo.polaritydebounce) { @@ -791,12 +804,12 @@ static void wp_tdmv_remora_voicedaa_check_hook(wp_tdmv_remora_t *wr, int mod_no) if (wr->mod[mod_no].fxo.polaritydebounce < 1) { if (wr->mod[mod_no].fxo.lastpol != wr->mod[mod_no].fxo.polarity) { DEBUG_TDMV( - "%s: Module %d: Polarity reversed %d -> %d (%lu)\n", + "%s: Module %d: Polarity reversed %d -> %d (%u)\n", wr->devname, mod_no + 1, wr->mod[mod_no].fxo.polarity, wr->mod[mod_no].fxo.lastpol, - SYSTEM_TICKS); + (u32)SYSTEM_TICKS); if (wr->mod[mod_no].fxo.polarity){ zt_qevent_lock(&wr->chans[mod_no], ZT_EVENT_POLARITY); @@ -855,7 +868,6 @@ static void wp_tdmv_remora_proslic_check_hook(wp_tdmv_remora_t *wr, int mod_no) DEBUG_TDMV( "%s: Module %d: Going off hook\n", wr->devname, mod_no + 1); - wr->rxsig_state[mod_no] = ZT_RXSIG_OFFHOOK; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); #if 0 if (robust) @@ -868,7 +880,6 @@ static void wp_tdmv_remora_proslic_check_hook(wp_tdmv_remora_t *wr, int mod_no) DEBUG_TDMV( "%s: Module %d: Going on hook\n", wr->devname, mod_no + 1); - wr->rxsig_state[mod_no] = ZT_RXSIG_ONHOOK; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_ONHOOK); wr->mod[mod_no].fxs.oldrxhook = 0; } @@ -893,16 +904,6 @@ static int wp_tdmv_remora_check_hook(sdla_fe_t *fe, int mod_no) wp_tdmv_remora_voicedaa_check_hook(wr, mod_no); } -#if 0 - if (wr->rxsig_state[mod_no] != wr->chans[mod_no].rxhooksig){ - DEBUG_EVENT( - "%s: Module %d: WARNING: Update RX SIG state again %X (%X)\n", - wr->devname, mod_no + 1, - wr->rxsig_state[mod_no], - wr->chans[mod_no].rxhooksig); - zt_hooksig(&wr->chans[mod_no], wr->rxsig_state[mod_no]); - } -#endif return 0; } @@ -917,10 +918,8 @@ static int wp_tdmv_remora_hook(sdla_fe_t *fe, int mod_no, int off_hook) wr = wan_tdmv->sc; if (off_hook){ - wr->rxsig_state[mod_no] = ZT_RXSIG_OFFHOOK; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_OFFHOOK); }else{ - wr->rxsig_state[mod_no] = ZT_RXSIG_ONHOOK; zt_hooksig(&wr->chans[mod_no], ZT_RXSIG_ONHOOK); } wr->mod[mod_no].fxs.lastrxhook = off_hook; @@ -987,15 +986,21 @@ static int wp_tdmv_remora_software_init(wan_tdmv_t *wan_tdmv) break; } - wr->battthresh = (fe->fe_cfg.cfg.remora.battthresh) ? - fe->fe_cfg.cfg.remora.battthresh : DEFAULT_BATT_THRESH; - wr->battdebounce = (fe->fe_cfg.cfg.remora.battdebounce) ? - fe->fe_cfg.cfg.remora.battdebounce : DEFAULT_BATT_DEBOUNCE; - DEBUG_EVENT("%s: Battery Threshhold %d (%d)\n", - wr->devname, wr->battthresh, DEFAULT_BATT_THRESH); - DEBUG_EVENT("%s: Battery Debounce %d (%d)\n", - wr->devname, wr->battdebounce, DEFAULT_BATT_DEBOUNCE); wr->dtmfsupport = card->u.aft.tdmv_hw_dtmf; + wr->battthresh = DEFAULT_BATT_THRESH; + wr->battdebounce= DEFAULT_BATT_DEBOUNCE; + if (fe->fe_cfg.cfg.remora.battthresh && + fe->fe_cfg.cfg.remora.battthresh != DEFAULT_BATT_THRESH){ + wr->battthresh = fe->fe_cfg.cfg.remora.battthresh; + DEBUG_EVENT("%s: A200/A400 Remora Battery Threshhold changed %d -> %d\n", + wr->devname, DEFAULT_BATT_THRESH, wr->battthresh); + } + if (fe->fe_cfg.cfg.remora.battdebounce && + fe->fe_cfg.cfg.remora.battdebounce != DEFAULT_BATT_DEBOUNCE){ + wr->battdebounce = fe->fe_cfg.cfg.remora.battdebounce; + DEBUG_EVENT("%s: A200/A400 Remora Battery Debounce changed %d -> %d\n", + wr->devname, DEFAULT_BATT_DEBOUNCE, wr->battdebounce); + } for (x = 0; x < MAX_REMORA_MODULES; x++) { if (wan_test_bit(x, &fe->rm_param.module_map)){ @@ -1033,7 +1038,6 @@ static int wp_tdmv_remora_software_init(wan_tdmv_t *wan_tdmv) wr->chans[x].pvt = wr; num++; } - wr->rxsig_state[x] = ZT_RXSIG_INITIAL; } wr->span.pvt = wr; wr->span.chans = wr->chans; @@ -1076,8 +1080,13 @@ static int wp_tdmv_remora_software_init(wan_tdmv_t *wan_tdmv) /* Initialize Callback event function pointers */ if (wr->dtmfsupport == WANOPT_YES){ + DEBUG_EVENT("%s: Enable HW DTMF detection!\n", wr->devname); card->wandev.event_callback.dtmf = wp_tdmv_remora_dtmf; } + if (fe->fe_cfg.cfg.remora.fxs_pulsedialing == WANOPT_YES){ + DEBUG_EVENT("%s: Enable Pulse Dialing mode\n", + wr->devname); + } return 0; } @@ -1178,8 +1187,8 @@ static int wp_tdmv_remora_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) wr->devname = card->devname; wr->max_timeslots = card->fe.rm_param.max_fe_channels; wr->max_rxtx_len = 0; - wan_spin_lock_init(&wr->lock); - wan_spin_lock_init(&wr->tx_rx_lock); + wan_spin_lock_irq_init(&wr->lockirq, "wan_rmtdmv_lock"); + wan_spin_lock_irq_init(&wr->tx_rx_lockirq, "wan_rmtdmv_txrx_lock"); if (tmp){ WAN_LIST_INSERT_AFTER(tmp, &card->wan_tdmv, next); @@ -1413,7 +1422,7 @@ static int wp_tdmv_remora_rx_chan(wan_tdmv_t *wan_tdmv, int channo, wan_tdmv_rxtx_pwr_t *pwr_rxtx = NULL; #endif sdla_t *card; - + WAN_ASSERT2(wr == NULL, -EINVAL); WAN_ASSERT2(channo < 0, -EINVAL); WAN_ASSERT2(channo > 31, -EINVAL); @@ -1454,7 +1463,7 @@ DEBUG_EVENT("Module %d: RX: %02X %02X %02X %02X %02X %02X %02X %02X\n", #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER if(pwr_rxtx->current_state != ECHO_ABSENT){ #endif - + if (wan_test_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status)) { /* Updated for SWRING buffer * Sets up the spike at 3 bytes */ @@ -1559,7 +1568,7 @@ static int wp_tdmv_remora_rx_tx_span(void *pcard) } else if (fe->rm_param.mod[x].type == MOD_TYPE_FXO) { if (wr->mod[x].fxo.echotune){ - DEBUG_EVENT("%s: Module %d: Setting echo registers: \n", + DEBUG_RM("%s: Module %d: Setting echo registers: \n", fe->name, x); /* Set the ACIM register */ @@ -1575,7 +1584,7 @@ static int wp_tdmv_remora_rx_tx_span(void *pcard) WRITE_RM_REG(x, 51, wr->mod[x].fxo.echoregs.coef7); WRITE_RM_REG(x, 52, wr->mod[x].fxo.echoregs.coef8); - DEBUG_EVENT("%s: Module %d: Set echo registers successfully\n", + DEBUG_RM("%s: Module %d: Set echo registers successfully\n", fe->name, x); wr->mod[x].fxo.echotune = 0; } @@ -1587,12 +1596,23 @@ static int wp_tdmv_remora_rx_tx_span(void *pcard) } #endif } + +#if defined(NEW_PULSE_DIALING) + if (fe->fe_cfg.cfg.remora.fxs_pulsedialing == WANOPT_YES){ + /* + ** Alex 31 Mar, 2006 + ** Check for HOOK status every interrupt + ** (in pulse mode is very critical) */ + wp_tdmv_remora_check_hook(fe, x); + } +#else #ifdef PULSE_DIALING /* ** Alex 31 Mar, 2006 ** Check for HOOK status every interrupt ** (in pulse mode is very critical) */ wp_tdmv_remora_check_hook(fe, x); +#endif #endif } @@ -1616,8 +1636,14 @@ static int wp_tdmv_remora_rx_tx_span(void *pcard) } #endif +#if defined(NEW_PULSE_DIALING) + if (fe->fe_cfg.cfg.remora.fxs_pulsedialing != WANOPT_YES){ + wp_tdmv_remora_check_hook(fe, x); + } +#else #ifndef PULSE_DIALING wp_tdmv_remora_check_hook(fe, x); +#endif #endif if (!(wr->intcount & 0xf0)){ if (fe->rm_param.mod[x].type == MOD_TYPE_FXS) { @@ -1670,25 +1696,29 @@ static void wp_tdmv_remora_dtmf (void* card_id, wan_event_t *event) wr = wan_tdmv->sc; if (event->type == WAN_EVENT_EC_DTMF){ - DEBUG_EVENT("%s: Received DTMF Event at TDM RM (%d:%c:%s:%s)!\n", + DEBUG_TDMV( + "[TDMV_RM]: %s: Received EC DTMF Event at TDM (%d:%c:%s:%s)!\n", card->devname, event->channel, event->digit, (event->dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", (event->dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP"); }else if (event->type == WAN_EVENT_RM_DTMF){ - DEBUG_EVENT("%s: Received DTMF Event at TDM RM (%d:%c)!\n", + DEBUG_TDMV( + "[TDMV_RM]: %s: Received RM DTMF Event at TDM (%d:%c)!\n", card->devname, event->channel, event->digit); } if (!(wr->dtmfmask & (1 << (event->channel-1)))){ - DEBUG_TDMV("%s: DTMF is not enabled for the channel %d\n", + DEBUG_TDMV( + "[TDMV] %s: DTMF is not enabled for the channel %d\n", card->devname, event->channel); return; } + if (event->dtmf_type == WAN_EC_TONE_PRESENT){ wr->dtmfactive |= (1 << event->channel); zt_qevent_lock( diff --git a/patches/kdrivers/src/net/sdla_sdlc.c b/patches/kdrivers/src/net/sdla_sdlc.c index df8dbe1..f7b7f89 100644 --- a/patches/kdrivers/src/net/sdla_sdlc.c +++ b/patches/kdrivers/src/net/sdla_sdlc.c @@ -250,7 +250,7 @@ int wp_sdlc_init (sdla_t* card, wandev_conf_t* conf) card->wandev.set_if_info = &chdlc_set_if_info; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; port_num = card->u.sdlc.comm_port; @@ -345,13 +345,13 @@ int wp_sdlc_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t* dev; volatile sdlc_private_area_t* sdlc_priv_area; unsigned long timeout; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -410,7 +410,7 @@ static int update (wan_device_t* wandev) static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; sdlc_private_area_t* sdlc_priv_area; int err = 0; @@ -518,6 +518,8 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) * since in some cases (mrouted) daemons continue * to call ioctl() after the device has gone down */ dev->do_ioctl = NULL; + dev->hard_header = NULL; + dev->rebuild_header = NULL; sdlc_set_intr_mode(card, 0); if (card->u.sdlc.comm_enabled){ @@ -1646,7 +1648,7 @@ static int set_sdlc_config(sdla_t* card) cfg.general_operational_config_bits=card->wandev.sdlc_cfg.general_operational_config_bits; - if (card->wandev.interface != WANOPT_RS232){ + if (card->wandev.electrical_interface != WANOPT_RS232){ cfg.general_operational_config_bits |= INTERFACE_LEVEL_V35; } @@ -2257,7 +2259,7 @@ static int chdlc_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_serial.c b/patches/kdrivers/src/net/sdla_serial.c new file mode 100644 index 0000000..d5acfd0 --- /dev/null +++ b/patches/kdrivers/src/net/sdla_serial.c @@ -0,0 +1,1016 @@ +/*************************************************************************** + * sdla_serial.c WANPIPE(tm) + * Serial A140 support module for A140 Serial FE. + * + * Author(s): Nenad Corbic + * + * Copyright: (c) 2007 Sangoma Technologies Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * ============================================================================ + * Nov 1, 2007 Nenad Corbic Initial version. + ****************************************************************************** + */ + +/******************************************************************************* +** INCLUDE FILES +*******************************************************************************/ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include /* for 'wanpipe_common_t' used in 'sdla_aft_te1.h'*/ +# include /* for 'private_area_t' */ +#elif (defined __WINDOWS__) +# include +# include +# include +# include +# include +# include +# include +# include +# include /* for 'wanpipe_common_t' used in 'sdla_aft_te1.h'*/ +# include /* for 'private_area_t' */ +#else +# include +# include +# include +# include +# include +# include +# include +# include +# include /* for 'wanpipe_common_t' used in 'sdla_aft_te1.h'*/ +# include /* for 'private_area_t' */ +#endif + +#undef DEBUG_SERIAL +#define DEBUG_SERIAL if(0)DEBUG_EVENT + +/* DEBUG macro definitions */ +#define DEBUG_HFC_INIT if(0)DEBUG_EVENT +#define DEBUG_HFC_MODE if(0)DEBUG_EVENT +#define DEBUG_HFC_S0_STATES if(0)DEBUG_EVENT +#define DEBUG_HFC_IRQ if(0)DEBUG_EVENT +#define DEBUG_HFC_SU_IRQ if(0)DEBUG_EVENT + +#define DEBUG_HFC_TX if(0)DEBUG_EVENT +#define DEBUG_TX_DATA if(0)DEBUG_EVENT +#define TX_EXTRA_DBG if(0)DEBUG_EVENT +#define TX_FAST_DBG if(0)DEBUG_EVENT + +#define DEBUG_HFC_RX if(0)DEBUG_EVENT +#define RX_EXTRA_DBG if(0)DEBUG_EVENT +#define DEBUG_RX1 if(0)DEBUG_EVENT +#define DBG_RX_DATA if(0)DEBUG_EVENT + +#define DEBUG_HFC_CLOCK if(0)DEBUG_EVENT + +#define BUILD_MOD_TESTER 0 /* for Production Test */ +#define DBG_MODULE_TESTER if(0)DEBUG_EVENT + +#define NT_STATE_FUNC() if(0)DEBUG_EVENT("%s(): line: %d\n", __FUNCTION__, __LINE__) +#define CLOCK_FUNC() if(0)DEBUG_EVENT("%s(): line: %d\n", __FUNCTION__, __LINE__) + +#define DBG_SPI if(0)DEBUG_EVENT + +#define DEBUG_FE_STATUS if(0)DEBUG_EVENT + +#define SERIAL_FUNC() if(1)DEBUG_EVENT("%s(): line: %d\n", __FUNCTION__, __LINE__) + +/* Timer interrupt counter - used by activation timer T3 */ +#define HFC_TIMER_COUNTER_T3 2 + +#undef NT_T1_COUNT + +#define FIFO_THRESHOLD_INDEX 1 + +#define LINE_STABILITY_THRESHOLD 3 + +enum { + WAITING_TO_STABILIZE=1, + LINE_STABLE, + LINE_DISCONNECTED +}; + +#define CHECK_DATA 0 + + +int aft_serial_write_cpld(void *card, unsigned short off,u_int16_t data); +unsigned char aft_serial_read_cpld(void *card, unsigned short cpld_off); + +/******************************************************************************* +** DEFINES AND MACROS +*******************************************************************************/ +#define REPORT_MOD_NO (mod_no+1) + +static u8 validate_fe_line_no(sdla_fe_t *fe, const char *caller_name) +{ + if ((int32_t)WAN_FE_LINENO(fe) < 0 || WAN_FE_LINENO(fe) > MAX_SERIAL_LINES){ + DEBUG_EVENT("%s(): %s: SERIAL: Invalid FE line number %d (Min=1 Max=%d)\n", + caller_name, fe->name, WAN_FE_LINENO(fe)+1, MAX_SERIAL_LINES); + return 1; + } + return 0; +} + +#define FE_LINENO_TO_MODULENO_AND_PORTNO(fe) \ +{ \ + mod_no = fe_line_no_to_physical_mod_no(fe); \ + port = fe_line_no_to_port_no(fe); \ +} + +#if 0 +/* wait for "milliseconds * 1/1000" of sec */ +static void WP_MDELAY(u32 milliseconds) +{ + for (; milliseconds > 0; --milliseconds){ + WP_DELAY(1000); + } +} +#endif + +/*******************************************************************************/ +/* Register Write/Read debugging funcitons */ + +/* Enabling/Disabling register debugging */ +#define WAN_DEBUG_SERIAL_REG 0 + +#if WAN_DEBUG_SERIAL_REG + +#define HFC_WRITE 1 +#define HFC_READ 2 + +#endif /* WAN_DEBUG_SERIAL_REG */ +/*******************************************************************************/ + +/*******************************************************************************/ + +/******************************************************************************* +** STRUCTURES AND TYPEDEFS +*******************************************************************************/ + +/******************************************************************************* +** GLOBAL VARIABLES +*******************************************************************************/ +#if !defined(__WINDOWS__) +extern WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head; +#endif + +/******************************************************************************* +** FUNCTION PROTOTYPES +*******************************************************************************/ +static int32_t serial_global_config(void* pfe); +static int32_t serial_global_unconfig(void* pfe); +static int32_t wp_serial_config(void *pfe); +static int32_t wp_serial_unconfig(void *pfe); +static int32_t wp_serial_post_init(void *pfe); +static int32_t wp_serial_if_config(void *pfe, u32 mod_map, u8); +static int32_t wp_serial_if_unconfig(void *pfe, u32 mod_map, u8); +//static int32_t wp_serial_disable_irq(sdla_fe_t *fe, u32 mod_no, u8 port); +//static void serial_enable_interrupts(sdla_fe_t *fe, u32 mod_no, u8 port); +static int32_t wp_serial_intr(sdla_fe_t *); +static int32_t wp_serial_check_intr(sdla_fe_t *); +static int32_t wp_serial_polling(sdla_fe_t*); +static int32_t wp_serial_udp(sdla_fe_t*, void*, u8*); +static u32 wp_serial_active_map(sdla_fe_t* fe, u8 line_no); +static u8 wp_serial_fe_media(sdla_fe_t *fe); +static int32_t wp_serial_set_dtmf(sdla_fe_t*, int32_t, u8); +static int wp_serial_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t, u_int8_t mode, unsigned int ts_map); +static int32_t wp_serial_event_ctrl(sdla_fe_t*, wan_event_ctrl_t*); + +static int wp_serial_get_fe_status(sdla_fe_t *fe, unsigned char *status); +static int wp_serial_set_fe_status(sdla_fe_t *fe, unsigned char status); + +#if 0 +static void wp_serial_enable_timer(sdla_fe_t* fe, u8 mod_no, u8 cmd, u32 delay); + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +static void wp_serial_timer(void*); +#elif defined(__WINDOWS__) +static void wp_serial_timer(IN PKDPC,void*,void*,void*); +#else +static void wp_serial_timer(void*); +#endif +#endif /* if 0 */ + +#if defined(AFT_TDM_API_SUPPORT) +static int32_t wp_serial_watchdog(sdla_fe_t *fe); +#endif + + +/* for selecting PCM direction */ +#define XHFC_DIRECTION_TX 0 +#define XHFC_DIRECTION_RX 1 + +#if 0 +static void xhfc_select_xhfc_channel(sdla_fe_t *fe, u32 mod_no, + u8 channel, u8 direction, u8 vrout_bitmap); +#endif + +//static int32_t check_f0cl_increment(sdla_fe_t *fe, u8 old_f0cl, u8 new_f0cl, int32_t *diff); + +/******************************************************************************* +** FUNCTION DEFINITIONS +*******************************************************************************/ + + +/*******************************************************************************/ + + + + +/****************************************************************************** +** wp_serial_iface_init) - +** +** OK +*/ +int32_t wp_serial_iface_init(void *pfe_iface) +{ + sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)pfe_iface; + + SERIAL_FUNC(); + fe_iface->global_config = &serial_global_config; /* not used in remora */ + fe_iface->global_unconfig = &serial_global_unconfig; /* not used in remora */ + + fe_iface->config = &wp_serial_config; + fe_iface->unconfig = &wp_serial_unconfig; + + fe_iface->post_init = &wp_serial_post_init; + + fe_iface->if_config = &wp_serial_if_config; + fe_iface->if_unconfig = &wp_serial_if_unconfig; + + fe_iface->active_map = &wp_serial_active_map; + + fe_iface->set_fe_status = &wp_serial_set_fe_status; + fe_iface->get_fe_status = &wp_serial_get_fe_status; + + fe_iface->isr = &wp_serial_intr; +// fe_iface->disable_irq = &wp_serial_disable_irq; + fe_iface->check_isr = &wp_serial_check_intr; + + fe_iface->polling = &wp_serial_polling; + fe_iface->process_udp = &wp_serial_udp; + fe_iface->get_fe_media = &wp_serial_fe_media; + + fe_iface->set_dtmf = &wp_serial_set_dtmf; + fe_iface->intr_ctrl = &wp_serial_intr_ctrl; + fe_iface->event_ctrl = &wp_serial_event_ctrl; + + +#if defined(AFT_TDM_API_SUPPORT) + fe_iface->watchdog = &wp_serial_watchdog; +#endif + + return 0; +} + +#if defined(NOTUSED) +/* Should be done only ONCE per card. */ +static int32_t wp_serial_spi_bus_reset(sdla_fe_t *fe) +{ + sdla_t *card = (sdla_t*)fe->card; + + SERIAL_FUNC(); + + DEBUG_EVENT("%s: Executing SPI bus reset....\n", fe->name); + + card->hw_iface.bus_write_4( card->hw, + SPI_INTERFACE_REG, + MOD_SPI_RESET); + WP_DELAY(1000); + card->hw_iface.bus_write_4( card->hw, + SPI_INTERFACE_REG, + 0x00000000); + WP_DELAY(1000); + return 0; +} +#endif + +/****************************************************************************** +* serial_global_config() +* +* Description : Global configuration for Sangoma SERIAL board. +* +* Notes : 1. This routine runs only ONCE for a physical 'base' CARD, +* not for 'additional' cards. +* 2. reset card's SPI. +* 3. Scan for installed Remoras and modules. +* +* Arguments : pfe - pointer to Front End structure. +* +* Returns : 0 - configred successfully, otherwise non-zero value. +*******************************************************************************/ +static int32_t serial_global_config(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + SERIAL_FUNC(); + + DEBUG_EVENT("%s: %s Global Front End configuration\n", + fe->name, FE_MEDIA_DECODE(fe)); + + return 0; +} + +/******************************************************************************* +* serial_global_unconfig() +* +* Description : Global un-configuration for Sangoma SERIAL board. +* Note: This routne runs only ONCE for a physical card. +* +* Arguments : +* +* Returns : 0 +*******************************************************************************/ +static int32_t serial_global_unconfig(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + sdla_t *card = (sdla_t*)fe->card; + + SERIAL_FUNC(); + aft_serial_write_cpld(card,0x08,0x00); + aft_serial_write_cpld(card,0x09,0x00); + + DEBUG_EVENT("%s: %s Global Front End unconfiguration!\n", + fe->name, FE_MEDIA_DECODE(fe)); + + return 0; +} + +/****************************************************************************** +* wp_serial_config() - initialise the XHFC ISDN Chip. +* +* Description : Configure the PHYSICAL module ONE time. +* On each module 2 lines will be configured +* in exactly the same way. +* +* Arguments : pfe - pointer to Front End structure. +* +* Returns : 0 - configred successfully, otherwise non-zero value. +*******************************************************************************/ +static int32_t wp_serial_config(void *pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + sdla_t *card = (sdla_t*)fe->card; + u32 reg; + u8 cpld_reg_val; + unsigned short cpld_reg=0; + + SERIAL_FUNC(); + + DEBUG_EVENT("%s: %s: Line %d Front End configuration\n", + fe->name, FE_MEDIA_DECODE(fe), WAN_FE_LINENO(fe) + 1); + + if(validate_fe_line_no(fe, __FUNCTION__)){ + return 1; + } + + + switch (card->wandev.line_coding){ + case WANOPT_NRZ: + case WANOPT_NRZI: + break; + default: + DEBUG_EVENT("%s: A140: Error: Unsupported line coding mode 0x%X\n", + card->devname, + card->wandev.line_coding); + return -1; + } + + switch (card->adptr_type) { + + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + DEBUG_EVENT("%s: A140: Configuring for V35\n", + card->devname); + + switch(WAN_FE_LINENO(fe)) { + + case 0: + case 2: + cpld_reg=0x08; + break; + case 1: + case 3: + cpld_reg=0x09; + break; + default: + DEBUG_EVENT("%s: Error: Invalid Serial Port Number! (%i) \n", + card->devname,WAN_FE_LINENO(fe)); + return -EINVAL; + }; + + cpld_reg_val=aft_serial_read_cpld(card,cpld_reg); + + if(card->wandev.clocking) { + +/*FIXME: Must check for case where first port started in external mode + At this time, if port 1 start in normal & prot 3 in master, the + port 1 will silently be reconfigured to Master after port 3 starts */ + + aft_serial_write_cpld(card,cpld_reg,0x05); + } else { + if (wan_test_bit(2,&cpld_reg_val)) { + DEBUG_EVENT("%s: Error: Clocking configuration mismatch!\n", + card->devname); + DEBUG_EVENT("%s: Ports 1&3 and 2&4 must use same clock source!\n", + card->devname); + return -EINVAL; + } + + aft_serial_write_cpld(card,cpld_reg,0x01); + } + break; + + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + + DEBUG_EVENT("%s: A140: Configuring for RS232\n", + card->devname); + + if (WAN_FE_LINENO(fe) < 2) { + cpld_reg=0x08; + } else { + cpld_reg=0x09; + } + + cpld_reg_val=aft_serial_read_cpld(card,cpld_reg); + if(card->wandev.clocking) { + wan_set_bit((WAN_FE_LINENO(fe)%2), &cpld_reg_val); + } else { + wan_clear_bit((WAN_FE_LINENO(fe)%2), &cpld_reg_val); + } + aft_serial_write_cpld(card,cpld_reg,cpld_reg_val); + + break; + + default: + DEBUG_EVENT("%s: Error: Invalid Serial Card Type 0x%X\n", + card->devname,card->adptr_type); + return -1; + } + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),®); + + DEBUG_EVENT("%s: A140: Configurfed for 0x%08X\n", + card->devname, + reg); + + + if (card->wandev.clocking) { + DEBUG_EVENT("%s: A140: Configuring for Internal Clocking: Baud=%i\n", + card->devname, + card->wandev.bps); + wan_set_bit(AFT_SERIAL_LCFG_CLK_SRC_BIT, ®); + aft_serial_set_baud_rate(®,card->wandev.bps); + } else { + DEBUG_EVENT("%s: A140: Configuring for External Clocking: Baud=%i\n", + card->devname, + card->wandev.bps); + wan_clear_bit(AFT_SERIAL_LCFG_CLK_SRC_BIT, ®); + } + + switch (card->wandev.line_coding){ + case WANOPT_NRZ: + DEBUG_EVENT("%s: A140: Configuring for NRZ\n", + card->devname); + aft_serial_set_lcoding(®,WANOPT_NRZ); + break; + case WANOPT_NRZI: + DEBUG_EVENT("%s: A140: Configuring for NRZI\n", + card->devname); + aft_serial_set_lcoding(®,WANOPT_NRZI); + break; + default: + /* Should never happen because we check above */ + DEBUG_EVENT("%s: A140: Error: Unsupported line coding mode 0x%X\n", + card->devname, + card->wandev.line_coding); + return -1; + } + + if (card->wandev.connection == WANOPT_SWITCHED){ + DEBUG_EVENT("%s: A140: Configuring for Switched CTS/RTS\n",card->devname); + wan_set_bit(AFT_SERIAL_LCFG_SWMODE_BIT, ®); + wan_set_bit(AFT_SERIAL_LCFG_IDLE_DET_BIT,®); + } else { + wan_clear_bit(AFT_SERIAL_LCFG_SWMODE_BIT, ®); + wan_clear_bit(AFT_SERIAL_LCFG_IDLE_DET_BIT,®); + } + + + /* Hardcode to sync device type */ + wan_clear_bit(AFT_SERIAL_LCFG_IFACE_TYPE_BIT,®); + + /* CTS/DCD Interrupt Enable */ + wan_set_bit(AFT_SERIAL_LCFG_CTS_INTR_EN_BIT,®); + wan_set_bit(AFT_SERIAL_LCFG_DCD_INTR_EN_BIT,®); + + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),reg); + + DEBUG_EVENT("%s: A140: Configurfed for 0x%08X\n", + card->devname, + reg); + + /* Raise RTS and DTR */ + wan_set_bit(AFT_SERIAL_LCFG_RTS_BIT,®); + wan_set_bit(AFT_SERIAL_LCFG_DTR_BIT,®); + + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),reg); + + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),®); + + DEBUG_EVENT("%s: A140: Configurfed for 0x%08X\n", + card->devname, + reg); + + return 0; +} + +/****************************************************************************** +** wp_serial_unconfig() - +** +** OK +*/ +static int32_t wp_serial_unconfig(void *pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + sdla_t *card = (sdla_t*)fe->card; + u32 reg=0; + unsigned short cpld_reg; + unsigned char cpld_reg_val; + + SERIAL_FUNC(); + + if(validate_fe_line_no(fe, __FUNCTION__)){ + return 1; + } + + switch (card->adptr_type) { + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + + if (WAN_FE_LINENO(fe) < 2) { + cpld_reg=0x08; + } else { + cpld_reg=0x09; + } + + cpld_reg_val=aft_serial_read_cpld(card,cpld_reg); + wan_clear_bit((WAN_FE_LINENO(fe)%2), &cpld_reg_val); + aft_serial_write_cpld(card,cpld_reg,cpld_reg_val); + break; + } + + card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),reg); + + return 0; +} + +/****************************************************************************** +** wp_serial_post_init() - +** +** OK +*/ +static int32_t wp_serial_post_init(void *pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + SERIAL_FUNC(); + + DEBUG_EVENT("%s: Running post initialization...\n", fe->name); + /* return sdla_rm_add_timer(fe, HZ); */ + return 0; +} + + +/****************************************************************************** +** wp_serial_if_config() - +** +** OK +*/ +static int32_t wp_serial_if_config(void *pfe, u32 mod_map, u8 usedby) +{ + SERIAL_FUNC(); + return 0; +} + + +/****************************************************************************** +** wp_serial_if_unconfig() - +** +** OK +*/ +static int32_t wp_serial_if_unconfig(void *pfe, u32 mod_map, u8 usedby) +{ + SERIAL_FUNC(); + return 0; +} + + + +#if defined(NOTUSED) +/******************************************************************************* +* serial_enable_interrupts() +* +* Description: Enable SERIAL interrupts - start interrupt and set interrupt mask. +* +* Arguments: +* +* Returns: +*******************************************************************************/ +static void serial_enable_interrupts(sdla_fe_t *fe, u32 mod_no, u8 port) +{ + + + SERIAL_FUNC(); + +} +#endif + +#if defined(NOTUSED) +/****************************************************************************** +** wp_serial_disable_irq() - disable all interrupts by disabling M_GLOB_IRQ_EN +** +** OK +*/ +static int32_t wp_serial_disable_irq(sdla_fe_t *fe, u32 mod_no, u8 port) +{ + + return 0; +} +#endif + +static u32 wp_serial_active_map(sdla_fe_t* fe, u8 line_no) +{ + SERIAL_FUNC(); + + return 0x01; +} + +/****************************************************************************** +* wp_serial_fe_status() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +static u8 wp_serial_fe_media(sdla_fe_t *fe) +{ + SERIAL_FUNC(); + return fe->fe_cfg.media; +} + +/****************************************************************************** +* wp_serial_set_dtmf() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +static int32_t wp_serial_set_dtmf(sdla_fe_t *fe, int32_t mod_no, u8 val) +{ + SERIAL_FUNC(); + + return -EINVAL; +} + +#if 0 + +/******************************************************************************* +* sdla_serial_timer() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +static void wp_serial_timer(void* pfe) +#elif defined(__WINDOWS__) +static void wp_serial_timer(IN PKDPC Dpc, void* pfe, void* arg2, void* arg3) +#else +static void wp_serial_timer(void *pfe) +#endif +{ + SERIAL_FUNC(); + return; +} + +/******************************************************************************* +* wp_serial_enable_timer() +* +* Description: Enable software timer interrupt in delay ms. +* Arguments: +* Returns: +*******************************************************************************/ +static void wp_serial_enable_timer(sdla_fe_t* fe, u8 mod_no, u8 cmd, u32 delay) +{ + SERIAL_FUNC(); + return; +} + +static int32_t wp_serial_regdump(sdla_fe_t* fe, u8 *data) +{ + SERIAL_FUNC(); + return 0; +} + +#endif /* if 0*/ + +static int32_t wp_serial_polling(sdla_fe_t* fe) +{ + SERIAL_FUNC(); + return 0; +} + +/******************************************************************************* +* wp_serial_udp() +* +* Description: +* Arguments: +* Returns: +*******************************************************************************/ +static int32_t wp_serial_udp(sdla_fe_t *fe, void* p_udp_cmd, u8* data) +{ + int32_t err = -EINVAL; + + SERIAL_FUNC(); +#if 0 + wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd; + + switch(udp_cmd->wan_cmd_command){ + case WAN_FE_REGDUMP: + err = wp_serial_regdump(fe, data); + if (err){ + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + udp_cmd->wan_cmd_data_len = (u16)err; + } + break; + + default: + udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; + udp_cmd->wan_cmd_data_len = 0; + break; + } +#endif + return err; +} + +/****************************************************************************** +* wp_serial_get_fe_status() +* +* Description : Get current FE line state - is it Connected or Disconnected +* +* Arguments : fe - pointer to Front End structure. +* status - pointer to location where the FE line state will +* be stored. +* +* Returns : always zero. +*******************************************************************************/ +static int wp_serial_get_fe_status(sdla_fe_t *fe, unsigned char *status) +{ + *status = fe->fe_status; + return 0; +} + +/****************************************************************************** +* wp_serial_set_fe_status() +* +* Description : Set FE line state to Connected or Disconnected. +* In SERIAL this means Activate or Deactivate the line. +* +* Arguments : fe - pointer to Front End structure. +* new_status - the new FE line state. +* +* Returns : 0 - success. +* 1 - failure. +*******************************************************************************/ +static int wp_serial_set_fe_status(sdla_fe_t *fe, unsigned char new_status) +{ + int rc=0; + SERIAL_FUNC(); + return rc; +} + + + +/****************************************************************************** +* wp_serial_event_ctrl() +* +* Description: Enable/Disable event types +* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) +* Returns: +******************************************************************************/ +static int32_t +wp_serial_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl) +{ + int32_t err = 0; + + SERIAL_FUNC(); + + WAN_ASSERT(ectrl == NULL); + + return err; +} + +#if defined(AFT_TDM_API_SUPPORT) +/****************************************************************************** +* wp_serial_watchdog() +* +* Description: +* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) +* Returns: +******************************************************************************/ +static int32_t wp_serial_watchdog(sdla_fe_t *fe) +{ + int32_t mod_no; + + SERIAL_FUNC(); + + return 0; +} +#endif + +/****************************************************************************** +* wp_serial_intr_ctrl() +* +* Description: Enable/Disable extra interrupt types +* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES) +* Returns: +******************************************************************************/ +static int wp_serial_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t type, u_int8_t mode, unsigned int ts_map) +{ + + SERIAL_FUNC(); + + return 0; + +} + +#if defined(NOTUSED) +/****************************************************************************** +* sdla_serial_set_status() +* +* Description: handle interrupt on a physical module +* Arguments: fe, mod_no +* Returns: 1 - interrupt recognized and handled +* 0 - interrupt not recognized (not generated by this module) +******************************************************************************/ +static void sdla_serial_set_status(sdla_fe_t* fe, u8 mod_no, u8 port_no, u8 status) +{ + sdla_t *card = (sdla_t*)fe->card; + u8 old_fe_status = fe->fe_status; + + + SERIAL_FUNC(); + + +#if 0 + if(old_fe_status == status){ + return; + } +#endif + + fe->fe_status = status; + + if (old_fe_status != fe->fe_status){ + if (fe->fe_status == FE_CONNECTED){ + DEBUG_EVENT("%s: %s Module: %d connected!\n", + fe->name, + FE_MEDIA_DECODE(fe), REPORT_MOD_NO + port_no); + + if (card->wandev.te_report_alarms){ + card->wandev.te_report_alarms(card, 0); + } + + }else{ + DEBUG_EVENT("%s: %s Module: %d disconnected!\n", + fe->name, + FE_MEDIA_DECODE(fe), REPORT_MOD_NO + port_no); + if (card->wandev.te_report_alarms){ + card->wandev.te_report_alarms(card, 1); + } + } + } + + return; +} +#endif + + +static int32_t wp_serial_check_intr(sdla_fe_t *fe) +{ + /* must return 1! */ + return 1; +} + +static int32_t wp_serial_intr(sdla_fe_t *fe) +{ + sdla_t *card = (sdla_t*)fe->card; + u32 reg; + + SERIAL_FUNC(); + card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),®); + DEBUG_EVENT("%s: DCD/CTS VALUES = 0x%02X\n",card->devname,(reg>>2)&0x03); + + return 0; +} + +/*************************************************************************** + Front End T1/E1 interface for Normal cards +***************************************************************************/ +int aft_serial_write_fe(void* phw, ...) +{ + va_list args; + u16 qaccess, off, line_no; + u8 value; +// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; + + va_start(args, phw); + qaccess = (u16)va_arg(args, int); + line_no = (u16)va_arg(args, int); + off = (u16)va_arg(args, int); + value = (u8)va_arg(args, int); + va_end(args); + + SERIAL_FUNC(); + + return 0; +} + + +/*============================================================================ + * Read TE1/56K Front end registers + */ + + +u32 aft_serial_read_fe (void* phw, ...) +{ + va_list args; + u_int16_t qaccess, line_no, off; + u_int8_t tmp=0; +// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; + + va_start(args, phw); + qaccess = (u_int16_t)va_arg(args, int); + line_no = (u_int16_t)va_arg(args, int); + off = (u_int8_t)va_arg(args, int); + va_end(args); + + SERIAL_FUNC(); + + return tmp; +} + +int aft_serial_write_cpld(void *pcard, unsigned short off,u_int16_t data) +{ + int err = -EINVAL; + sdla_t *card = (sdla_t*)pcard; + + if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + + if (card->hw_iface.write_cpld){ + err = card->hw_iface.write_cpld(card->hw, (u16)off, (u8)data); + } + + card->hw_iface.fe_clear_bit(card->hw,0); + return 0; +} + +unsigned char aft_serial_read_cpld(void *pcard, unsigned short cpld_off) +{ + u8 tmp=0; + int err = -EINVAL; + sdla_t *card = (sdla_t*)pcard; + + if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){ + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + card->devname, __FUNCTION__,__LINE__); + return 0x00; + } + + if (card->hw_iface.read_cpld){ + err = card->hw_iface.read_cpld(card->hw, (u16)cpld_off, &tmp); + } + + card->hw_iface.fe_clear_bit(card->hw,0); + return tmp; +} diff --git a/patches/kdrivers/src/net/sdla_tdmv.c b/patches/kdrivers/src/net/sdla_tdmv.c index c4d1950..96e318d 100644 --- a/patches/kdrivers/src/net/sdla_tdmv.c +++ b/patches/kdrivers/src/net/sdla_tdmv.c @@ -31,6 +31,7 @@ # include # include # include +# include # include /* WANPIPE TDM Voice definitions */ # include #elif (defined __WINDOWS__) @@ -40,6 +41,7 @@ # include # include # include +# include # include /* WANPIPE TDM Voice definitions */ #endif @@ -87,8 +89,6 @@ # if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) # undef ZT_DCHAN_TX # endif -#else -#warning "TDM VOICE DCHAN DISABLED" #endif #if defined(__FreeBSD__) @@ -142,8 +142,8 @@ typedef struct wp_tdmv_pvt_area { sdla_t* card; char* devname; - wan_spinlock_t lock; - wan_spinlock_t tx_rx_lock; + wan_spinlock_t lockirq; + wan_spinlock_t tx_rx_lockirq; int ise1; int num; int spanno; @@ -192,6 +192,11 @@ typedef struct wp_tdmv_pvt_area unsigned int dchan_map; netdevice_t *dchan_dev; + u_int8_t dtmfsupport; + unsigned int dtmfactive; + unsigned int dtmfmask; + unsigned int dtmfmutemask; + } wp_tdmv_softc_t; @@ -235,7 +240,6 @@ static int wp_tdmv_hwec(struct zt_chan *chan, int enable); #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan); #endif - static int wp_tdmv_state(void* pcard, int state); static int wp_tdmv_running(void* pcard); @@ -271,6 +275,8 @@ static inline void stop_alarm(wp_tdmv_softc_t* wp); static int wp_tdmv_init(void* pcard, wanif_conf_t *conf); +static void wp_tdmv_callback_dtmf (void*, wan_event_t*); + /****************************************************************************** ** wp_tdmv_te1_init() - ** @@ -368,8 +374,8 @@ static int wp_tdmv_create(void* pcard, wan_tdmv_conf_t *tdmv_conf) wp->ise1 = IS_E1_FEMEDIA(&card->fe) ? 1 : 0; wp->max_timeslots = IS_E1_FEMEDIA(&card->fe) ? 31: 24; wp->max_rxtx_len = 0; - wan_spin_lock_init(&wp->lock); - wan_spin_lock_init(&wp->tx_rx_lock); + wan_spin_lock_irq_init(&wp->lockirq, "wan_te1tdmv_lock"); + wan_spin_lock_irq_init(&wp->tx_rx_lockirq, "wan_te1tdmv_txrx_lock"); /* AHDLC */ if (tdmv_conf->dchan){ /* PRI signalling is selected with hw HDLC (dchan is not 0) */ @@ -575,10 +581,10 @@ static int wp_tdmv_remove(void* pcard) return -EINVAL; } - wan_spin_lock_irq(&wp->lock, &flags); + wan_spin_lock_irq(&wp->lockirq, &flags); card->wandev.te_report_rbsbits = NULL; card->wandev.te_report_alarms = NULL; - wan_spin_unlock_irq(&wp->lock, &flags); + wan_spin_unlock_irq(&wp->lockirq, &flags); if (wp){ wan_clear_bit(WP_TDMV_RUNNING, &wp->flags); @@ -716,6 +722,7 @@ static void wp_tdmv_report_rbsbits(void* pcard, int channel, unsigned char statu if (!(wp->chans[i].sig & ZT_SIG_CLEAR) && (wp->chans[i].rxsig != rxs)){ zt_rbsbits(&wp->chans[i], rxs); +#if 1 DEBUG_TDMV( "[TDMV] %s: %s:%02d(%d) RX RBS: A:%1d B:%1d C:%1d D:%1d\n", wp->devname, @@ -725,6 +732,7 @@ static void wp_tdmv_report_rbsbits(void* pcard, int channel, unsigned char statu (rxs & ZT_BBIT) ? 1 : 0, (rxs & ZT_CBIT) ? 1 : 0, (rxs & ZT_DBIT) ? 1 : 0); +#endif } } @@ -811,13 +819,13 @@ static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm) if (wp->ise1) { if (te_alarm & WAN_TE_BIT_RED_ALARM) alarms |= ZT_ALARM_RED; - if (te_alarm & WAN_TE_BIT_OOF_ALARM) + if (te_alarm & WAN_TE_BIT_OOF_ALARM) alarms |= ZT_ALARM_RED; } else { /* Check actual alarm status */ if (te_alarm & WAN_TE_BIT_RED_ALARM) alarms |= ZT_ALARM_RED; - if (te_alarm & WAN_TE_BIT_OOF_ALARM) + if (te_alarm & WAN_TE_BIT_OOF_ALARM) alarms |= ZT_ALARM_RED; } /* Keep track of recovering */ @@ -848,7 +856,6 @@ static void wp_tdmv_report_alarms(void* pcard, unsigned long te_alarm) wp->span.alarms = alarms; zt_alarm_notify(&wp->span); - return; } @@ -1130,7 +1137,11 @@ static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv) wp->spanno + 1); DEBUG_EVENT(" Possible cause: Another TDM driver already loaded!\n"); DEBUG_EVENT(" Solution: Unload wanpipe and check currently\n"); +#if defined(__LINUX__) DEBUG_EVENT(" used spans in /proc/zaptel directory.\n"); +#else + DEBUG_EVENT(" used spans.\n"); +#endif DEBUG_EVENT(" Reconfiguring device %s to new span number # %d\n", wp->devname,wp->span.spanno); DEBUG_EVENT("\n"); @@ -1161,6 +1172,14 @@ static int wp_tdmv_software_init(wan_tdmv_t *wan_tdmv) card->tdmv_iface.is_rbsbits = wp_tdmv_is_rbsbits; card->tdmv_iface.rbsbits_poll = wp_tdmv_rbsbits_poll; } + + wp->dtmfsupport = card->u.aft.tdmv_hw_dtmf; + /* Initialize Callback event function pointers */ + if (wp->dtmfsupport == WANOPT_YES){ + DEBUG_EVENT("%s: Enable HW DTMF detection!\n", wp->devname); + card->wandev.event_callback.dtmf = wp_tdmv_callback_dtmf; + } + return 0; } @@ -1210,9 +1229,9 @@ static int wp_tdmv_shutdown(struct zt_span *span) WAN_ASSERT2(span->pvt == NULL, -ENODEV); wp = span->pvt; wan_clear_bit(WP_TDMV_RUNNING, &wp->flags); - wan_spin_lock_irq(&wp->lock, &flags); + wan_spin_lock_irq(&wp->lockirq, &flags); span->flags &= ~ZT_FLAG_RUNNING; - wan_spin_unlock_irq(&wp->lock, &flags); + wan_spin_unlock_irq(&wp->lockirq, &flags); return 0; } @@ -1231,7 +1250,7 @@ static int wp_tdmv_maint(struct zt_span *span, int cmd) WAN_ASSERT2(span == NULL, -ENODEV); WAN_ASSERT2(span->pvt == NULL, -ENODEV); wp = span->pvt; - wan_spin_lock_irq(&wp->lock, &flags); + wan_spin_lock_irq(&wp->lockirq, &flags); if (wp->ise1) { #if 0 /* FIXME: Support E1 */ @@ -1328,7 +1347,7 @@ static int wp_tdmv_maint(struct zt_span *span, int cmd) res = -EINVAL; } } - wan_spin_unlock_irq(&wp->lock, &flags); + wan_spin_unlock_irq(&wp->lockirq, &flags); return res; } @@ -1549,9 +1568,8 @@ static int wp_tdmv_rbsbits(struct zt_chan *chan, int bits) if (bits & ZT_DBIT) ABCD_bits |= WAN_RBS_SIG_D; if (IS_CHAN_HARDHDLC(chan)){ - return 0; - } - + return 0; + } DEBUG_TDMV( "[TDMV] %s: %s:%02d(%d) TX RBS: A:%1d B:%1d C:%1d D:%1d\n", wp->devname, @@ -1787,25 +1805,68 @@ wp_tdmv_ioctl(struct zt_chan *chan, unsigned int cmd, caddr_t data) wp_tdmv_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) #endif { - int err = -ENOTTY; - wp_tdmv_softc_t *wp=NULL; + sdla_t *card = NULL; + wp_tdmv_softc_t *wp = NULL; + wan_event_ctrl_t *event_ctrl = NULL; + int err = -ENOTTY, x; #ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER - wp_tdmv_softc_t *echo_detect_wp = NULL; int echo_detect_chan = 0; #endif + WAN_ASSERT(chan == NULL || chan->pvt == NULL); wp = chan->pvt; - + WAN_ASSERT(wp->card == NULL); + card = wp->card; + switch(cmd) { + case ZT_TONEDETECT: + err = WAN_COPY_FROM_USER(&x, (int*)data, sizeof(int)); + if (err) return -EFAULT; + if (wp->dtmfsupport != WANOPT_YES || card->wandev.ec_dev == NULL){ + return -ENOSYS; + } + DEBUG_TDMV("[TDMV] %s: Hardware Tone Event detection (%s:%s)!\n", + wp->devname, + (x & ZT_TONEDETECT_ON) ? "ON" : "OFF", + (x & ZT_TONEDETECT_MUTE) ? "Mute ON" : "Mute OFF"); + + if (x & ZT_TONEDETECT_ON){ + wp->dtmfmask |= (1 << (chan->chanpos - 1)); + }else{ + wp->dtmfmask &= ~(1 << (chan->chanpos - 1)); + } + if (x & ZT_TONEDETECT_MUTE){ + wp->dtmfmutemask |= (1 << (chan->chanpos - 1)); + }else{ + wp->dtmfmutemask &= ~(1 << (chan->chanpos - 1)); + } + +#if defined(CONFIG_WANPIPE_HWEC) + event_ctrl = wan_malloc(sizeof(wan_event_ctrl_t)); + if (event_ctrl==NULL){ + DEBUG_EVENT( + "%s: Failed to allocate memory for event ctrl!\n", + wp->devname); + return -EFAULT; + } + event_ctrl->type = WAN_EVENT_EC_CHAN_MODIFY; + event_ctrl->channel = chan->chanpos-1; + event_ctrl->mode = (x & ZT_TONEDETECT_MUTE) ? WAN_EVENT_ENABLE : WAN_EVENT_DISABLE; + if (wanpipe_ec_event_ctrl(card->wandev.ec_dev, card, event_ctrl)){ + wan_free(event_ctrl); + } + err = 0; +#else + err = -EINVAL; +#endif + break; + #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(ZT_DCHAN_TX) case ZT_DCHAN_TX: - WAN_ASSERT(chan == NULL || chan->pvt == NULL); - wp = chan->pvt; - if (wp->dchan_dev && wp->dchan_dev->hard_start_xmit){ wp_tdmv_tx_dchan(chan, (int)data); err=0; @@ -1821,16 +1882,16 @@ wp_tdmv_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) WAN_ASSERT(chan == NULL || chan->pvt == NULL); - echo_detect_wp = chan->pvt; echo_detect_chan = chan->chanpos - 1; - DEBUG_ECHO("on span: %d, chanpos: %d\n", echo_detect_wp->spanno, - echo_detect_chan); + DEBUG_ECHO("on span: %d, chanpos: %d\n", + wp->spanno, + echo_detect_chan); if(echo_detect_chan > 30 || echo_detect_chan < 0){ err=-EOPNOTSUPP; }else{ - wan_tdmv_t *wan_tdmv = &echo_detect_wp->card->wan_tdmv; + wan_tdmv_t *wan_tdmv = &wp->card->wan_tdmv; wan_tdmv_rxtx_pwr_t *pwr_rxtx = &wan_tdmv->chan_pwr[echo_detect_chan]; DEBUG_ECHO("%s():using %s table.\n", __FUNCTION__, @@ -1880,29 +1941,30 @@ static int wp_tdmv_hwec(struct zt_chan *chan, int enable) WAN_ASSERT2(wp->card == NULL, -ENODEV); card = wp->card; + if (!wp->ise1){ + channel--; + } + if (enable) { wan_set_bit(channel,&card->wandev.rtp_tap_call_map); } else { wan_clear_bit(channel,&card->wandev.rtp_tap_call_map); } - - + if (card->wandev.ec_enable){ - DEBUG_TDMV("[TDMV]: %s: %s HW echo canceller on channel %d\n", + DEBUG_TDMV("[TDMV] %s: %s HW echo canceller on channel %d\n", wp->devname, (enable) ? "Enable" : "Disable", channel); - if (!wp->ise1){ - channel--; - } + /* The ec persist flag enables and disables * persistent echo control. In persist mode * echo cancellation is enabled regardless of * asterisk. In persist mode off asterisk - * controls hardware echo cancellation */ + * controls hardware echo cancellation */ if (card->hwec_conf.persist_disable || IS_CHAN_HARDHDLC(chan)) { - err = card->wandev.ec_enable(card, enable, channel); + err = card->wandev.ec_enable(card, enable, chan->chanpos); } else { err = 0; } @@ -2031,7 +2093,6 @@ static int wp_tdmv_rx_dchan(wan_tdmv_t *wan_tdmv, int channo, wp->devname); return -EINVAL; } - if (!IS_CHAN_HARDHDLC(ms)){ DEBUG_TDMV("%s: ERROR: %s not defined as D-CHAN!\n", wp->devname, ms->name); @@ -2093,18 +2154,15 @@ static int wp_tdmv_rx_dchan(wan_tdmv_t *wan_tdmv, int channo, wake_up_interruptible(&ms->eventbufq); #elif defined(__FreeBSD__) || defined(__OpenBSD__) wakeup(&ms->readbufq); - wakeup(&ms->sel); + _selwakeup(&ms->sel); if (ms->iomask & ZT_IOMUX_READ) wakeup(&ms->eventbufq); - #endif } return 0; } #endif - - #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL) static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan) { @@ -2150,7 +2208,6 @@ static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len) WAN_ASSERT2(chan->pvt == NULL, -ENODEV); wp = chan->pvt; WAN_ASSERT(wp->dchan_dev == NULL); - if (len <= 2){ return -EINVAL; @@ -2187,7 +2244,6 @@ static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len) #endif - /****************************************************************************** ** wp_tdmv_rx_chan() - ** @@ -2307,6 +2363,7 @@ static int wp_tdmv_rx_chan(wan_tdmv_t *wan_tdmv, int channo, return 0; } + static int wp_tdmv_span_buf_rotate(void *pcard, u32 buf_sz, unsigned long mask) { sdla_t *card = (sdla_t*)pcard; @@ -2353,7 +2410,6 @@ static int wp_tdmv_span_buf_rotate(void *pcard, u32 buf_sz, unsigned long mask) } } - return 0; } @@ -2420,3 +2476,51 @@ static int wp_tdmv_init(void* pcard, wanif_conf_t *conf) return -EINVAL; } +/****************************************************************************** +** wp_tdmv_callback_dtmf() - +* +** OK +*/ +static void wp_tdmv_callback_dtmf (void* card_id, wan_event_t *event) +{ + sdla_t *card = (sdla_t*)card_id; + wan_tdmv_t *wan_tdmv = &card->wan_tdmv; + wp_tdmv_softc_t *wp = NULL; + + WAN_ASSERT1(wan_tdmv->sc == NULL); + wp = wan_tdmv->sc; + + if (event->type != WAN_EVENT_EC_DTMF){ + DEBUG_EVENT("ERROR: %s: Invalid event type %X!\n", + card->devname, event->type); + return; + } + DEBUG_TDMV( + "[TDMV] %s: Received EC DTMF Event at TDM (%d:%c:%s:%s)!\n", + card->devname, + event->channel, + event->digit, + (event->dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", + (event->dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP"); + + if (!(wp->dtmfmask & (1 << (event->channel-1)))){ + DEBUG_TDMV( + "[TDMV] %s: DTMF is not enabled for the channel %d\n", + card->devname, + event->channel); + return; + } + + if (event->dtmf_type == WAN_EC_TONE_PRESENT){ + wp->dtmfactive |= (1 << event->channel); + zt_qevent_lock( + &wp->span.chans[event->channel-1], + (ZT_EVENT_DTMFDOWN | event->digit)); + }else{ + wp->dtmfactive &= ~(1 << event->channel); + zt_qevent_lock( + &wp->span.chans[event->channel-1], + (ZT_EVENT_DTMFUP | event->digit)); + } + return; +} diff --git a/patches/kdrivers/src/net/sdla_te1.c b/patches/kdrivers/src/net/sdla_te1.c index 77be60b..4bbbb79 100644 --- a/patches/kdrivers/src/net/sdla_te1.c +++ b/patches/kdrivers/src/net/sdla_te1.c @@ -29,25 +29,27 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: sdla_te1.c,v 1.255 2007/03/30 21:13:30 sangoma Exp $ + * $Id: sdla_te1.c,v 1.285 2008/03/06 21:29:43 sangoma Exp $ */ /* - ****************************************************************************** - * sdla_te1.c WANPIPE(tm) Multiprotocol WAN Link Driver. - * T1/E1 board configuration. - * - * Author: Alex Feldman - * - * ============================================================================ - * Aprl 29, 2001 Alex Feldman Initial version. - * - * - * - * MAr 7, 2007 Alex Feldman Remove Squence option. Some equipment - * doesn't like it. - ****************************************************************************** - */ +******************************************************************************* +** sdla_te1.c WANPIPE(tm) Multiprotocol WAN Link Driver. +** T1/E1 board configuration. +** +** Author: Alex Feldman +** +** ============================================================================ +** Aprl 29, 2001 Alex Feldman Initial version. +** Mar 7, 2007 Alex Feldman Remove Squence option. Some equipment +** doesn't like it. +** Nov 16, 2007 Alex Feldman Enable SQUELCHE bit in RLPS register. +** In some cases, LOS/ALOS is going crazy +** while cable doesn't have termination. +** (specialy for A102 old cards) +** Nov 21, 2007 Alex Feldman Add LOS Alarm for link state verification +** in Unframed mode. +******************************************************************************/ /****************************************************************************** * INCLUDE FILES @@ -84,7 +86,15 @@ /****************************************************************************** * DEFINES AND MACROS ******************************************************************************/ -#define WAN_TE1_IGNORE_RLPS_ALOS +#define WAN_TE1_IGNORE_RLPS_ALOS + +#if 0 +# define FE_ALOS_ENABLE +# define FE_LOS_ENABLE +# define FE_OOF_PRINT +# define FE_LOS_PRINT +# define FE_ALOS_PRINT +#endif #define FIRST_SAMPLE 0 #define LAST_SAMPLE 23 @@ -99,39 +109,44 @@ static int te_reg_verify = 0; if (te_reg_verify){\ unsigned char current_val;\ current_val=fe->read_fe_reg( \ - fe->card, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ (int)fe->fe_cfg.line_no, \ (int)((reg) + (fe->fe_cfg.line_no*PMC4_LINE_DELTA)));\ DEBUG_EVENT("%s: Writing Reg:%02X=%02X (%02X)\n", \ fe->name,(unsigned char)(reg),(unsigned char)(val),current_val);\ }\ fe->write_fe_reg( \ - fe->card, \ - (int)fe->fe_cfg.line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe->fe_cfg.line_no, \ (int)((reg) + (fe->fe_cfg.line_no*PMC4_LINE_DELTA)), \ (int)(val)) #define WRITE_REG_LINE(fe_line_no, reg,val) \ fe->write_fe_reg( \ - fe->card, \ - (int)fe_line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe_line_no, \ (int)((reg) + (fe_line_no)*PMC4_LINE_DELTA), \ (int)(val)) #define READ_REG(reg) \ fe->read_fe_reg( \ - fe->card, \ - (int)fe->fe_cfg.line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe->fe_cfg.line_no, \ (int)((reg) + (fe->fe_cfg.line_no*PMC4_LINE_DELTA))) #define READ_REG_LINE(fe_line_no, reg) \ fe->read_fe_reg( \ - fe->card, \ - (int)fe_line_no, \ + ((sdla_t*)fe->card)->hw, \ + (int)(((sdla_t*)fe->card)->wandev.state==WAN_CONNECTED), \ + (int)fe_line_no, \ (int)((reg) + (fe_line_no)*PMC4_LINE_DELTA)) /* Enabling/Disabling register debugging */ - #undef WAN_DEBUG_TE1_REG +#undef WAN_DEBUG_TE1_REG #ifdef WAN_DEBUG_TE1_REG # define TEST_REG(reg,value){ \ @@ -199,7 +214,8 @@ static int te_reg_verify = 0; #define WAN_TE1_FRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_OOF_ALARM) -#define WAN_TE1_UNFRAMED_ALARMS (WAN_TE_BIT_RED_ALARM | WAN_TE_BIT_LOS_ALARM) +/* Nov 21, 2007 AF */ +#define WAN_TE1_UNFRAMED_ALARMS (WAN_TE_BIT_RED_ALARM|WAN_TE_BIT_LOS_ALARM) #if 0 #define TE1_FRAME_ALARM (\ @@ -214,14 +230,6 @@ static int te_reg_verify = 0; WAN_TE_BIT_LOS_ALARM) #endif -#if 0 -# define FE_ALOS_ENABLE - -# define FE_OOF_PRINT -# define FE_LOS_PRINT -# define FE_ALOS_PRINT -#endif - /****************************************************************************** * STRUCTURES AND TYPEDEFS ******************************************************************************/ @@ -2300,7 +2308,7 @@ static int sdla_te_intr(sdla_fe_t *); static int sdla_te_check_intr(sdla_fe_t *); static int sdla_te_polling(sdla_fe_t*); static int sdla_te_udp(sdla_fe_t*, void*, unsigned char*); -static void sdla_te_set_status(sdla_fe_t*, unsigned long); +static void sdla_te_set_status(sdla_fe_t*, u_int32_t ); static int sdla_te_get_snmp_data(sdla_fe_t* fe, void* pdev, void* data); static int sdla_te_set_lbmode(sdla_fe_t*, unsigned char, unsigned char); @@ -2327,11 +2335,11 @@ static void sdla_te_abcd_update(sdla_fe_t* fe); static int sdla_te_pmon(sdla_fe_t *fe, int); static int sdla_te_flush_pmon(sdla_fe_t *fe); -static unsigned int sdla_te_read_alarms(sdla_fe_t *fe, int action); +static u_int32_t sdla_te_read_alarms(sdla_fe_t *fe, int action); static int sdla_te_print_alarms(sdla_fe_t* fe, unsigned int); static char* sdla_te_print_channels(sdla_fe_t* fe); -static int sdla_te_set_alarms(sdla_fe_t* pfe, unsigned int); -static int sdla_te_clear_alarms(sdla_fe_t* pfe, unsigned long); +static int sdla_te_set_alarms(sdla_fe_t* pfe, u_int32_t); +static int sdla_te_clear_alarms(sdla_fe_t* pfe, u_int32_t); static int sdla_te_sigctrl(sdla_fe_t*, int, unsigned long, int); static int sdla_te_add_event(sdla_fe_t*, sdla_fe_timer_event_t*); @@ -3292,8 +3300,9 @@ int sdla_te_default_cfg(void* pfe, void* pfe_cfg, int media) * Returns: ****************************************************************************** */ -int sdla_te_iface_init(void *pfe_iface) +int sdla_te_iface_init(void *p_fe, void *pfe_iface) { + sdla_fe_t *fe = (sdla_fe_t*)p_fe; sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)pfe_iface; fe_iface->reset = &sdla_te_reset; @@ -3308,6 +3317,7 @@ int sdla_te_iface_init(void *pfe_iface) fe_iface->disable_irq = &sdla_te_disable_irq; fe_iface->check_isr = &sdla_te_check_intr; fe_iface->polling = &sdla_te_polling; + fe_iface->add_timer = &sdla_te_add_timer; fe_iface->process_udp = &sdla_te_udp; fe_iface->print_fe_alarm = &sdla_te_print_alarms; fe_iface->print_fe_act_channels = &sdla_te_print_channels; @@ -3331,6 +3341,11 @@ int sdla_te_iface_init(void *pfe_iface) fe_iface->get_snmp_data = &sdla_te_get_snmp_data; #endif + /* Initial FE state */ + fe->fe_status = FE_UNITIALIZED; /*FE_DISCONNECTED;*/ + WAN_LIST_INIT(&fe->event); + wan_spin_lock_irq_init(&fe->lockirq, "wan_te1_lock"); + return 0; } @@ -3459,7 +3474,7 @@ static int sdla_pmc4351_te_config(sdla_fe_t *fe, u16 adapter_type) /* XLPG Line Driver Configuration (Reg. 0xF0) */ if (IS_FE_TXTRISTATE(fe)){ - DEBUG_EVENT("%s: Disable Transmitter (tx tri-state mode)!\n", + DEBUG_EVENT("%s: Disable TX (tri-state mode)\n", fe->name); WRITE_REG(REG_XLPG_LINE_CFG, BIT_XLPG_LINE_CFG_HIGHZ); }else{ @@ -3522,6 +3537,8 @@ static int sdla_pmc4351_te_config(sdla_fe_t *fe, u16 adapter_type) } if (WAN_FE_FRAME(fe) == WAN_FR_ESF){ value |= BIT_T1_XBAS_ESF; + }else if (WAN_FE_FRAME(fe) == WAN_FR_SLC96){ + value |= BIT_T1_XBAS_FMS1; } if (IS_J1_FEMEDIA(fe)){ value |= BIT_T1_XBAS_JPN; @@ -3532,6 +3549,8 @@ static int sdla_pmc4351_te_config(sdla_fe_t *fe, u16 adapter_type) value = 0x00; if (WAN_FE_FRAME(fe) == WAN_FR_ESF){ value = BIT_T1_FRMR_ESF | BIT_T1_FRMR_ESFFA; + }else if (WAN_FE_FRAME(fe) == WAN_FR_SLC96){ + value = BIT_T1_FRMR_FMS1; } if (IS_J1_FEMEDIA(fe)){ value |= BIT_T1_FRMR_JPN; @@ -3542,6 +3561,8 @@ static int sdla_pmc4351_te_config(sdla_fe_t *fe, u16 adapter_type) value = 0x00; if (WAN_FE_FRAME(fe) == WAN_FR_ESF){ value = BIT_T1_ALMI_CFG_ESF; + }else if (WAN_FE_FRAME(fe) == WAN_FR_SLC96){ + value |= BIT_T1_ALMI_CFG_FMS1; } WRITE_REG(REG_T1_ALMI_CFG, value); } @@ -3619,7 +3640,7 @@ static int sdla_pmc4351_te_config(sdla_fe_t *fe, u16 adapter_type) } /* RLPS Configuration and Status (Reg 0xF8) */ - /* AF Nov 2007 + /* AF Nov 16, 2007 ** Set SQUELCHE to 1. This forces RLPS to stop sending pulses ** to CDRC during ALOS conditions */ #if defined (WAN_TE1_IGNORE_RLPS_ALOS) @@ -3815,6 +3836,8 @@ static int sdla_pmc4354_te_config(sdla_fe_t *fe, u16 adapter_type) } if (WAN_FE_FRAME(fe) == WAN_FR_ESF){ value |= BIT_T1_XBAS_ESF; + //}else if (WAN_FE_FRAME(fe) == WAN_FR_SLC96){ + // value |= BIT_T1_XBAS_FMS1; } if (IS_J1_FEMEDIA(fe)){ value |= BIT_T1_XBAS_JPN; @@ -3825,7 +3848,10 @@ static int sdla_pmc4354_te_config(sdla_fe_t *fe, u16 adapter_type) value = 0x00; if (WAN_FE_FRAME(fe) == WAN_FR_ESF){ value = BIT_T1_FRMR_ESF | BIT_T1_FRMR_ESFFA; + }else if (WAN_FE_FRAME(fe) == WAN_FR_SLC96){ + value = BIT_T1_FRMR_FMS1; } + if (IS_J1_FEMEDIA(fe)){ value |= BIT_T1_FRMR_JPN; } @@ -3835,6 +3861,8 @@ static int sdla_pmc4354_te_config(sdla_fe_t *fe, u16 adapter_type) value = 0x00; if (WAN_FE_FRAME(fe) == WAN_FR_ESF){ value |= BIT_T1_ALMI_CFG_ESF; + }else if (WAN_FE_FRAME(fe) == WAN_FR_SLC96){ + value |= BIT_T1_ALMI_CFG_FMS1; } WRITE_REG(REG_T1_ALMI_CFG, value); } @@ -3932,16 +3960,16 @@ static int sdla_pmc4354_te_config(sdla_fe_t *fe, u16 adapter_type) } /* RLPS Configuration and Status (Reg 0xQF8) */ - /* AF Nov 2007 - ** Set SQUELCHE to 1. This forces RLPS to stop sending pulses - ** to CDRC during ALOS conditions */ + /* AF Nov 16, 2007 + ** Set SQUELCHE to 1. This forces RLPS to stop sending pulses + ** to CDRC during ALOS conditions */ #if defined (WAN_TE1_IGNORE_RLPS_ALOS) - WRITE_REG(REG_RLPS_CFG_STATUS, - BIT_RLPS_CFG_STATUS_LONGE | - BIT_RLPS_CFG_STATUS_SQUELCHE); + WRITE_REG(REG_RLPS_CFG_STATUS, + BIT_RLPS_CFG_STATUS_LONGE | + BIT_RLPS_CFG_STATUS_SQUELCHE); #else - WRITE_REG(REG_RLPS_CFG_STATUS, - BIT_RLPS_CFG_STATUS_LONGE); + WRITE_REG(REG_RLPS_CFG_STATUS, + BIT_RLPS_CFG_STATUS_LONGE); #endif /* RLPS ALOS Detection/Clearance Thresholds (Reg 0xQF9) */ @@ -4052,7 +4080,7 @@ static int sdla_pmc4354_te_config(sdla_fe_t *fe, u16 adapter_type) /* XLPG Line Driver Configuration (Reg. 0xQF0) */ if (IS_FE_TXTRISTATE(fe)){ - DEBUG_EVENT("%s: Disable Transmitter (tx tri-state mode)!\n", + DEBUG_EVENT("%s: Disable TX (tri-state mode)\n", fe->name); WRITE_REG(REG_XLPG_LINE_CFG, BIT_XLPG_LINE_CFG_HIGHZ); }else{ @@ -4113,79 +4141,177 @@ static int sdla_pmc4354_rlps_optim(sdla_fe_t *fe) return 0; } +/****************************************************************************** +** sdla_t1_cfg_verify() +** +** Description: Verify T1 Front-End configuration +** Arguments: +** Returns: 0 - successfully, otherwise -EINVAL. +*******************************************************************************/ +static int sdla_t1_cfg_verify(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + /* Verify FE framing type */ + switch(WAN_FE_FRAME(fe)){ + case WAN_FR_D4: case WAN_FR_ESF: case WAN_FR_UNFRAMED: + break; + case WAN_FR_NONE: + DEBUG_EVENT("%s: Defaulting T1 Frame = ESF\n", + fe->name); + WAN_FE_FRAME(fe) = WAN_FR_ESF; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Framing type (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_FE_FRAME(fe)); + return -EINVAL; + break; + } + + /* Verify FE line code type */ + switch(WAN_FE_LCODE(fe)){ + case WAN_LCODE_B8ZS: case WAN_LCODE_AMI: + break; + case WAN_LCODE_NONE: + DEBUG_EVENT("%s: Defaulting T1 Line Code = B8ZS\n", + fe->name); + WAN_FE_LCODE(fe) = WAN_LCODE_B8ZS; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Line code type (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_FE_LCODE(fe)); + return -EINVAL; + break; + } + + /* Verify LBO */ + switch(WAN_TE1_LBO(fe)) { + case WAN_T1_LBO_0_DB: case WAN_T1_LBO_75_DB: + case WAN_T1_LBO_15_DB: case WAN_T1_LBO_225_DB: + case WAN_T1_0_133: case WAN_T1_133_266: case WAN_T1_110_220: + case WAN_T1_266_399: case WAN_T1_220_330: + case WAN_T1_399_533: case WAN_T1_330_440: case WAN_T1_440_550: + case WAN_T1_533_655: case WAN_T1_550_660: + break; + case WAN_T1_LBO_NONE: + DEBUG_EVENT("%s: Defaulting T1 LBO = 0 db\n", + fe->name); + WAN_TE1_LBO(fe) = WAN_T1_LBO_0_DB; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s LBO value (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_TE1_LBO(fe)); + return -EINVAL; + break; + } + return 0; +} + +/****************************************************************************** +** sdla_e1_cfg_verify() +** +** Description: Verify E1 Front-End configuration +** Arguments: +** Returns: 0 - successfully, otherwise -EINVAL. +*******************************************************************************/ +static int sdla_e1_cfg_verify(void* pfe) +{ + sdla_fe_t *fe = (sdla_fe_t*)pfe; + + /* Verify FE framing type */ + switch(WAN_FE_FRAME(fe)){ + case WAN_FR_NCRC4: case WAN_FR_CRC4: case WAN_FR_UNFRAMED: + break; + case WAN_FR_NONE: + DEBUG_EVENT("%s: Defaulting E1 Frame = CRC4\n", + fe->name); + WAN_FE_FRAME(fe) = WAN_FR_CRC4; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Framing type (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_FE_FRAME(fe)); + return -EINVAL; + break; + } + /* Verify FE line code type */ + switch(WAN_FE_LCODE(fe)){ + case WAN_LCODE_HDB3: case WAN_LCODE_AMI: + break; + case WAN_LCODE_NONE: + DEBUG_EVENT("%s: Defaulting E1 Line Code = HDB3\n", + fe->name); + WAN_FE_LCODE(fe) = WAN_LCODE_HDB3; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s FE Line code type (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_FE_LCODE(fe)); + return -EINVAL; + break; + } + + /* Verify LBO */ + switch(WAN_TE1_LBO(fe)) { + case WAN_E1_120: case WAN_E1_75: + break; + case WAN_T1_LBO_NONE: + DEBUG_EVENT("%s: Defaulting E1 LBO = 120 OH\n", + fe->name); + WAN_TE1_LBO(fe) = WAN_E1_120; + break; + default: + DEBUG_EVENT("%s: Error: Invalid %s LBO value (%X)\n", + fe->name, + FE_MEDIA_DECODE(fe), + WAN_TE1_LBO(fe)); + return -EINVAL; + break; + } + + switch(WAN_TE1_SIG_MODE(fe)){ + case WAN_TE1_SIG_CAS: case WAN_TE1_SIG_CCS: + break; + case WAN_TE1_SIG_NONE: + DEBUG_EVENT("%s: Defaulting E1 Signalling = CCS\n", + fe->name); + WAN_TE1_SIG_MODE(fe) = WAN_TE1_SIG_CCS; + break; + default: + DEBUG_EVENT("%s: Error: Invalid E1 Signalling type (%X)\n", + fe->name, + WAN_TE1_SIG_MODE(fe)); + return -EINVAL; + break; + } + return 0; +} + /* - ****************************************************************************** - * sdla_te_chip_config() - * - * Description: Configure Sangoma T1/E1 chip - * Arguments: - * Returns: - ****************************************************************************** - */ +****************************************************************************** +** sdla_te_chip_config() +** +** Description: Configure Sangoma T1/E1 chip +** Arguments: +** Returns: +******************************************************************************/ static int sdla_te_chip_config(sdla_fe_t *fe) { sdla_t* card = (sdla_t*)fe->card; u16 adapter_type; - unsigned char value = 0x00; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - /* Revision/Chip ID (Reg. 0x0D) */ - value = READ_REG_LINE(0, REG_REVISION_CHIP_ID); - fe->fe_chip_id = value & MASK_CHIP_ID; - switch(fe->fe_chip_id){ - case CHIP_ID_COMET: - fe->fe_cfg.line_no = 0; - break; - case CHIP_ID_COMET_QUAD: - if ((int)WAN_FE_LINENO(fe) < 0 || WAN_FE_LINENO(fe) > 3){ - DEBUG_EVENT("%s: TE Config: Invalid Port selected %d (Min=1 Max=4)\n", - fe->name, - WAN_FE_LINENO(fe)+1); - return -EINVAL; - } - break; - default: - DEBUG_EVENT("%s: ERROR: Unsupported PMC %s CHIP (%02X)\n", - fe->name, - FE_MEDIA_DECODE(fe), - (fe->fe_chip_id >> 5)); - return -EINVAL; - } - - card->hw_iface.getcfg(card->hw, SDLA_ADAPTERTYPE, &adapter_type); - DEBUG_EVENT("%s: Configuring PMC %s %s FE\n", - fe->name, - DECODE_CHIPID(fe->fe_chip_id), - FE_MEDIA_DECODE(fe)); - DEBUG_EVENT("%s: Port %d,%s,%s,%s\n", - fe->name, - WAN_FE_LINENO(fe)+1, - FE_LCODE_DECODE(fe), - FE_FRAME_DECODE(fe), - TE_LBO_DECODE(fe)); - DEBUG_EVENT("%s: Clk %s:%d, Ch %X\n", - fe->name, - TE_CLK_DECODE(fe), - WAN_TE1_REFCLK(fe), - WAN_TE1_ACTIVE_CH(fe)); - - if (IS_E1_FEMEDIA(fe)){ - DEBUG_EVENT("%s: Sig Mode %s\n", - fe->name, - WAN_TE1_SIG_DECODE(fe)); - } - - if (WAN_FE_FRAME(fe) == WAN_FR_UNFRAMED && - WAN_TE1_ACTIVE_CH(fe) != ENABLE_ALL_CHANNELS){ - DEBUG_EVENT( - "%s: ERROR: Invalid active channel list for Unframed mode (%X)!\n", - fe->name, WAN_TE1_ACTIVE_CH(fe)); - return -EINVAL; - } - fe->te_param.max_channels = (IS_E1_FEMEDIA(fe)) ? NUM_OF_E1_TIMESLOTS: NUM_OF_T1_CHANNELS; fe->te_param.lb_rx_code = LINELB_DS1LINE_DISABLE; @@ -4248,24 +4374,14 @@ static int sdla_te_chip_config(sdla_fe_t *fe) static int sdla_te_config(void* pfe) { sdla_fe_t *fe = (sdla_fe_t*)pfe; + int err = 0; + unsigned char value; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - /* Initial FE state */ - fe->fe_status = FE_UNITIALIZED; /*FE_DISCONNECTED;*/ - WAN_LIST_INIT(&fe->event); - wan_spin_lock_init(&fe->lock); - -#if 1 memset(&fe->te_param, 0, sizeof(sdla_te_param_t)); - if (sdla_te_chip_config(fe)){ - DEBUG_EVENT("%s: Failed to configure %s Front-End chip!\n", - fe->name, - FE_MEDIA_DECODE(fe)); - return -EINVAL; - } -#else + /* Revision/Chip ID (Reg. 0x0D) */ value = READ_REG_LINE(0, REG_REVISION_CHIP_ID); fe->fe_chip_id = value & MASK_CHIP_ID; @@ -4289,8 +4405,18 @@ static int sdla_te_config(void* pfe) return -EINVAL; } + if (IS_T1_FEMEDIA(fe) || IS_J1_FEMEDIA(fe)){ + err = sdla_t1_cfg_verify(fe); + }else if (IS_E1_FEMEDIA(fe)){ + err = sdla_e1_cfg_verify(fe); + }else{ + DEBUG_EVENT("%s: Error: Invalid FE Media type (%X)\n", + fe->name, + WAN_FE_MEDIA(fe)); + err =-EINVAL; + } + if (err) return -EINVAL; - card->hw_iface.getcfg(card->hw, SDLA_ADAPTERTYPE, &adapter_type); DEBUG_EVENT("%s: Configuring PMC %s %s FE\n", fe->name, DECODE_CHIPID(fe->fe_chip_id), @@ -4313,8 +4439,6 @@ static int sdla_te_config(void* pfe) WAN_TE1_SIG_DECODE(fe)); } - memset(&fe->te_param, 0, sizeof(sdla_te_param_t)); - if (WAN_FE_FRAME(fe) == WAN_FR_UNFRAMED && WAN_TE1_ACTIVE_CH(fe) != ENABLE_ALL_CHANNELS){ DEBUG_EVENT( @@ -4323,57 +4447,17 @@ static int sdla_te_config(void* pfe) return -EINVAL; } - fe->te_param.max_channels = - (IS_E1_FEMEDIA(fe)) ? NUM_OF_E1_TIMESLOTS: NUM_OF_T1_CHANNELS; - fe->te_param.lb_rx_code = LINELB_DS1LINE_DISABLE; - switch(fe->fe_chip_id){ - case CHIP_ID_COMET: - sdla_pmc4351_te_config(fe, adapter_type); - break; - - case CHIP_ID_COMET_QUAD: - sdla_pmc4354_te_config(fe, adapter_type); - sdla_pmc4354_rlps_optim(fe); - break; - - default: - DEBUG_EVENT("%s: ERROR: Unsupported T1/E1 CHIP (0x%02X)\n", - fe->name, (fe->fe_chip_id >> 5)); + if (sdla_te_chip_config(fe)){ + DEBUG_EVENT("%s: Failed to configure %s Front-End chip!\n", + fe->name, + FE_MEDIA_DECODE(fe)); return -EINVAL; } - ClearRPSCReg(fe); - ClearTPSCReg(fe); - DisableAllChannels(fe); - EnableChannels(fe); -#if 0 - if (WAN_TE1_ACTIVE_CH(fe) == ENABLE_ALL_CHANNELS){ - DEBUG_EVENT("%s: All channels enabled\n", fe->name); - EnableAllChannels(fe); - }else{ - int channel_range = (IS_T1_FEMEDIA(fe)) ? - NUM_OF_T1_CHANNELS : NUM_OF_E1_CHANNELS; - //NUM_OF_T1_CHANNELS : NUM_OF_E1_TIMESLOTS; - - int i = 0; - - for(i = 1; i <= channel_range; i++){ - if (WAN_TE1_ACTIVE_CH(fe) & (1 << (i - 1))){ - DEBUG_EVENT("%s: Enable channel %d\n", - fe->name, i-1); - EnableTxChannel(fe, i-1); - EnableRxChannel(fe, i-1); - } - } - } -#endif - -#endif - /* Set initial FE status to uninitialized value and let the next function - * set correct value */ - fe->fe_status = FE_UNITIALIZED; /*FE_DISCONNECTED;*/ - /* Read initial alarm status and then enable T1/E1 alarm interrupts */ - /* sdla_te_alarm(fe, 0); */ + /* Read initial alarm status */ + sdla_te_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); + sdla_te_pmon(fe, WAN_FE_PMON_UPDATE); + sdla_te_flush_pmon(fe); wan_set_bit(TE_CONFIGURED,(void*)&fe->te_param.critical); return 0; @@ -4407,7 +4491,7 @@ static int sdla_te_reconfig(sdla_fe_t* fe) WRITE_REG(REG_E1_FRMR_CFG, value); }else if (WAN_TE1_SIG_MODE(fe) == WAN_TE1_SIG_CCS){ - DEBUG_EVENT("%s: Disable E1 CAS signalling mode!\n", + DEBUG_EVENT("%s: Enable E1 CCS signalling mode!\n", fe->name); /* E1-TRAN Configuration (Reg. 0x80) */ value = READ_REG(REG_E1_TRAN_CFG); @@ -4468,8 +4552,9 @@ static int sdla_te_post_init(void *pfe) static int sdla_te_pre_release(void* pfe) { sdla_fe_t *fe = (sdla_fe_t*)pfe; - sdla_fe_timer_event_t *fe_event; + sdla_fe_timer_event_t *fe_event = NULL; wan_smp_flag_t smp_flags; + int empty = 0; /* Kill TE timer poll command */ wan_set_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical); @@ -4477,13 +4562,19 @@ static int sdla_te_pre_release(void* pfe) wan_del_timer(&fe->timer); } wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); - wan_spin_lock_irq(&fe->lock,&smp_flags); - while(!WAN_LIST_EMPTY(&fe->event)){ - fe_event = WAN_LIST_FIRST(&fe->event); - WAN_LIST_REMOVE(fe_event, next); + do { + wan_spin_lock_irq(&fe->lockirq,&smp_flags); + if (!WAN_LIST_EMPTY(&fe->event)){ + fe_event = WAN_LIST_FIRST(&fe->event); + WAN_LIST_REMOVE(fe_event, next); + }else{ + empty = 1; + } + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); + /* Free should be called not from spin_lock_irq (windows) !!!! */ if (fe_event) wan_free(fe_event); - } - wan_spin_unlock_irq(&fe->lock,&smp_flags); + fe_event = NULL; + }while(!empty); return 0; } @@ -4500,12 +4591,14 @@ static int sdla_te_pre_release(void* pfe) static void sdla_te_set_intr(sdla_fe_t* fe) { - DEBUG_EVENT("%s: Enabling %s Interrupts \n", + DEBUG_EVENT("%s: Enable %s Interrupts \n", fe->name, FE_MEDIA_DECODE(fe)); +#if defined(FE_LOS_ENABLE) /* Enable LOS interrupt */ WRITE_REG(REG_CDRC_INT_EN, BIT_CDRC_INT_EN_LOSE); +#endif #if defined(FE_ALOS_ENABLE) /* Enable ALOS interrupt */ @@ -4517,6 +4610,8 @@ static void sdla_te_set_intr(sdla_fe_t* fe) WRITE_REG(REG_T1_RBOC_ENABLE, BIT_T1_RBOC_ENABLE_IDLE | BIT_T1_RBOC_ENABLE_BOCE); + /* Clear ALM status register */ + READ_REG(REG_T1_ALMI_INT_STATUS); /* Enable interrupt on RED, AIS, YEL alarms */ WRITE_REG(REG_T1_ALMI_INT_EN, BIT_T1_ALMI_INT_EN_FASTD | @@ -4536,7 +4631,10 @@ static void sdla_te_set_intr(sdla_fe_t* fe) /* Enable PMON interrupt */ WRITE_REG(REG_PMON_INT_EN_STATUS, READ_REG(REG_PMON_INT_EN_STATUS) | BIT_PMON_INT_EN_STATUS_INTE); + sdla_te_pmon(fe, WAN_FE_PMON_UPDATE); /* Update PMON registers */ return; + + } /* @@ -4551,7 +4649,7 @@ static void sdla_te_set_intr(sdla_fe_t* fe) static void sdla_te_clear_intr(sdla_fe_t* fe) { - DEBUG_EVENT("%s: Clearing %s Interrupts\n", + DEBUG_EVENT("%s: Disable %s Interrupts\n", fe->name, FE_MEDIA_DECODE(fe)); @@ -4589,7 +4687,7 @@ static void sdla_te_clear_intr(sdla_fe_t* fe) /* Disable PMON interrupt */ WRITE_REG(REG_PMON_INT_EN_STATUS, READ_REG(REG_PMON_INT_EN_STATUS) & ~BIT_PMON_INT_EN_STATUS_INTE); - + sdla_te_pmon(fe, WAN_FE_PMON_UPDATE); /* Clean PMON registers */ return; } @@ -4678,8 +4776,8 @@ static int sdla_te_unconfig(void* pfe) /* Verify the FE timer is stopped */ if (!wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ - DEBUG_EVENT("%s: Front-End timer is not stopped!\n", - fe->name); + DEBUG_EVENT("%s: %s(): Front-End timer is not stopped!\n", + fe->name, __FUNCTION__); return -EINVAL; } @@ -4759,18 +4857,26 @@ static int sdla_te_normal_clock(sdla_fe_t *fe) return 0; } -static int sdla_te_is_t1_alarm(sdla_fe_t *fe, unsigned long alarm) +static u_int32_t sdla_te_is_t1_alarm(sdla_fe_t *fe, u_int32_t alarms) { - return (alarm & WAN_TE1_FRAMED_ALARMS); + u_int32_t alarm_mask = WAN_TE1_FRAMED_ALARMS; + + if (fe->fe_cfg.cfg.te_cfg.ignore_yel_alarm == WANOPT_NO){ + alarm_mask |= WAN_TE_BIT_RAI_ALARM; + } + return (alarms & alarm_mask); } -static int sdla_te_is_e1_alarm(sdla_fe_t *fe, unsigned long alarm) +static u_int32_t sdla_te_is_e1_alarm(sdla_fe_t *fe, u_int32_t alarms) { + u_int32_t alarm_mask = 0x00; if (WAN_FE_FRAME(fe) == WAN_FR_UNFRAMED){ - return (alarm & WAN_TE1_UNFRAMED_ALARMS); + alarm_mask = WAN_TE1_UNFRAMED_ALARMS; + }else{ + alarm_mask = WAN_TE1_FRAMED_ALARMS; } - return (alarm & WAN_TE1_FRAMED_ALARMS); + return (alarms & alarm_mask); } /* @@ -4783,42 +4889,37 @@ static int sdla_te_is_e1_alarm(sdla_fe_t *fe, unsigned long alarm) * Returns: ****************************************************************************** */ -static void sdla_te_set_status(sdla_fe_t* fe, unsigned long alarms) +static void sdla_te_set_status(sdla_fe_t* fe, u_int32_t alarms) { sdla_t *card = (sdla_t*)fe->card; + u_int32_t valid_rx_alarms = 0x00; unsigned char curr_fe_status = fe->fe_status; if (IS_T1_FEMEDIA(fe)){ - if (sdla_te_is_t1_alarm(fe, alarms)){ - if (fe->fe_status != FE_DISCONNECTED){ + valid_rx_alarms = sdla_te_is_t1_alarm(fe, alarms); + }else if (IS_E1_FEMEDIA(fe)){ + valid_rx_alarms = sdla_te_is_e1_alarm(fe, alarms); + } + + if (valid_rx_alarms){ + if (fe->fe_status != FE_DISCONNECTED){ + if (!(valid_rx_alarms & WAN_TE_BIT_RAI_ALARM)){ sdla_te_set_alarms(fe, WAN_TE_BIT_YEL_ALARM); - fe->fe_status = FE_DISCONNECTED; } - }else{ + fe->fe_status = FE_DISCONNECTED; + }else if (fe->te_param.tx_yel_alarm && valid_rx_alarms & WAN_TE_BIT_RAI_ALARM){ + /* Special case for loopback */ sdla_te_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); - if (!(fe->fe_alarm & WAN_TE_BIT_YEL_ALARM)){ - if (fe->fe_status != FE_CONNECTED){ - fe->fe_status = FE_CONNECTED; - } - }else{ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: T1 Waiting for Yellow Alarm to clear...\n", - fe->name); - } - fe->fe_status = FE_DISCONNECTED; - } - } + } }else{ - if (sdla_te_is_e1_alarm(fe, alarms)){ - if (fe->fe_status != FE_DISCONNECTED){ - fe->fe_status = FE_DISCONNECTED; - } - }else{ - if (fe->fe_status != FE_CONNECTED){ - fe->fe_status = FE_CONNECTED; + if (fe->fe_status != FE_CONNECTED){ + if (fe->te_param.tx_yel_alarm){ + sdla_te_clear_alarms(fe, WAN_TE_BIT_YEL_ALARM); } + fe->fe_status = FE_CONNECTED; } } + if (curr_fe_status != fe->fe_status){ if (fe->fe_status == FE_CONNECTED){ DEBUG_EVENT("%s: %s connected!\n", @@ -4949,16 +5050,15 @@ static void sdla_channels(sdla_fe_t* fe, unsigned long active_ch) * bit A - YEL (T1) ****************************************************************************** */ -static unsigned int sdla_te_read_alarms(sdla_fe_t *fe, int action) +static u_int32_t sdla_te_read_alarms(sdla_fe_t *fe, int action) { + u_int32_t new_alarms = 0; WAN_ASSERT(fe->write_fe_reg == NULL); WAN_ASSERT(fe->read_fe_reg == NULL); - if (IS_FE_ALARM_READ(action)){ - - unsigned long status = 0x00; - unsigned char value = 0x00; + /* Always read it (compatable with previous cards */ + if (IS_FE_ALARM_READ(action) || 1){ /* Check common alarm for E1 and T1 configuration ** 1. ALOS alarm @@ -4966,86 +5066,96 @@ static unsigned int sdla_te_read_alarms(sdla_fe_t *fe, int action) ** Reg 0xF8 (ALOSI = 1) */ if (READ_REG(REG_RLPS_ALOS_DET_PER) && (READ_REG(REG_RLPS_CFG_STATUS) & BIT_RLPS_CFG_STATUS_ALOSV)){ - status |= WAN_TE_BIT_ALOS_ALARM; + new_alarms |= WAN_TE_BIT_ALOS_ALARM; } /* 2. LOS alarm ** Reg 0x12 */ if (READ_REG(REG_CDRC_INT_STATUS) & BIT_CDRC_INT_STATUS_LOSV){ - status |= WAN_TE_BIT_LOS_ALARM; + new_alarms |= WAN_TE_BIT_LOS_ALARM; } /* 3. ALTLOS alarm ?????????????????? ** Reg 0x13 */ if (READ_REG(REG_ALTLOS_STATUS) & BIT_ALTLOS_STATUS_ALTLOS){ - status |= WAN_TE_BIT_ALTLOS_ALARM; + new_alarms |= WAN_TE_BIT_ALTLOS_ALARM; } /* Check specific E1 and T1 alarms */ if (IS_E1_FEMEDIA(fe)){ + u_int8_t e1_status, e1_mnt_status; + + e1_status = READ_REG(REG_E1_FRMR_FR_STATUS); + e1_mnt_status = READ_REG(REG_E1_FRMR_MAINT_STATUS); /* 4. OOF alarm */ if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ - if (READ_REG(REG_E1_FRMR_FR_STATUS) & BIT_E1_FRMR_FR_STATUS_OOFV){ - status |= WAN_TE_BIT_OOF_ALARM; + if (e1_status & BIT_E1_FRMR_FR_STATUS_OOFV){ + new_alarms |= WAN_TE_BIT_OOF_ALARM; } } /* 5. OOSMF alarm */ - if (READ_REG(REG_E1_FRMR_FR_STATUS) & BIT_E1_FRMR_FR_STATUS_OOSMFV){ - status |= WAN_TE_BIT_OOSMF_ALARM; + if (e1_status & BIT_E1_FRMR_FR_STATUS_OOSMFV){ + new_alarms |= WAN_TE_BIT_OOSMF_ALARM; } /* 6. OOCMF alarm */ - if (READ_REG(REG_E1_FRMR_FR_STATUS) & BIT_E1_FRMR_FR_STATUS_OOCMFV){ - status |= WAN_TE_BIT_OOCMF_ALARM; + if (e1_status & BIT_E1_FRMR_FR_STATUS_OOCMFV){ + new_alarms |= WAN_TE_BIT_OOCMF_ALARM; } /* 7. OOOF alarm */ - if (READ_REG(REG_E1_FRMR_FR_STATUS) & BIT_E1_FRMR_FR_STATUS_OOOFV){ - status |= WAN_TE_BIT_OOOF_ALARM; + if (e1_status & BIT_E1_FRMR_FR_STATUS_OOOFV){ + new_alarms |= WAN_TE_BIT_OOOF_ALARM; } /* 8. RAI alarm */ - if (READ_REG(REG_E1_FRMR_MAINT_STATUS) & BIT_E1_FRMR_MAINT_STATUS_RAIV){ - status |= WAN_TE_BIT_RAI_ALARM; + if (e1_mnt_status & BIT_E1_FRMR_MAINT_STATUS_RAIV){ + new_alarms |= WAN_TE_BIT_RAI_ALARM; } /* 9. RED alarm ** Reg 0x97 (REDD) */ - if (READ_REG(REG_E1_FRMR_MAINT_STATUS) & BIT_E1_FRMR_MAINT_STATUS_RED){ - status |= WAN_TE_BIT_RED_ALARM; + if (e1_mnt_status & BIT_E1_FRMR_MAINT_STATUS_RED){ + new_alarms |= WAN_TE_BIT_RED_ALARM; } /* 10. AIS alarm ** Reg 0x91 (AISC) ** Reg 0x97 (AIS) */ if ((READ_REG(REG_E1_FRMR_MAINT_OPT) & BIT_E1_FRMR_MAINT_OPT_AISC) && - (READ_REG(REG_E1_FRMR_MAINT_STATUS) & BIT_E1_FRMR_MAINT_STATUS_AIS)){ - status |= WAN_TE_BIT_AIS_ALARM; + (e1_mnt_status & BIT_E1_FRMR_MAINT_STATUS_AIS)){ + new_alarms |= WAN_TE_BIT_AIS_ALARM; } } else { + u_int8_t t1_status = 0x00, t1_alm_status = 0x00; + /* 4. OOF alarm ** Reg 0x4A (INFR=0 T1 mode) */ if (!(READ_REG(REG_T1_FRMR_INT_STATUS) & BIT_T1_FRMR_INT_STATUS_INFR)){ - status |= WAN_TE_BIT_OOF_ALARM; + new_alarms |= WAN_TE_BIT_OOF_ALARM; } - value = READ_REG(REG_T1_ALMI_DET_STATUS); + t1_alm_status = READ_REG(REG_T1_ALMI_INT_STATUS); + t1_status = READ_REG(REG_T1_ALMI_DET_STATUS); /* 5. AIS alarm ** Reg 0x62 (AIS) ** Reg 0x63 (AISD) */ - if (value & BIT_T1_ALMI_DET_STATUS_AISD){ - status |= WAN_TE_BIT_AIS_ALARM; + if (t1_status & BIT_T1_ALMI_DET_STATUS_AISD){ + new_alarms |= WAN_TE_BIT_AIS_ALARM; } /* 6. RED alarm ** Reg 0x63 (REDD) */ - if (value & BIT_T1_ALMI_DET_STATUS_REDD){ - status |= WAN_TE_BIT_RED_ALARM; + if ((t1_status & BIT_T1_ALMI_DET_STATUS_REDD) || + (t1_alm_status & BIT_T1_ALMI_INT_STATUS_RED)){ + new_alarms |= WAN_TE_BIT_RED_ALARM; } /* 7. YEL alarm ** Reg 0x62 (YEL) ** Reg 0x63 (YELD) */ - if (value & BIT_T1_ALMI_DET_STATUS_YELD){ - status |= WAN_TE_BIT_YEL_ALARM; + if (t1_status & BIT_T1_ALMI_DET_STATUS_YELD){ + new_alarms |= WAN_TE_BIT_RAI_ALARM; //WAN_TE_BIT_YEL_ALARM; } } - fe->fe_alarm = status; } - + if (IS_FE_ALARM_UPDATE(action) || 1){ + fe->fe_alarm = new_alarms; + } + if (IS_FE_ALARM_PRINT(action)){ sdla_te_print_alarms(fe, fe->fe_alarm); } @@ -5060,7 +5170,7 @@ static unsigned int sdla_te_read_alarms(sdla_fe_t *fe, int action) ** Arguments: ** Returns: */ -static int sdla_te_print_alarms(sdla_fe_t* fe, unsigned int alarms) +static int sdla_te_print_alarms(sdla_fe_t* fe, u_int32_t alarms) { if (!alarms){ alarms = fe->fe_alarm; @@ -5077,28 +5187,28 @@ static int sdla_te_print_alarms(sdla_fe_t* fe, unsigned int alarms) FE_MEDIA_DECODE(fe)); if (alarms & WAN_TE_BIT_ALOS_ALARM){ - DEBUG_EVENT("%s: ALOS alarm is ON\n", fe->name); + DEBUG_EVENT("%s: ALOS : ON\n", fe->name); } if (alarms & WAN_TE_BIT_LOS_ALARM){ - DEBUG_EVENT("%s: LOS alarm is ON\n", fe->name); + DEBUG_EVENT("%s: LOS : ON\n", fe->name); } if (alarms & WAN_TE_BIT_ALTLOS_ALARM){ - DEBUG_EVENT("%s: ATLLOS alarm is ON\n", fe->name); + DEBUG_EVENT("%s: ALTLOS : ON\n", fe->name); } if (alarms & WAN_TE_BIT_OOF_ALARM){ - DEBUG_EVENT("%s: OOF alarm is ON\n", fe->name); + DEBUG_EVENT("%s: OOF : ON\n", fe->name); } if (alarms & WAN_TE_BIT_RAI_ALARM){ - DEBUG_EVENT("%s: RAI alarm is ON\n", fe->name); + DEBUG_EVENT("%s: RAI : ON\n", fe->name); } if (alarms & WAN_TE_BIT_RED_ALARM){ - DEBUG_EVENT("%s: RED alarm is ON\n", fe->name); + DEBUG_EVENT("%s: RED : ON\n", fe->name); } if (alarms & WAN_TE_BIT_AIS_ALARM){ - DEBUG_EVENT("%s: AIS alarm is ON\n", fe->name); + DEBUG_EVENT("%s: AIS : ON\n", fe->name); } if (alarms & WAN_TE_BIT_YEL_ALARM){ - DEBUG_EVENT("%s: YEL alarm is ON\n", fe->name); + DEBUG_EVENT("%s: YEL : ON\n", fe->name); } return 0; } @@ -5111,18 +5221,19 @@ static int sdla_te_print_alarms(sdla_fe_t* fe, unsigned int alarms) ** Arguments: ** Returns: */ -static int sdla_te_set_alarms(sdla_fe_t* fe, unsigned int alarms) +static int sdla_te_set_alarms(sdla_fe_t* fe, u_int32_t alarms) { unsigned char value = 0x00; if (alarms & WAN_TE_BIT_YEL_ALARM){ - if (IS_T1_FEMEDIA(fe)){ + if (IS_T1_FEMEDIA(fe) && + fe->fe_cfg.cfg.te_cfg.ignore_yel_alarm == WANOPT_NO){ value = READ_REG(REG_T1_XBAS_ALARM_TX); if (!(value & BIT_T1_XBAS_ALARM_TX_XYEL)){ - value |= BIT_T1_XBAS_ALARM_TX_XYEL; - DEBUG_EVENT("%s: Setting YELLOW alarm!\n", + DEBUG_EVENT("%s: Set YELLOW alarm!\n", fe->name); - WRITE_REG(REG_T1_XBAS_ALARM_TX, value); + WRITE_REG(REG_T1_XBAS_ALARM_TX, value | BIT_T1_XBAS_ALARM_TX_XYEL); + fe->te_param.tx_yel_alarm = 1; } } } @@ -5137,33 +5248,32 @@ static int sdla_te_set_alarms(sdla_fe_t* fe, unsigned int alarms) ** Arguments: ** Returns: */ -static int sdla_te_clear_alarms(sdla_fe_t* fe, unsigned long alarms) +static int sdla_te_clear_alarms(sdla_fe_t* fe, u_int32_t alarms) { unsigned char value = 0x00; if (alarms & WAN_TE_BIT_YEL_ALARM){ - if (IS_T1_FEMEDIA(fe)){ + if (IS_T1_FEMEDIA(fe) && + fe->fe_cfg.cfg.te_cfg.ignore_yel_alarm == WANOPT_NO){ value = READ_REG(REG_T1_XBAS_ALARM_TX); if (value & BIT_T1_XBAS_ALARM_TX_XYEL){ - value &= ~BIT_T1_XBAS_ALARM_TX_XYEL; - DEBUG_EVENT("%s: Clearing YELLOW alarm!\n", + DEBUG_EVENT("%s: Clear YELLOW alarm!\n", fe->name); - WRITE_REG(REG_T1_XBAS_ALARM_TX, value); + WRITE_REG(REG_T1_XBAS_ALARM_TX, value & ~BIT_T1_XBAS_ALARM_TX_XYEL); + fe->te_param.tx_yel_alarm = 0; } } } return 0; } -/* - ****************************************************************************** - * sdla_te_pmon() - * - * Description: Read PMC performance monitoring counters - * Arguments: - * Returns: - ****************************************************************************** - */ +/****************************************************************************** +* sdla_te_pmon() +* +* Description: Read PMC performance monitoring counters +* Arguments: +* Returns: +******************************************************************************/ #define PMON_DEF_NUM 0x1FFF static int sdla_te_pmon(sdla_fe_t *fe, int action) { @@ -5216,15 +5326,14 @@ static int sdla_te_pmon(sdla_fe_t *fe, int action) return 0; } -/* - ****************************************************************************** - * sdla_fe_flush_pmon() - * - * Description: Flush PMC performance monitoring counters - * Arguments: - * Returns: - ****************************************************************************** - */ + +/****************************************************************************** +* sdla_fe_flush_pmon() +* +* Description: Flush PMC performance monitoring counters +* Arguments: +* Returns: +******************************************************************************/ static int sdla_te_flush_pmon(sdla_fe_t *fe) { fe->fe_stats.te_pmon.lcv_errors = 0; @@ -5292,12 +5401,11 @@ static int sdla_te_check_intr(sdla_fe_t *fe) if (!wan_test_bit(TE_CONFIGURED,(void*)&fe->te_param.critical)){ return 0; } - if (fe->fe_chip_id == CHIP_ID_COMET_QUAD){ val = READ_REG_LINE(0, REG_COMET_QUAD_MASTER_INTR); val &= BITS_COMET_QUAD_MASTER_INTR; if (!(val & (1 << WAN_FE_LINENO(fe)))){ - DEBUG_TEST("%s: This interrupt not for this port %d\n", + DEBUG_ISR("%s: This interrupt not for this port %d\n", fe->name, WAN_FE_LINENO(fe)+1); return 0; @@ -5319,7 +5427,7 @@ static int sdla_te_intr(sdla_fe_t *fe) val = READ_REG_LINE(0, REG_COMET_QUAD_MASTER_INTR); val &= BITS_COMET_QUAD_MASTER_INTR; if (!(val & (1 << WAN_FE_LINENO(fe)))){ - DEBUG_TEST("%s: This interrupt not for this port %d\n", + DEBUG_ISR("%s: This interrupt not for this port %d\n", fe->name, WAN_FE_LINENO(fe)+1); return 0; @@ -5347,7 +5455,7 @@ static int sdla_te_intr(sdla_fe_t *fe) sdla_te_tx_intr(fe); sdla_te_rx_intr(fe); - DEBUG_TEST("%s: FE Interrupt Alarms=0x%lX\n", + DEBUG_ISR("%s: FE Interrupt Alarms=0x%X\n", fe->name,fe->fe_alarm); sdla_te_set_status(fe, fe->fe_alarm); @@ -5486,34 +5594,28 @@ static void sdla_t1_rx_intr(sdla_fe_t* fe) if (status & BIT_T1_ALMI_INT_STATUS_YELI){ if (status & BIT_T1_ALMI_INT_STATUS_YEL){ if (!(fe->fe_alarm & WAN_TE_BIT_YEL_ALARM)){ -#if 0 -Alex Sep 16 - DEBUG_EVENT("%s: T1 YELLOW alarm is ON\n", + DEBUG_EVENT("%s: RAI alarm is ON\n", fe->name); - fe->fe_alarm |= WAN_TE_BIT_YEL_ALARM; -#endif + fe->fe_alarm |= WAN_TE_BIT_RAI_ALARM; //WAN_TE_BIT_YEL_ALARM; } }else{ if (fe->fe_alarm & WAN_TE_BIT_YEL_ALARM){ -#if 0 -Alex Sep 16 - DEBUG_EVENT("%s: T1 YELLOW alarm is OFF\n", + DEBUG_EVENT("%s: RAI alarm is OFF\n", fe->name); - fe->fe_alarm &= ~WAN_TE_BIT_YEL_ALARM; -#endif + fe->fe_alarm &= ~WAN_TE_BIT_RAI_ALARM; //~WAN_TE_BIT_YEL_ALARM; } } } if (status & BIT_T1_ALMI_INT_STATUS_REDI){ if (status & BIT_T1_ALMI_INT_STATUS_RED){ if (!(fe->fe_alarm & WAN_TE_BIT_RED_ALARM)){ - DEBUG_EVENT("%s: T1 RED alarm is ON\n", + DEBUG_EVENT("%s: RED alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_RED_ALARM; } }else{ if (fe->fe_alarm & WAN_TE_BIT_RED_ALARM){ - DEBUG_EVENT("%s: T1 RED alarm is OFF\n", + DEBUG_EVENT("%s: RED alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_RED_ALARM; } @@ -5522,77 +5624,26 @@ Alex Sep 16 if (status & BIT_T1_ALMI_INT_STATUS_AISI){ if (status & BIT_T1_ALMI_INT_STATUS_AIS){ if (!(fe->fe_alarm & WAN_TE_BIT_AIS_ALARM)){ - DEBUG_EVENT("%s: T1 Alarm Indication Signal is ON\n", + DEBUG_EVENT("%s: AIS alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_AIS_ALARM; } }else{ if (fe->fe_alarm & WAN_TE_BIT_AIS_ALARM){ - DEBUG_EVENT("%s: T1 Alarm Indication Signal is OFF\n", - fe->name); - fe->fe_alarm &= ~WAN_TE_BIT_AIS_ALARM; - } - } - } - -#if 0 - if (status & - (BIT_T1_ALMI_INT_STATUS_YELI | - BIT_T1_ALMI_INT_STATUS_REDI | - BIT_T1_ALMI_INT_STATUS_AISI)){ - if (status & (BIT_T1_ALMI_INT_STATUS_YEL | - BIT_T1_ALMI_INT_STATUS_RED | - BIT_T1_ALMI_INT_STATUS_AIS)){ - - /* Update T1/E1 alarm status */ - if (!(fe->fe_alarm & WAN_TE_BIT_YEL_ALARM) && - (status & BIT_T1_ALMI_INT_STATUS_YEL)){ - DEBUG_EVENT("%s: T1 YELLOW alarm is ON\n", - fe->name); - fe->fe_alarm |= WAN_TE_BIT_YEL_ALARM; - } - if (!(fe->fe_alarm & WAN_TE_BIT_RED_ALARM) && - (status & BIT_T1_ALMI_INT_STATUS_RED)){ - DEBUG_EVENT("%s: T1 RED alarm is ON\n", - fe->name); - fe->fe_alarm |= WAN_TE_BIT_RED_ALARM; - } - if (!(fe->fe_alarm & WAN_TE_BIT_AIS_ALARM) && - (status & BIT_T1_ALMI_INT_STATUS_AIS)){ - DEBUG_EVENT("%s: T1 Alarm Indication Signal is ON\n", - fe->name); - fe->fe_alarm |= WAN_TE_BIT_AIS_ALARM; - } - }else{ - /* Update T1/E1 alarm status */ - if ((fe->fe_alarm & WAN_TE_BIT_YEL_ALARM) && - !(status & BIT_T1_ALMI_INT_STATUS_YEL)){ - DEBUG_EVENT("%s: T1 YELLOW alarm is OFF\n", - fe->name); - fe->fe_alarm &= ~WAN_TE_BIT_YEL_ALARM; - } - if ((fe->fe_alarm & WAN_TE_BIT_RED_ALARM) && - !(status & BIT_T1_ALMI_INT_STATUS_RED)){ - DEBUG_EVENT("%s: T1 RED alarm is OFF\n", - fe->name); - fe->fe_alarm &= ~WAN_TE_BIT_RED_ALARM; - } - if ((fe->fe_alarm & WAN_TE_BIT_AIS_ALARM) && - !(status & BIT_T1_ALMI_INT_STATUS_AIS)){ - DEBUG_EVENT("%s: T1 Alarm Indication Signal is OFF\n", + DEBUG_EVENT("%s: AIS alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_AIS_ALARM; } } } -#endif } /* 8. RBOC */ if (fe->te_param.intr_src3 & BIT_INT_SRC_3_RBOC){ status = READ_REG(REG_T1_RBOC_CODE_STATUS); if (status & BIT_T1_RBOC_CODE_STATUS_BOCI){ - unsigned long time; + wan_ticks_t time; + time = SYSTEM_TICKS; status &= MASK_T1_RBOC_CODE_STATUS; switch(status){ @@ -5735,13 +5786,13 @@ Alex Sep 16 (status & BIT_T1_FRMR_INT_STATUS_INFRI)){ if (status & BIT_T1_FRMR_INT_STATUS_INFR){ if (!(fe->fe_alarm & WAN_TE_BIT_OOF_ALARM)){ - DEBUG_EVENT("%s: T1 Out of Frame alarm is ON!\n", + DEBUG_EVENT("%s: OOF alarm is ON!\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_OOF_ALARM; } }else{ if (fe->fe_alarm & WAN_TE_BIT_OOF_ALARM){ - DEBUG_EVENT("%s: T1 Out of Frame alarm is OFF!\n", + DEBUG_EVENT("%s: OOF alarm is OFF!\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_OOF_ALARM; } @@ -5756,7 +5807,7 @@ Alex Sep 16 if (status & BIT_RLPS_CFG_STATUS_ALOSV){ if (!(fe->fe_alarm & WAN_TE_BIT_ALOS_ALARM)){ if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: T1 ALOS alarm is ON\n", + DEBUG_EVENT("%s: ALOS alarm is ON\n", fe->name); } fe->fe_alarm |= WAN_TE_BIT_ALOS_ALARM; @@ -5764,7 +5815,7 @@ Alex Sep 16 }else{ if (fe->fe_alarm & WAN_TE_BIT_ALOS_ALARM){ if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: T1 ALOS alarm is OFF\n", + DEBUG_EVENT("%s: ALOS alarm is OFF\n", fe->name); } fe->fe_alarm &= ~WAN_TE_BIT_ALOS_ALARM; @@ -5781,7 +5832,7 @@ Alex Sep 16 if (status & BIT_CDRC_INT_STATUS_LOSV){ if (!(fe->fe_alarm & WAN_TE_BIT_LOS_ALARM)){ if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: T1 LOS alarm is ON\n", + DEBUG_EVENT("%s: LOS alarm is ON\n", fe->name); } fe->fe_alarm |= WAN_TE_BIT_LOS_ALARM; @@ -5789,7 +5840,7 @@ Alex Sep 16 }else{ if (fe->fe_alarm & WAN_TE_BIT_LOS_ALARM){ if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: T1 LOS alarm is OFF\n", + DEBUG_EVENT("%s: LOS alarm is OFF\n", fe->name); } fe->fe_alarm &= ~WAN_TE_BIT_LOS_ALARM; @@ -5815,13 +5866,13 @@ Alex Sep 16 if ((status & BIT_ALTLOS_STATUS_ALTLOSI) && (status & BIT_ALTLOS_STATUS_ALTLOSE)){ if (status & BIT_ALTLOS_STATUS_ALTLOS){ if (!(fe->fe_alarm & WAN_TE_BIT_ALTLOS_ALARM)){ - DEBUG_EVENT("%s: T1 Alternate Loss of Signal alarm is ON\n", + DEBUG_EVENT("%s: ALTLOS alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_ALTLOS_ALARM; } }else{ if (fe->fe_alarm & WAN_TE_BIT_ALTLOS_ALARM){ - DEBUG_EVENT("%s: T1 Alternate Loss of Signal alarm is OFF\n", + DEBUG_EVENT("%s: ALTLOS alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_ALTLOS_ALARM; } @@ -5958,13 +6009,13 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) if (WAN_FE_FRAME(fe) != WAN_FR_UNFRAMED){ if (status & BIT_E1_FRMR_FR_STATUS_OOFV){ if (!(fe->fe_alarm & WAN_TE_BIT_OOF_ALARM)){ - DEBUG_EVENT("%s: E1 Out of Frame alarm is ON\n", + DEBUG_EVENT("%s: OOF alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_OOF_ALARM; } }else{ if (fe->fe_alarm & WAN_TE_BIT_OOF_ALARM){ - DEBUG_EVENT("%s: E1 Out of Frame alarm is OFF\n", + DEBUG_EVENT("%s: OOF alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_OOF_ALARM; } @@ -5975,11 +6026,11 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) if ((int_en & BIT_E1_FRMR_FRM_STAT_INT_EN_OOSMFE) && (int_status & BIT_E1_FRMR_FRM_STAT_INT_IND_OOSMFI)){ if (status & BIT_E1_FRMR_FR_STATUS_OOSMFV){ - DEBUG_EVENT("%s: E1 Loss of Signaling multiframe alarm is ON\n", + DEBUG_EVENT("%s: OOSMF alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_OOSMF_ALARM; }else{ - DEBUG_EVENT("%s: E1 Loss of Signaling multiframe alarm is OFF\n", + DEBUG_EVENT("%s: OOSMF alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_OOSMF_ALARM; } @@ -5988,11 +6039,11 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) if ((int_en & BIT_E1_FRMR_FRM_STAT_INT_EN_OOCMFE) && (int_status & BIT_E1_FRMR_FRM_STAT_INT_IND_OOCMFI)){ if (status & BIT_E1_FRMR_FR_STATUS_OOCMFV){ - DEBUG_EVENT("%s: E1 Loss of CRC multiframe alarm is ON\n", + DEBUG_EVENT("%s: OOCMF alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_OOCMF_ALARM; }else{ - DEBUG_EVENT("%s: E1 Loss of CRC multiframe alarm is OFF\n", + DEBUG_EVENT("%s: OOCMF alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_OOCMF_ALARM; } @@ -6003,11 +6054,11 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) if ((READ_REG(REG_E1_FRMR_P_A_INT_EN) & BIT_E1_FRMR_P_A_INT_EN_OOOFE) && (status & BIT_E1_FRMR_P_A_INT_STAT_OOOFI)){ if (READ_REG(REG_E1_FRMR_FR_STATUS) & BIT_E1_FRMR_FR_STATUS_OOOFV){ - DEBUG_EVENT("%s: E1 out of offline frame alarm is ON\n", + DEBUG_EVENT("%s: OOOF alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_OOOF_ALARM; }else{ - DEBUG_EVENT("%s: E1 out of offline frame alarm is OFF\n", + DEBUG_EVENT("%s: OOOF alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_OOOF_ALARM; } @@ -6023,17 +6074,17 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) if ((int_en & BIT_E1_FRMR_M_A_INT_EN_REDE) && (int_status & BIT_E1_FRMR_M_A_INT_IND_REDI)){ if (status & BIT_E1_FRMR_MAINT_STATUS_RED){ - DEBUG_EVENT("%s: E1 RED alarm is ON\n", fe->name); + DEBUG_EVENT("%s: RED alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_RED_ALARM; }else{ - DEBUG_EVENT("%s: E1 RED alarm is OFF\n", fe->name); + DEBUG_EVENT("%s: RED alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_RED_ALARM; } } if ((int_en & BIT_E1_FRMR_M_A_INT_EN_AISE) && (int_status & BIT_E1_FRMR_M_A_INT_IND_AISI)){ if (status & BIT_E1_FRMR_MAINT_STATUS_AIS){ - DEBUG_EVENT("%s: E1 AIS alarm is ON\n", fe->name); + DEBUG_EVENT("%s: AIS alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_AIS_ALARM; /* AS/ACIF S016 Clause 5.2.3 */ WRITE_REG(REG_E1_TRAN_TX_ALARM_CTRL, @@ -6043,7 +6094,7 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) sdla_te_master_clock(fe); } }else{ - DEBUG_EVENT("%s: E1 AIS alarm is OFF\n", fe->name); + DEBUG_EVENT("%s: AIS alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_AIS_ALARM; /* AS/ACIF S016 Clause 5.2.3 */ WRITE_REG(REG_E1_TRAN_TX_ALARM_CTRL, @@ -6057,10 +6108,10 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) if ((int_en & BIT_E1_FRMR_M_A_INT_EN_RAIE) && (int_status & BIT_E1_FRMR_M_A_INT_IND_RAII)){ if (status & BIT_E1_FRMR_MAINT_STATUS_RAIV){ - DEBUG_EVENT("%s: E1 RAI alarm is ON\n", fe->name); + DEBUG_EVENT("%s: RAI alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_RAI_ALARM; }else{ - DEBUG_EVENT("%s: E1 RAI alarm is OFF\n", fe->name); + DEBUG_EVENT("%s: RAI alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_RAI_ALARM; } } @@ -6074,7 +6125,7 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) (status & BIT_RLPS_CFG_STATUS_ALOSI)){ if (status & BIT_RLPS_CFG_STATUS_ALOSV){ if (!(fe->fe_alarm & WAN_TE_BIT_ALOS_ALARM)){ - DEBUG_EVENT("%s: E1 ALOS alarm is ON\n", + DEBUG_EVENT("%s: ALOS alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_ALOS_ALARM; /* AS/ACIF S016 Clause 5.2.3 */ @@ -6084,7 +6135,7 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) } }else{ if (fe->fe_alarm & WAN_TE_BIT_ALOS_ALARM){ - DEBUG_EVENT("%s: E1 ALOS alarm is OFF\n", + DEBUG_EVENT("%s: ALOS alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_ALOS_ALARM; /* AS/ACIF S016 Clause 5.2.3 */ @@ -6103,12 +6154,12 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) (status & BIT_CDRC_INT_STATUS_LOSI)){ if (status & BIT_CDRC_INT_STATUS_LOSV){ if (!(fe->fe_alarm & WAN_TE_BIT_LOS_ALARM)){ - DEBUG_EVENT("%s: E1 LOS alarm is ON\n", fe->name); + DEBUG_EVENT("%s: LOS alarm is ON\n", fe->name); fe->fe_alarm |= WAN_TE_BIT_LOS_ALARM; } }else{ if (fe->fe_alarm & WAN_TE_BIT_LOS_ALARM){ - DEBUG_EVENT("%s: E1 LOS alarm is OFF\n", fe->name); + DEBUG_EVENT("%s: LOS alarm is OFF\n", fe->name); fe->fe_alarm &= ~WAN_TE_BIT_LOS_ALARM; } } @@ -6147,7 +6198,7 @@ static void sdla_e1_rx_intr(sdla_fe_t* fe) if (fe->te_param.intr_src1 & BIT_INT_SRC_1_PMON){ status = READ_REG(REG_PMON_INT_EN_STATUS); if (status & BIT_PMON_INT_EN_STATUS_XFER){ - sdla_te_pmon(fe, 0); + sdla_te_pmon(fe, WAN_FE_PMON_READ); } } #if 0 @@ -6202,6 +6253,7 @@ sdla_te_set_lbmode(sdla_fe_t *fe, unsigned char type, unsigned char mode) case WAN_TE1_PAYLB_MODE: err = sdla_te_paylb(fe, mode); break; + case WAN_TE1_DDLB_MODE: err = sdla_te_ddlb(fe, mode); break; @@ -6328,8 +6380,12 @@ static void sdla_te_timer(unsigned long pfe) fe->name, FE_MEDIA_DECODE(fe)); + DEBUG_TE1("%s(): line: %d\n", __FUNCTION__, __LINE__); + if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); + + DEBUG_TE1("%s(): line: %d\n", __FUNCTION__, __LINE__); return; } if (!wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)){ @@ -6341,9 +6397,9 @@ static void sdla_te_timer(unsigned long pfe) wan_clear_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical); /* Enable hardware interrupt for TE1 */ - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); empty = WAN_LIST_EMPTY(&fe->event); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); if (!empty){ if (wan_test_and_set_bit(TE_TIMER_EVENT_PENDING,(void*)&fe->te_param.critical)){ DEBUG_EVENT("%s: RM timer event is pending!\n", fe->name); @@ -6392,7 +6448,7 @@ sdla_te_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *fe_event) } memcpy(new_fe_event, fe_event, sizeof(sdla_fe_timer_event_t)); - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); if (WAN_LIST_EMPTY(&fe->event)){ WAN_LIST_INSERT_HEAD(&fe->event, new_fe_event, next); }else{ @@ -6402,12 +6458,12 @@ sdla_te_add_event(sdla_fe_t *fe, sdla_fe_timer_event_t *fe_event) } if (tmp == NULL){ DEBUG_EVENT("%s: Internal Error!!!\n", fe->name); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); return -EINVAL; } WAN_LIST_INSERT_AFTER(tmp, new_fe_event, next); } - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); return 0; } @@ -6424,15 +6480,17 @@ static int sdla_te_add_timer(sdla_fe_t* fe, unsigned long delay) { int err=0; - if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical)){ + if (wan_test_bit(TE_TIMER_KILL,(void*)&fe->te_param.critical) || + wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)) { return 0; } - if (wan_test_bit(TE_TIMER_RUNNING,(void*)&fe->te_param.critical)) { - return 0; - } - +#if defined(__WINDOWS__) + /* delay is in MS, so it can be used directly by wan_add_timer() */ + err = wan_add_timer(&fe->timer, delay); +#else err = wan_add_timer(&fe->timer, delay * HZ / 1000); +#endif if (err){ /* Failed to add timer */ return -EINVAL; @@ -6461,22 +6519,21 @@ static int sdla_te_polling(sdla_fe_t* fe) u_int8_t pending = 0; wan_smp_flag_t smp_flags; - WAN_ASSERT(fe->write_fe_reg == NULL); - WAN_ASSERT(fe->read_fe_reg == NULL); + WAN_ASSERT_RC(fe->write_fe_reg == NULL, 0); + WAN_ASSERT_RC(fe->read_fe_reg == NULL, 0); - wan_spin_lock_irq(&fe->lock,&smp_flags); + wan_spin_lock_irq(&fe->lockirq,&smp_flags); if (WAN_LIST_EMPTY(&fe->event)){ - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); DEBUG_EVENT("%s: WARNING: No FE events in a queue!\n", fe->name); - sdla_te_add_timer(fe, HZ); - return 0; + return HZ; } fe_event = WAN_LIST_FIRST(&fe->event); WAN_LIST_REMOVE(fe_event, next); - wan_spin_unlock_irq(&fe->lock,&smp_flags); + wan_spin_unlock_irq(&fe->lockirq,&smp_flags); - DEBUG_TEST("%s: %s Polling State=%s Cmd=0x%X!\n", + DEBUG_TE1("%s: %s Polling State=%s Cmd=0x%X!\n", fe->name, FE_MEDIA_DECODE(fe), fe->fe_status==FE_CONNECTED?"Con":"Disconn", fe_event->type); @@ -6517,7 +6574,7 @@ static int sdla_te_polling(sdla_fe_t* fe) break; case TE_LINKDOWN_TIMER: - sdla_te_read_alarms(fe, WAN_FE_ALARM_READ); + sdla_te_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); sdla_te_pmon(fe, WAN_FE_PMON_UPDATE); sdla_te_set_status(fe, fe->fe_alarm); if (fe->fe_status == FE_CONNECTED){ @@ -6567,7 +6624,7 @@ static int sdla_te_polling(sdla_fe_t* fe) if (sdla_te_chip_config(fe)){ DEBUG_EVENT("%s: Failed to re-configuring Front-End chip!\n", fe->name); - return -EINVAL; + break; } fe_event->type = TE_LINKDOWN_TIMER; fe_event->delay = POLLING_TE1_TIMER; @@ -6575,14 +6632,16 @@ static int sdla_te_polling(sdla_fe_t* fe) break; case TE_POLL_READ: - DEBUG_EVENT("%s: Reading %s Front-End register: Reg[%04X]=%02X\n", + fe->te_param.reg_dbg_value = READ_REG(fe_event->te_event.reg); + DEBUG_TE1("%s: Read %s Front-End Reg:%04X=%02X\n", fe->name, FE_MEDIA_DECODE(fe), fe_event->te_event.reg, - READ_REG(fe_event->te_event.value)); + fe->te_param.reg_dbg_value); + fe->te_param.reg_dbg_ready = 1; break; case TE_POLL_WRITE: - DEBUG_EVENT("%s: Writting %s Front-End register: Reg[%04X]=%02X\n", + DEBUG_TE1("%s: Write %s Front-End Reg:%04X=%02X\n", fe->name, FE_MEDIA_DECODE(fe), fe_event->te_event.reg, fe_event->te_event.value); @@ -6599,11 +6658,9 @@ static int sdla_te_polling(sdla_fe_t* fe) /* Add fe timer */ fe_event = WAN_LIST_FIRST(&fe->event); if (fe_event){ - sdla_te_add_timer(fe, fe_event->delay); - }else{ - sdla_te_add_timer(fe, HZ); + return fe_event->delay; } - return 0; + return HZ; } /* @@ -6688,8 +6745,17 @@ static int sdla_te_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) #if 0 *(unsigned long *)&data[0] = fe->fe_alarm; #endif - /* TE1 Update T1/E1 perfomance counters */ + sdla_te_pmon(fe, WAN_FE_PMON_READ); memcpy(&data[0], &fe->fe_stats, sizeof(sdla_fe_stats_t)); + if (udp_cmd->wan_cmd_fe_force){ + sdla_fe_stats_t *fe_stats = (sdla_fe_stats_t*)&data[0]; + /* force to read FE alarms */ + DEBUG_EVENT("%s: Force to read Front-End alarms\n", + fe->name); + fe_stats->alarms = + sdla_te_read_alarms(fe, WAN_FE_ALARM_READ); + } + /* TE1 Update T1/E1 perfomance counters */ udp_cmd->wan_cmd_return_code = WAN_CMD_OK; udp_cmd->wan_cmd_data_len = sizeof(sdla_fe_stats_t); break; @@ -6814,13 +6880,27 @@ static int sdla_te_udp(sdla_fe_t *fe, void* p_udp_cmd, unsigned char* data) break; case WAN_FE_DEBUG_REG: + if (fe->te_param.reg_dbg_busy){ + if (fe_debug->fe_debug_reg.read == 2 && fe->te_param.reg_dbg_ready){ + /* Poll the register value */ + fe_debug->fe_debug_reg.value = fe->te_param.reg_dbg_value; + udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + fe->te_param.reg_dbg_busy = 0; + } + break; + } fe_event.type = (fe_debug->fe_debug_reg.read) ? - TE_POLL_READ : TE_POLL_WRITE; - fe_event.te_event.reg = fe_debug->fe_debug_reg.reg; + TE_POLL_READ : TE_POLL_WRITE; + fe_event.te_event.reg = (u_int16_t)fe_debug->fe_debug_reg.reg; fe_event.te_event.value = fe_debug->fe_debug_reg.value; fe_event.delay = POLLING_TE1_TIMER; + if (fe_debug->fe_debug_reg.read){ + fe->te_param.reg_dbg_busy = 1; + fe->te_param.reg_dbg_ready = 0; + } sdla_te_add_event(fe, &fe_event); udp_cmd->wan_cmd_return_code = WAN_CMD_OK; + break; default: udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; break; diff --git a/patches/kdrivers/src/net/sdla_te3.c b/patches/kdrivers/src/net/sdla_te3.c index 2a7f91a..c7c0733 100644 --- a/patches/kdrivers/src/net/sdla_te3.c +++ b/patches/kdrivers/src/net/sdla_te3.c @@ -52,27 +52,18 @@ ** DEFINES AND MACROS ******************************************************************************/ -#if defined(DEBUG) -# define WRITE_CPLD(reg,val) \ - DEBUG_EVENT("%s: Write to CPLD reg %d value %X\n", \ - fe->name, reg, val); +#define WRITE_CPLD(reg,val) \ + fe->write_cpld(fe->card, (reg), (val)) -# define WRITE_REG(reg,val) \ - DEBUG_EVENT("%s: Write to Framer off %X value %X\n", \ - fe->name, reg, val); -#else +#define WRITE_EXAR_CPLD(reg,val) \ + fe->write_fe_cpld(fe->card, (reg), (val)) -# define WRITE_CPLD(reg,val) \ - (fe->write_cpld) ? fe->write_cpld(fe->card, reg, val) : -EINVAL - -# define WRITE_EXAR_CPLD(reg,val) \ - (fe->write_fe_cpld) ? fe->write_fe_cpld(fe->card, reg, val) : -EINVAL - -# define WRITE_REG(reg,val) \ - (fe->write_framer) ? fe->write_framer(fe->card, reg, val) : -EINVAL -# define READ_REG(reg) \ - (fe->read_framer) ? fe->read_framer(fe->card, reg) : 0 -#endif +#define WRITE_REG(reg,val) \ + fe->write_fe_reg( \ + ((sdla_t*)fe->card)->hw,(int)(reg),(int)(val)); +#define READ_REG(reg) \ + fe->read_fe_reg( \ + ((sdla_t*)fe->card)->hw,(int)(reg)); #define WAN_FE_SWAP_BIT(value, mask) \ if ((value) & mask){ \ @@ -105,8 +96,9 @@ static int sdla_ds3_isr(sdla_fe_t *fe); static int sdla_e3_isr(sdla_fe_t *fe); static int sdla_te3_isr(sdla_fe_t *fe); static int sdla_te3_udp(sdla_fe_t *fe, void*, unsigned char*); -static unsigned int sdla_te3_alarm(sdla_fe_t *fe, int); +static unsigned int sdla_te3_read_alarms(sdla_fe_t *fe, int); static int sdla_te3_read_pmon(sdla_fe_t *fe, int); +static int sdla_te3_flush_pmon(sdla_fe_t *fe); static int sdla_te3_update_alarm_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt); static int sdla_te3_update_pmon_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt); @@ -221,6 +213,8 @@ static int sdla_ds3_tx_isr(sdla_fe_t *fe) { unsigned char value; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); value = READ_REG(REG_TxDS3_LAPD_STATUS); if (value & BIT_TxDS3_LAPD_STATUS_INT){ DEBUG_EVENT("%s: LAPD Interrupt!\n", @@ -240,43 +234,35 @@ static int sdla_ds3_rx_isr(sdla_fe_t *fe) { unsigned char value, status; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); /* RxDS3 Interrupt status register (0x13) */ value = READ_REG(REG_RxDS3_INT_STATUS); status = READ_REG(REG_RxDS3_CFG_STATUS); if (fe->fe_cfg.frame == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_CPBIT_ERR){ - if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: CP Bit Error interrupt detected!\n", + DEBUG_TE3("%s: CP Bit Error interrupt detected!\n", fe->name); - } } if (value & BIT_RxDS3_INT_STATUS_LOS){ if (status & BIT_RxDS3_CFG_STATUS_RxLOS){ - if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s: LOS Status ON!\n", fe->name); - } fe->fe_alarm |= WAN_TE3_BIT_LOS_ALARM; }else{ - if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s: LOS Status OFF!\n", fe->name); - } fe->fe_alarm &= ~WAN_TE3_BIT_LOS_ALARM; } } if (value & BIT_RxDS3_INT_STATUS_AIS){ - if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s: AIS status %s!\n", fe->name, (status & BIT_RxDS3_CFG_STATUS_RxAIS) ? "ON" : "OFF"); - } } if (value & BIT_RxDS3_INT_STATUS_IDLE){ - if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: IDLE condition status %s!\n", + DEBUG_EVENT("%s: IDLE condition status %s!\n", fe->name, (status & BIT_RxDS3_CFG_STATUS_RxIDLE) ? "ON" : "OFF"); - } } if (value & BIT_RxDS3_INT_STATUS_OOF){ if (status & BIT_RxDS3_CFG_STATUS_RxLOS){ @@ -302,27 +288,23 @@ static int sdla_ds3_rx_isr(sdla_fe_t *fe) } } if (fe->fe_cfg.frame == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_AIC){ - if (WAN_NET_RATELIMIT()){ DEBUG_TE3("%s: AIC bit-field status %s!\n", fe->name, (status & BIT_RxDS3_STATUS_RxAIC) ? "ON" : "OFF"); - } } if (value & BIT_RxDS3_INT_STATUS_PBIT_ERR){ - if (WAN_NET_RATELIMIT()){ DEBUG_TE3("%s: P-Bit error interrupt!\n", fe->name); - } } /* RxDS3 FEAC Interrupt (0x17) */ value = READ_REG(REG_RxDS3_FEAC_INT); if (value & BIT_RxDS3_FEAC_REMOVE_INT_STATUS){ - DEBUG_TE3("%s: RxFEAC Remove Interrupt!\n", + DEBUG_EVENT("%s: RxFEAC Remove Interrupt!\n", fe->name); } if (value & BIT_RxDS3_FEAC_VALID_INT_STATUS){ - DEBUG_TE3("%s: RxFEAC Valid Interrupt!\n", + DEBUG_EVENT("%s: RxFEAC Valid Interrupt!\n", fe->name); } @@ -340,6 +322,8 @@ static int sdla_ds3_isr(sdla_fe_t *fe) { unsigned char value; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); value = READ_REG(REG_BLOCK_INT_STATUS); if (value & BIT_BLOCK_INT_STATUS_RxDS3_E3){ sdla_ds3_rx_isr(fe); @@ -379,6 +363,9 @@ static int sdla_e3_rx_isr(sdla_fe_t *fe) unsigned char int_status1, int_status2; unsigned char status; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + int_status1 = READ_REG(REG_RxE3_INT_STATUS_1); int_status2 = READ_REG(REG_RxE3_INT_STATUS_2); status = READ_REG(REG_RxE3_CFG_STATUS_2); @@ -457,6 +444,9 @@ static int sdla_e3_isr(sdla_fe_t *fe) { unsigned char value; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + value = READ_REG(REG_BLOCK_INT_STATUS); if (value & BIT_BLOCK_INT_STATUS_RxDS3_E3){ sdla_e3_rx_isr(fe); @@ -478,10 +468,8 @@ static int sdla_e3_isr(sdla_fe_t *fe) static int sdla_te3_isr(sdla_fe_t *fe) { sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned char value; int err = 0; - value = READ_REG(REG_BLOCK_INT_STATUS); switch(fe_cfg->media){ case WAN_MEDIA_DS3: err = sdla_ds3_isr(fe); @@ -490,113 +478,135 @@ static int sdla_te3_isr(sdla_fe_t *fe) err = sdla_e3_isr(fe); break; } - fe->fe_alarm = sdla_te3_alarm(fe, 1); + sdla_te3_set_status(fe); return err; } /****************************************************************************** - * sdla_te3_alarm() + * sdla_te3_read_alarms() * * Description: * Arguments: * Returns: ****************************************************************************** */ -static unsigned int sdla_te3_alarm(sdla_fe_t *fe, int update) +static unsigned int sdla_te3_read_framer_alarms(sdla_fe_t *fe) { sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned int alarm = 0; + unsigned int alarms = 0; unsigned char value; - + + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + if (fe_cfg->media == WAN_MEDIA_DS3){ value = READ_REG(REG_RxDS3_CFG_STATUS); if (value & BIT_RxDS3_CFG_STATUS_RxAIS){ - alarm |= WAN_TE3_BIT_AIS_ALARM; - DEBUG_TE3("%s: (T3/E3) AIS Alarm is ON\n", fe->name); + alarms |= WAN_TE3_BIT_AIS_ALARM; }else{ - alarm &= ~WAN_TE3_BIT_AIS_ALARM; - DEBUG_TE3("%s: (T3/E3) AIS Alarm is OFF\n", fe->name); + alarms &= ~WAN_TE3_BIT_AIS_ALARM; } if (value & BIT_RxDS3_CFG_STATUS_RxLOS){ - alarm |= WAN_TE3_BIT_LOS_ALARM; - DEBUG_TE3("%s: (T3/E3) LOS Alarm is ON\n", fe->name); + alarms |= WAN_TE3_BIT_LOS_ALARM; }else{ - alarm &= ~WAN_TE3_BIT_LOS_ALARM; - DEBUG_TE3("%s: (T3/E3) LOS Alarm is OFF\n", fe->name); + alarms &= ~WAN_TE3_BIT_LOS_ALARM; } if (value & BIT_RxDS3_CFG_STATUS_RxOOF){ - alarm |= WAN_TE3_BIT_OOF_ALARM; - DEBUG_TE3("%s: (T3/E3) OOF Alarm is ON\n", fe->name); + alarms |= WAN_TE3_BIT_OOF_ALARM; }else{ - alarm &= ~WAN_TE3_BIT_OOF_ALARM; - DEBUG_TE3("%s: (T3/E3) OOF Alarm is OFF\n", fe->name); + alarms &= ~WAN_TE3_BIT_OOF_ALARM; } value = READ_REG(REG_RxDS3_STATUS); if (value & BIT_RxDS3_STATUS_RxFERF){ - alarm |= WAN_TE3_BIT_YEL_ALARM; - DEBUG_TE3("%s: (T3/E3) YEL Alarm is ON\n", fe->name); + alarms |= WAN_TE3_BIT_YEL_ALARM; }else{ - alarm &= ~WAN_TE3_BIT_YEL_ALARM; - DEBUG_TE3("%s: (T3/E3) YEL Alarm is OFF\n", fe->name); + alarms &= ~WAN_TE3_BIT_YEL_ALARM; } }else{ value = READ_REG(REG_RxE3_CFG_STATUS_2); if (value & BIT_RxE3_CFG_STATUS_RxOOF){ - DEBUG_TE3("%s: (T3/E3) OOF Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_OOF_ALARM; + alarms |= WAN_TE3_BIT_OOF_ALARM; }else{ - DEBUG_TE3("%s: (T3/E3) OOF Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_OOF_ALARM; + alarms &= ~WAN_TE3_BIT_OOF_ALARM; } if (value & BIT_RxE3_CFG_STATUS_RxLOF){ - DEBUG_TE3("%s: (T3/E3) LOF Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_LOF_ALARM; + alarms |= WAN_TE3_BIT_LOF_ALARM; }else{ - DEBUG_TE3("%s: (T3/E3) LOF Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_LOF_ALARM; + alarms &= ~WAN_TE3_BIT_LOF_ALARM; } if (value & BIT_RxE3_CFG_STATUS_RxLOS){ - DEBUG_TE3("%s: (T3/E3) LOS Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_LOS_ALARM; + alarms |= WAN_TE3_BIT_LOS_ALARM; }else{ - DEBUG_TE3("%s: (T3/E3) LOS Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_LOS_ALARM; + alarms &= ~WAN_TE3_BIT_LOS_ALARM; } if (value & BIT_RxE3_CFG_STATUS_RxAIS){ - DEBUG_TE3("%s: (T3/E3) AIS Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_AIS_ALARM; + alarms |= WAN_TE3_BIT_AIS_ALARM; }else{ - DEBUG_TE3("%s: (T3/E3) AIS Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_AIS_ALARM; + alarms &= ~WAN_TE3_BIT_AIS_ALARM; } if (value & BIT_RxE3_CFG_STATUS_RxFERF){ - DEBUG_TE3("%s: (T3/E3) Rx FERF status is ON (YELLOW)!\n", - fe->name); - alarm |= WAN_TE3_BIT_YEL_ALARM; + alarms |= WAN_TE3_BIT_YEL_ALARM; }else{ - DEBUG_TE3("%s: (T3/E3) Rx FERF status is OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_YEL_ALARM; + alarms &= ~WAN_TE3_BIT_YEL_ALARM; } } + return alarms; +} - fe->fe_alarm = alarm; - if (update){ - sdla_te3_set_status(fe); +static int sdla_te3_print_alarms(sdla_fe_t *fe, unsigned int alarms) +{ + + DEBUG_EVENT("%s: %s Framer Alarms status (%X):\n", + fe->name, + FE_MEDIA_DECODE(fe), + alarms); + + if (!alarms){ + DEBUG_EVENT("%s: %s Alarms status: No alarms detected!\n", + fe->name, + FE_MEDIA_DECODE(fe)); + return 0; } - return alarm; + if (alarms & WAN_TE3_BIT_AIS_ALARM){ + DEBUG_EVENT("%s: AIS Alarm is ON\n", fe->name); + } + if (alarms & WAN_TE3_BIT_LOS_ALARM){ + DEBUG_EVENT("%s: LOS Alarm is ON\n", fe->name); + } + if (alarms & WAN_TE3_BIT_OOF_ALARM){ + DEBUG_EVENT("%s: OOF Alarm is ON\n", fe->name); + } + if (alarms & WAN_TE3_BIT_YEL_ALARM){ + DEBUG_EVENT("%s: YEL Alarm is ON\n", fe->name); + } + if (alarms & WAN_TE3_BIT_LOF_ALARM){ + DEBUG_EVENT("%s: LOF Alarm OFF!\n", fe->name); + } + + return 0; +} + +static unsigned int sdla_te3_read_alarms(sdla_fe_t *fe, int action) +{ + unsigned int alarms = 0; + + if (IS_FE_ALARM_READ(action)){ + alarms = sdla_te3_read_framer_alarms(fe); + } + + if (IS_FE_ALARM_PRINT(action)){ + sdla_te3_print_alarms(fe, alarms); + } + + if (IS_FE_ALARM_UPDATE(action)){ + fe->fe_alarm = alarms; + sdla_te3_set_status(fe); + } + return alarms; } @@ -616,18 +626,20 @@ static int sdla_te3_set_alarm(sdla_fe_t *fe, unsigned int alarm) } /****************************************************************************** - * sdla_te3_read_pmon() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ +* sdla_te3_read_pmon() +* +* Description: +* Arguments: +* Returns: +******************************************************************************/ static int sdla_te3_read_pmon(sdla_fe_t *fe, int action) { sdla_te3_pmon_t *pmon = (sdla_te3_pmon_t*)&fe->fe_stats.u.te3_pmon; unsigned char value_msb, value_lsb; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + value_msb = READ_REG(REG_PMON_LCV_MSB); value_lsb = READ_REG(REG_PMON_LCV_LSB); pmon->pmon_lcv += ((value_msb << 8) | value_lsb); @@ -650,8 +662,6 @@ static int sdla_te3_read_pmon(sdla_fe_t *fe, int action) return 0; } - - /****************************************************************************** * sdla_te3_flush_pmon() * @@ -721,6 +731,8 @@ sdla_te3_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) { unsigned char data = 0x00; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); DEBUG_EVENT("%s: %s %s mode...\n", fe->name, WAN_TE3_LB_MODE_DECODE(mode), @@ -756,7 +768,6 @@ sdla_te3_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) return 0; } - /****************************************************************************** * sdla_te3_udp() * @@ -772,7 +783,6 @@ static int sdla_te3_udp(sdla_fe_t *fe, void *pudp_cmd, unsigned char *data) int err = -EINVAL; switch(udp_cmd->wan_cmd_command){ - case WAN_GET_MEDIA_TYPE: data[0] = fe->fe_cfg.media; udp_cmd->wan_cmd_return_code = WAN_CMD_OK; @@ -792,14 +802,14 @@ static int sdla_te3_udp(sdla_fe_t *fe, void *pudp_cmd, unsigned char *data) break; case WAN_FE_GET_STAT: - /* Read T3/E3 alarms */ + /* TE1_56K Read T1/E1/56K alarms */ sdla_te3_read_pmon(fe, 0); if (udp_cmd->wan_cmd_fe_force){ /* force to read FE alarms */ DEBUG_EVENT("%s: Force to read Front-End alarms\n", fe->name); fe->fe_stats.alarms = - sdla_te3_alarm(fe, 1); + sdla_te3_read_alarms(fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); } memcpy(&data[0], &fe->fe_stats, sizeof(sdla_fe_stats_t)); udp_cmd->wan_cmd_return_code = WAN_CMD_OK; @@ -829,11 +839,13 @@ static int sdla_te3_udp(sdla_fe_t *fe, void *pudp_cmd, unsigned char *data) return 0; } - static int sdla_te3_set_intr(sdla_fe_t *fe) { sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + DEBUG_EVENT("%s: Enabling interrupts for %s (%d)!\n", fe->name, FE_MEDIA_DECODE(fe), IS_DS3(fe_cfg)); /* Enable Framer Interrupts */ @@ -896,6 +908,7 @@ sdla_te3_liu_config(sdla_fe_t *fe, sdla_te3_liu_cfg_t *liu, char *name) sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; unsigned char data = 0x00; + WAN_ASSERT(fe->write_cpld == NULL); if (fe_cfg->media == WAN_MEDIA_E3){ data |= BIT_CPLD_CNTRL_E3; } @@ -930,33 +943,7 @@ sdla_te3_liu_config(sdla_fe_t *fe, sdla_te3_liu_cfg_t *liu, char *name) name); data &= ~BIT_CPLD_STATUS_TAOS; } - switch(liu->lb_mode){ - case WAN_TE3_LIU_LB_NORMAL: - break; - case WAN_TE3_LIU_LB_ANALOG: - DEBUG_TE3("%s: (T3/E3) Enable Analog Loopback mode!\n", - name); - data |= BIT_CPLD_STATUS_LLB; - data &= ~BIT_CPLD_STATUS_RLB; - break; - case WAN_TE3_LIU_LB_REMOTE: - DEBUG_TE3("%s: (T3/E3) Enable Remote Loopback mode!\n", - name); - data &= ~BIT_CPLD_STATUS_LLB; - data |= BIT_CPLD_STATUS_RLB; - break; - case WAN_TE3_LIU_LB_DIGITAL: - DEBUG_TE3("%s: (T3/E3) Enable Digital Loopback mode!\n", - name); - data |= BIT_CPLD_STATUS_LLB; - data |= BIT_CPLD_STATUS_RLB; - break; - default : - DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", - name); - break; - } - /* Write value to CPLD Status/Control register */ + /* Write value to CPLD Status register */ WRITE_CPLD(REG_CPLD_STATUS, data); return 0; } @@ -975,11 +962,13 @@ sdla_te3_shark_liu_config(sdla_fe_t *fe, sdla_te3_liu_cfg_t *liu, char *name) sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; unsigned char data = 0x00; + WAN_ASSERT(fe->write_fe_cpld == NULL); + fe->te3_param.cpld_cntrl = 0x00; if (fe_cfg->media == WAN_MEDIA_E3){ - data |= BIT_EXAR_CPLD_CNTRL_E3; + fe->te3_param.cpld_cntrl |= BIT_EXAR_CPLD_CNTRL_E3; } /* Write value to CPLD Control register */ - WRITE_EXAR_CPLD(REG_EXAR_CPLD_CNTRL, data); + WRITE_EXAR_CPLD(REG_EXAR_CPLD_CNTRL, fe->te3_param.cpld_cntrl); data = 0x00; if (liu->rx_equal == WAN_TRUE){ @@ -1010,33 +999,6 @@ sdla_te3_shark_liu_config(sdla_fe_t *fe, sdla_te3_liu_cfg_t *liu, char *name) data &= ~BIT_LINE_INTERFACE_DRIVE_TAOS; } - switch(liu->lb_mode){ - case WAN_TE3_LIU_LB_NORMAL: - break; - case WAN_TE3_LIU_LB_ANALOG: - DEBUG_TE3("%s: (T3/E3) Enable Analog Loopback mode!\n", - name); - data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; - data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - case WAN_TE3_LIU_LB_REMOTE: - DEBUG_TE3("%s: (T3/E3) Enable Remote Loopback mode!\n", - name); - data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; - data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - case WAN_TE3_LIU_LB_DIGITAL: - DEBUG_TE3("%s: (T3/E3) Enable Digital Loopback mode!\n", - name); - data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; - data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - default : - DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", - name); - break; - } - WRITE_REG(REG_LINE_INTERFACE_DRIVE, data); return 0; } @@ -1052,8 +1014,9 @@ int sdla_te3_iface_init(void *p_fe_iface) fe_iface->polling = &sdla_te3_polling; fe_iface->isr = &sdla_te3_isr; fe_iface->process_udp = &sdla_te3_udp; - fe_iface->read_alarm = &sdla_te3_alarm; + fe_iface->read_alarm = &sdla_te3_read_alarms; fe_iface->read_pmon = &sdla_te3_read_pmon; + fe_iface->flush_pmon = &sdla_te3_flush_pmon; fe_iface->set_fe_alarm = &sdla_te3_set_alarm; fe_iface->get_fe_status = &sdla_te3_get_fe_status; fe_iface->get_fe_media = &sdla_te3_get_fe_media; @@ -1072,6 +1035,9 @@ static int sdla_te3_config(void *p_fe) u16 adptr_subtype; unsigned char data = 0x00; + WAN_ASSERT(fe->write_fe_reg == NULL); + WAN_ASSERT(fe->read_fe_reg == NULL); + card->hw_iface.getcfg(card->hw, SDLA_ADAPTERSUBTYPE, &adptr_subtype); data = READ_REG(0x02); @@ -1185,7 +1151,7 @@ static int sdla_te3_config(void *p_fe) fe->fe_status = FE_DISCONNECTED; DEBUG_EVENT("%s: %s disconnected!\n", fe->name, FE_MEDIA_DECODE(fe)); - sdla_te3_alarm(fe, 1); + sdla_te3_read_alarms(fe, 1); sdla_te3_set_intr(fe); return 0; diff --git a/patches/kdrivers/src/net/sdla_te3.c~ b/patches/kdrivers/src/net/sdla_te3.c~ deleted file mode 100644 index 3da0120..0000000 --- a/patches/kdrivers/src/net/sdla_te3.c~ +++ /dev/null @@ -1,1268 +0,0 @@ -/****************************************************************************** - * - * sdla_te3.c Sangoma T3/E3 front end. - * - * Alex Feldman - * - * Copyright Sangoma Technologies Inc. 1999, 2000,2001, 2002, 2003, 2004 - * - * This program is provided subject to the Software License included in - * this package in the file license.txt. By using this program you agree - * to be bound bythe terms of this license. - * - * Should you not have a copy of the file license.txt, or wish to obtain - * a hard copy of the Software License, please contact Sangoma - * technologies Corporation. - * - * Contact: Sangoma Technologies Inc. 905-474-1990, info@sangoma.com - * - *****************************************************************************/ - - -/****************************************************************************** -** INCLUDE FILES -******************************************************************************/ - -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) -# include -# if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) -# include -# endif -# include -# include -# include -# include /* WANPIPE common user API definitions */ -# include -#elif (defined __LINUX__) || (defined __KERNEL__) -# include -# include -# include -# include -# include -# include /* WANPIPE common user API definitions */ -#else -# error "No OS Defined" -#endif - -/****************************************************************************** -** DEFINES AND MACROS -******************************************************************************/ - -/****************************************************************************** -** DEFINES AND MACROS -******************************************************************************/ - -#if defined(DEBUG) -# define WRITE_CPLD(reg,val) \ - DEBUG_EVENT("%s: Write to CPLD reg %d value %X\n", \ - fe->name, reg, val); - -# define WRITE_REG(reg,val) \ - DEBUG_EVENT("%s: Write to Framer off %X value %X\n", \ - fe->name, reg, val); -#else - -# define WRITE_CPLD(reg,val) \ - (fe->write_cpld) ? fe->write_cpld(fe->card, reg, val) : -EINVAL - -# define WRITE_EXAR_CPLD(reg,val) \ - (fe->write_fe_cpld) ? fe->write_fe_cpld(fe->card, reg, val) : -EINVAL - -# define WRITE_REG(reg,val) \ - (fe->write_framer) ? fe->write_framer(fe->card, reg, val) : -EINVAL -# define READ_REG(reg) \ - (fe->read_framer) ? fe->read_framer(fe->card, reg) : 0 -#endif - -#define WAN_FE_SWAP_BIT(value, mask) \ - if ((value) & mask){ \ - (value) &= ~mask; \ - }else{ \ - (value) |= mask; \ - } - -/* DS3: Define DS3 alarm states: LOS OOF YEL */ -#define IS_DS3_ALARM(alarm) ((alarm) & \ - (WAN_TE3_BIT_LOS_ALARM | \ - WAN_TE3_BIT_YEL_ALARM | \ - WAN_TE3_BIT_OOF_ALARM)) - -/* DS3: Define E3 alarm states: LOS OOF YEL */ -#define IS_E3_ALARM(alarm) ((alarm) & \ - (WAN_TE3_BIT_LOS_ALARM | \ - WAN_TE3_BIT_YEL_ALARM | \ - WAN_TE3_BIT_OOF_ALARM)) - -/****************************************************************************** -** FUNCTION DEFINITIONS -******************************************************************************/ - -static int sdla_te3_config(void *p_fe); -static int sdla_te3_unconfig(void *p_fe); -static int sdla_te3_get_fe_status(sdla_fe_t *fe, unsigned char *status); -static int sdla_te3_polling(sdla_fe_t *fe); -static int sdla_ds3_isr(sdla_fe_t *fe); -static int sdla_e3_isr(sdla_fe_t *fe); -static int sdla_te3_isr(sdla_fe_t *fe); -static int sdla_te3_udp(sdla_fe_t *fe, void*, unsigned char*); -static unsigned int sdla_te3_alarm(sdla_fe_t *fe, int); -static int sdla_te3_read_pmon(sdla_fe_t *fe, int); - -static int sdla_te3_update_alarm_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt); -static int sdla_te3_update_pmon_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt); - -/****************************************************************************** - * sdla_te3_get_fe_status() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static char* sdla_te3_get_fe_media_string(void) -{ - return ("AFT T3/E3"); -} - -/****************************************************************************** - * sdla_te3_get_fe_status() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static unsigned char sdla_te3_get_fe_media(sdla_fe_t *fe) -{ - return fe->fe_cfg.media; -} - -/****************************************************************************** - * sdla_te3_get_fe_status() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_te3_get_fe_status(sdla_fe_t *fe, unsigned char *status) -{ - *status = fe->fe_status; - return 0; -} - -/****************************************************************************** - * sdla_te3_polling() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_te3_polling(sdla_fe_t *fe) -{ - DEBUG_EVENT("%s: %s: This function is still not supported!\n", - fe->name, __FUNCTION__); - return -EINVAL; -} - -/****************************************************************************** - * sdla_te3_set_status() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_te3_set_status(sdla_fe_t *fe) -{ - if (IS_DS3(&fe->fe_cfg)){ - if (IS_DS3_ALARM(fe->fe_alarm)){ - if (fe->fe_status != FE_DISCONNECTED){ - DEBUG_EVENT("%s: DS3 disconnected!\n", - fe->name); - fe->fe_status = FE_DISCONNECTED; - } - }else{ - if (fe->fe_status != FE_CONNECTED){ - DEBUG_EVENT("%s: DS3 connected!\n", - fe->name); - fe->fe_status = FE_CONNECTED; - } - } - }else if (IS_E3(&fe->fe_cfg)){ - if (IS_E3_ALARM(fe->fe_alarm)){ - if (fe->fe_status != FE_DISCONNECTED){ - DEBUG_EVENT("%s: E3 disconnected!\n", - fe->name); - fe->fe_status = FE_DISCONNECTED; - } - }else{ - if (fe->fe_status != FE_CONNECTED){ - DEBUG_EVENT("%s: E3 connected!\n", - fe->name); - fe->fe_status = FE_CONNECTED; - } - } - }else{ - return -EINVAL; - } - return 0; -} - -/****************************************************************************** -** sdla_ds3_tx_isr() -** -** Description: -** Arguments: -** Returns: -******************************************************************************/ -static int sdla_ds3_tx_isr(sdla_fe_t *fe) -{ - unsigned char value; - - value = READ_REG(REG_TxDS3_LAPD_STATUS); - if (value & BIT_TxDS3_LAPD_STATUS_INT){ - DEBUG_EVENT("%s: LAPD Interrupt!\n", - fe->name); - } - return 0; -} - -/****************************************************************************** -** sdla_ds3_rx_isr() -** -** Description: -** Arguments: -** Returns: -******************************************************************************/ -static int sdla_ds3_rx_isr(sdla_fe_t *fe) -{ - unsigned char value, status; - - /* RxDS3 Interrupt status register (0x13) */ - value = READ_REG(REG_RxDS3_INT_STATUS); - status = READ_REG(REG_RxDS3_CFG_STATUS); - if (fe->fe_cfg.frame == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_CPBIT_ERR){ - if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: CP Bit Error interrupt detected!\n", - fe->name); - } - } - if (value & BIT_RxDS3_INT_STATUS_LOS){ - if (status & BIT_RxDS3_CFG_STATUS_RxLOS){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: LOS Status ON!\n", - fe->name); - } - fe->fe_alarm |= WAN_TE3_BIT_LOS_ALARM; - }else{ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: LOS Status OFF!\n", - fe->name); - } - fe->fe_alarm &= ~WAN_TE3_BIT_LOS_ALARM; - } - } - if (value & BIT_RxDS3_INT_STATUS_AIS){ - if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: AIS status %s!\n", - fe->name, - (status & BIT_RxDS3_CFG_STATUS_RxAIS) ? "ON" : "OFF"); - } - } - if (value & BIT_RxDS3_INT_STATUS_IDLE){ - if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: IDLE condition status %s!\n", - fe->name, - (status & BIT_RxDS3_CFG_STATUS_RxIDLE) ? "ON" : "OFF"); - } - } - if (value & BIT_RxDS3_INT_STATUS_OOF){ - if (status & BIT_RxDS3_CFG_STATUS_RxLOS){ - DEBUG_EVENT("%s: OOF Alarm ON!\n", - fe->name); - fe->fe_alarm |= WAN_TE3_BIT_OOF_ALARM; - }else{ - DEBUG_EVENT("%s: OOF Alarm OFF!\n", - fe->name); - fe->fe_alarm &= ~WAN_TE3_BIT_OOF_ALARM; - } - } - status = READ_REG(REG_RxDS3_STATUS); - if (value & BIT_RxDS3_INT_STATUS_FERF){ - if (status & BIT_RxDS3_STATUS_RxFERF){ - DEBUG_EVENT("%s: Rx FERF status is ON (YELLOW)!\n", - fe->name); - fe->fe_alarm |= WAN_TE3_BIT_YEL_ALARM; - }else{ - DEBUG_EVENT("%s: Rx FERF status is OFF!\n", - fe->name); - fe->fe_alarm &= ~WAN_TE3_BIT_YEL_ALARM; - } - } - if (fe->fe_cfg.frame == WAN_FR_DS3_Cbit && value & BIT_RxDS3_INT_STATUS_AIC){ - if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: AIC bit-field status %s!\n", - fe->name, - (status & BIT_RxDS3_STATUS_RxAIC) ? "ON" : "OFF"); - } - } - if (value & BIT_RxDS3_INT_STATUS_PBIT_ERR){ - if (WAN_NET_RATELIMIT()){ - DEBUG_TE3("%s: P-Bit error interrupt!\n", - fe->name); - } - } - - /* RxDS3 FEAC Interrupt (0x17) */ - value = READ_REG(REG_RxDS3_FEAC_INT); - if (value & BIT_RxDS3_FEAC_REMOVE_INT_STATUS){ - DEBUG_TE3("%s: RxFEAC Remove Interrupt!\n", - fe->name); - } - if (value & BIT_RxDS3_FEAC_VALID_INT_STATUS){ - DEBUG_TE3("%s: RxFEAC Valid Interrupt!\n", - fe->name); - } - - return 0; -} - -/****************************************************************************** -** sdla_ds3_isr() -** -** Description: -** Arguments: -** Returns: -******************************************************************************/ -static int sdla_ds3_isr(sdla_fe_t *fe) -{ - unsigned char value; - - value = READ_REG(REG_BLOCK_INT_STATUS); - if (value & BIT_BLOCK_INT_STATUS_RxDS3_E3){ - sdla_ds3_rx_isr(fe); - } - if (value & BIT_BLOCK_INT_STATUS_TxDS3_E3){ - sdla_ds3_tx_isr(fe); - } - - return 0; -} - -/****************************************************************************** -** sdla_e3_tx_isr() -** -** Description: -** Arguments: -** Returns: -******************************************************************************/ -static int sdla_e3_tx_isr(sdla_fe_t *fe) -{ - DEBUG_EVENT("%s: %s: This function is still not supported!\n", - fe->name, __FUNCTION__); - - return 0; -} - - -/****************************************************************************** -** sdla_e3_rx_isr() -** -** Description: -** Arguments: -** Returns: -******************************************************************************/ -static int sdla_e3_rx_isr(sdla_fe_t *fe) -{ - unsigned char int_status1, int_status2; - unsigned char status; - - int_status1 = READ_REG(REG_RxE3_INT_STATUS_1); - int_status2 = READ_REG(REG_RxE3_INT_STATUS_2); - status = READ_REG(REG_RxE3_CFG_STATUS_2); - if (int_status1 & BIT_RxE3_INT_STATUS_OOF){ - if (status & BIT_RxE3_CFG_STATUS_RxOOF){ - DEBUG_EVENT("%s: OOF Alarm ON!\n", - fe->name); - fe->fe_alarm |= WAN_TE3_BIT_OOF_ALARM; - }else{ - DEBUG_EVENT("%s: OOF Alarm OFF!\n", - fe->name); - fe->fe_alarm &= ~WAN_TE3_BIT_OOF_ALARM; - } - } - - if (int_status1 & BIT_RxE3_INT_STATUS_LOF){ - if (status & BIT_RxE3_CFG_STATUS_RxLOF){ - DEBUG_EVENT("%s: LOF Alarm ON!\n", - fe->name); - fe->fe_alarm |= WAN_TE3_BIT_LOF_ALARM; - }else{ - DEBUG_EVENT("%s: LOF Alarm OFF!\n", - fe->name); - fe->fe_alarm &= ~WAN_TE3_BIT_LOF_ALARM; - } - } - - if (int_status1 & BIT_RxE3_INT_STATUS_LOS){ - if (status & BIT_RxE3_CFG_STATUS_RxLOS){ - DEBUG_EVENT("%s: LOS Alarm ON!\n", - fe->name); - fe->fe_alarm |= WAN_TE3_BIT_LOS_ALARM; - }else{ - DEBUG_EVENT("%s: LOS Alarm OFF!\n", - fe->name); - fe->fe_alarm &= ~WAN_TE3_BIT_LOS_ALARM; - } - } - - if (int_status1 & BIT_RxE3_INT_STATUS_AIS){ - if (status & BIT_RxE3_CFG_STATUS_RxAIS){ - DEBUG_EVENT("%s: AIS Alarm ON!\n", - fe->name); - fe->fe_alarm |= WAN_TE3_BIT_AIS_ALARM; - }else{ - DEBUG_EVENT("%s: AIS Alarm OFF!\n", - fe->name); - fe->fe_alarm &= ~WAN_TE3_BIT_AIS_ALARM; - } - } - - if (int_status2 & BIT_RxE3_INT_STATUS_FERF){ - if (status & BIT_RxE3_CFG_STATUS_RxFERF){ - DEBUG_EVENT("%s: Rx FERF status is ON (YELLOW)!\n", - fe->name); - fe->fe_alarm |= WAN_TE3_BIT_YEL_ALARM; - }else{ - DEBUG_EVENT("%s: Rx FERF status is OFF!\n", - fe->name); - fe->fe_alarm &= ~WAN_TE3_BIT_YEL_ALARM; - } - } - - return 0; -} - -/****************************************************************************** - * sdla_e3_isr() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_e3_isr(sdla_fe_t *fe) -{ - unsigned char value; - - value = READ_REG(REG_BLOCK_INT_STATUS); - if (value & BIT_BLOCK_INT_STATUS_RxDS3_E3){ - sdla_e3_rx_isr(fe); - } - if (value & BIT_BLOCK_INT_STATUS_TxDS3_E3){ - sdla_e3_tx_isr(fe); - } - return -EINVAL; -} - -/****************************************************************************** - * sdla_te3_isr() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_te3_isr(sdla_fe_t *fe) -{ - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned char value; - int err = 0; - - value = READ_REG(REG_BLOCK_INT_STATUS); - switch(fe_cfg->media){ - case WAN_MEDIA_DS3: - err = sdla_ds3_isr(fe); - break; - case WAN_MEDIA_E3: - err = sdla_e3_isr(fe); - break; - } - fe->fe_alarm = sdla_te3_alarm(fe, 1); - return err; -} - -/****************************************************************************** - * sdla_te3_alarm() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static unsigned int sdla_te3_alarm(sdla_fe_t *fe, int update) -{ - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned int alarm = 0; - unsigned char value; - - if (fe_cfg->media == WAN_MEDIA_DS3){ - value = READ_REG(REG_RxDS3_CFG_STATUS); - if (value & BIT_RxDS3_CFG_STATUS_RxAIS){ - alarm |= WAN_TE3_BIT_AIS_ALARM; - DEBUG_TE3("%s: (T3/E3) AIS Alarm is ON\n", fe->name); - }else{ - alarm &= ~WAN_TE3_BIT_AIS_ALARM; - DEBUG_TE3("%s: (T3/E3) AIS Alarm is OFF\n", fe->name); - } - if (value & BIT_RxDS3_CFG_STATUS_RxLOS){ - alarm |= WAN_TE3_BIT_LOS_ALARM; - DEBUG_TE3("%s: (T3/E3) LOS Alarm is ON\n", fe->name); - }else{ - alarm &= ~WAN_TE3_BIT_LOS_ALARM; - DEBUG_TE3("%s: (T3/E3) LOS Alarm is OFF\n", fe->name); - } - if (value & BIT_RxDS3_CFG_STATUS_RxOOF){ - alarm |= WAN_TE3_BIT_OOF_ALARM; - DEBUG_TE3("%s: (T3/E3) OOF Alarm is ON\n", fe->name); - }else{ - alarm &= ~WAN_TE3_BIT_OOF_ALARM; - DEBUG_TE3("%s: (T3/E3) OOF Alarm is OFF\n", fe->name); - } - value = READ_REG(REG_RxDS3_STATUS); - if (value & BIT_RxDS3_STATUS_RxFERF){ - alarm |= WAN_TE3_BIT_YEL_ALARM; - DEBUG_TE3("%s: (T3/E3) YEL Alarm is ON\n", fe->name); - }else{ - alarm &= ~WAN_TE3_BIT_YEL_ALARM; - DEBUG_TE3("%s: (T3/E3) YEL Alarm is OFF\n", fe->name); - } - }else{ - value = READ_REG(REG_RxE3_CFG_STATUS_2); - if (value & BIT_RxE3_CFG_STATUS_RxOOF){ - DEBUG_TE3("%s: (T3/E3) OOF Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_OOF_ALARM; - }else{ - DEBUG_TE3("%s: (T3/E3) OOF Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_OOF_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxLOF){ - DEBUG_TE3("%s: (T3/E3) LOF Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_LOF_ALARM; - }else{ - DEBUG_TE3("%s: (T3/E3) LOF Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_LOF_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxLOS){ - DEBUG_TE3("%s: (T3/E3) LOS Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_LOS_ALARM; - }else{ - DEBUG_TE3("%s: (T3/E3) LOS Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_LOS_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxAIS){ - DEBUG_TE3("%s: (T3/E3) AIS Alarm ON!\n", - fe->name); - alarm |= WAN_TE3_BIT_AIS_ALARM; - }else{ - DEBUG_TE3("%s: (T3/E3) AIS Alarm OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_AIS_ALARM; - } - - if (value & BIT_RxE3_CFG_STATUS_RxFERF){ - DEBUG_TE3("%s: (T3/E3) Rx FERF status is ON (YELLOW)!\n", - fe->name); - alarm |= WAN_TE3_BIT_YEL_ALARM; - }else{ - DEBUG_TE3("%s: (T3/E3) Rx FERF status is OFF!\n", - fe->name); - alarm &= ~WAN_TE3_BIT_YEL_ALARM; - } - } - - fe->fe_alarm = alarm; - if (update){ - sdla_te3_set_status(fe); - } - return alarm; -} - - -/****************************************************************************** - * sdla_te3_set_alarm() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_te3_set_alarm(sdla_fe_t *fe, unsigned int alarm) -{ - DEBUG_EVENT("%s: %s: This function is still not supported!\n", - fe->name, __FUNCTION__); - return -EINVAL; -} - -/****************************************************************************** - * sdla_te3_read_pmon() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_te3_read_pmon(sdla_fe_t *fe, int action) -{ - sdla_te3_pmon_t *pmon = (sdla_te3_pmon_t*)&fe->fe_stats.u.te3_pmon; - unsigned char value_msb, value_lsb; - - value_msb = READ_REG(REG_PMON_LCV_MSB); - value_lsb = READ_REG(REG_PMON_LCV_LSB); - pmon->pmon_lcv += ((value_msb << 8) | value_lsb); - - value_msb = READ_REG(REG_PMON_FRAMING_ERR_CNT_MSB); - value_lsb = READ_REG(REG_PMON_FRAMING_ERR_CNT_LSB); - pmon->pmon_framing += ((value_msb << 8) | value_lsb); - - value_msb = READ_REG(REG_PMON_PARITY_ERR_CNT_MSB); - value_lsb = READ_REG(REG_PMON_PARITY_ERR_CNT_LSB); - pmon->pmon_parity += ((value_msb << 8) | value_lsb); - - value_msb = READ_REG(REG_PMON_FEBE_EVENT_CNT_MSB); - value_lsb = READ_REG(REG_PMON_FEBE_EVENT_CNT_LSB); - pmon->pmon_febe += ((value_msb << 8) | value_lsb); - - value_msb = READ_REG(REG_PMON_CPBIT_ERROR_CNT_MSB); - value_lsb = READ_REG(REG_PMON_CPBIT_ERROR_CNT_LSB); - pmon->pmon_cpbit += ((value_msb << 8) | value_lsb); - return 0; -} - - - -/****************************************************************************** -* sdla_te3_flush_pmon() -* -* Description: -* Arguments: -* Returns: -******************************************************************************/ -static int sdla_te3_flush_pmon(sdla_fe_t *fe) -{ - sdla_te3_pmon_t *pmon = (sdla_te3_pmon_t*)&fe->fe_stats.u.te3_pmon; - - pmon->pmon_lcv = 0; - pmon->pmon_framing = 0; - pmon->pmon_parity = 0; - pmon->pmon_febe = 0; - pmon->pmon_cpbit = 0; - return 0; -} - -/****************************************************************************** -* sdla_te3_old_set_lb_modes() -* -* Description: -* Arguments: -* Returns: -******************************************************************************/ -static int -sdla_te3_old_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) -{ - - WAN_ASSERT(fe->write_cpld == NULL); - DEBUG_EVENT("%s: %s %s mode...\n", - fe->name, - WAN_TE3_LB_MODE_DECODE(mode), - WAN_TE3_LB_TYPE_DECODE(type)); - - if (mode == WAN_TE3_DEACTIVATE_LB){ - fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_LLB; - fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_RLB; - }else{ - switch(type){ - case WAN_TE3_LIU_LB_ANALOG: - fe->te3_param.cpld_status |= BIT_CPLD_STATUS_LLB; - fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_RLB; - break; - case WAN_TE3_LIU_LB_REMOTE: - fe->te3_param.cpld_status &= ~BIT_CPLD_STATUS_LLB; - fe->te3_param.cpld_status |= BIT_CPLD_STATUS_RLB; - break; - case WAN_TE3_LIU_LB_DIGITAL: - fe->te3_param.cpld_status |= BIT_CPLD_STATUS_LLB; - fe->te3_param.cpld_status |= BIT_CPLD_STATUS_RLB; - break; - default : - DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", - fe->name); - break; - } - } - /* Write value to CPLD Status/Control register */ - WRITE_CPLD(REG_CPLD_STATUS, fe->te3_param.cpld_status); - return 0; -} - -static int -sdla_te3_set_lb_modes(sdla_fe_t *fe, unsigned char type, unsigned char mode) -{ - unsigned char data = 0x00; - - WAN_ASSERT(fe->write_fe_reg == NULL); - WAN_ASSERT(fe->read_fe_reg == NULL); - DEBUG_EVENT("%s: %s %s mode...\n", - fe->name, - WAN_TE3_LB_MODE_DECODE(mode), - WAN_TE3_LB_TYPE_DECODE(type)); - - data = READ_REG(REG_LINE_INTERFACE_DRIVE); - if (mode == WAN_TE3_DEACTIVATE_LB){ - data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; - data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; - }else{ - switch(type){ - case WAN_TE3_LIU_LB_NORMAL: - break; - case WAN_TE3_LIU_LB_ANALOG: - data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; - data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - case WAN_TE3_LIU_LB_REMOTE: - data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; - data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - case WAN_TE3_LIU_LB_DIGITAL: - data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; - data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - default : - DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", - fe->name); - break; - } - } - WRITE_REG(REG_LINE_INTERFACE_DRIVE, data); - return 0; -} - - -/****************************************************************************** - * sdla_te3_udp() - * - * Description: - * Arguments: - * Returns: - ****************************************************************************** - */ -static int sdla_te3_udp(sdla_fe_t *fe, void *pudp_cmd, unsigned char *data) -{ - sdla_t *card = (sdla_t*)fe->card; - wan_cmd_t *udp_cmd = (wan_cmd_t*)pudp_cmd; - int err = -EINVAL; - - switch(udp_cmd->wan_cmd_command){ - - case WAN_GET_MEDIA_TYPE: - data[0] = fe->fe_cfg.media; - udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(unsigned char); - break; - - case WAN_FE_SET_LB_MODE: - /* Activate/Deactivate Line Loopback modes */ - if (card->adptr_subtype == AFT_SUBTYPE_NORMAL){ - err = sdla_te3_old_set_lb_modes(fe, data[0], data[1]); - }else if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ - err = sdla_te3_set_lb_modes(fe, data[0], data[1]); - } - udp_cmd->wan_cmd_return_code = - (!err) ? WAN_CMD_OK : WAN_UDP_FAILED_CMD; - udp_cmd->wan_cmd_data_len = 0x00; - break; - - case WAN_FE_GET_STAT: - /* TE1_56K Read T1/E1/56K alarms */ - sdla_te3_read_pmon(fe, 0); - if (udp_cmd->wan_cmd_fe_force){ - /* force to read FE alarms */ - DEBUG_EVENT("%s: Force to read Front-End alarms\n", - fe->name); - fe->fe_stats.alarms = - sdla_te3_alarm(fe, 1); - } - memcpy(&data[0], &fe->fe_stats, sizeof(sdla_fe_stats_t)); - udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(sdla_fe_stats_t); - break; - - case WAN_FE_FLUSH_PMON: - /* TE1 Flush T1/E1 pmon counters */ - sdla_te3_flush_pmon(fe); - udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - break; - - case WAN_FE_GET_CFG: - /* Read T1/E1 configuration */ - memcpy(&data[0], - &fe->fe_cfg, - sizeof(sdla_fe_cfg_t)); - udp_cmd->wan_cmd_return_code = WAN_CMD_OK; - udp_cmd->wan_cmd_data_len = sizeof(sdla_te_cfg_t); - break; - - default: - udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD; - udp_cmd->wan_cmd_data_len = 0; - break; - } - return 0; -} - - -static int sdla_te3_set_intr(sdla_fe_t *fe) -{ - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - - DEBUG_EVENT("%s: Enabling interrupts for %s (%d)!\n", - fe->name, FE_MEDIA_DECODE(fe), IS_DS3(fe_cfg)); - /* Enable Framer Interrupts */ - /* 1. Block Interrupt Enable */ - WRITE_REG(REG_BLOCK_INT_ENABLE, - BIT_BLOCK_INT_ENABLE_RxDS3_E3 | - BIT_BLOCK_INT_ENABLE_TxDS3_E3); - if (IS_DS3(fe_cfg)){ - /* 1. RxDS3 Interrupt Enable */ - WRITE_REG(REG_RxDS3_INT_ENABLE, - BIT_RxDS3_INT_ENABLE_CPBIT_ERR | - BIT_RxDS3_INT_ENABLE_LOS | - BIT_RxDS3_INT_ENABLE_OOF | - BIT_RxDS3_INT_ENABLE_AIS | - BIT_RxDS3_INT_ENABLE_IDLE | - BIT_RxDS3_INT_ENABLE_FERF | - BIT_RxDS3_INT_ENABLE_AIC | - BIT_RxDS3_INT_ENABLE_PBIT_ERR ); - - /* RxDS3 FEAC */ - WRITE_REG(REG_RxDS3_FEAC_INT, - BIT_RxDS3_FEAC_REMOVE_INT_EN | - BIT_RxDS3_FEAC_VALID_INT_EN); - - /* RxDS3 LAPD */ - WRITE_REG(REG_TxDS3_LAPD_STATUS, - BIT_TxDS3_LAPD_STATUS_INT_EN); - - }else if (IS_E3(fe_cfg)){ - /* RxE3 Interrupt Enable 1 (0x12) */ - WRITE_REG(REG_RxE3_INT_ENABLE_1, - BIT_RxE3_INT_ENABLE_OOF | - BIT_RxE3_INT_ENABLE_LOS | - BIT_RxE3_INT_ENABLE_LOF | - BIT_RxE3_INT_ENABLE_AIS); - - /* RxE3 Interrupt Enable 2 (0x13) */ - WRITE_REG(REG_RxE3_INT_ENABLE_2, - BIT_RxE3_INT_ENABLE_FERF | - BIT_RxE3_INT_ENABLE_FRAMING); - }else{ - return -EINVAL; - } - - return 0; -} - - -/****************************************************************************** - * sdla_te3_liu_config() - * - * Description: Configure Sangoma TE3 board - * Arguments: - * Returns: WAN_TRUE - TE3 configred successfully, otherwise WAN_FALSE. - ****************************************************************************** - */ -static int -sdla_te3_liu_config(sdla_fe_t *fe, sdla_te3_liu_cfg_t *liu, char *name) -{ - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned char data = 0x00; - - if (fe_cfg->media == WAN_MEDIA_E3){ - data |= BIT_CPLD_CNTRL_E3; - } - if (liu->rx_equal == WAN_TRUE){ - DEBUG_TE3("%s: (T3/E3) Enable Receive Equalizer\n", - name); - data |= BIT_CPLD_CNTRL_REQEN; - }else{ - DEBUG_TE3("%s: (T3/E3) Disable Receive Equalizer\n", - name); - data &= ~BIT_CPLD_CNTRL_REQEN; - } - if (liu->tx_lbo == WAN_TRUE){ - DEBUG_TE3("%s: (T3/E2) Enable Transmit Build-out\n", - name); - data |= BIT_CPLD_CNTRL_TxLEV; - }else{ - DEBUG_TE3("%s: (T3/E3) Disable Transmit Build-out\n", - name); - data &= ~BIT_CPLD_CNTRL_TxLEV; - } - /* Write value to CPLD Control register */ - WRITE_CPLD(REG_CPLD_CNTRL, data); - - data = 0x00; - if (liu->taos == WAN_TRUE){ - DEBUG_TE3("%s: (T3/E3) Enable Transmit All Ones\n", - name); - data |= BIT_CPLD_STATUS_TAOS; - }else{ - DEBUG_TE3("%s: (T3/E3) Disable Transmit All Ones\n", - name); - data &= ~BIT_CPLD_STATUS_TAOS; - } - switch(liu->lb_mode){ - case WAN_TE3_LIU_LB_NORMAL: - break; - case WAN_TE3_LIU_LB_ANALOG: - DEBUG_TE3("%s: (T3/E3) Enable Analog Loopback mode!\n", - name); - data |= BIT_CPLD_STATUS_LLB; - data &= ~BIT_CPLD_STATUS_RLB; - break; - case WAN_TE3_LIU_LB_REMOTE: - DEBUG_TE3("%s: (T3/E3) Enable Remote Loopback mode!\n", - name); - data &= ~BIT_CPLD_STATUS_LLB; - data |= BIT_CPLD_STATUS_RLB; - break; - case WAN_TE3_LIU_LB_DIGITAL: - DEBUG_TE3("%s: (T3/E3) Enable Digital Loopback mode!\n", - name); - data |= BIT_CPLD_STATUS_LLB; - data |= BIT_CPLD_STATUS_RLB; - break; - default : - DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", - name); - break; - } - /* Write value to CPLD Status/Control register */ - WRITE_CPLD(REG_CPLD_STATUS, data); - return 0; -} - -/****************************************************************************** - * sdla_te3_shark_liu_config() - * - * Description: Configure Sangoma TE3 Shark board - * Arguments: - * Returns: WAN_TRUE - TE3 configred successfully, otherwise WAN_FALSE. - ****************************************************************************** - */ -static int -sdla_te3_shark_liu_config(sdla_fe_t *fe, sdla_te3_liu_cfg_t *liu, char *name) -{ - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - unsigned char data = 0x00; - - if (fe_cfg->media == WAN_MEDIA_E3){ - data |= BIT_EXAR_CPLD_CNTRL_E3; - } - /* Write value to CPLD Control register */ - WRITE_EXAR_CPLD(REG_EXAR_CPLD_CNTRL, data); - - data = 0x00; - if (liu->rx_equal == WAN_TRUE){ - DEBUG_TE3("%s: (T3/E3) Enable Receive Equalizer\n", - name); - data |= BIT_LINE_INTERFACE_DRIVE_REQB; - }else{ - DEBUG_TE3("%s: (T3/E3) Disable Receive Equalizer\n", - name); - data &= ~BIT_LINE_INTERFACE_DRIVE_REQB; - } - if (liu->tx_lbo == WAN_TRUE){ - DEBUG_TE3("%s: (T3/E2) Enable Transmit Build-out\n", - name); - data |= BIT_LINE_INTERFACE_DRIVE_TxLEV; - }else{ - DEBUG_TE3("%s: (T3/E3) Disable Transmit Build-out\n", - name); - data &= ~BIT_LINE_INTERFACE_DRIVE_TxLEV; - } - if (liu->taos == WAN_TRUE){ - DEBUG_TE3("%s: (T3/E3) Enable Transmit All Ones\n", - name); - data |= BIT_LINE_INTERFACE_DRIVE_TAOS; - }else{ - DEBUG_TE3("%s: (T3/E3) Disable Transmit All Ones\n", - name); - data &= ~BIT_LINE_INTERFACE_DRIVE_TAOS; - } - - switch(liu->lb_mode){ - case WAN_TE3_LIU_LB_NORMAL: - break; - case WAN_TE3_LIU_LB_ANALOG: - DEBUG_TE3("%s: (T3/E3) Enable Analog Loopback mode!\n", - name); - data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; - data &= ~BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - case WAN_TE3_LIU_LB_REMOTE: - DEBUG_TE3("%s: (T3/E3) Enable Remote Loopback mode!\n", - name); - data &= ~BIT_LINE_INTERFACE_DRIVE_LLOOP; - data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - case WAN_TE3_LIU_LB_DIGITAL: - DEBUG_TE3("%s: (T3/E3) Enable Digital Loopback mode!\n", - name); - data |= BIT_LINE_INTERFACE_DRIVE_LLOOP; - data |= BIT_LINE_INTERFACE_DRIVE_RLOOP; - break; - default : - DEBUG_EVENT("%s: (T3/E3) Unknown loopback mode!\n", - name); - break; - } - WRITE_REG(REG_LINE_INTERFACE_DRIVE, data); - - return 0; -} - - -int sdla_te3_iface_init(void *p_fe_iface) -{ - sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)p_fe_iface; - - /* Inialize Front-End interface functions */ - fe_iface->config = &sdla_te3_config; - fe_iface->unconfig = &sdla_te3_unconfig; - fe_iface->polling = &sdla_te3_polling; - fe_iface->isr = &sdla_te3_isr; - fe_iface->process_udp = &sdla_te3_udp; - fe_iface->read_alarm = &sdla_te3_alarm; - fe_iface->read_pmon = &sdla_te3_read_pmon; - fe_iface->set_fe_alarm = &sdla_te3_set_alarm; - fe_iface->get_fe_status = &sdla_te3_get_fe_status; - fe_iface->get_fe_media = &sdla_te3_get_fe_media; - fe_iface->get_fe_media_string = &sdla_te3_get_fe_media_string; - fe_iface->update_alarm_info = &sdla_te3_update_alarm_info; - fe_iface->update_pmon_info = &sdla_te3_update_pmon_info; - - return 0; -} -static int sdla_te3_config(void *p_fe) -{ - sdla_fe_t *fe = (sdla_fe_t*)p_fe; - sdla_t* card = (sdla_t*)fe->card; - sdla_fe_cfg_t *fe_cfg = &fe->fe_cfg; - sdla_te3_cfg_t *te3_cfg = &fe_cfg->cfg.te3_cfg; - u16 adptr_subtype; - unsigned char data = 0x00; - - card->hw_iface.getcfg(card->hw, SDLA_ADAPTERSUBTYPE, &adptr_subtype); - - data = READ_REG(0x02); - - /* configure Line Interface Unit */ - if (card->adptr_subtype == AFT_SUBTYPE_NORMAL){ - sdla_te3_liu_config(fe, &te3_cfg->liu_cfg, fe->name); - }else if (card->adptr_subtype == AFT_SUBTYPE_SHARK){ - sdla_te3_shark_liu_config(fe, &te3_cfg->liu_cfg, fe->name); - }else{ - DEBUG_EVENT("%s: Unknown Adapter Subtype (%X)\n", - fe->name, card->adptr_subtype); - return -EINVAL; - } - - switch(fe_cfg->media){ - case WAN_MEDIA_DS3: - DEBUG_TE3("%s: (T3/E3) Media type DS3\n", - fe->name); - data |= BIT_OPMODE_DS3; - break; - case WAN_MEDIA_E3: - DEBUG_TE3("%s: (T3/E3) Media type E3\n", - fe->name); - data &= ~BIT_OPMODE_DS3; - break; - default: - DEBUG_EVENT("%s: Invalid Media type 0x%X\n", - fe->name,fe_cfg->media); - return -EINVAL; - } - - switch(fe_cfg->frame){ - case WAN_FR_E3_G751: - if (fe_cfg->media != WAN_MEDIA_E3){ - DEBUG_EVENT("%s: (T3/E3) Invalid Frame Format!\n", - fe->name); - return -EINVAL; - } - DEBUG_TE3("%s: (T3/E3) Frame type G.751\n", - fe->name); - data &= ~BIT_OPMODE_FRAME_FRMT; - break; - case WAN_FR_E3_G832: - if (fe_cfg->media != WAN_MEDIA_E3){ - DEBUG_EVENT("%s: (T3/E3) Invalid Frame Format!\n", - fe->name); - return -EINVAL; - } - DEBUG_TE3("%s: (T3/E3) Frame type G.832\n", - fe->name); - data |= BIT_OPMODE_FRAME_FRMT; - break; - case WAN_FR_DS3_Cbit: - if (fe_cfg->media != WAN_MEDIA_DS3){ - DEBUG_EVENT("%s: (T3/E3) Invalid Frame Format!\n", - fe->name); - return -EINVAL; - } - DEBUG_TE3("%s: (T3/E3) Frame type C-bit Parity\n", - fe->name); - data &= ~BIT_OPMODE_FRAME_FRMT; - break; - case WAN_FR_DS3_M13: - if (fe_cfg->media != WAN_MEDIA_DS3){ - DEBUG_EVENT("%s: (T3/E3) Invalid Frame Format!\n", - fe->name); - return -EINVAL; - } - DEBUG_TE3("%s: (T3/E3) Frame type M13\n", - fe->name); - data |= BIT_OPMODE_FRAME_FRMT; - break; - default: - DEBUG_EVENT("%s: Invalid Frame type 0x%X\n", - fe->name,fe_cfg->frame); - return -EINVAL; - } - data |= BIT_OPMODE_INTERNAL_LOS; - data |= (BIT_OPMODE_TIMREFSEL1 | BIT_OPMODE_TIMREFSEL0); - WRITE_REG(REG_OPMODE, data); - - data = 0x00; - switch(fe_cfg->lcode){ - case WAN_LCODE_AMI: - DEBUG_TE3("%s: (T3/E3) Line code AMI\n", - fe->name); - data |= BIT_IO_CONTROL_AMI; - break; - case WAN_LCODE_HDB3: - DEBUG_TE3("%s: (T3/E3) Line code HDB3\n", - fe->name); - data &= ~BIT_IO_CONTROL_AMI; - break; - case WAN_LCODE_B3ZS: - DEBUG_TE3("%s: (T3/E3) Line code B3ZS\n", - fe->name); - data &= ~BIT_IO_CONTROL_AMI; - break; - default: - DEBUG_EVENT("%s: Invalid Lcode 0x%X\n", - fe->name,fe_cfg->lcode); - return -EINVAL; - } - data |= BIT_IO_CONTROL_DISABLE_TXLOC; - data |= BIT_IO_CONTROL_DISABLE_RXLOC; - data |= BIT_IO_CONTROL_RxLINECLK; - WRITE_REG(REG_IO_CONTROL, data); - - /* Initialize Front-End parameters */ - fe->fe_status = FE_DISCONNECTED; - DEBUG_EVENT("%s: %s disconnected!\n", - fe->name, FE_MEDIA_DECODE(fe)); - sdla_te3_alarm(fe, 1); - - sdla_te3_set_intr(fe); - return 0; -} - -static int sdla_te3_unconfig(void *p_fe) -{ - sdla_fe_t *fe = (sdla_fe_t*)p_fe; - DEBUG_EVENT("%s: Unconfiguring T3/E3 interface\n", - fe->name); - return 0; -} - -static int -sdla_te3_update_alarm_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt) -{ - if (IS_DS3(&fe->fe_cfg)){ - PROC_ADD_LINE(m, - "=============================== DS3 Alarms ===============================\n"); - PROC_ADD_LINE(m, - PROC_STATS_ALARM_FORMAT, - "AIS", WAN_TE3_AIS_ALARM(fe->fe_alarm), - "LOS", WAN_TE3_LOS_ALARM(fe->fe_alarm)); - PROC_ADD_LINE(m, - PROC_STATS_ALARM_FORMAT, - "OOF", WAN_TE3_OOF_ALARM(fe->fe_alarm), - "YEL", WAN_TE3_YEL_ALARM(fe->fe_alarm)); - }else{ - PROC_ADD_LINE(m, - "=============================== E3 Alarms ===============================\n"); - PROC_ADD_LINE(m, - PROC_STATS_ALARM_FORMAT, - "AIS", WAN_TE3_AIS_ALARM(fe->fe_alarm), - "LOS", WAN_TE3_LOS_ALARM(fe->fe_alarm)); - PROC_ADD_LINE(m, - PROC_STATS_ALARM_FORMAT, - "OFF", WAN_TE3_OOF_ALARM(fe->fe_alarm), - "YEL", WAN_TE3_YEL_ALARM(fe->fe_alarm)); - PROC_ADD_LINE(m, - PROC_STATS_ALARM_FORMAT, - "LOF", WAN_TE3_LOF_ALARM(fe->fe_alarm), - "", ""); - } - - return m->count; -} - -static int sdla_te3_update_pmon_info(sdla_fe_t* fe, struct seq_file* m, int* stop_cnt) -{ - PROC_ADD_LINE(m, - "=========================== %s PMON counters ============================\n", - (IS_DS3(&fe->fe_cfg)) ? "DS3" : "E3"); - PROC_ADD_LINE(m, - PROC_STATS_PMON_FORMAT, - "Line Code Violation", fe->fe_stats.u.te3_pmon.pmon_lcv, - "Framing Bit/Byte Error", fe->fe_stats.u.te3_pmon.pmon_framing); - if (IS_DS3(&fe->fe_cfg)){ - if (fe->fe_cfg.frame == WAN_FR_DS3_Cbit){ - PROC_ADD_LINE(m, - PROC_STATS_PMON_FORMAT, - "Parity Error", fe->fe_stats.u.te3_pmon.pmon_parity, - "CP-Bit Error Event", fe->fe_stats.u.te3_pmon.pmon_cpbit); - }else{ - PROC_ADD_LINE(m, - PROC_STATS_PMON_FORMAT, - "Parity Error", fe->fe_stats.u.te3_pmon.pmon_parity, - "FEBE Event", fe->fe_stats.u.te3_pmon.pmon_febe); - - } - }else{ - PROC_ADD_LINE(m, - PROC_STATS_PMON_FORMAT, - "Parity Error", fe->fe_stats.u.te3_pmon.pmon_parity, - "FEBE Event", fe->fe_stats.u.te3_pmon.pmon_febe); - } - - return m->count; -} diff --git a/patches/kdrivers/src/net/sdla_x25.c b/patches/kdrivers/src/net/sdla_x25.c index b583103..e3b4e32 100644 --- a/patches/kdrivers/src/net/sdla_x25.c +++ b/patches/kdrivers/src/net/sdla_x25.c @@ -343,9 +343,7 @@ typedef struct x25_channel /* FIXME Take this out */ #pragma pack(1) - #ifdef NEX_OLD_CALL_INFO - typedef struct x25_call_info { char dest[17]; ;/* ASCIIZ destination address */ @@ -371,8 +369,9 @@ typedef struct x25_call_info unsigned short lcn ; } x25_call_info_t; #endif - #pragma pack() + + /*=============================================== * Private Function Prototypes @@ -731,7 +730,7 @@ int wpx_init (sdla_t* card, wandev_conf_t* conf) u.cfg.station = 0; /* DCE mode */ } - if (conf->interface != WANOPT_RS232 ){ + if (conf->electrical_interface != WANOPT_RS232 ){ u.cfg.hdlcOptions |= 0x80; /* V35 mode */ } @@ -927,7 +926,7 @@ int wpx_init (sdla_t* card, wandev_conf_t* conf) /* Initialize protocol-specific fields of adapter data space */ card->wandev.bps = conf->bps; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.clocking = conf->clocking; card->wandev.station = conf->u.x25.station; card->isr = &wpx_isr; @@ -1049,7 +1048,7 @@ static int update (wan_device_t* wandev) int err=0; /* sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL)) + if ((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if (wandev->state == WAN_UNCONFIGURED) @@ -1062,7 +1061,7 @@ static int update (wan_device_t* wandev) if (dev == NULL) return -ENODEV; - card = wandev->private; + card = wandev->priv; spin_lock_irqsave(&card->wandev.lock, smp_flags); @@ -1108,7 +1107,7 @@ static int update (wan_device_t* wandev) */ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; x25_channel_t* chan; int err = 0; @@ -1265,7 +1264,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) static int del_if (wan_device_t* wandev, netdevice_t* dev) { unsigned long smp_flags; - sdla_t *card=wandev->private; + sdla_t *card=wandev->priv; x25_channel_t* chan = dev->priv; /* Delete interface name from proc fs. */ @@ -1339,7 +1338,8 @@ static int if_init (netdevice_t* dev) /* Initialize device driver entry points */ dev->open = &if_open; dev->stop = &if_close; - + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; dev->do_ioctl = &x25_ioctl; @@ -6797,7 +6797,7 @@ static int x25_set_dev_config(struct file *file, if (wandev == NULL) return count; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); diff --git a/patches/kdrivers/src/net/sdla_xilinx.c b/patches/kdrivers/src/net/sdla_xilinx.c index 2b68335..089146e 100644 --- a/patches/kdrivers/src/net/sdla_xilinx.c +++ b/patches/kdrivers/src/net/sdla_xilinx.c @@ -245,11 +245,11 @@ static int del_if(wan_device_t *wandev, netdevice_t *dev); static int if_init (netdevice_t* dev); static int wanpipe_xilinx_open (netdevice_t* dev); static int wanpipe_xilinx_close (netdevice_t* dev); -static int wanpipe_xilinx_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); -static struct net_device_stats* wanpipe_xilinx_ifstats (netdevice_t* dev); +static int wanpipe_xilinx_ioctl(netdevice_t*, struct ifreq*, wan_ioctl_cmd_t); #if defined(__LINUX__) static int wanpipe_xilinx_send (netskb_t* skb, netdevice_t* dev); +static struct net_device_stats* wanpipe_xilinx_ifstats (netdevice_t* dev); #else static int wan_aft_output(netdevice_t*, netskb_t*, struct sockaddr*, struct rtentry*); @@ -394,7 +394,6 @@ static int aft_tdmv_free(sdla_t *card); static int aft_tdmv_if_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf); static int aft_tdmv_if_free(sdla_t *card, private_area_t *chan); static void aft_critical_shutdown (sdla_t *card); -static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt); #ifdef AFT_TDM_API_SUPPORT static int aft_read_rbs_bits(void *chan_ptr, u32 ch, u8 *rbs_bits); @@ -405,6 +404,8 @@ static int aft_tdm_api_update_state_channelized(sdla_t *card, private_area_t *ch static int aft_tdm_api_free_channelized(sdla_t *card, private_area_t *chan); #endif +static void wanpipe_wake_stack(private_area_t* chan); + static void xilinx_delay(int sec) { #if 0 @@ -484,16 +485,12 @@ int wp_xilinx_init (sdla_t* card, wandev_conf_t* conf) return -EINVAL; } -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("%s: Total Mem %d\n", - __FUNCTION__,wan_atomic_read(&wan_debug_mem)); -#endif /* Obtain hardware configuration parameters */ card->wandev.clocking = conf->clocking; card->wandev.ignore_front_end_status = conf->ignore_front_end_status; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; card->wandev.comm_port = conf->comm_port; card->wandev.udp_port = conf->udp_port; card->wandev.new_if_cnt = 0; @@ -534,11 +531,11 @@ int wp_xilinx_init (sdla_t* card, wandev_conf_t* conf) } memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; - card->fe.write_fe_reg = write_front_end_reg; - card->fe.read_fe_reg = read_front_end_reg; + card->fe.write_fe_reg = card->hw_iface.fe_write; //write_front_end_reg; + card->fe.read_fe_reg = card->hw_iface.fe_read; //read_front_end_reg; card->wandev.te_report_rbsbits = aft_report_rbsbits; card->wandev.fe_enable_timer = enable_timer; @@ -550,7 +547,7 @@ int wp_xilinx_init (sdla_t* card, wandev_conf_t* conf) card->fe.fe_cfg.cfg.te_cfg.te_ref_clock = WAN_TE1_REFCLK_OSC; } - conf->interface = + conf->electrical_interface = IS_T1_CARD(card) ? WANOPT_V35 : WANOPT_RS232; if (card->wandev.comm_port == WANOPT_PRI){ @@ -739,13 +736,13 @@ int wp_xilinx_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t *card = wandev->private; + sdla_t *card = wandev->priv; netdevice_t *dev; volatile private_area_t *chan; wan_smp_flag_t smp_flags; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -815,7 +812,7 @@ static int aft_tdm_api_init(sdla_t *card, private_area_t *chan, int logic_ch, wa /* Initilaize TDM API Parameters */ wp_tdm_api_dev->chan = chan; wp_tdm_api_dev->card = card; - wan_spin_lock_init(&wp_tdm_api_dev->lock); + wan_spin_lock_init(&wp_tdm_api_dev->lock, "wan_tdmapi_lock"); strncpy(wp_tdm_api_dev->name,chan->if_name,WAN_IFNAME_SZ); if (conf->hdlc_streaming) { @@ -931,6 +928,23 @@ static int aft_tdm_api_free_channelized(sdla_t *card, private_area_t *chan) #endif + + +static void wanpipe_wake_stack(private_area_t* chan) +{ + WAN_NETIF_WAKE_QUEUE(chan->common.dev); +#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) + if (chan->common.usedby == API){ +# if defined(__LINUX__) + wan_wakeup_api(chan); +# endif + }else if (chan->common.usedby == STACK){ + wanpipe_lip_kick(chan,0); + } +#endif +} + + /*============================================================================ * new_if - Create new logical channel. * @@ -967,7 +981,7 @@ static int aft_tdm_api_free_channelized(sdla_t *card, private_area_t *chan) */ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf, int channelized) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; private_area_t* chan; int err = 0; @@ -1481,7 +1495,6 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* chan->common.iface.close = &wanpipe_xilinx_close; chan->common.iface.output = &wan_aft_output; chan->common.iface.ioctl = &wanpipe_xilinx_ioctl; - chan->common.iface.get_stats = &wanpipe_xilinx_ifstats; chan->common.iface.tx_timeout= &wanpipe_xilinx_tx_timeout; if (wan_iface.attach){ wan_iface.attach(dev, NULL, chan->common.is_netdev); @@ -1512,7 +1525,7 @@ new_if_error: static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) { int err=-EINVAL; - sdla_t *card=wandev->private; + sdla_t *card=wandev->priv; wan_netif_set_priv(dev, NULL); @@ -1871,6 +1884,8 @@ static int if_init (netdevice_t* dev) } dev->hard_header_len = 0; + dev->hard_header = NULL; + dev->rebuild_header = NULL; /* Enable Mulitcasting if user selected */ if (chan->mc == WANOPT_YES){ @@ -2017,11 +2032,7 @@ static int wanpipe_xilinx_open (netdevice_t* dev) set_chan_state(card, dev, WAN_CONNECTED); WAN_NETIF_WAKE_QUEUE(dev); WAN_NETIF_CARRIER_ON(dev); - if (chan->common.usedby == API){ - wan_wakeup_api(chan); - }else if (chan->common.usedby == STACK){ - wanpipe_lip_kick(chan,0); - } + wanpipe_wake_stack(chan); } wan_spin_unlock_irq(&card->wandev.lock,&flags); @@ -2188,15 +2199,8 @@ static void wanpipe_xilinx_tx_timeout (netdevice_t* dev) xilinx_tx_fifo_under_recover(card,chan); - WAN_NETIF_WAKE_QUEUE(dev); /*netif_wake_queue (dev);*/ + wanpipe_wake_stack(chan); - if (chan->common.usedby == API){ -# if defined(__LINUX__) - wan_wakeup_api(chan); -# endif - }else if (chan->common.usedby == STACK){ - wanpipe_lip_kick(chan,0); - } } @@ -2334,8 +2338,13 @@ static int wanpipe_xilinx_send (netskb_t* skb, netdevice_t* dev) goto xilinx_tx_dma; } else if (wan_skb_queue_len(&chan->wp_tx_pending_list) > chan->max_tx_bufs){ - WAN_NETIF_STOP_QUEUE(dev); /*stop_net_queue(dev);*/ - xilinx_dma_tx(card,chan); + wan_smp_flag_t smp_flags; + wan_spin_lock_irq(&card->wandev.lock, &smp_flags); + WAN_NETIF_STOP_QUEUE(dev); /*stop_net_queue(dev);*/ + wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + if (chan->hdlc_eng) { + xilinx_dma_tx(card,chan); + } return 1; }else{ xilinx_tx_dma: @@ -2364,7 +2373,9 @@ xilinx_tx_dma: } wan_skb_queue_tail(&chan->wp_tx_pending_list,skb); - xilinx_dma_tx(card,chan); + if (chan->hdlc_eng) { + xilinx_dma_tx(card,chan); + } wan_netif_set_ticks(dev, SYSTEM_TICKS); } } @@ -2394,6 +2405,7 @@ if_send_exit_crit: } +#if defined(__LINUX__) /*============================================================================ * if_stats * @@ -2416,9 +2428,7 @@ static struct net_device_stats* wanpipe_xilinx_ifstats (netdevice_t* dev) return &chan->if_stats; } - - - +#endif /*======================================================================== * @@ -2440,7 +2450,7 @@ static struct net_device_stats* wanpipe_xilinx_ifstats (netdevice_t* dev) * */ static int -wanpipe_xilinx_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +wanpipe_xilinx_ioctl(netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t cmd) { private_area_t* chan; sdla_t *card; @@ -3942,16 +3952,7 @@ tx_post_ok: tx_post_exit: if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ - WAN_NETIF_WAKE_QUEUE(chan->common.dev); -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) - if (chan->common.usedby == API){ -# if defined(__LINUX__) - wan_wakeup_api(chan); -# endif - }else if (chan->common.usedby == STACK){ - wanpipe_lip_kick(chan,0); - } -#endif + wanpipe_wake_stack(chan); } #ifdef AFT_TDM_API_SUPPORT @@ -4439,10 +4440,13 @@ static void enable_timer (void* card_id) WAN_TASKQ_SCHEDULE((&card->u.aft.port_task)); #else wan_smp_flag_t smp_flags; - int err = 0; + int delay = 0; wan_spin_lock_irq(&card->wandev.lock, &smp_flags); - err = card->wandev.fe_iface.polling(&card->fe); + delay = card->wandev.fe_iface.polling(&card->fe); wan_spin_unlock_irq(&card->wandev.lock, &smp_flags); + if (delay){ + card->wandev.fe_iface.add_timer(&card->fe, delay); + } #endif DEBUG_TEST("%s: %s Sdla Polling End!\n", @@ -4545,7 +4549,9 @@ static void wp_bh(void *data, int pending) continue; } new_skb->protocol = htons(PVC_PROT); + wan_skb_reset_mac_header(new_skb); + new_skb->dev = chan->common.dev; new_skb->pkt_type = WAN_PACKET_DATA; @@ -4671,7 +4677,7 @@ static void wp_bh(void *data, int pending) chan->if_stats.rx_bytes+=len; } - while((skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ + while(chan->hdlc_eng && (skb=wan_skb_dequeue(&chan->wp_tx_complete_list)) != NULL){ xilinx_tx_post_complete (chan->common.card,chan,skb); wan_skb_free(skb); } @@ -5146,10 +5152,11 @@ static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, break; case DIGITAL_LOOPTEST: - wan_udp_pkt->wan_udp_return_code = - digital_loop_test(card,wan_udp_pkt); + wan_udp_pkt->wan_udp_return_code = 0; + DEBUG_EVENT("Ready to send some data!!!\n"); break; + case AFT_MODEM_STATUS: wan_udp_pkt->wan_udp_return_code = 0; if (card->wandev.state == WAN_CONNECTED){ @@ -6115,7 +6122,7 @@ static int update_comms_stats(sdla_t* card) if (IS_TE1_CARD(card)) { wan_smp_flag_t smp_flags; card->hw_iface.hw_lock(card->hw,&smp_flags); - card->wandev.fe_iface.read_alarm(&card->fe, 0); + card->wandev.fe_iface.read_alarm(&card->fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); /* TE1 Update T1/E1 perfomance counters */ card->wandev.fe_iface.read_pmon(&card->fe, 0); card->hw_iface.hw_unlock(card->hw,&smp_flags); @@ -6193,20 +6200,18 @@ static void xilinx_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) if (chan->tx_dma_skb){ wan_skb_queue_head(&chan->wp_tx_pending_list, chan->tx_dma_skb); chan->tx_dma_skb=NULL; + if (chan->lip_atm) { + netskb_t *tmpskb = chan->tx_dma_skb; + chan->tx_dma_skb=NULL; + wan_skb_free(tmpskb); + } else { + wan_skb_queue_head(&chan->wp_tx_pending_list, chan->tx_dma_skb); + chan->tx_dma_skb=NULL; + } } - /* Wake up the stack, because tx dma interrupt - * failed */ -#if defined(__LINUX__) - if (WAN_NETIF_QUEUE_STOPPED(chan->common.dev)){ - WAN_NETIF_WAKE_QUEUE(chan->common.dev); - if (chan->common.usedby == API){ -#ifndef CONFIG_PRODUCT_WANPIPE_GENERIC - wan_wakeup_api(chan); -#endif - } - } -#endif + /* Wake up the stack, because tx dma interrupt failed */ + wanpipe_wake_stack(chan); if (!chan->hdlc_eng){ if (wan_test_bit(0,&chan->idle_start)){ @@ -6227,9 +6232,9 @@ static void xilinx_tx_fifo_under_recover (sdla_t *card, private_area_t *chan) static int xilinx_write_ctrl_hdlc(sdla_t *card, u32 timeslot, u8 reg_off, u32 data) { - u32 reg; - u32 ts_orig=timeslot; - unsigned long timeout=SYSTEM_TICKS; + u32 reg; + u32 ts_orig=timeslot; + wan_ticks_t timeout=SYSTEM_TICKS; if (timeslot == 0){ timeslot=card->u.aft.num_of_time_slots-2; @@ -6311,7 +6316,6 @@ static int set_chan_state(sdla_t* card, netdevice_t* dev, int state) wan_update_api_state(chan); } #endif - if (chan->common.usedby == STACK){ if (state == WAN_CONNECTED){ wanpipe_lip_connect(chan,0); @@ -6664,7 +6668,7 @@ void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb) if (chan->common.protocol == WANCONFIG_GENERIC){ skb->protocol = htons(ETH_P_HDLC); skb->dev = chan->common.dev; - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); netif_rx(skb); return 0; } @@ -6673,7 +6677,7 @@ void protocol_recv(sdla_t *card, private_area_t *chan, netskb_t *skb) #if defined(__LINUX__) skb->protocol = htons(ETH_P_IP); skb->dev = chan->common.dev; - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); netif_rx(skb); #else if (wan_iface.input){ @@ -6783,6 +6787,7 @@ This conversion is done in te1 sources. skb->pkt_type = WAN_PACKET_ERR; skb->protocol=htons(PVC_PROT); skb->dev=chan->common.dev; + DEBUG_TEST("%s: Sending OOB message len=%i\n", chan->if_name, wan_skb_len(skb)); @@ -7047,11 +7052,15 @@ static void aft_port_task (struct work_struct *work) static void aft_port_task (void * card_ptr, int arg) #endif { -#if defined(__LINUX__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) +#if defined(__LINUX__) +# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)) sdla_t *card = (sdla_t *)container_of(work, sdla_t, u.aft.port_task); +# else + sdla_t *card = (sdla_t *)card_ptr; +# endif #else sdla_t *card = (sdla_t *)card_ptr; -#endif +#endif wan_smp_flag_t smp_flags; if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){ @@ -7076,10 +7085,12 @@ static void aft_port_task (void * card_ptr, int arg) aft_fe_intr_ctrl(card, 0); if (card->wandev.fe_iface.polling){ wan_smp_flag_t smp_flags; - int err = 0; - - err = card->wandev.fe_iface.polling(&card->fe); + int delay = 0; + delay = card->wandev.fe_iface.polling(&card->fe); + if (delay){ + card->wandev.fe_iface.add_timer(&card->fe, delay); + } wan_spin_lock_irq(&card->wandev.lock,&smp_flags); handle_front_end_state(card); wan_spin_unlock_irq(&card->wandev.lock,&smp_flags); @@ -7577,75 +7588,5 @@ static void aft_critical_shutdown (sdla_t *card) -static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt) -{ - netskb_t* skb; - netdevice_t* dev; - char* buf; - private_area_t *chan; - - dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); - if (dev == NULL) { - return 1; - } - chan = wan_netif_priv(dev); - if (chan == NULL) { - return 1; - } - - if (chan->common.state != WAN_CONNECTED) { - DEBUG_EVENT("%s: Loop test failed: dev not connected!\n", - card->devname); - return 2; - } - - skb = wan_skb_alloc(wan_udp_pkt->wan_udp_data_len+100); - if (skb == NULL) { - return 3; - } - - switch (chan->common.usedby) { - - case API: - wan_skb_push(skb, sizeof(api_rx_hdr_t)); - break; - - case STACK: - case WANPIPE: - break; - - case TDM_VOICE: - case TDM_VOICE_API: - case TDM_VOICE_DCHAN: - if (card->u.aft.tdmv_dchan) { - break; - } else { - DEBUG_EVENT("%s: Loop test failed: no dchan in TDMV mode!\n", - card->devname); - } - /* Fall into the default case */ - - default: - DEBUG_EVENT("%s: Loop test failed: invalid operation mode!\n", - card->devname); - wan_skb_free(skb); - return 4; - } - - buf = wan_skb_put(skb, wan_udp_pkt->wan_udp_data_len); - memcpy(buf, wan_udp_pkt->wan_udp_data, wan_udp_pkt->wan_udp_data_len); - - - skb->next = skb->prev = NULL; - skb->dev = dev; - skb->protocol = htons(ETH_P_IP); - wan_skb_reset_mac_header(skb); - dev_queue_xmit(skb); - - return 0; -} - - - /****** End ****************************************************************/ diff --git a/patches/kdrivers/src/net/sdladrv.c b/patches/kdrivers/src/net/sdladrv.c index 3bb30e0..1707e42 100644 --- a/patches/kdrivers/src/net/sdladrv.c +++ b/patches/kdrivers/src/net/sdladrv.c @@ -4,7 +4,7 @@ * This module is a library of common hardware-specific functions * used by all Sangoma drivers. * -* Author: Alex Feldman, Nenad Corbic, Gideon Hack +* Authors: Alex Feldman, Nenad Corbic, Gideon Hack, David Rokhvarg * * Copyright: (c) 1995-2003 Sangoma Technologies Inc. * @@ -13,6 +13,9 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* Jan 14, 2008 Alex Feldman Add AUTO PCI probe for FreeBSD +* Support FreeBSD-7 +* Jul 06, 2007 David Rokhvarg Added detection of A500 - ISDN BRI modules. * Apr 04, 2007 Alex Feldman Add support T3/E3 SHART cards * Mar 04, 2007 Alex Feldman Add support ISDN/BRI cards * Dec 15. 2003 Nenad Corbic Redesigned hw abstraction layer to @@ -112,7 +115,6 @@ # undef WANDEBUG /* Uncomment this line for debug purpose */ #endif - /*************************************************************************** **** I N C L U D E F I L E S **** ***************************************************************************/ @@ -125,7 +127,17 @@ # include # include # include +# if defined(SDLA_AUTO_PROBE) +# include +# endif # include +#elif defined(__WINDOWS__) +# include +# include +# include /* SDLA firmware module definitions */ +# include /* SDLA PCI hardware definitions */ +# include +# include /* API definitions */ #elif defined(__LINUX__)||defined(__KERNEL__) # define _K22X_MODULE_FIX_ # include @@ -141,15 +153,20 @@ # error "Unsupported Operating System!" #endif +#if !defined(__WINDOWS__) #if 1 #define AFT_FUNC_DEBUG() #else #define AFT_FUNC_DEBUG() DEBUG_EVENT("%s:%d\n",__FUNCTION__,__LINE__) #endif +#endif /*************************************************************************** **** M A C R O S / D E F I N E S **** ***************************************************************************/ +#define SDLA_HWPROBE_NAME "sdladrv" +#define SDLA_HWEC_NAME "wanec" + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) # define EXPORT_SYMBOL(symbol) #endif @@ -164,9 +181,10 @@ * EXEC_TIMEOUT=EXEC_DELAY*2000 = 40000 * 40000 ~= 80 jiffies = EXEC_TIMEOUT */ -#define EXEC_HZ_DIVISOR 8/10 /* We don't want to wait a full second on sdla_exec - * timeout, thus use HZ * EXEC_HZ_DIVISOR to get - * the number of jiffies we would like to wait */ +#define EXEC_HZ_DIVISOR 8/10 /* We don't want to wait a full second on + * sdla_exec timeout, thus use + * HZ * EXEC_HZ_DIVISOR to get the number of + * jiffies we would like to wait */ /* I/O port address range */ @@ -202,8 +220,6 @@ #define SDLA_PCI_CARD 1 #define SDLA_PCI_EXP_CARD 2 -#define SDLA_MAGIC(hw) WAN_ASSERT(hw->magic != SDLADRV_MAGIC) - /****** Function Prototypes *************************************************/ /* Hardware-specific functions */ @@ -221,7 +237,10 @@ static int sdla_intr (sdlahw_t* hw); #endif static int sdla_mapmem (void* phw, unsigned long addr); static int sdla_check_mismatch(void* phw, unsigned char media); + static int sdla_getcfg(void* phw, int type, void*); +static int sdla_setcfg(void* phw, int type, void* value); + #if defined(WAN_ISA_SUPPORT) static int sdla_isa_read_1(void* phw, unsigned int offset, u8*); static int sdla_isa_write_1(void* phw, unsigned int offset, u8); @@ -241,8 +260,10 @@ static int sdla_pci_read_config_byte(void*, int, u8*); static int sdla_pci_read_config_word(void*, int, u16*); static int sdla_pci_read_config_dword(void*, int, u32*); -static int sdla_pci_bridge_write_config_dword(void*, int, u32); -static int sdla_pci_bridge_read_config_dword(void*, int, u32*); +int sdla_pci_bridge_write_config_dword(void*, int, u_int32_t); +static int sdla_pci_bridge_write_config_byte(void*, int, u_int8_t); +int sdla_pci_bridge_read_config_dword(void*, int, u_int32_t*); +static int sdla_pci_bridge_read_config_byte(void*, int, u_int8_t*); static int sdla_cmd (void* phw, unsigned long offset, wan_mbox_t* mbox); @@ -265,12 +286,8 @@ static int sdla_memory_map(sdlahw_t* hw, int cpu_no); static int sdla_memory_unmap(sdlahw_t* hw); static int sdla_detect (sdlahw_t* hw); -static int sdla_autodpm (sdlahw_t* hw); -static int sdla_setdpm (sdlahw_t* hw); static int sdla_start(sdlahw_t* hw, unsigned addr); /*ALEXstatic int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len);*/ -static int sdla_init (sdlahw_t* hw); -static unsigned long sdla_memtest (sdlahw_t* hw); static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo); static unsigned char sdla_make_config_byte (sdlahw_t* hw); @@ -285,6 +302,13 @@ static int sdla_detect_s502e (sdlahw_t* hw); static int sdla_detect_s503 (sdlahw_t* hw); static int sdla_detect_s507 (sdlahw_t* hw); static int sdla_detect_s508 (sdlahw_t* hw); + +static int sdla_autodpm (sdlahw_t* hw); +static int sdla_setdpm (sdlahw_t* hw); +static int sdla_init (sdlahw_t* hw); +static unsigned long sdla_memtest (sdlahw_t* hw); +static unsigned sdla_check_memregion (sdlahw_t* hw); +static int sdla_get_option_index (unsigned* optlist, unsigned optval); #endif static int sdla_detect_s514 (sdlahw_t* hw); @@ -297,8 +321,6 @@ static int sdla_is_56k(void* phw); static sdlahw_t* sdla_find_adapter(wandev_conf_t* conf, char* devname); /* Miscellaneous functions */ -static int sdla_get_option_index (unsigned* optlist, unsigned optval); -static unsigned sdla_check_memregion (sdlahw_t* hw); static unsigned sdla_test_memregion (sdlahw_t* hw, unsigned len); static unsigned short sdla_checksum (unsigned char* buf, unsigned len); static int sdla_init_pci_slot(sdlahw_t *); @@ -307,27 +329,58 @@ static int sdla_init_pci_slot(sdlahw_t *); static sdlahw_card_t* sdla_card_register(unsigned char hw_type, int slot_no, int bus_no, int ioport); static int sdla_card_unregister (unsigned char hw_type, int slot_no, int bus_no, int ioport); static sdlahw_card_t* sdla_card_search(unsigned char hw_type, int slot_no, int bus_no, int ioport); +static int sdla_card_info(sdlahw_card_t*); -static sdlahw_t* sdla_hw_register(sdlahw_card_t* card, int cpu_no, int irq, void*); -static int sdla_hw_unregister(sdlahw_card_t* card, int cpu_no); -static sdlahw_t* sdla_hw_search(unsigned char hw_type, int slot_no, int bus_no, int ioport, int cpu_no); +static sdlahw_cpu_t* sdla_hwcpu_register(sdlahw_card_t* card, int cpu_no, int irq, void*); +static int sdla_hwcpu_unregister(sdlahw_cpu_t*); +static sdlahw_cpu_t* sdla_hwcpu_search(unsigned char hw_type, int slot_no, int bus_no, int ioport, int cpu_no); +static int sdla_hwcpu_info(sdlahw_cpu_t*); -static int sdla_s514_hw_select (sdlahw_card_t* card, int cpu_no, int irq, void*); -static int sdla_adsl_hw_select (sdlahw_card_t* card, int cpu_no, int irq, void*); -static int sdla_aft_hw_select (sdlahw_card_t* card, int cpu_no, int irq, void*); -static void sdla_save_hw_probe (sdlahw_t* hw, int port); -static int sdla_save_Remora_hw_probe_verbose(sdlahw_t* hw, int port); +static sdlahw_t* sdla_hw_register(sdlahw_cpu_t* hwcpu, int port_no); +static int sdla_hw_unregister(sdlahw_t*); +static sdlahw_t* sdla_hw_search(sdlahw_cpu_t* hwcpu, int port_no); +static int sdla_hw_info(sdlahw_t*); + +static int sdla_hwport_unregister(sdlahw_cpu_t*); +static sdlahw_t* sdla_hwport_register(sdlahw_cpu_t* hwcpu, int); +static sdlahw_t* sdla_hwport_te1_register(sdlahw_cpu_t*, int); +static sdlahw_t* sdla_hwport_Remora_register(sdlahw_cpu_t*, int*); +static sdlahw_t* sdla_hwport_ISDN_register(sdlahw_cpu_t*, int*); + +static int sdla_s514_hw_select (sdlahw_card_t*, int, int, void*); +static int sdla_adsl_hw_select (sdlahw_card_t*, int, int, void*); +static int sdla_aft_hw_select (sdlahw_card_t*, int, int, void*); +static void sdla_save_hw_probe (sdlahw_t* hw); static int sdla_hw_lock(void *phw, wan_smp_flag_t *flag); static int sdla_hw_unlock(void *phw, wan_smp_flag_t *flag); +static int sdla_hw_ec_trylock(void *phw, wan_smp_flag_t *flag); static int sdla_hw_ec_lock(void *phw, wan_smp_flag_t *flag); static int sdla_hw_ec_unlock(void *phw, wan_smp_flag_t *flag); +static wan_dma_descr_t *sdla_busdma_descr_alloc(void *phw, int num); +static void sdla_busdma_descr_free(void *phw, wan_dma_descr_t *dma_descr); +#if defined(__FreeBSD__) +static void sdla_busdma_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error); +#endif +static int sdla_busdma_tag_create(void *phw, wan_dma_descr_t*, u32, u32,int); +static int sdla_busdma_tag_destroy(void *phw, wan_dma_descr_t*, int); +static int sdla_busdma_create(void *phw, wan_dma_descr_t*); +static int sdla_busdma_destroy(void *phw, wan_dma_descr_t*); +static int sdla_busdma_alloc(void *phw, wan_dma_descr_t*); +static void sdla_busdma_free(void *phw, wan_dma_descr_t*); +static int sdla_busdma_load(void *phw, wan_dma_descr_t*, u32); +static void sdla_busdma_unload(void *phw, wan_dma_descr_t*); +static void sdla_busdma_map(void *phw, wan_dma_descr_t*, void *buf, int len, int map_len, int dir); +static void sdla_busdma_unmap(void *phw, wan_dma_descr_t*, int dir); +static void sdla_busdma_sync(void *phw, wan_dma_descr_t*, int ndescr, int single, int dir); + static sdla_dma_addr_t sdla_pci_map_dma(void *phw, void *buf, int len, int ctrl); static int sdla_pci_unmap_dma(void *phw, sdla_dma_addr_t buf, int len, int ctrl); static int sdla_is_same_hwcard(void* phw1, void *phw2); +static int sdla_is_same_hwcpu(void* phw1, void *phw2); int sdla_hw_fe_test_and_set_bit(void *phw,int value); int sdla_hw_fe_test_bit(void *phw,int value); int sdla_hw_fe_set_bit(void *phw,int value); @@ -340,21 +393,38 @@ extern int sdla_te1_write_fe(void* phw, ...); extern u_int8_t sdla_te1_read_fe (void* phw, ...); extern int sdla_shark_te1_write_fe(void *phw, ...); +extern u_int8_t __sdla_shark_te1_read_fe (void *phw, ...); extern u_int8_t sdla_shark_te1_read_fe (void *phw, ...); extern int sdla_shark_rm_write_fe (void* phw, ...); +extern u_int8_t __sdla_shark_rm_read_fe (void* phw, ...); extern u_int8_t sdla_shark_rm_read_fe (void* phw, ...); +extern int sdla_shark_bri_write_fe (void* phw, ...); +extern u_int8_t sdla_shark_bri_read_fe (void* phw, ...); +static int sdla_scan_isdn_bri_modules(sdlahw_t* hw, int *rm_mod_type, u_int8_t rm_no); + extern int sdla_shark_56k_write_fe(void *phw, ...); +extern u_int8_t __sdla_shark_56k_read_fe (void *phw, ...); extern u_int8_t sdla_shark_56k_read_fe (void *phw, ...); +extern int sdla_shark_serial_write_fe (void* phw, ...); +extern u_int8_t sdla_shark_serial_read_fe (void* phw, ...); + +extern int sdla_te3_write_fe(void *phw, ...); +extern u_int8_t sdla_te3_read_fe(void *phw, ...); + +extern int sdla_plxctrl_read8(void *phw, short, unsigned char*); +extern int sdla_plxctrl_write8(void *phw, short, unsigned char); + #if defined(__LINUX__) -#if defined(WAN_DEBUG_MEM) - atomic_t wan_debug_mem; - EXPORT_SYMBOL(wan_debug_mem); -#endif + static int sdla_pci_probe(sdlahw_t*); #endif + +static int sdla_is_pciexpress(void *phw); +static int sdla_get_hwec_index(void *phw); + /****** Global Data ********************************************************** * Note: All data must be explicitly initialized!!! */ @@ -370,8 +440,10 @@ extern int Sangoma_cards_no; /* total number of SDLA cards */ extern int Sangoma_devices_no; /* Max number of Sangoma dev */ extern int Sangoma_PCI_cards_no; /* total number of S514 cards */ -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#if !defined(SDLA_AUTO_PROBE) +# if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) extern sdladev_t sdladev[]; /* SDLA info structure */ +# endif #endif /* private data */ @@ -386,18 +458,29 @@ static char *wan_fullname = "WANPIPE(tm) Hardware Support Module"; /* Array of already initialized PCI slots */ static int pci_slot_ar[MAX_S514_CARDS]; -WAN_LIST_HEAD(, sdlahw_card) sdlahw_card_head = +WAN_LIST_HEAD(NAME_PLACEHOLDER, sdlahw_card) sdlahw_card_head = WAN_LIST_HEAD_INITIALIZER(&sdlahw_card_head); -WAN_LIST_HEAD(, sdlahw) sdlahw_head = +WAN_LIST_HEAD(NAME_PLACEHOLDER1, sdlahw_cpu) sdlahw_cpu_head = + WAN_LIST_HEAD_INITIALIZER(&sdlahw_cpu_head); +WAN_LIST_HEAD(NAME_PLACEHOLDER2, sdlahw_port) sdlahw_head = WAN_LIST_HEAD_INITIALIZER(&sdlahw_head); -WAN_LIST_HEAD(, sdla_hw_probe) sdlahw_probe_head = +WAN_LIST_HEAD(NAME_PLACEHOLDER3, sdla_hw_probe) sdlahw_probe_head = WAN_LIST_HEAD_INITIALIZER(&sdlahw_probe_head); -static sdla_hw_type_cnt_t sdla_adapter_cnt; -#if defined(__LINUX__) + +static sdla_hw_type_cnt_t sdla_adapter_cnt; +static int sdla_hwec_no = 0; + +#if defined(__LINUX__) || defined(__WINDOWS__) static unsigned long EXEC_TIMEOUT; #endif +#if defined(__WINDOWS__) +extern int get_usage_counter(sdla_t *card); +extern wan_spinlock_t* get_card_spin_lock(sdla_t *card); +extern u32 get_card_serial_number(sdla_t *card); +#endif + /* Hardware configuration options. * These are arrays of configuration options used by verification routines. * The first element of each array is its size (i.e. number of options). @@ -492,22 +575,167 @@ static unsigned char s507_irqmask[] = /* Entry Point for Low-Level function */ int sdladrv_init(void*); int sdladrv_exit(void*); +#if 0 +int sdladrv_shutdown(void*); +int sdladrv_ready_unload(void*); +#endif /*****************************************************************************/ /* Loadable kernel module function interface */ -#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) +#if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) && !defined(__WINDOWS__) # if !defined(__OpenBSD__) && !defined(__NetBSD__) WAN_MODULE_DEFINE( sdladrv, "sdladrv", "Alex Feldman ", "Sangoma WANPIPE: HW Layer", "GPL", - sdladrv_init, sdladrv_exit, NULL); + sdladrv_init, sdladrv_exit, + NULL); WAN_MODULE_VERSION(sdladrv, SDLADRV_MAJOR_VER); # endif #endif +/*****************************************************************************/ +/* Memory Debug Code +*/ + +# if defined(WAN_DEBUG_MEM) + +static int wan_debug_mem; + +wan_spinlock_t wan_debug_mem_lock; +EXPORT_SYMBOL(wan_debug_mem_lock); + +WAN_LIST_HEAD(NAME_PLACEHOLDER_MEM, sdla_memdbg_el) sdla_memdbg_head = + WAN_LIST_HEAD_INITIALIZER(&sdla_memdbg_head); + +typedef struct sdla_memdbg_el +{ + unsigned int len; + unsigned int line; + char cmd_func[128]; + void *mem; + WAN_LIST_ENTRY(sdla_memdbg_el) next; +}sdla_memdbg_el_t; + +int sdla_memdbg_init(void) +{ + wan_spin_lock_init(&wan_debug_mem_lock,"wan_debug_mem_lock"); + WAN_LIST_INIT(&sdla_memdbg_head); + return 0; +} + + +int sdla_memdbg_push(void *mem, char *func_name, int line, int len) +{ + sdla_memdbg_el_t *sdla_mem_el; + wan_smp_flag_t flags; + + sdla_mem_el = kmalloc(sizeof(sdla_memdbg_el_t),GFP_ATOMIC); + if (!sdla_mem_el) { + DEBUG_EVENT("%s:%d Critical failed to allocate memory!\n", + __FUNCTION__,__LINE__); + return -ENOMEM; + } + + memset(sdla_mem_el,0,sizeof(sdla_memdbg_el_t)); + + sdla_mem_el->len=len; + sdla_mem_el->line=line; + sdla_mem_el->mem=mem; + strncpy(sdla_mem_el->cmd_func,func_name,sizeof(sdla_mem_el->cmd_func)-1); + + + wan_spin_lock_irq(&wan_debug_mem_lock,&flags); + wan_debug_mem+=sdla_mem_el->len; + WAN_LIST_INSERT_HEAD(&sdla_memdbg_head, sdla_mem_el, next); + wan_spin_unlock_irq(&wan_debug_mem_lock,&flags); + + DEBUG_EVENT("%s:%d: Alloc %p Len=%i Total=%i\n", + sdla_mem_el->cmd_func,sdla_mem_el->line, + sdla_mem_el->mem, sdla_mem_el->len,wan_debug_mem); + + return 0; + +} +EXPORT_SYMBOL(sdla_memdbg_push); + +int sdla_memdbg_pull(void *mem, char *func_name, int line) +{ + sdla_memdbg_el_t *sdla_mem_el; + wan_smp_flag_t flags; + int err=-1; + + wan_spin_lock_irq(&wan_debug_mem_lock,&flags); + + WAN_LIST_FOREACH(sdla_mem_el, &sdla_memdbg_head, next){ + if (sdla_mem_el->mem == mem) { + break; + } + } + + if (sdla_mem_el) { + + WAN_LIST_REMOVE(sdla_mem_el, next); + wan_debug_mem-=sdla_mem_el->len; + wan_spin_unlock_irq(&wan_debug_mem_lock,&flags); + + DEBUG_EVENT("%s:%d: DeAlloc %p Len=%i Total=%i (From %s:%d)\n", + func_name,line, + sdla_mem_el->mem, sdla_mem_el->len, wan_debug_mem, + sdla_mem_el->cmd_func,sdla_mem_el->line); + + kfree(sdla_mem_el); + err=0; + } else { + wan_spin_unlock_irq(&wan_debug_mem_lock,&flags); + } + + if (err) { + DEBUG_EVENT("%s:%d: Critical Error: Unknows Memeory %p\n", + __FUNCTION__,__LINE__,mem); + } + + return err; +} +EXPORT_SYMBOL(sdla_memdbg_pull); + +int sdla_memdbg_free(void) +{ + sdla_memdbg_el_t *sdla_mem_el; + int total=0; + + DEBUG_EVENT("sdladrv: Memory Still Allocated=%i \n", + wan_debug_mem); + + DEBUG_EVENT("=====================BEGIN================================\n"); + + sdla_mem_el = WAN_LIST_FIRST(&sdla_memdbg_head); + while(sdla_mem_el){ + sdla_memdbg_el_t *tmp = sdla_mem_el; + + DEBUG_EVENT("%s:%d: Mem Leak %p Len=%i \n", + sdla_mem_el->cmd_func,sdla_mem_el->line, + sdla_mem_el->mem, sdla_mem_el->len); + total+=sdla_mem_el->len; + + sdla_mem_el = WAN_LIST_NEXT(sdla_mem_el, next); + WAN_LIST_REMOVE(tmp, next); + kfree(tmp); + } + + DEBUG_EVENT("=====================END==================================\n"); + DEBUG_EVENT("sdladrv: Memory Still Allocated=%i Leaks Found=%i Missing=%i\n", + wan_debug_mem,total,wan_debug_mem-total); + + return 0; +} + +# endif + + + /*============================================================================ * Module init point. */ @@ -536,9 +764,27 @@ int sdladrv_init(void* arg) memset(&sdla_adapter_cnt,0,sizeof(sdla_hw_type_cnt_t)); +#ifdef WAN_DEBUG_MEM + sdla_memdbg_init(); +#endif + return 0; } +#if 0 +int sdladrv_shutdown(void *arg) +{ + DEBUG_EVENT("Shutting down SDLADRV module ...\n"); + return 0; +} + +int sdladrv_ready_unload(void *arg) +{ + DEBUG_EVENT("Is SDLADRV module ready to unload...\n"); + return 0; +} +#endif + /*============================================================================ * Module deinit point. * o release all remaining system resources @@ -546,24 +792,29 @@ int sdladrv_init(void* arg) int sdladrv_exit (void *arg) { sdla_hw_probe_t *elm_hw_probe; - sdlahw_t *elm_hw; + sdlahw_cpu_t *elm_hw_cpu; sdlahw_card_t *elm_hw_card; + + DEBUG_MOD("Unloading SDLADRV module ...\n"); - elm_hw = WAN_LIST_FIRST(&sdlahw_head); - while(elm_hw){ - sdlahw_t *tmp = elm_hw; - elm_hw = WAN_LIST_NEXT(elm_hw, next); - if (sdla_hw_unregister(tmp->hwcard, tmp->cpu_no) == -EBUSY){ + elm_hw_cpu = WAN_LIST_FIRST(&sdlahw_cpu_head); + while(elm_hw_cpu){ + sdlahw_cpu_t *tmp = elm_hw_cpu; + elm_hw_cpu = WAN_LIST_NEXT(elm_hw_cpu, next); + if (sdla_hwport_unregister(tmp) == -EBUSY){ + return -EBUSY; + } + if (sdla_hwcpu_unregister(tmp) == -EBUSY){ return -EBUSY; } } - WAN_LIST_INIT(&sdlahw_head); + WAN_LIST_INIT(&sdlahw_cpu_head); elm_hw_card = WAN_LIST_FIRST(&sdlahw_card_head); - while(elm_hw){ + while(elm_hw_card){ sdlahw_card_t *tmp = elm_hw_card; elm_hw_card = WAN_LIST_NEXT(elm_hw_card, next); - if (sdla_card_unregister(tmp->hw_type, + if (sdla_card_unregister((u8)tmp->hw_type, tmp->slot_no, tmp->bus_no, tmp->ioport) == -EBUSY){ @@ -576,7 +827,7 @@ int sdladrv_exit (void *arg) while(elm_hw_probe){ sdla_hw_probe_t *tmp = elm_hw_probe; elm_hw_probe = WAN_LIST_NEXT(elm_hw_probe, next); - if (tmp->used){ + if (tmp->internal_used){ DEBUG_EVENT("sdladrv: HW probe info is in used (%s)\n", tmp->hw_info); return -EBUSY; @@ -585,9 +836,11 @@ int sdladrv_exit (void *arg) wan_free(tmp); } + #if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("sdladrv: Total Mem %d\n",wan_atomic_read(&wan_debug_mem)); -#endif + sdla_memdbg_free(); +#endif + return 0; } @@ -615,207 +868,321 @@ G*** S A N G O M A H A R D W A R E P R O B E ***** "%-10s : SLOT=%d : BUS=%d : IRQ=%d : CPU=%c : PORT=%d : HWEC=%d : V=%02X" #define SDLA_HWPROBE_A200_SH_FORMAT \ "%-10s : SLOT=%d : BUS=%d : IRQ=%d : CPU=%c : PORT=%s : HWEC=%d : V=%02X" - +#define SDLA_HWPROBE_A500_SH_FORMAT \ + "%-10s : SLOT=%d : BUS=%d : IRQ=%d : PORT=%d : HWEC=%d : V=%02X" static void -sdla_save_hw_probe (sdlahw_t* hw, int port) +sdla_save_hw_probe (sdlahw_t* hw) { - sdla_hw_probe_t *tmp_hw_probe, *tmp; - unsigned char id_str[50]; + sdlahw_cpu_t *hwcpu; + sdla_hw_probe_t *hwprobe; - memset(id_str,0,sizeof(id_str)); + WAN_ASSERT_VOID(hw == NULL); + WAN_ASSERT_VOID(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + hwprobe = hw->hwprobe; - tmp_hw_probe = wan_malloc(sizeof(sdla_hw_probe_t)); - if (!tmp_hw_probe) - return; - - memset(tmp_hw_probe,0,sizeof(sdla_hw_probe_t)); - - if (hw->hwcard->hw_type == SDLA_PCI_CARD){ - switch(hw->hwcard->adptr_type){ + if (hwcpu->hwcard->hw_type == SDLA_PCI_CARD){ + switch(hwcpu->hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_AFT_SH_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port+1, /* line_no */ - hw->hwcard->hwec_chan_no, - hw->hwcard->core_rev); + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no+1, /* line_no */ + hwcpu->hwcard->hwec_chan_no, + hwcpu->hwcard->core_rev); }else{ /*sprintf(tmp_hw_probe->hw_info,*/ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_AFT_1_2_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port ? "SEC" : "PRI", - hw->hwcard->core_rev); + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no ? "SEC" : "PRI", + hwcpu->hwcard->core_rev); } - - if (hw->hwcard->core_id == AFT_DS_FE_CORE_ID) { - strcpy(id_str,"DS26521"); - } else { - strcpy(id_str,"PMC4351"); - } - sprintf(&tmp_hw_probe->hw_info_verbose[0], "\n+%02d:%s:%s", - port+1, id_str, - AFT_PCITYPE_DECODE(hw->hwcard)); - - - break; + break; case A104_ADPTR_4TE1: case A108_ADPTR_8TE1: - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_AFT_SH_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port+1, /* line_no */ - hw->hwcard->hwec_chan_no, - hw->hwcard->core_rev); + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no+1, /* line_no */ + hwcpu->hwcard->hwec_chan_no, + hwcpu->hwcard->core_rev); }else{ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_AFT_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port+1, - hw->hwcard->core_rev + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no+1, + hwcpu->hwcard->core_rev ); /* line_no */ } - - if (hw->hwcard->core_id == AFT_DS_FE_CORE_ID) { - if (hw->hwcard->adptr_type == A108_ADPTR_8TE1) { - strcpy(id_str,"DS26528"); - } else { - strcpy(id_str,"DS26524"); - } - } else { - strcpy(id_str,"PMC4354"); - } - - sprintf(&tmp_hw_probe->hw_info_verbose[0], "\n+%02d:%s:%s", - port+1, id_str, - AFT_PCITYPE_DECODE(hw->hwcard)); break; case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: /*sprintf(tmp_hw_probe->hw_info,*/ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_A200_SH_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port ? "SEC" : "PRI", - hw->hwcard->hwec_chan_no, - hw->hwcard->core_rev); + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no ? "SEC" : "PRI", + hwcpu->hwcard->hwec_chan_no, + hwcpu->hwcard->core_rev); break; case A300_ADPTR_U_1TE3: - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + case AFT_ADPTR_56K: + if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_AFT_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port+1, - hw->hwcard->core_rev); /* line_no */ + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no+1, + hwcpu->hwcard->core_rev); /* line_no */ }else{ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_PCI_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port ? "SEC" : "PRI"); + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no ? "SEC" : "PRI"); } break; + + case AFT_ADPTR_ISDN: + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), + SDLA_HWPROBE_A500_SH_FORMAT, + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + hw->port_no+1, /* Physical line number */ + hwcpu->hwcard->hwec_chan_no, + hwcpu->hwcard->core_rev); + break; + + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), + SDLA_HWPROBE_AFT_FORMAT, + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no+1, + hwcpu->hwcard->core_rev); /* line_no */ + break; default: /*sprintf(tmp_hw_probe->hw_info,*/ - snprintf(tmp_hw_probe->hw_info, - sizeof(tmp_hw_probe->hw_info), + snprintf(hwprobe->hw_info, + sizeof(hwprobe->hw_info), SDLA_HWPROBE_PCI_FORMAT, - hw->hwcard->adptr_name, - hw->hwcard->slot_no, - hw->hwcard->bus_no, - hw->irq, - SDLA_GET_CPU(hw->cpu_no), - port ? "SEC" : "PRI"); + hwcpu->hwcard->adptr_name, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->irq, + SDLA_GET_CPU(hwcpu->cpu_no), + hw->port_no ? "SEC" : "PRI"); break; } }else{ /*sprintf(tmp_hw_probe->hw_info, */ - snprintf(tmp_hw_probe->hw_info, sizeof(tmp_hw_probe->hw_info), - SDLA_HWPROBE_ISA_FORMAT, - "S508-ISA",hw->hwcard->ioport, port ? "SEC" : "PRI"); + snprintf(hwprobe->hw_info, sizeof(hwprobe->hw_info), + SDLA_HWPROBE_ISA_FORMAT, + "S508-ISA", + hwcpu->hwcard->ioport, + hw->port_no ? "SEC" : "PRI"); } + return; +} - hw->hwport[port].hwprobe = tmp_hw_probe; - hw->max_ports++; - tmp_hw_probe->used++; +static void sdla_get_hwcard_name(sdlahw_card_t* hwcard) +{ + WAN_ASSERT_VOID(hwcard == NULL); + sprintf(hwcard->adptr_name, "%s%s%s", + SDLA_ADPTR_NAME(hwcard->adptr_type), + AFT_SUBTYPE(hwcard->adptr_subtype), + AFT_SECURITY(hwcard->adptr_security)); + return; +} - WAN_LIST_FOREACH(tmp, &sdlahw_probe_head, next){ - if (!WAN_LIST_NEXT(tmp, next)){ - break; + +static sdlahw_t* sdla_hwport_register(sdlahw_cpu_t* hwcpu, int max_ports_no) +{ + sdlahw_t *hw = NULL, *first_hw = NULL; + int port; + + for(port = 0; port < max_ports_no; port++){ + if ((hw = sdla_hw_register(hwcpu, port)) == NULL){ + sdla_hwport_unregister(hwcpu); + return NULL; + } + if (first_hw == NULL){ + first_hw = hw; } } - if (tmp){ - WAN_LIST_INSERT_AFTER(tmp, tmp_hw_probe, next); - }else{ - WAN_LIST_INSERT_HEAD(&sdlahw_probe_head, tmp_hw_probe, next); + return first_hw; +} +static int sdla_hwport_unregister(sdlahw_cpu_t* hwcpu) +{ + sdlahw_t *hw, *tmp_hw; + + WAN_ASSERT(hwcpu == NULL); + hw = WAN_LIST_FIRST(&sdlahw_head); + while(hw){ + + tmp_hw = hw; + hw = WAN_LIST_NEXT(hw, next); + + if (tmp_hw->hwcpu == hwcpu){ + if (sdla_hw_unregister(tmp_hw)){ + return -EBUSY; + } + } } - return; + return 0; } -static void sdla_get_adptr_name(sdlahw_t* hw) +static sdlahw_t* sdla_hwport_serial_register(sdlahw_cpu_t* hwcpu, int max_ports_no) { - sprintf(hw->hwcard->adptr_name, "%s%s%s", - SDLA_ADPTR_NAME(hw->hwcard->adptr_type), - AFT_SUBTYPE(hw->hwcard->adptr_subtype), - AFT_SECURITY(hw->hwcard->adptr_security)); - return; + sdlahw_t *hw = NULL, *first_hw = NULL; + int port; + unsigned char id_str[50]; + + memset(id_str, 0x00, 50); + for(port = 0; port < max_ports_no; port++){ + switch(hwcpu->hwcard->adptr_type){ + case AFT_ADPTR_2SERIAL_V35X21: + strcpy(id_str, "AFT-A142 2 Port V.35/X.21"); + break; + case AFT_ADPTR_4SERIAL_V35X21: + strcpy(id_str, "AFT-A144 4 Port V.35/X.21"); + break; + case AFT_ADPTR_2SERIAL_RS232: + strcpy(id_str, "AFT-A142 2 Port RS232"); + break; + case AFT_ADPTR_4SERIAL_RS232: + strcpy(id_str, "AFT-A144 4 Port RS232"); + break; + } + + if ((hw = sdla_hw_register(hwcpu, port)) == NULL){ + sdla_hwport_unregister(hwcpu); + return NULL; + } + if (first_hw == NULL){ + first_hw = hw; + } + sprintf(&hw->hwprobe->hw_info_verbose[0], "\n+%02d:%s:%s", + port+1, id_str, + AFT_PCITYPE_DECODE(hwcpu->hwcard)); + } + return first_hw; } - -static int sdla_save_Remora_hw_probe_verbose(sdlahw_t* hw, int port) +static sdlahw_t* sdla_hwport_te1_register(sdlahw_cpu_t* hwcpu, int max_ports_no) { + sdlahw_t *hw = NULL, *first_hw = NULL; + int port; + unsigned char id_str[50]; + + memset(id_str, 0x00, 50); + for(port = 0; port < max_ports_no; port++){ + if (hwcpu->hwcard->type == SDLA_S514){ + strcpy(id_str, "PMC4351"); + }else if (hwcpu->hwcard->type == SDLA_AFT){ + if (hwcpu->hwcard->cfg_type == WANOPT_AFT){ + strcpy(id_str, "PMC4351"); + }else if (hwcpu->hwcard->cfg_type == WANOPT_AFT101){ + strcpy(id_str, "DS26521"); + }else if (hwcpu->hwcard->cfg_type == WANOPT_AFT102){ + strcpy(id_str, "DS26521"); + }else if (hwcpu->hwcard->cfg_type == WANOPT_AFT104){ + if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + strcpy(id_str, "DS26524"); + }else{ + strcpy(id_str, "PMC4354"); + } + }else if (hwcpu->hwcard->cfg_type == WANOPT_AFT108){ + strcpy(id_str, "DS26528"); + } + }else{ + continue; + } + + if ((hw = sdla_hw_register(hwcpu, port)) == NULL){ + sdla_hwport_unregister(hwcpu); + return NULL; + } + if (first_hw == NULL){ + first_hw = hw; + } + sprintf(&hw->hwprobe->hw_info_verbose[0], "\n+%02d:%s:%s", + port+1, id_str, + AFT_PCITYPE_DECODE(hwcpu->hwcard)); + } + return first_hw; +} + +static sdlahw_t *sdla_hwport_Remora_register(sdlahw_cpu_t* hwcpu, int *max_ports_no) +{ + sdlahw_t *hw; u32 reg; - int mod_no, off = 0; + int mod_no, off = 0, port_cnt = 0; + int rm_mod_type[MAX_REMORA_MODULES+2]; + u_int32_t port_map = 0; unsigned char value, str[50]; - WAN_ASSERT(hw == NULL); - - memset(hw->hwport[port].hwprobe->hw_info_verbose, '\0', 500); + WAN_ASSERT_RC(hwcpu == NULL, NULL); + *max_ports_no = 0; + if ((hw = sdla_hw_register(hwcpu, 0)) == NULL){ + return NULL; + } if (sdla_memory_map(hw, SDLA_CPU_A)){ - return -EINVAL; + sdla_hw_unregister(hw); + return NULL; } /* A200 clear reset */ @@ -837,15 +1204,15 @@ static int sdla_save_Remora_hw_probe_verbose(sdlahw_t* hw, int port) WP_DELAY(1000); sdla_bus_write_4(hw,SPI_INTERFACE_REG,0x00000000); WP_DELAY(1000); - - for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no += 2){ - + + for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no ++){ + rm_mod_type[mod_no] = MOD_TYPE_NONE; + //rm_mod_type[mod_no+1] = MOD_TYPE_NONE; value = sdla_shark_rm_read_fe(hw, mod_no, MOD_TYPE_FXS, 0, 0); if ((value & 0x0F) == 0x05){ - hw->hwcard->rm_mod_type[mod_no] = MOD_TYPE_FXS; - hw->hwcard->rm_mod_type[mod_no+1] = MOD_TYPE_FXS; + rm_mod_type[mod_no] = MOD_TYPE_FXS; + // rm_mod_type[mod_no+1] = MOD_TYPE_FXS; } - } /* Reset SPI bus */ @@ -853,26 +1220,31 @@ static int sdla_save_Remora_hw_probe_verbose(sdlahw_t* hw, int port) WP_DELAY(1000); sdla_bus_write_4(hw,SPI_INTERFACE_REG,0x00000000); WP_DELAY(1000); - for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no += 2){ + for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no ++){ - if (hw->hwcard->rm_mod_type[mod_no] != MOD_TYPE_NONE) continue; + if (rm_mod_type[mod_no] != MOD_TYPE_NONE) continue; value = sdla_shark_rm_read_fe(hw, mod_no, MOD_TYPE_FXO, 1, 2); if (value == 0x03){ - hw->hwcard->rm_mod_type[mod_no] = MOD_TYPE_FXO; - hw->hwcard->rm_mod_type[mod_no+1] = MOD_TYPE_FXO; + rm_mod_type[mod_no] = MOD_TYPE_FXO; + //rm_mod_type[mod_no+1] = MOD_TYPE_FXO; } } + port_map = 0; for(mod_no = 0; mod_no < MAX_REMORA_MODULES; mod_no ++){ - if (hw->hwcard->rm_mod_type[mod_no] == MOD_TYPE_FXS){ - sprintf(str, "\n+%02d:FXS:%s", mod_no+1,AFT_PCITYPE_DECODE(hw->hwcard)); - }else if (hw->hwcard->rm_mod_type[mod_no] == MOD_TYPE_FXO){ - sprintf(str, "\n+%02d:FXO:%s", mod_no+1,AFT_PCITYPE_DECODE(hw->hwcard)); + if (rm_mod_type[mod_no] == MOD_TYPE_FXS){ + sprintf(str, "\n+%02d:FXS", mod_no+1); + port_cnt++; + port_map |= (1 << (mod_no+1)); + }else if (rm_mod_type[mod_no] == MOD_TYPE_FXO){ + sprintf(str, "\n+%02d:FXO", mod_no+1); + port_cnt++; + port_map |= (1 << (mod_no+1)); }else{ sprintf(str, "\n+%02d:EMPTY", mod_no+1); } - memcpy(&hw->hwport[0].hwprobe->hw_info_verbose[off], + memcpy(&hw->hwprobe->hw_info_verbose[off], str, strlen(str)); off += strlen(str); } @@ -889,33 +1261,242 @@ static int sdla_save_Remora_hw_probe_verbose(sdlahw_t* hw, int port) sdla_bus_write_4(hw,0x40,reg); sdla_memory_unmap(hw); - return 0; + *max_ports_no = port_cnt; + hwcpu->max_ports = port_cnt; /* overwrite with real port number */ + hwcpu->port_map = port_map; + + return hw; } -static int sdla_save_ISDN_hw_probe_verbose(sdlahw_t* hw, int port) +static sdlahw_t *sdla_hwport_ISDN_register(sdlahw_cpu_t* hwcpu, int *ports_no) { + sdlahw_t *hw, *first_hw = NULL; + int port_cnt = 0, mod_no, rm_no; + u32 reg, port_map=0; + int rm_mod_type[MAX_REMORA_MODULES+2]; + unsigned char str[50]; + + WAN_ASSERT_RC(hwcpu == NULL, NULL); + + if ((hw = sdla_hw_register(hwcpu, 0)) == NULL){ + return NULL; + } + + if (sdla_memory_map(hw, SDLA_CPU_A)){ + sdla_hw_unregister(hw); + return NULL; + } - /* FIXME: Add code for ISDN card for module detection */ - return 0; + /* A500 clear reset. Disable Global Chip/FrontEnd/CPLD Reset. */ + sdla_bus_read_4(hw, 0x40,®); + wan_set_bit(1,®); + wan_set_bit(2,®); + sdla_bus_write_4(hw,0x40,reg); + + WP_DELAY(10); + + wan_clear_bit(1,®); + wan_clear_bit(2,®); + sdla_bus_write_4(hw,0x40,reg); + + WP_DELAY(10); + + /* Reset SPI bus */ + sdla_bus_write_4(hw,SPI_INTERFACE_REG,MOD_SPI_RESET); + WP_DELAY(1000); + sdla_bus_write_4(hw,SPI_INTERFACE_REG,0x00000000); + WP_DELAY(1000); + + for(mod_no = 0; mod_no < MAX_BRI_LINES; mod_no++){ + rm_mod_type[mod_no] = MOD_TYPE_NONE; + } + + for(rm_no = 0; rm_no < MAX_BRI_REMORAS; rm_no++){ + port_cnt += sdla_scan_isdn_bri_modules(hw, rm_mod_type, (u8)rm_no); + } + + /* The sdla_scan_isdn_bri_modules() call returns number of PHYSICAL modules. + But sdla_save_ISDN_hw_probe() must return number of LOGICAL modules, + which is actually number of BRI ports. + */ + port_cnt *= BRI_MAX_PORTS_PER_CHIP; + + /* A500 has a hwport for each BRI port */ + for(mod_no = 0; mod_no < MAX_BRI_LINES; mod_no ++){ + + if (rm_mod_type[mod_no] == MOD_TYPE_TE){ + sprintf(str, "\n+%02d:TE", mod_no+1); + port_map |= (1 << (mod_no+1)); + }else if (rm_mod_type[mod_no] == MOD_TYPE_NT){ + sprintf(str, "\n+%02d:NT", mod_no+1); + port_map |= (1 << (mod_no+1)); + }else{ + /* EMPTY */ + continue; + } + + if (first_hw == NULL){ + sdla_hwport_unregister(hwcpu); + } + if ((hw = sdla_hw_register(hwcpu, mod_no)) == NULL){ + sdla_memory_unmap(hw); + sdla_hwport_unregister(hwcpu); + return NULL; + } + if (first_hw == NULL){ + first_hw = hw; + } + memcpy(&hw->hwprobe->hw_info_verbose[0], + str, strlen(str)); + } + + /* Reset SPI bus */ + sdla_bus_write_4(hw,SPI_INTERFACE_REG,MOD_SPI_RESET); + WP_DELAY(1000); + sdla_bus_write_4(hw,SPI_INTERFACE_REG,0x00000000); + WP_DELAY(1000); + + WP_DELAY(10); + + wan_set_bit(1,®); + wan_set_bit(2,®); + sdla_bus_write_4(hw,0x40,reg); + + sdla_memory_unmap(hw); + *ports_no = port_cnt; + hwcpu->max_ports = port_cnt; /* overwrite with real port number */ + hwcpu->port_map = port_map; + return first_hw; +} + +/****************************************************************************** + * sdla_scan_isdn_bri_modules() + * + * Description : Scan for installed modules. + * + * Arguments : pfe - pointer to Front End structure. + * Returns : number of discovered modules. + *******************************************************************************/ + +static int sdla_scan_isdn_bri_modules(sdlahw_t* hw, int *rm_mod_type, u_int8_t rm_no) +{ + u_int8_t mod_no = 0x3; /* to read remora status register ALWAYS put 0x3 into mod_addr. */ + u_int8_t value, ind, mod_counter = 0; + u_int8_t mod_no_index; /* index in the array of ALL modules (NOT lines) on ALL remoras. From 0 to 11 */ + + /* format of remora status register: + bit 0 == 1 - module 1 active (exist) + bit 1 - type of module 1 (0 - NT, 1 - TE) + + bit 2 == 1 - module 2 active (exist) + bit 3 - type of module 1 (0 - NT, 1 - TE) + + bit 4 == 1 - module 3 active (exist) + bit 5 - type of module 1 (0 - NT, 1 - TE) + + bit 6,7 - has to be zeros for active remora. if non-zero, remora does not exist. + */ + + value = sdla_shark_bri_read_fe( hw, + mod_no, + MOD_TYPE_NONE, + rm_no, + 0); + +#define MODULE1 0 +#define MODULE2 2 +#define MODULE3 4 + + DEBUG_TEST("remora number: %d, remora status register: 0x%02X\n", rm_no, value); + + if(((value >> 7) & 0x01) || ((value >> 8) & 0x01)){ + DEBUG_EVENT("%s: Remora number %d does not exist.\n", hw->devname, rm_no); + return 0; + } + + for(ind = 0; ind < 6; ind++){ + + switch(ind){ + + case MODULE1: + case MODULE2: + case MODULE3: + DEBUG_TEST("module Number on REMORA (0-2): %d\n", ind / 2); + + /* 0-11, all (even and odd) numbers */ + mod_no_index = rm_no * MAX_BRI_MODULES_PER_REMORA + ind / 2; + DEBUG_TEST("mod_no_index on CARD (should be 0-11): %d\n", mod_no_index); + + /* 0-23, only even numbers */ + mod_no_index = mod_no_index * 2;//???? + DEBUG_TEST("mod_no_index (line number) on CARD (should be 0-23): %d\n", mod_no_index); + + if(mod_no_index >= MAX_BRI_LINES){ + DEBUG_EVENT("%s: Error: Module %d/%d exceeds maximum (%d)\n", + hw->devname, mod_no_index, mod_no_index, MAX_BRI_LINES); + return 0; + } + + if((value >> ind) & 0x01){ + + mod_counter++; + + if((value >> (ind + 1)) & 0x01){ + + DEBUG_TEST("%s: Module %d type is: TE\n", + hw->devname, mod_no_index); + + rm_mod_type[mod_no_index] = MOD_TYPE_TE; + rm_mod_type[mod_no_index+1] = MOD_TYPE_TE; + + }else{ + DEBUG_TEST("%s: Module %d type is: NT\n", + hw->devname, mod_no_index); + + rm_mod_type[mod_no_index] = MOD_TYPE_NT; + rm_mod_type[mod_no_index+1] = MOD_TYPE_NT; + } + + }else{ + DEBUG_TEST("%s: Module %d is not installed\n", + hw->devname, mod_no_index); + } + DEBUG_TEST("=================================\n\n"); + break; + }/* switch() */ + }/* for() */ + + return mod_counter; } #define AFT_CHIP_CFG_REG 0x40 #define AFT_CHIPCFG_SFR_IN_BIT 2 #define AFT_CHIPCFG_SFR_EX_BIT 1 -static int sdla_get_cpld_info(sdlahw_t* hw) +#if !defined(__WINDOWS__) +static +#endif +int sdla_get_hw_info(sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; unsigned int reg, reg1; unsigned short cpld_off; - unsigned char status = 0, tmp = 0, adptr_sec = 0; + unsigned char status = 0, tmp = 0, adptr_sec = 0; AFT_FUNC_DEBUG(); + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + if (sdla_memory_map(hw, SDLA_CPU_A)){ return -EINVAL; } - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ - switch(hw->hwcard->adptr_type){ + if (hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: cpld_off = AFT_SECURITY_CPLD_REG; @@ -924,11 +1505,11 @@ static int sdla_get_cpld_info(sdlahw_t* hw) switch(adptr_sec){ case AFT_SECURITY_1LINE_UNCH: case AFT_SECURITY_2LINE_UNCH: - hw->hwcard->adptr_security = AFT_SECURITY_UNCHAN; + hwcard->adptr_security = AFT_SECURITY_UNCHAN; break; case AFT_SECURITY_1LINE_CH: case AFT_SECURITY_2LINE_CH: - hw->hwcard->adptr_security = AFT_SECURITY_CHAN; + hwcard->adptr_security = AFT_SECURITY_CHAN; break; default: DEBUG_EVENT( @@ -950,12 +1531,12 @@ static int sdla_get_cpld_info(sdlahw_t* hw) sdla_hw_read_cpld(hw, cpld_off, &tmp); adptr_sec = AFT_GET_SECURITY(tmp); if (adptr_sec == AFT_SECURITY_1LINE_UNCH){ - hw->hwcard->adptr_security = AFT_SECURITY_UNCHAN; + hwcard->adptr_security = AFT_SECURITY_UNCHAN; }else if (adptr_sec == AFT_SECURITY_1LINE_CH){ - hw->hwcard->adptr_security = AFT_SECURITY_CHAN; + hwcard->adptr_security = AFT_SECURITY_CHAN; }else if (adptr_sec == 0x02){ /*FIXME: ALEX CHANGE HARDCODED VALUE FOR SHARK */ - hw->hwcard->adptr_security = AFT_SECURITY_CHAN; + hwcard->adptr_security = AFT_SECURITY_CHAN; }else{ DEBUG_EVENT( "%s: AFT-A104 Critical error: Unknown Security ID (%02X)!\n", @@ -967,10 +1548,10 @@ static int sdla_get_cpld_info(sdlahw_t* hw) break; } - }else if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ - switch(hw->hwcard->core_id){ + }else if (hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + switch(hwcard->core_id){ case AFT_PMC_FE_CORE_ID: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A104_ADPTR_4TE1: /* Enable memory access */ sdla_bus_read_4(hw, AFT_CHIP_CFG_REG, ®1); @@ -981,19 +1562,19 @@ static int sdla_get_cpld_info(sdlahw_t* hw) cpld_off = AFT_SH_CPLD_BOARD_STATUS_REG; sdla_hw_read_cpld(hw, cpld_off, &status); - hw->hwcard->hwec_chan_no = A104_ECCHAN(AFT_SH_SECURITY(status)); + hwcard->hwec_chan_no = A104_ECCHAN(AFT_SH_SECURITY(status)); /* Restore original value */ sdla_bus_write_4(hw, AFT_CHIP_CFG_REG, reg1); break; case A300_ADPTR_U_1TE3: /* By default, AFT-A300 is unchannelized! */ - hw->hwcard->adptr_security = AFT_SECURITY_UNCHAN; + hwcard->adptr_security = AFT_SECURITY_UNCHAN; break; } break; case AFT_DS_FE_CORE_ID: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: case A104_ADPTR_4TE1: @@ -1007,7 +1588,7 @@ static int sdla_get_cpld_info(sdlahw_t* hw) cpld_off = AFT_SH_CPLD_BOARD_STATUS_REG; sdla_hw_read_cpld(hw, cpld_off, &status); - hw->hwcard->hwec_chan_no = A108_ECCHAN(AFT_SH_SECURITY(status)); + hwcard->hwec_chan_no = A108_ECCHAN(AFT_SH_SECURITY(status)); /* Restore original value */ sdla_bus_write_4(hw, AFT_CHIP_CFG_REG, reg1); @@ -1015,7 +1596,7 @@ static int sdla_get_cpld_info(sdlahw_t* hw) } break; default: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: /* Enable memory access */ @@ -1027,9 +1608,9 @@ static int sdla_get_cpld_info(sdlahw_t* hw) cpld_off = A200_SH_CPLD_BOARD_STATUS_REG; sdla_hw_read_cpld(hw, cpld_off, &status); - hw->hwcard->hwec_chan_no = AFT_RM_ECCHAN(AFT_SH_SECURITY(status)); + hwcard->hwec_chan_no = AFT_RM_ECCHAN(AFT_SH_SECURITY(status)); - if (hw->hwcard->hwec_chan_no){ + if (hwcard->hwec_chan_no){ /* Check EC access */ /* Clear octasic reset */ @@ -1043,8 +1624,40 @@ static int sdla_get_cpld_info(sdlahw_t* hw) /* Restore original value */ sdla_bus_write_4(hw, AFT_CHIP_CFG_REG, reg1); - break; + + case AFT_ADPTR_ISDN: + AFT_FUNC_DEBUG(); + /* Enable memory access */ + sdla_bus_read_4(hw, AFT_CHIP_CFG_REG, ®1); + reg = reg1; + wan_clear_bit(AFT_CHIPCFG_SFR_IN_BIT, ®); + wan_clear_bit(AFT_CHIPCFG_SFR_EX_BIT, ®); + sdla_bus_write_4(hw, AFT_CHIP_CFG_REG, reg); + + /* Restore original value */ + //sdla_bus_write_4(hw, AFT_CHIP_CFG_REG, reg1); + cpld_off = A200_SH_CPLD_BOARD_STATUS_REG; + sdla_hw_read_cpld(hw, cpld_off, &status); + + DEBUG_BRI("at A200_SH_CPLD_BOARD_STATUS_REG: 0x%X\n", status); + + hwcard->hwec_chan_no = A500_ECCHAN(AFT_SH_SECURITY(status)); + + DEBUG_BRI("hwcard->hwec_chan_no: %d\n", hwcard->hwec_chan_no); + + if (hwcard->hwec_chan_no){ + /* Check EC access */ + /* Clear octasic reset */ + cpld_off = 0x00; + sdla_hw_write_cpld(hw, cpld_off, 0x01); + + /* Set octasic reset */ + cpld_off = 0x00; + sdla_hw_write_cpld(hw, cpld_off, 0x00); + } + break; + case AFT_ADPTR_56K: AFT_FUNC_DEBUG(); /* Enable memory access */ @@ -1056,12 +1669,49 @@ static int sdla_get_cpld_info(sdlahw_t* hw) cpld_off = AFT_SH_CPLD_BOARD_STATUS_REG; sdla_hw_read_cpld(hw, cpld_off, &status); - hw->hwcard->hwec_chan_no = 0; - + hwcard->hwec_chan_no = 0; + break; + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + /* AFT-SERIAL: Add code here */ break; } break; } + /* Only for those cards that have PLX PCI Express chip as master */ + if (hwcard->pci_bridge_dev){ + u_int16_t vendor_id; + u_int8_t val; + + sdla_plxctrl_read8(hw, 0x00, &val); + /* For now, all PLX with blank EEPROM is our new + ** cards from production. */ + if (val == PLX_EEPROM_ENABLE){ + + sdla_plxctrl_read8(hw, PLX_EEPROM_VENDOR_OFF, &val); + vendor_id = val << 8; + sdla_plxctrl_read8(hw, PLX_EEPROM_VENDOR_OFF+1, &val); + vendor_id |= val; + if (vendor_id != SANGOMA_PCI_VENDOR){ + hwcard->pci_bridge_dev = NULL; + hwcard->pci_bridge_bus = 0; + hwcard->pci_bridge_slot = 0; + } + } + } + } + if (hwcard->hwec_chan_no){ + /* These card has Echo Cancellation module */ +#if defined(__WINDOWS__) + /* Special case for Windows driver: + ** Serial number of the physical card, NOT changing + ** when a port is restarted. */ + hwcard->hwec_ind = get_card_serial_number(hw->p_sdla); +#else + hwcard->hwec_ind = ++sdla_hwec_no; +#endif } sdla_memory_unmap(hw); return 0; @@ -1072,53 +1722,62 @@ static int sdla_get_cpld_info(sdlahw_t* hw) ** sdla_hw_select ***************************************************************************** */ -static int sdla_s514_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* dev) +static int +sdla_s514_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* dev) { - sdlahw_t* hw=NULL; + sdlahw_cpu_t *hwcpu=NULL; + sdlahw_t *hw=NULL; int number_of_cards = 0; hwcard->cfg_type = WANOPT_S51X; hwcard->type = SDLA_S514; + sdla_get_hwcard_name(hwcard); sdla_adapter_cnt.s514x_adapters++; switch(hwcard->adptr_type){ case S5144_ADPTR_1_CPU_T1E1: - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ return -EINVAL; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_te1_register(hwcpu, 2)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 2; DEBUG_EVENT( "%s: %s T1/E1 card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, hwcard->bus_no, hwcard->slot_no, irq); - sdla_save_hw_probe(hw, 0); - sdla_save_hw_probe(hw, 1); - number_of_cards += 2; break; case S5145_ADPTR_1_CPU_56K: - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ return -EINVAL; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_register(hwcpu, 2)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 2; DEBUG_EVENT( "%s: %s 56K card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, hwcard->bus_no, hwcard->slot_no, irq); - sdla_save_hw_probe(hw, 0); - sdla_save_hw_probe(hw, 1); - number_of_cards += 2; break; case S5142_ADPTR_2_CPU_SERIAL: - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ return -EINVAL; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_register(hwcpu, 2)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 2; /* Print the message only for CPU A. ** BSD calls this function for both CPUs */ if (cpu_no == SDLA_CPU_A){ @@ -1128,45 +1787,54 @@ static int sdla_s514_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void hwcard->adptr_name, hwcard->bus_no, hwcard->slot_no, irq); }else{ -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +#if !defined(SDLA_AUTO_PROBE) +# if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) sdla_adapter_cnt.s514x_adapters--; +# endif #endif } - sdla_save_hw_probe(hw, 0); - sdla_save_hw_probe(hw, 1); - number_of_cards += 2; -#if defined(__LINUX__) - if ((hw = sdla_hw_register(hwcard, SDLA_CPU_B, irq, dev)) == NULL){ +#if defined(__LINUX__) || defined(SDLA_AUTO_PROBE) + if ((hwcpu = sdla_hwcpu_register(hwcard, SDLA_CPU_B, irq, dev)) == NULL){ return -EINVAL; } - sdla_save_hw_probe(hw, 0); - sdla_save_hw_probe(hw, 1); + /* Aug 10, 2007 + ** Do not overwrite first hw for this Serial card */ + if (sdla_hwport_register(hwcpu, 2) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } number_of_cards += 2; #endif break; case S5143_ADPTR_1_CPU_FT1: - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ return -EINVAL; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_te1_register(hwcpu, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 1; DEBUG_EVENT( "%s: %s FT1 card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, hwcard->bus_no, hwcard->slot_no, irq); - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; break; case S5147_ADPTR_2_CPU_T1E1: - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ return -EINVAL; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_te1_register(hwcpu, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 1; /* Print the message only for CPU A. ** BSD calls this function for both CPUs */ if (cpu_no == SDLA_CPU_A){ @@ -1181,67 +1849,83 @@ static int sdla_s514_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void #endif } - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; #if defined(__LINUX__) - if ((hw = sdla_hw_register(hwcard, SDLA_CPU_B, irq, dev)) == NULL){ + if ((hwcpu = sdla_hwcpu_register(hwcard, SDLA_CPU_B, irq, dev)) == NULL){ return -EINVAL; } - sdla_save_hw_probe(hw, 0); + /* Aug 10, 2007 + ** Do not overwrite first hw for this Serial card */ + if (sdla_hwport_te1_register(hwcpu, 1) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } number_of_cards += 1; #endif break; case S5148_ADPTR_1_CPU_T1E1: hwcard->adptr_type = S5144_ADPTR_1_CPU_T1E1; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ + sdla_get_hwcard_name(hwcard); + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ return -EINVAL; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_te1_register(hwcpu, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 1; DEBUG_EVENT( "%s: S514-8-PCI T1/E1 card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->bus_no, hwcard->slot_no, irq); - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; break; default: - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ return -EINVAL; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_register(hwcpu, 2)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 2; DEBUG_EVENT( "%s: S514-1-PCI V35/RS232/FT1 card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->bus_no, hwcard->slot_no, irq); - sdla_save_hw_probe(hw, 0); - sdla_save_hw_probe(hw, 1); - number_of_cards += 2; break; } + while(hw){ + sdla_save_hw_probe(hw); + hw = WAN_LIST_NEXT(hw, next); + } return number_of_cards; } -static int sdla_adsl_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* dev) +static int +sdla_adsl_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* dev) { - sdlahw_t* hw=NULL; + sdlahw_cpu_t *hwcpu = NULL; + sdlahw_t *hw=NULL; int number_of_cards = 0; hwcard->cfg_type = WANOPT_ADSL; hwcard->type = SDLA_ADSL; + sdla_get_hwcard_name(hwcard); switch(hwcard->adptr_type){ case S518_ADPTR_1_CPU_ADSL: sdla_adapter_cnt.s518_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; } - sdla_get_adptr_name(hw); + if ((hw = sdla_hwport_register(hwcpu, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 1; DEBUG_EVENT( "%s: %s ADSL card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, hwcard->bus_no, hwcard->slot_no, irq); - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; break; default: @@ -1251,85 +1935,122 @@ static int sdla_adsl_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void break; } + while(hw){ + sdla_save_hw_probe(hw); + hw = WAN_LIST_NEXT(hw, next); + } return number_of_cards; } - static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* dev) { - sdlahw_t* hw=NULL; - int number_of_cards = 0; + sdlahw_cpu_t *hwcpu=NULL; + sdlahw_t *hw=NULL; +#if defined(__LINUX__) || defined(SDLA_AUTO_PROBE) + sdlahw_cpu_t *hwcpu2=NULL; + sdlahw_t *hw2= NULL; +#endif + int number_of_cards = 0, ports_no = 1; hwcard->type = SDLA_AFT; + sdla_get_hwcard_name(hwcard); switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: hwcard->cfg_type = WANOPT_AFT; sdla_adapter_cnt.aft101_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; - } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; if (hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ hwcard->cfg_type = WANOPT_AFT; }else if (hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ hwcard->cfg_type = WANOPT_AFT101; } + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; + } + if ((hw = sdla_hwport_te1_register(hwcpu, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + sdla_get_hw_info(hw); + sdla_get_hwcard_name(hwcard); + number_of_cards += 1; DEBUG_EVENT( "%s: %s%s T1/E1 card found (%s rev.%X), cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); break; case A101_ADPTR_2TE1: - sdla_adapter_cnt.aft101_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; - } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; if (hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ hwcard->cfg_type = WANOPT_AFT; + sdla_adapter_cnt.aft101_adapters++; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; + } + if ((hw = sdla_hwport_te1_register(hwcpu, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + sdla_get_hw_info(hw); + sdla_get_hwcard_name(hwcard); + number_of_cards += 1; #if defined(__LINUX__) if (hwcard->pci_dev->resource[1].flags){ - if ((hw = sdla_hw_register(hwcard, SDLA_CPU_B, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu2 = sdla_hwcpu_register(hwcard, SDLA_CPU_B, irq, dev)) == NULL){ + return 0; + } + if ((hw2 = sdla_hwport_te1_register(hwcpu2, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; } - sdla_save_hw_probe(hw, 0); number_of_cards += 1; } +#elif defined(__FreeBSD__) && defined(SDLA_AUTO_PROBE) + if ((hwcpu2 = sdla_hwcpu_register(hwcard, SDLA_CPU_B, irq, dev)) == NULL){ + return 0; + } + if ((hw2 = sdla_hwport_te1_register(hwcpu2, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu2); + return 0; + } + number_of_cards += 1; #endif if (cpu_no == SDLA_CPU_A){ DEBUG_EVENT( "%s: %s%s T1/E1 card found (%s rev.%X), cpu(s) 2, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); }else{ +#if !defined(SDLA_AUTO_PROBE) #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) sdla_adapter_cnt.aft101_adapters--; +#endif #endif } }else if (hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ hwcard->cfg_type = WANOPT_AFT102; - sdla_save_hw_probe(hw, 1); - number_of_cards += 1; + sdla_adapter_cnt.aft101_adapters++; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; + } + if ((hw = sdla_hwport_te1_register(hwcpu, 2)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + sdla_get_hw_info(hw); + number_of_cards += 2; DEBUG_EVENT( "%s: %s%s T1/E1 card found (%s rev.%X), cpu(s) 1, line(s) 2, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); @@ -1339,24 +2060,22 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* case A104_ADPTR_4TE1: hwcard->cfg_type = WANOPT_AFT104; sdla_adapter_cnt.aft104_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - number_of_cards ++; - sdla_save_hw_probe(hw, 1); - number_of_cards ++; - sdla_save_hw_probe(hw, 2); - number_of_cards ++; - sdla_save_hw_probe(hw, 3); - number_of_cards ++; + if ((hw = sdla_hwport_te1_register(hwcpu, 4)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + sdla_get_hw_info(hw); + sdla_get_hwcard_name(hwcard); + number_of_cards += 4; + DEBUG_EVENT( "%s: %s%s T1/E1 card found (%s rev.%X), cpu(s) 1, line(s) 4, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); @@ -1365,32 +2084,20 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* case A108_ADPTR_8TE1: hwcard->cfg_type = WANOPT_AFT108; sdla_adapter_cnt.aft108_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - number_of_cards ++; - sdla_save_hw_probe(hw, 1); - number_of_cards ++; - sdla_save_hw_probe(hw, 2); - number_of_cards ++; - sdla_save_hw_probe(hw, 3); - number_of_cards ++; - sdla_save_hw_probe(hw, 4); - number_of_cards ++; - sdla_save_hw_probe(hw, 5); - number_of_cards ++; - sdla_save_hw_probe(hw, 6); - number_of_cards ++; - sdla_save_hw_probe(hw, 7); - number_of_cards ++; + if ((hw = sdla_hwport_te1_register(hwcpu, 8)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += 8; + sdla_get_hw_info(hw); DEBUG_EVENT( "%s: %s%s T1/E1 card found (%s rev.%X), cpu(s) 1, line(s) 8, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); @@ -1400,18 +2107,20 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* hwcard->cfg_type = WANOPT_AFT300; sdla_adapter_cnt.aft300_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; + } + if ((hw = sdla_hw_register(hwcpu, 0)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); number_of_cards += 1; + sdla_get_hw_info(hw); DEBUG_EVENT( "%s: %s%s T3/E3 card found (%s rev.%X), cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); @@ -1422,21 +2131,21 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* hwcard->cfg_type = WANOPT_AFT_ANALOG; sdla_adapter_cnt.aft200_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - /* Verify FXS/FXO modules */ - sdla_save_Remora_hw_probe_verbose(hw, 0); + if ((hw = sdla_hwport_Remora_register(hwcpu, &ports_no)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards ++; + sdla_get_hw_info(hw); - number_of_cards += 1; DEBUG_EVENT( "%s: %s%s FXO/FXS card found (%s rev.%X), cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); @@ -1446,21 +2155,23 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* hwcard->cfg_type = WANOPT_AFT_ISDN; sdla_adapter_cnt.aft_isdn_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - /* Verify FXS/FXO modules */ - sdla_save_ISDN_hw_probe_verbose(hw, 0); + if ((hw = sdla_hwport_ISDN_register(hwcpu, &ports_no)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + sdla_get_hw_info(hw); + + /* Verify BRI TE/NT modules */ + number_of_cards += ports_no; - number_of_cards += 1; DEBUG_EVENT( "%s: %s%s ISDN BRI card found (%s rev.%X), cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); @@ -1470,44 +2181,60 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* hwcard->cfg_type = WANOPT_AFT_56K; sdla_adapter_cnt.aft_56k_adapters++; - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; + } + if ((hw = sdla_hwport_register(hwcpu, 1)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; + sdla_get_hw_info(hw); + DEBUG_EVENT( "%s: %s%s 56K card found (%s rev.%X), cpu(s) 1, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, - AFT_PCIEXPRESS_DECODE(hwcard), + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), hwcard->core_rev, hwcard->bus_no, hwcard->slot_no, irq); break; - default: -#if 0 - hwcard->cfg_type = WANOPT_AFT104; - sdla_adapter_cnt.aft_x_adapters++; - - if ((hw = sdla_hw_register(hwcard, cpu_no, irq, dev)) == NULL){ - return -EINVAL; + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + if (hwcard->adptr_type == AFT_ADPTR_2SERIAL_V35X21 || + hwcard->adptr_type == AFT_ADPTR_2SERIAL_RS232){ + ports_no = 2; + }else{ + ports_no = 4; } - sdla_get_cpld_info(hw); - sdla_get_adptr_name(hw); - sdla_save_hw_probe(hw, 0); - number_of_cards += 1; + hwcard->cfg_type = WANOPT_AFT_SERIAL; + sdla_adapter_cnt.aft_serial_adapters++; + + if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){ + return 0; + } + if ((hw = sdla_hwport_serial_register(hwcpu, ports_no)) == NULL){ + sdla_hwcpu_unregister(hwcpu); + return 0; + } + number_of_cards += ports_no; + sdla_get_hw_info(hw); + DEBUG_EVENT( - "%s: %s PCI-X card found (%s rev.%X), cpu(s) 1, bus #%d, slot #%d, irq #%d\n", + "%s: %s%s Serial card found (%s rev.%X), cpu(s) %d, bus #%d, slot #%d, irq #%d\n", wan_drvname, hwcard->adptr_name, + AFT_PCITYPE_DECODE(hwcard), AFT_CORE_ID_DECODE(hwcard->core_id), - hwcard->core_rev, + hwcard->core_rev, ports_no, hwcard->bus_no, hwcard->slot_no, irq); -#else + break; + + default: DEBUG_EVENT( "%s: Unknown adapter %04X (bus #%d, slot #%d, irq #%d)!\n", wan_drvname, @@ -1515,10 +2242,12 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* hwcard->bus_no, hwcard->slot_no, irq); -#endif break; } - + while(hw){ + sdla_save_hw_probe(hw); + hw = WAN_LIST_NEXT(hw, next); + } return number_of_cards; } @@ -1527,442 +2256,522 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void* ** sdla_pci_probe ***************************************************************************** */ +static int +sdla_pci_probe_S(sdlahw_t *hw, int slot, int bus, int irq) +{ + sdlahw_card_t *hwcard = NULL, *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; + u16 PCI_subsys_vendor; + u16 pci_subsystem_id; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + sdla_pci_read_config_word(hw,PCI_SUBSYS_VENDOR_WORD,&PCI_subsys_vendor); + + if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR) return 0; + + sdla_pci_read_config_word(hw,PCI_SUBSYS_ID_WORD,&pci_subsystem_id); + + hwcard = sdla_card_register(SDLA_PCI_CARD, slot, bus, 0); + if (hwcard == NULL) return 0; + + hwcard->adptr_type = pci_subsystem_id & 0xFF; + hwcard->pci_dev = tmp_hwcard->pci_dev; + + /* A dual cpu card can support up to 4 physical connections, + * where a single cpu card can support up to 2 physical + * connections. The FT1 card can only support a single + * connection, however we cannot distinguish between a Single + * CPU card and an FT1 card. */ + return sdla_s514_hw_select(hwcard, SDLA_CPU_A, irq, NULL); +} + +static int +sdla_pci_probe_adsl(sdlahw_t *hw, int slot, int bus, int irq) +{ + sdlahw_card_t *hwcard = NULL, *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; + u16 pci_subsystem_id; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + sdla_pci_read_config_word(hw, PCI_SUBSYS_ID_WORD, &pci_subsystem_id); + +#if 0 + if ((pci_subsystem_id & 0xFF) != S518_ADPTR_1_CPU_ADSL){ + continue; + } +#else + pci_subsystem_id=S518_ADPTR_1_CPU_ADSL; +#endif + + hwcard = sdla_card_register(SDLA_PCI_CARD, slot, bus, 0); + if (hwcard == NULL) return 0; + + hwcard->adptr_type = pci_subsystem_id & 0xFF; + hwcard->pci_dev = tmp_hwcard->pci_dev; + + return sdla_adsl_hw_select(hwcard, SDLA_CPU_A, irq, NULL); +} + +static int +sdla_pci_probe_adsl_2(sdlahw_t *hw, int slot, int bus, int irq) +{ + sdlahw_card_t *hwcard = NULL, *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; + u16 pci_subsystem_id; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + sdla_pci_read_config_word(hw, PCI_SUBSYS_ID_WORD, &pci_subsystem_id); + + pci_subsystem_id=S518_ADPTR_1_CPU_ADSL; + + hwcard = sdla_card_register(SDLA_PCI_CARD, slot, bus, 0); + if (hwcard == NULL){ + return 0; + } + hwcard->adptr_type = pci_subsystem_id & 0xFF; + hwcard->pci_dev = tmp_hwcard->pci_dev; + + return sdla_adsl_hw_select(hwcard, SDLA_CPU_A, irq, NULL); +} + +static int +sdla_pci_probe_aft(sdlahw_t *hw, int slot_no, int bus_no, int irq) +{ + sdlahw_card_t *hwcard = NULL, *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; + u16 pci_device_id; + u16 PCI_subsys_vendor; + u16 pci_subsystem_id; +#if defined(__LINUX__) + struct pci_dev* pci_bridge_dev = NULL; + struct pci_bus* bus = NULL; +#endif + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + WAN_ASSERT(hw->hwcpu->hwcard->pci_dev == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + /* ALEX 11/18 + * Supporting different aft cards */ + sdla_pci_read_config_word(hw, + PCI_DEVICE_ID_WORD, + &pci_device_id); + if (pci_device_id == SANGOMA_PCI_DEVICE || pci_device_id == SANGOMA_PCI_4_DEVICE){ + /* Old A-series cards, keep original sequence */ + return 0; + } + sdla_pci_read_config_word(hw, + PCI_SUBSYS_VENDOR_WORD, + &PCI_subsys_vendor); + sdla_pci_read_config_word(hw, + PCI_SUBSYS_ID_WORD, + &pci_subsystem_id); + + hwcard = sdla_card_register(SDLA_PCI_CARD, slot_no, bus_no, 0); + if (hwcard == NULL){ + return 0; + } + + switch(PCI_subsys_vendor){ + case A101_1TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_1TE1; + break; + case A101_2TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_2TE1; + break; + case A104_4TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A104_ADPTR_4TE1; + break; + case AFT_1TE1_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_1TE1; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_2TE1_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_2TE1; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_4TE1_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A104_ADPTR_4TE1; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_8TE1_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A108_ADPTR_8TE1; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case A300_UTE3_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A300_ADPTR_U_1TE3; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case A305_CTE3_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A305_ADPTR_C_1TE3; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case A200_REMORA_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A200_ADPTR_ANALOG; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case A400_REMORA_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A400_ADPTR_ANALOG; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = AFT_ADPTR_ISDN; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_56K_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = AFT_ADPTR_56K; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_2SERIAL_V35X21_SUBSYS_VENDOR: + hwcard->adptr_type = AFT_ADPTR_2SERIAL_V35X21; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_4SERIAL_V35X21_SUBSYS_VENDOR: + hwcard->adptr_type = AFT_ADPTR_4SERIAL_V35X21; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_2SERIAL_RS232_SUBSYS_VENDOR: + hwcard->adptr_type = AFT_ADPTR_2SERIAL_RS232; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + case AFT_4SERIAL_RS232_SUBSYS_VENDOR: + hwcard->adptr_type = AFT_ADPTR_4SERIAL_RS232; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + default: + DEBUG_EVENT( + "%s: Unsupported SubVendor ID:%04X (bus=%d, slot=%d)\n", + wan_drvname, + PCI_subsys_vendor, slot_no, bus_no); + sdla_card_unregister(SDLA_PCI_CARD, slot_no, bus_no, 0); + return 0; + } +#if defined(__LINUX__) + /* Detect PCI Express cards (only valid for production test) */ + switch(PCI_subsys_vendor){ + case A200_REMORA_SHARK_SUBSYS_VENDOR: + case A400_REMORA_SHARK_SUBSYS_VENDOR: + case AFT_1TE1_SHARK_SUBSYS_VENDOR: + case AFT_2TE1_SHARK_SUBSYS_VENDOR: + case AFT_4TE1_SHARK_SUBSYS_VENDOR: + case AFT_8TE1_SHARK_SUBSYS_VENDOR: + case AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR: + case AFT_56K_SHARK_SUBSYS_VENDOR: + case AFT_2SERIAL_V35X21_SUBSYS_VENDOR: + case AFT_4SERIAL_V35X21_SUBSYS_VENDOR: + case AFT_2SERIAL_RS232_SUBSYS_VENDOR: + case AFT_4SERIAL_RS232_SUBSYS_VENDOR: + if (tmp_hwcard->pci_dev->bus == NULL) break; + bus = tmp_hwcard->pci_dev->bus; + if (bus->self == NULL) break; + pci_bridge_dev = bus->self; + if (pci_bridge_dev->vendor == PLX_VENDOR_ID && + (pci_bridge_dev->device == PLX_DEVICE_ID || + pci_bridge_dev->device == PLX2_DEVICE_ID)){ + hwcard->pci_bridge_dev = pci_bridge_dev; + hwcard->pci_bridge_bus = bus_no; + hwcard->pci_bridge_slot = slot_no; + DEBUG_TEST("%s: PCI-Express card (bus:%d, slot:%d)\n", + wan_drvname, bus_no, slot_no); + } + break; + } +#endif + + hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); + hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); + if (hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + switch(hwcard->core_id){ + case AFT_ANALOG_FE_CORE_ID: + case AFT_PMC_FE_CORE_ID: + case AFT_DS_FE_CORE_ID: + break; + default: + DEBUG_EVENT("%s: Unsupported core id (%X)\n", + wan_drvname, hwcard->core_id); + sdla_card_unregister(SDLA_PCI_CARD, slot_no, bus_no, 0); + return 0; + break; + } + } + hwcard->pci_dev = tmp_hwcard->pci_dev; + return sdla_aft_hw_select(hwcard, SDLA_CPU_A, irq, NULL); +} + +static int +sdla_pci_probe_aft_v2(sdlahw_t *hw, int slot_no, int bus_no, int irq) +{ + sdlahw_card_t *hwcard = NULL, *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; + u16 PCI_subsys_vendor; + u16 pci_subsystem_id; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + /* ALEX 11/18 + * Supporting different aft cards */ + sdla_pci_read_config_word(hw, + PCI_SUBSYS_VENDOR_WORD, + &PCI_subsys_vendor); + + hwcard = sdla_card_register(SDLA_PCI_CARD, slot_no, bus_no, 0); + if (hwcard == NULL){ + return 0; + } + + switch(PCI_subsys_vendor){ + case A101_1TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_1TE1; + break; + case A101_2TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_2TE1; + break; + case A300_UTE3_SUBSYS_VENDOR: + hwcard->adptr_type = A300_ADPTR_U_1TE3; + break; + default: + DEBUG_EVENT("%s: Unsupported subsystem vendor id %04X (bus=%d, slot=%d)\n", + wan_drvname, PCI_subsys_vendor, bus_no, slot_no); + return 0; + } + + sdla_pci_read_config_word(hw, + PCI_SUBSYS_ID_WORD, + &pci_subsystem_id); + hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); + hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); + hwcard->pci_dev = tmp_hwcard->pci_dev; + return sdla_aft_hw_select(hwcard, SDLA_CPU_A, irq, NULL); +} + +static int +sdla_pci_probe_aft_v1(sdlahw_t *hw, int slot_no, int bus_no, int irq) +{ + sdlahw_card_t *hwcard = NULL, *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; + u16 PCI_subsys_vendor; + u16 pci_subsystem_id; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + /* ALEX 11/18 + * Supporting different aft cards */ + sdla_pci_read_config_word(hw, + PCI_SUBSYS_VENDOR_WORD, + &PCI_subsys_vendor); + sdla_pci_read_config_word(hw, + PCI_SUBSYS_ID_WORD, + &pci_subsystem_id); + hwcard = sdla_card_register(SDLA_PCI_CARD, slot_no, bus_no, 0); + if (hwcard == NULL){ + return 0; + } + + switch(PCI_subsys_vendor){ + case A101_1TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_1TE1; + break; + case A101_2TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_2TE1; + break; + case A104_4TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A104_ADPTR_4TE1; + break; + case AFT_4TE1_SHARK_SUBSYS_VENDOR: + hwcard->adptr_type = A104_ADPTR_4TE1; + hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; + break; + default: + DEBUG_EVENT("%s: Unsupported subsystem vendor id %04X (bus=%d, slot=%d)\n", + wan_drvname, PCI_subsys_vendor, bus_no, slot_no); + return 0; + } + + hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); + hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); + hwcard->pci_dev = tmp_hwcard->pci_dev; + return sdla_aft_hw_select(hwcard, SDLA_CPU_A, irq, NULL); +} + +static int +sdla_pci_probe_aft_old(sdlahw_t *hw, int slot_no, int bus_no, int irq) +{ + sdlahw_card_t *hwcard = NULL, *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; + u16 PCI_subsys_vendor; + u16 pci_subsystem_id; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + /* ALEX 11/18 + * Supporting different aft cards */ + sdla_pci_read_config_word(hw, + PCI_SUBSYS_VENDOR_WORD, + &PCI_subsys_vendor); + hwcard = sdla_card_register(SDLA_PCI_CARD, slot_no, bus_no, 0); + if (hwcard == NULL) return 0; + + switch(PCI_subsys_vendor){ + case A101_1TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_1TE1; + break; + case A101_2TE1_SUBSYS_VENDOR: + hwcard->adptr_type = A101_ADPTR_2TE1; + break; + case A300_UTE3_SUBSYS_VENDOR: + hwcard->adptr_type = A300_ADPTR_U_1TE3; + break; + default: + DEBUG_EVENT("%s: Unsupported subsystem vendor id %04X (bus=%d, slot=%d)\n", + wan_drvname, PCI_subsys_vendor, bus_no, slot_no); + return 0; + } + + sdla_pci_read_config_word(hw, + PCI_SUBSYS_ID_WORD, + &pci_subsystem_id); + hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); + hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); + hwcard->pci_dev = tmp_hwcard->pci_dev; + return sdla_aft_hw_select(hwcard, SDLA_CPU_A, irq, NULL); +} + #if defined(__LINUX__) static int sdla_pci_probe(sdlahw_t *hw) { - sdlahw_card_t* tmp_hwcard = NULL; - sdlahw_card_t* hwcard = NULL; +// sdlahw_card_t *hwcard = NULL; + sdlahw_card_t *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu; int number_pci_cards = 0; - u16 pci_device_id; - u16 PCI_subsys_vendor; - u16 pci_subsystem_id; - struct pci_dev* pci_dev = NULL, *pci_bridge_dev = NULL; - struct pci_bus* bus = NULL; +// u16 pci_device_id; +// u16 PCI_subsys_vendor; +// u16 pci_subsystem_id; + struct pci_dev *pci_dev = NULL; +// struct pci_dev *pci_bridge_dev = NULL; +// struct pci_bus* bus = NULL; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - tmp_hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; while ((pci_dev = pci_get_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev)) != NULL) { - tmp_hwcard->pci_dev = pci_dev; - sdla_pci_read_config_word(hw, - PCI_SUBSYS_VENDOR_WORD, - &PCI_subsys_vendor); - - if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR) - continue; - - sdla_pci_read_config_word(hw, - PCI_SUBSYS_ID_WORD, - &pci_subsystem_id); - - hwcard = sdla_card_register(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - if (hwcard == NULL){ - continue; - } - hwcard->adptr_type = pci_subsystem_id & 0xFF; - hwcard->pci_dev = pci_dev; - - /* A dual cpu card can support up to 4 physical connections, - * where a single cpu card can support up to 2 physical - * connections. The FT1 card can only support a single - * connection, however we cannot distinguish between a Single - * CPU card and an FT1 card. */ - number_pci_cards += - sdla_s514_hw_select(hwcard, SDLA_CPU_A, pci_dev->irq, NULL); - + tmp_hwcard->pci_dev = pci_dev; + number_pci_cards += sdla_pci_probe_S( + hw, + ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->bus->number, + pci_dev->irq); } /* Search for Pulsar PCI cards */ pci_dev = NULL; - while ((pci_dev = pci_get_device(PCI_VENDOR_ID_GSI, PCI_DEVICE_ID_GSI_ADSL, pci_dev)) != NULL) { - tmp_hwcard->pci_dev = pci_dev; - sdla_pci_read_config_word(hw, PCI_SUBSYS_ID_WORD, &pci_subsystem_id); - - if ((pci_subsystem_id & 0xFF) != S518_ADPTR_1_CPU_ADSL){ - continue; - } - - hwcard = sdla_card_register(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - if (hwcard == NULL){ - continue; - } - hwcard->adptr_type = pci_subsystem_id & 0xFF; - hwcard->pci_dev = pci_dev; - - number_pci_cards += - sdla_adsl_hw_select(hwcard, SDLA_CPU_A, pci_dev->irq, NULL); - + tmp_hwcard->pci_dev = pci_dev; + number_pci_cards += sdla_pci_probe_adsl( + hw, + ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->bus->number, + pci_dev->irq); } - /* Search for Pulsar PCI cards */ pci_dev = NULL; - while ((pci_dev = pci_get_device(PCI_VENDOR_ID_GSI, PCI_ANY_ID, pci_dev)) + while ((pci_dev = pci_get_device(PCI_VENDOR_ID_GSI, PCI_DEVICE_ID_GSI_ADSL_V2, pci_dev)) != NULL) { tmp_hwcard->pci_dev = pci_dev; - sdla_pci_read_config_word(hw, PCI_SUBSYS_ID_WORD, &pci_subsystem_id); - - pci_subsystem_id=S518_ADPTR_1_CPU_ADSL; - - hwcard = sdla_card_register(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - if (hwcard == NULL){ - continue; - } - hwcard->adptr_type = pci_subsystem_id & 0xFF; - hwcard->pci_dev = pci_dev; - - number_pci_cards += - sdla_adsl_hw_select(hwcard, SDLA_CPU_A, pci_dev->irq, NULL); - + number_pci_cards += sdla_pci_probe_adsl_2( + hw, + ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->bus->number, + pci_dev->irq); } - pci_dev=NULL; while((pci_dev = pci_get_device(SANGOMA_PCI_VENDOR, PCI_ANY_ID, pci_dev)) != NULL){ - bus = pci_dev->bus; - tmp_hwcard->pci_dev = pci_dev; - /* ALEX 11/18 - * Supporting different aft cards */ - sdla_pci_read_config_word(hw, - PCI_DEVICE_ID_WORD, - &pci_device_id); - if (pci_device_id == SANGOMA_PCI_DEVICE || pci_device_id == SANGOMA_PCI_4_DEVICE){ - /* Old A-series cards, keep original sequence */ - continue; - } - sdla_pci_read_config_word(hw, - PCI_SUBSYS_VENDOR_WORD, - &PCI_subsys_vendor); - sdla_pci_read_config_word(hw, - PCI_SUBSYS_ID_WORD, - &pci_subsystem_id); - - hwcard = sdla_card_register(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - if (hwcard == NULL){ - continue; - } - - switch(PCI_subsys_vendor){ - case A101_1TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_1TE1; - break; - - case A101_2TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_2TE1; - break; - - case A104_4TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A104_ADPTR_4TE1; - break; - - case AFT_1TE1_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_1TE1; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case AFT_2TE1_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_2TE1; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case AFT_4TE1_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A104_ADPTR_4TE1; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case AFT_8TE1_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A108_ADPTR_8TE1; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case A300_UTE3_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A300_ADPTR_U_1TE3; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case A305_CTE3_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A305_ADPTR_C_1TE3; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case A200_REMORA_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A200_ADPTR_ANALOG; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case A400_REMORA_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A400_ADPTR_ANALOG; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = AFT_ADPTR_ISDN; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - case AFT_56K_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = AFT_ADPTR_56K; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - default: - DEBUG_EVENT("%s: Unsupported subsystem vendor id %04X (bus=%d, slot=%d)\n", - wan_drvname, - PCI_subsys_vendor, - pci_dev->bus->number, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK)); - continue; - } - /* Detect PCI Express cards (only valid for production test) */ - switch(PCI_subsys_vendor){ - case A200_REMORA_SHARK_SUBSYS_VENDOR: - case A400_REMORA_SHARK_SUBSYS_VENDOR: - case AFT_1TE1_SHARK_SUBSYS_VENDOR: - case AFT_2TE1_SHARK_SUBSYS_VENDOR: - case AFT_4TE1_SHARK_SUBSYS_VENDOR: - case AFT_8TE1_SHARK_SUBSYS_VENDOR: - case AFT_ISDN_BRI_SHARK_SUBSYS_VENDOR: - case AFT_56K_SHARK_SUBSYS_VENDOR: - if (pci_dev->bus == NULL) break; - bus = pci_dev->bus; - if (bus->self == NULL) break; - pci_bridge_dev = bus->self; - - if (pci_bridge_dev->vendor == PLX_VENDOR_ID && - (pci_bridge_dev->device == PLX_DEVICE_ID || - pci_bridge_dev->device == PLX2_DEVICE_ID)){ - - hwcard->pci_bridge_dev = pci_bridge_dev; - DEBUG_TEST("%s: PCI-Express PLX card (bus:%d, slot:%d)\n", - wan_drvname, - pci_bridge_dev->bus->number, - ((pci_bridge_dev->devfn >> 3) & PCI_DEV_SLOT_MASK)); - - }else if (pci_bridge_dev->vendor == TUNDRA_VENDOR_ID && - pci_bridge_dev->device == TUNDRA_DEVICE_ID){ - - hwcard->pci_bridge_dev = pci_bridge_dev; - DEBUG_TEST("%s: PCI-Express card (TUNDRA PCI Bridge, bus:%d, slot:%d)\n", - wan_drvname, hwcard->bus_no, hwcard->slot_no); - } - - break; - } - - hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); - hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); - if (hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ - switch(hwcard->core_id){ - case AFT_ANALOG_FE_CORE_ID: - case AFT_PMC_FE_CORE_ID: - case AFT_DS_FE_CORE_ID: - break; - default: - DEBUG_EVENT("%s: Unsupported core id (%X)\n", - wan_drvname, hwcard->core_id); - sdla_card_unregister(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - continue; - break; - } - } - hwcard->pci_dev = pci_dev; - number_pci_cards += - sdla_aft_hw_select(hwcard, SDLA_CPU_A, pci_dev->irq, NULL); - /* ALEX sdla_adapter_cnt.AFT_adapters++; */ + number_pci_cards += sdla_pci_probe_aft( + hw, + ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->bus->number, + pci_dev->irq); } pci_dev=NULL; while((pci_dev = pci_get_device(SANGOMA_PCI_VENDOR, SANGOMA_PCI_DEVICE, pci_dev)) != NULL){ - bus = pci_dev->bus; - tmp_hwcard->pci_dev = pci_dev; - /* ALEX 11/18 - * Supporting different aft cards */ - sdla_pci_read_config_word(hw, - PCI_SUBSYS_VENDOR_WORD, - &PCI_subsys_vendor); - - hwcard = sdla_card_register(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - if (hwcard == NULL){ - continue; - } - - switch(PCI_subsys_vendor){ - case A101_1TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_1TE1; - break; - - case A101_2TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_2TE1; - break; - - case A300_UTE3_SUBSYS_VENDOR: - hwcard->adptr_type = A300_ADPTR_U_1TE3; - break; - - default: - DEBUG_EVENT("%s: Unsupported subsystem vendor id %04X (bus=%d, slot=%d)\n", - wan_drvname, - PCI_subsys_vendor, - pci_dev->bus->number, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK)); - continue; - } - - sdla_pci_read_config_word(hw, - PCI_SUBSYS_ID_WORD, - &pci_subsystem_id); - hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); - hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); - hwcard->pci_dev = pci_dev; - number_pci_cards += - sdla_aft_hw_select(hwcard, SDLA_CPU_A, pci_dev->irq, NULL); - /*ALEX sdla_adapter_cnt.AFT_adapters++; */ + number_pci_cards += sdla_pci_probe_aft_v2( + hw, + ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->bus->number, + pci_dev->irq); } pci_dev=NULL; while((pci_dev = pci_get_device(SANGOMA_PCI_VENDOR, SANGOMA_PCI_4_DEVICE, pci_dev)) != NULL){ - bus = pci_dev->bus; - tmp_hwcard->pci_dev = pci_dev; - /* ALEX 11/18 - * Supporting different aft cards */ - sdla_pci_read_config_word(hw, - PCI_SUBSYS_VENDOR_WORD, - &PCI_subsys_vendor); - sdla_pci_read_config_word(hw, - PCI_SUBSYS_ID_WORD, - &pci_subsystem_id); - - hwcard = sdla_card_register(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - if (hwcard == NULL){ - continue; - } - - switch(PCI_subsys_vendor){ - case A101_1TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_1TE1; - break; - - case A101_2TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_2TE1; - break; - - case A104_4TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A104_ADPTR_4TE1; - break; - - case AFT_4TE1_SHARK_SUBSYS_VENDOR: - hwcard->adptr_type = A104_ADPTR_4TE1; - hwcard->adptr_subtype = AFT_SUBTYPE_SHARK; - break; - - default: - DEBUG_EVENT("%s: Unsupported subsystem vendor id %04X (bus=%d, slot=%d)\n", - wan_drvname, - PCI_subsys_vendor, - pci_dev->bus->number, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK)); - continue; - } - - hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); - hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); - hwcard->pci_dev = pci_dev; - number_pci_cards += - sdla_aft_hw_select(hwcard, SDLA_CPU_A, pci_dev->irq, NULL); - /* ALEX sdla_adapter_cnt.AFT_adapters++; */ + number_pci_cards += sdla_pci_probe_aft_v1( + hw, + ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->bus->number, + pci_dev->irq); } pci_dev=NULL; while ((pci_dev = pci_get_device(SANGOMA_PCI_VENDOR_OLD, SANGOMA_PCI_DEVICE, pci_dev)) != NULL) { - bus = pci_dev->bus; - - tmp_hwcard->pci_dev = pci_dev; - /* ALEX 11/18 - * Supporting different aft cards */ - sdla_pci_read_config_word(hw, - PCI_SUBSYS_VENDOR_WORD, - &PCI_subsys_vendor); - - hwcard = sdla_card_register(SDLA_PCI_CARD, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), - pci_dev->bus->number, - 0); - if (hwcard == NULL){ - continue; - } - - switch(PCI_subsys_vendor){ - case A101_1TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_1TE1; - break; - - case A101_2TE1_SUBSYS_VENDOR: - hwcard->adptr_type = A101_ADPTR_2TE1; - break; - - case A300_UTE3_SUBSYS_VENDOR: - hwcard->adptr_type = A300_ADPTR_U_1TE3; - break; - - default: - DEBUG_EVENT("%s: Unsupported subsystem vendor id %04X (bus=%d, slot=%d)\n", - wan_drvname, - PCI_subsys_vendor, - pci_dev->bus->number, - ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK)); - continue; - } - - sdla_pci_read_config_word(hw, - PCI_SUBSYS_ID_WORD, - &pci_subsystem_id); - hwcard->core_id = AFT_CORE_ID(pci_subsystem_id); - hwcard->core_rev= AFT_CORE_REV(pci_subsystem_id); - hwcard->pci_dev = pci_dev; - number_pci_cards += - sdla_aft_hw_select(hwcard, SDLA_CPU_A, pci_dev->irq, NULL); - /* ALEX sdla_adapter_cnt.AFT_adapters++; */ + tmp_hwcard->pci_dev = pci_dev; + number_pci_cards += sdla_pci_probe_aft_old( + hw, + ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK), + pci_dev->bus->number, + pci_dev->irq); } - + return number_pci_cards; } + EXPORT_SYMBOL(sdla_hw_bridge_probe); unsigned int sdla_hw_bridge_probe(void) { @@ -2040,6 +2849,119 @@ unsigned int sdla_hw_bridge_probe(void) } return number_pci_x_bridges; } + +#elif defined(__FreeBSD__) +# if defined(SDLA_AUTO_PROBE) +static int sdla_pci_auto_probe(sdlahw_t *hw) +{ + struct pci_devinfo *dinfo = NULL; + sdlahw_card_t *tmp_hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; + int number_pci_cards = 0, cards = 0; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + tmp_hwcard = hwcpu->hwcard; + + STAILQ_FOREACH(dinfo, &pci_devq, pci_links){ + + if (dinfo->cfg.vendor == V3_VENDOR_ID && dinfo->cfg.device == V3_DEVICE_ID){ + + tmp_hwcard->pci_dev = dinfo->cfg.dev; + cards = sdla_pci_probe_S( + hw, + pci_get_slot(dinfo->cfg.dev), + pci_get_bus(dinfo->cfg.dev), + dinfo->cfg.intline); + if (cards){ + number_pci_cards += cards; + continue; + } + } + if (dinfo->cfg.vendor == PCI_VENDOR_ID_GSI && dinfo->cfg.device == PCI_DEVICE_ID_GSI_ADSL){ + + tmp_hwcard->pci_dev = dinfo->cfg.dev; + cards += sdla_pci_probe_adsl( + hw, + pci_get_slot(dinfo->cfg.dev), + pci_get_bus(dinfo->cfg.dev), + dinfo->cfg.intline); + if (cards){ + number_pci_cards += cards; + continue; + } + } + if (dinfo->cfg.vendor == PCI_VENDOR_ID_GSI && dinfo->cfg.device == PCI_DEVICE_ID_GSI_ADSL_V2){ + + tmp_hwcard->pci_dev = dinfo->cfg.dev; + cards = sdla_pci_probe_adsl_2( + hw, + pci_get_slot(dinfo->cfg.dev), + pci_get_bus(dinfo->cfg.dev), + dinfo->cfg.intline); + if (cards){ + number_pci_cards += cards; + continue; + } + } + if (dinfo->cfg.vendor == SANGOMA_PCI_VENDOR){ + + tmp_hwcard->pci_dev = dinfo->cfg.dev; + cards = sdla_pci_probe_aft( + hw, + pci_get_slot(dinfo->cfg.dev), + pci_get_bus(dinfo->cfg.dev), + dinfo->cfg.intline); + if (cards){ + number_pci_cards += cards; + continue; + } + } + if (dinfo->cfg.vendor == SANGOMA_PCI_VENDOR && dinfo->cfg.device == SANGOMA_PCI_DEVICE){ + + tmp_hwcard->pci_dev = dinfo->cfg.dev; + cards = sdla_pci_probe_aft_v2( + hw, + pci_get_slot(dinfo->cfg.dev), + pci_get_bus(dinfo->cfg.dev), + dinfo->cfg.intline); + if (cards){ + number_pci_cards += cards; + continue; + } + } + if (dinfo->cfg.vendor == SANGOMA_PCI_VENDOR && dinfo->cfg.device == SANGOMA_PCI_4_DEVICE){ + + tmp_hwcard->pci_dev = dinfo->cfg.dev; + cards = sdla_pci_probe_aft_v1( + hw, + pci_get_slot(dinfo->cfg.dev), + pci_get_bus(dinfo->cfg.dev), + dinfo->cfg.intline); + if (cards){ + number_pci_cards += cards; + continue; + } + } + if (dinfo->cfg.vendor == SANGOMA_PCI_VENDOR_OLD && dinfo->cfg.device == SANGOMA_PCI_DEVICE){ + + tmp_hwcard->pci_dev = dinfo->cfg.dev; + cards = sdla_pci_probe_aft_old( + hw, + pci_get_slot(dinfo->cfg.dev), + pci_get_bus(dinfo->cfg.dev), + dinfo->cfg.intline); + if (cards){ + number_pci_cards += cards; + continue; + } + } + } + return number_pci_cards; +} +# endif #endif /* @@ -2049,15 +2971,14 @@ unsigned int sdla_hw_bridge_probe(void) */ EXPORT_SYMBOL(sdla_hw_probe); +#if defined(__LINUX__) unsigned int sdla_hw_probe(void) { sdlahw_card_t* hwcard; -#if defined(__LINUX__) sdlahw_card_t tmp_hwcard; + sdlahw_cpu_t tmp_hwcpu, *hwcpu; sdlahw_t tmp_hw; -#if defined(WAN_ISA_SUPPORT) unsigned* opt = s508_port_options; -#endif unsigned int cardno=0; int i; @@ -2068,15 +2989,16 @@ unsigned int sdla_hw_probe(void) //} memset(&tmp_hw, 0, sizeof(tmp_hw)); - tmp_hw.hwcard = &tmp_hwcard; + memset(&tmp_hwcpu, 0, sizeof(tmp_hwcpu)); + memset(&tmp_hwcard, 0, sizeof(tmp_hwcard)); + tmp_hwcpu.hwcard = &tmp_hwcard; + tmp_hw.hwcpu = &tmp_hwcpu; tmp_hw.magic = SDLADRV_MAGIC; -#if defined(WAN_ISA_SUPPORT) for (i = 1; i <= opt[0]; i++) { tmp_hwcard.hw_type = SDLA_ISA_CARD; tmp_hwcard.ioport = opt[i]; if (!sdla_detect_s508(&tmp_hw)){ - sdlahw_t* hw; DEBUG_EVENT("%s: S508-ISA card found, port 0x%x\n", wan_drvname, tmp_hwcard.ioport); hwcard = sdla_card_register(SDLA_ISA_CARD, @@ -2090,8 +3012,8 @@ unsigned int sdla_hw_probe(void) hwcard->pci_dev = NULL; hwcard->cfg_type = WANOPT_S50X; - hw = sdla_hw_register(hwcard, SDLA_CPU_A, 0, NULL); - if (hw == NULL){ + hwcpu = sdla_hwcpu_register(hwcard, SDLA_CPU_A, 0, NULL); + if (hwcpu == NULL){ sdla_card_unregister ( SDLA_ISA_CARD, 0, @@ -2099,8 +3021,8 @@ unsigned int sdla_hw_probe(void) tmp_hwcard.ioport); continue; } - sdla_save_hw_probe(hw, 1); - sdla_save_hw_probe(hw, 0); + sdla_hw_register(hwcpu, 1); + sdla_hw_register(hwcpu, 2); /* S508 card can support up to two physical links */ cardno += 2; @@ -2109,7 +3031,6 @@ unsigned int sdla_hw_probe(void) } tmp_hwcard.ioport = 0x00; } -#endif # ifdef CONFIG_PCI tmp_hwcard.hw_type = SDLA_PCI_CARD; @@ -2120,19 +3041,61 @@ unsigned int sdla_hw_probe(void) DEBUG_EVENT( "Warning, Kernel not compiled for PCI support!\n"); DEBUG_EVENT( "PCI Hardware Probe Failed!\n"); # endif - return cardno; -#else - sdladev_t* dev = NULL; - sdla_pci_dev_t pci_dev = NULL; - int cnt = 0; +} +#elif defined(__WINDOWS__) +unsigned int sdla_hw_probe(void) +{ + sdlahw_card_t* hwcard; + sdlahw_card_t tmp_hwcard; + sdlahw_cpu_t tmp_hwcpu, *hwcpu; + sdlahw_t tmp_hw; + unsigned int cardno=0; + int i; + + //if (!WAN_LIST_EMPTY(&sdlahw_card_head)){ + // DEBUG_EVENT("ADBG> SDLA_HW_PROBE: Number configured cards %d\n", + // cardno); + // return cardno; + //} + + memset(&tmp_hw, 0, sizeof(tmp_hw)); + memset(&tmp_hwcpu, 0, sizeof(tmp_hwcpu)); + memset(&tmp_hwcard, 0, sizeof(tmp_hwcard)); + tmp_hwcpu.hwcard = &tmp_hwcard; + tmp_hw.hwcpu = &tmp_hwcpu; + tmp_hw.magic = SDLADRV_MAGIC; + +# ifdef CONFIG_PCI + tmp_hwcard.hw_type = SDLA_PCI_CARD; + tmp_hwcard.slot_no = 0; + tmp_hwcard.bus_no = 0; + cardno += sdla_pci_probe(&tmp_hw); +# else + DEBUG_EVENT( "Warning, Kernel not compiled for PCI support!\n"); + DEBUG_EVENT( "PCI Hardware Probe Failed!\n"); +# endif + return cardno; +} +#else /* !LINUX */ +unsigned int sdla_hw_probe(void) +{ +#if !defined(SDLA_AUTO_PROBE) + sdlahw_card_t *hwcard; + int cnt = 0; +#endif + /* Probe ISA card */ +#if defined(WAN_ISA_SUPPORT) for(cnt=0; cnt< Sangoma_cards_no; cnt++){ + sdladev_t *dev = NULL; + sdla_pci_dev_t pci_dev = NULL; dev = &sdladev[cnt]; if (dev->type == SDLA_S508){ -#if defined(WAN_ISA_SUPPORT) - sdlahw_t* hw; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; + sdlahw_t *hw; DEBUG_EVENT( "%s: S508-ISA card found, port 0x%x\n", wan_drvname, sdladev_ioport(dev)); hwcard = sdla_card_register( @@ -2146,8 +3109,8 @@ unsigned int sdla_hw_probe(void) hwcard->pci_dev = NULL; hwcard->cfg_type = WANOPT_S50X; - hw = sdla_hw_register(hwcard, SDLA_CPU_A, 0, dev); - if (hw == NULL){ + hwcpu = sdla_hwcpu_register(hwcard, SDLA_CPU_A, 0, dev); + if (hwcpu == NULL){ sdla_card_unregister ( SDLA_ISA_CARD, 0, @@ -2155,30 +3118,54 @@ unsigned int sdla_hw_probe(void) sdladev_ioport(dev)); continue; } - hw->irq = sdladev_irq(dev); - hw->dpmbase = sdladev_maddr(dev); + hwcpu->irq = sdladev_irq(dev); + hwcpu->dpmbase = sdladev_maddr(dev); #if defined(__NetBSD__) || defined(__OpenBSD__) - hw->ioh = dev->u.isa.ioh; + hwcpu->ioh = dev->u.isa.ioh; hwcard->iot = dev->sc->ia.ia_iot; hwcard->memt = dev->sc->ia.ia_memt; -#endif - sdla_save_hw_probe(hw, 1); - sdla_save_hw_probe(hw, 0); +#endif /* __NetBSD__ || __OpenBSD__ */ + sdla_hw_register(hwcpu, 1); + sdla_hw_register(hwcpu, 0); + card_no += 2; sdla_adapter_cnt.s508_adapters++; -# else - DEBUG_EVENT( "%s: S508-ISA card is not supported!\n", - wan_drvname); -# endif - continue; } + } +#endif + + +#if defined(SDLA_AUTO_PROBE) + sdlahw_card_t tmp_hwcard; + sdlahw_cpu_t tmp_hwcpu; + sdlahw_t tmp_hw; + unsigned int cardno=0; + + memset(&tmp_hw, 0, sizeof(tmp_hw)); + tmp_hwcpu.hwcard = &tmp_hwcard; + tmp_hw.hwcpu = &tmp_hwcpu; + tmp_hw.magic = SDLADRV_MAGIC; + + tmp_hwcard.hw_type = SDLA_PCI_CARD; + tmp_hwcard.slot_no = 0; + tmp_hwcard.bus_no = 0; + + cardno += sdla_pci_auto_probe(&tmp_hw); + return cardno; +#else + /* Probe PCI/PCI-Exp cards */ + for(cnt=0; cnt 400000) pci_dev = dev->sc->dev; # else pci_dev = dev->u.pci.pci_dev; -# endif +# endif /* __FreeBSD_version */ # else pci_dev = &dev->sc->pa; # endif @@ -2253,6 +3240,7 @@ unsigned int sdla_hw_probe(void) return Sangoma_devices_no; #endif } +#endif /* ***************************************************************************** @@ -2277,28 +3265,38 @@ void *sdla_get_hw_adptr_cnt (void) return &sdla_adapter_cnt; } -/* -***************************************************************************** -** sdla_card_register -***************************************************************************** -*/ -static sdlahw_card_t* -sdla_card_register(unsigned char hw_type, int slot_no, int bus_no, int ioport) + +/***************************************************************************** +** Hardware structure interface per Physical Card +*****************************************************************************/ +static int sdla_card_info(sdlahw_card_t *hwcard) +{ + WAN_ASSERT(hwcard == NULL); + if (hwcard->hw_type == SDLA_PCI_CARD){ + DEBUG_EVENT("%s: Card info: slot=%d,bus=%d!\n", + __FUNCTION__, + hwcard->slot_no, + hwcard->bus_no); + }else{ + DEBUG_EVENT("%s: Card info: ioport=%d!\n", + __FUNCTION__, + hwcard->ioport); + } + return 0; +} + +static sdlahw_card_t* sdla_card_register( unsigned char hw_type, + int slot_no, + int bus_no, + int ioport) { sdlahw_card_t *new_hwcard, *last_hwcard; new_hwcard = sdla_card_search(hw_type, slot_no, bus_no, ioport); if (new_hwcard){ - if (hw_type == SDLA_PCI_CARD){ - DEBUG_EVENT("%s: Card is already exists (slot=%d,bus=%d)!\n", - __FUNCTION__, - slot_no, - bus_no); - }else{ - DEBUG_EVENT("%s: Card is already exists (ioport=%d)!\n", - __FUNCTION__, - ioport); - } + + DEBUG_EVENT("%s: Card is already exists!\n", __FUNCTION__); + sdla_card_info(new_hwcard); return NULL; } new_hwcard = wan_malloc(sizeof(sdlahw_card_t)); @@ -2312,8 +3310,8 @@ sdla_card_register(unsigned char hw_type, int slot_no, int bus_no, int ioport) new_hwcard->slot_no = slot_no; new_hwcard->bus_no = bus_no; new_hwcard->ioport = ioport; - wan_spin_lock_init(&new_hwcard->pcard_lock); - wan_spin_lock_init(&new_hwcard->pcard_ec_lock); + wan_spin_lock_init(&new_hwcard->pcard_lock,"wan_hwcard_lock"); + wan_spin_lock_init(&new_hwcard->pcard_ec_lock,"wan_hwcard_ec_lock"); WAN_LIST_FOREACH(last_hwcard, &sdlahw_card_head, next){ if (!WAN_LIST_NEXT(last_hwcard, next)){ @@ -2329,13 +3327,10 @@ sdla_card_register(unsigned char hw_type, int slot_no, int bus_no, int ioport) return new_hwcard; } -/* -***************************************************************************** -** sdla_card_unregister -***************************************************************************** -*/ -static int -sdla_card_unregister (unsigned char hw_type, int slot_no, int bus_no, int ioport) +static int sdla_card_unregister( unsigned char hw_type, + int slot_no, + int bus_no, + int ioport) { sdlahw_card_t* tmp_card; @@ -2364,32 +3359,22 @@ sdla_card_unregister (unsigned char hw_type, int slot_no, int bus_no, int ioport } return -EFAULT; } - if (tmp_card->used){ - if (hw_type == SDLA_PCI_CARD){ - DEBUG_EVENT("%s: Error: This card is still in used (slot=%d,bus=%d,used=%d)\n", + if (tmp_card->internal_used){ + DEBUG_EVENT("%s: Error: This card is still in used (used=%d)!\n", __FUNCTION__, - slot_no, - bus_no, - tmp_card->used); - }else{ - DEBUG_EVENT("%s: Error: This card is still in used (ioport=%d,used=%d)\n", - __FUNCTION__, - ioport, - tmp_card->used); - } + tmp_card->internal_used); + sdla_card_info(tmp_card); return -EBUSY; } WAN_LIST_REMOVE(tmp_card, next); wan_free(tmp_card); return 0; } -/* -***************************************************************************** -** sdla_card_search -***************************************************************************** -*/ -static sdlahw_card_t* -sdla_card_search(unsigned char hw_type, int slot_no, int bus_no, int ioport) + +static sdlahw_card_t* sdla_card_search( unsigned char hw_type, + int slot_no, + int bus_no, + int ioport) { sdlahw_card_t* tmp_card; @@ -2413,45 +3398,200 @@ sdla_card_search(unsigned char hw_type, int slot_no, int bus_no, int ioport) return NULL; } +/***************************************************************************** +** Hardware structure interface per CPU +*****************************************************************************/ +static int sdla_hwcpu_info(sdlahw_cpu_t *hwcpu) +{ + + WAN_ASSERT(hwcpu == NULL); + WAN_ASSERT(hwcpu->hwcard == NULL); + if (hwcpu->hwcard->hw_type == SDLA_PCI_CARD){ + DEBUG_TEST("%s: HW Card Cpu info: slot=%d,bus=%d,cpu=%c!\n", + __FUNCTION__, + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + SDLA_GET_CPU(hwcpu->cpu_no)); + }else{ + DEBUG_TEST("%s: HW Card Cpu info: ioport=%d!\n", + __FUNCTION__, + hwcpu->hwcard->ioport); + } + return 0; +} + +static sdlahw_cpu_t* sdla_hwcpu_register( sdlahw_card_t *hwcard, + int cpu_no, + int irq, + void *sdla_dev) +{ + sdlahw_cpu_t *new_hwcpu, *last_hwcpu; + + new_hwcpu = sdla_hwcpu_search( (u8)hwcard->hw_type, + hwcard->slot_no, + hwcard->bus_no, + hwcard->ioport, + cpu_no); + if (new_hwcpu){ + DEBUG_TEST("%s: HW Card CPU is already exists!\n", + __FUNCTION__); + sdla_hwcpu_info(new_hwcpu); + return NULL; + } + new_hwcpu = wan_malloc(sizeof(sdlahw_cpu_t)); + if (!new_hwcpu) + return NULL; + + memset(new_hwcpu,0,sizeof(sdlahw_cpu_t)); + new_hwcpu->cpu_no = cpu_no; + new_hwcpu->irq = irq; + new_hwcpu->hwcard = hwcard; +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + new_hwcpu->sdla_dev = sdla_dev; /* Internal kernel BSD structure */ +#endif + new_hwcpu->magic = SDLADRV_MAGIC; + hwcard->internal_used++; + + + WAN_LIST_FOREACH(last_hwcpu, &sdlahw_cpu_head, next){ + if (!WAN_LIST_NEXT(last_hwcpu, next)){ + break; + } + } + if (last_hwcpu){ + WAN_LIST_INSERT_AFTER(last_hwcpu, new_hwcpu, next); + }else{ + WAN_LIST_INSERT_HEAD(&sdlahw_cpu_head, new_hwcpu, next); + } + return new_hwcpu; +} + +static int sdla_hwcpu_unregister(sdlahw_cpu_t *hwcpu) +{ + + WAN_ASSERT(hwcpu == NULL); + if (hwcpu->internal_used){ + DEBUG_EVENT("%s: Error: HW Card Cpu is still in used (used=%d)\n", + __FUNCTION__, + hwcpu->internal_used); + sdla_hwcpu_info(hwcpu); + return -EBUSY; + } + if (hwcpu == WAN_LIST_FIRST(&sdlahw_cpu_head)){ + WAN_LIST_FIRST(&sdlahw_cpu_head) = WAN_LIST_NEXT(hwcpu, next); + }else{ + WAN_LIST_REMOVE(hwcpu, next); + } + + hwcpu->hwcard->internal_used--; /* Decrement card usage */ + hwcpu->hwcard = NULL; + wan_free(hwcpu); + return 0; +} + +static sdlahw_cpu_t* sdla_hwcpu_search( unsigned char hw_type, + int slot_no, + int bus_no, + int ioport, + int cpu_no) +{ + sdlahw_cpu_t* tmp_hwcpu; + + WAN_LIST_FOREACH(tmp_hwcpu, &sdlahw_cpu_head, next){ + WAN_ASSERT_RC(tmp_hwcpu->hwcard == NULL, NULL); + if (tmp_hwcpu->hwcard->hw_type != hw_type){ + continue; + } + switch(hw_type){ + case SDLA_PCI_CARD: + if (tmp_hwcpu->hwcard->slot_no == slot_no && + tmp_hwcpu->hwcard->bus_no == bus_no && + tmp_hwcpu->cpu_no == cpu_no){ + return tmp_hwcpu; + } + break; + case SDLA_ISA_CARD: + if (tmp_hwcpu->hwcard->ioport == ioport){ + return tmp_hwcpu; + } + break; + } + } + return NULL; +} + /* ***************************************************************************** -** sdla_cpu_register +** Hardware structure interface per Port ***************************************************************************** */ -static sdlahw_t* -sdla_hw_register(sdlahw_card_t* hwcard, int cpu_no, int irq, void* dev) +static int sdla_hw_info(sdlahw_t *hw) +{ + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + + if (hw->hwcpu->hwcard->hw_type == SDLA_PCI_CARD){ + DEBUG_TEST("%s: HW Port info: slot=%d,bus=%d,cpu=%c,port=%d!\n", + __FUNCTION__, + hw->hwcpu->hwcard->slot_no, + hw->hwcpu->hwcard->bus_no, + SDLA_GET_CPU(hw->hwcpu->cpu_no), + hw->port_no); + }else{ + DEBUG_TEST("%s: HW Port info: ioport=%d,port=%d!\n", + __FUNCTION__, + hw->hwcpu->hwcard->ioport, + hw->port_no); + } + return 0; +} + +static sdlahw_t* sdla_hw_register( sdlahw_cpu_t *hwcpu, + int port_no) { sdlahw_t *new_hw, *last_hw; + sdla_hw_probe_t *hwprobe, *tmp_hwprobe; - new_hw = sdla_hw_search(hwcard->hw_type, hwcard->slot_no, hwcard->bus_no, hwcard->ioport, cpu_no); + new_hw = sdla_hw_search(hwcpu, port_no); if (new_hw){ - if (hwcard->hw_type == SDLA_PCI_CARD){ - DEBUG_TEST("%s: CPU is already exists (slot=%d,bus=%d,cpu=%c)!\n", + DEBUG_TEST( + "%s: Port is already exists (slot=%d,bus=%d,cpu=%c,port=%d)!\n", __FUNCTION__, - hwcard->slot_no, - hwcard->bus_no, - SDLA_GET_CPU(cpu_no)); - }else{ - DEBUG_TEST("%s: CPU is already exists (ioport=%d)!\n", - __FUNCTION__, - hwcard->ioport); - } + hwcpu->hwcard->slot_no, + hwcpu->hwcard->bus_no, + hwcpu->cpu_no, + port_no); + sdla_hw_info(new_hw); return NULL; } new_hw = wan_malloc(sizeof(sdlahw_t)); if (!new_hw) return NULL; + + hwprobe = wan_malloc(sizeof(sdla_hw_probe_t)); + if (!hwprobe){ + wan_free(new_hw); + return NULL; + } + memset(hwprobe,0,sizeof(sdla_hw_probe_t)); + memset(hwprobe->hw_info, '\0', 100); + memset(hwprobe->hw_info_verbose, '\0', 500); memset(new_hw,0,sizeof(sdlahw_t)); - new_hw->devname = NULL; - new_hw->cpu_no = cpu_no; - new_hw->irq = irq; - new_hw->hwcard = hwcard; - new_hw->dev = dev; + new_hw->devname = SDLA_HWPROBE_NAME; + new_hw->hwcpu = hwcpu; new_hw->magic = SDLADRV_MAGIC; - hwcard->used++; + new_hw->port_no = port_no; - + hwcpu->internal_used++; + hwcpu->max_ports++; + hwcpu->hwport[port_no] = new_hw; + + new_hw->hwprobe = hwprobe; + hwprobe->internal_used++; + + /* Link new hw port */ WAN_LIST_FOREACH(last_hw, &sdlahw_head, next){ if (!WAN_LIST_NEXT(last_hw, next)){ break; @@ -2461,113 +3601,85 @@ sdla_hw_register(sdlahw_card_t* hwcard, int cpu_no, int irq, void* dev) WAN_LIST_INSERT_AFTER(last_hw, new_hw, next); }else{ WAN_LIST_INSERT_HEAD(&sdlahw_head, new_hw, next); - } - return new_hw; -} -/* -***************************************************************************** -** sdla_hw_unregister -***************************************************************************** -*/ -static int -sdla_hw_unregister (sdlahw_card_t* hwcard, int cpu_no) -{ - sdlahw_t* tmp_hw; - int i; - - WAN_LIST_FOREACH(tmp_hw, &sdlahw_head, next){ - if (tmp_hw->hwcard != hwcard){ - continue; - } - if (tmp_hw->cpu_no == cpu_no){ + /* Link new hw probe */ + WAN_LIST_FOREACH(tmp_hwprobe, &sdlahw_probe_head, next){ + if (!WAN_LIST_NEXT(tmp_hwprobe, next)){ break; } } - if (tmp_hw == NULL){ - if (hwcard->hw_type == SDLA_PCI_CARD){ - DEBUG_EVENT("%s: Error: Devive didn't find (slot=%d,bus=%d,cpu=%c)\n", - __FUNCTION__, - hwcard->slot_no, - hwcard->bus_no, - SDLA_GET_CPU(cpu_no)); - }else{ - DEBUG_EVENT("%s: Error: Device didn't find (ioport=%d,cpu=%c)\n", - __FUNCTION__, - hwcard->ioport, - SDLA_GET_CPU(cpu_no)); - } - return -EFAULT; + if (tmp_hwprobe){ + WAN_LIST_INSERT_AFTER(tmp_hwprobe, hwprobe, next); + }else{ + WAN_LIST_INSERT_HEAD(&sdlahw_probe_head, hwprobe, next); } - if (tmp_hw->used){ - if (hwcard->hw_type == SDLA_PCI_CARD){ - DEBUG_EVENT("%s: Error: This cpu is still in used (slot=%d,bus=%d,cpu=%c,used=%d)\n", + + return new_hw; +} + +static int sdla_hw_unregister (sdlahw_t* hw) +{ + sdla_hw_probe_t *hwprobe; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + + if (hw->internal_used){ + DEBUG_EVENT( + "%s: Error: HW Port is still in used (used=%d)\n", __FUNCTION__, - hwcard->slot_no, - hwcard->bus_no, - SDLA_GET_CPU(cpu_no), - hwcard->used); - }else{ - DEBUG_EVENT("%s: Error: This cpu is still in used (ioport=%d, used=%d)\n", - __FUNCTION__, - hwcard->ioport, - hwcard->used); - } + hw->internal_used); + sdla_hw_info(hw); return -EBUSY; } - for(i = 0; i < SDLA_MAX_PORTS; i++){ - if (tmp_hw->hwport[i].hwprobe){ - tmp_hw->hwport[i].hwprobe->used--; - tmp_hw->hwport[i].hwprobe = NULL; - } - } - tmp_hw->hwcard = NULL; - hwcard->used--; /* Decrement card usage */ - WAN_LIST_REMOVE(tmp_hw, next); - wan_free(tmp_hw); + hwprobe = hw->hwprobe; + hwprobe->internal_used--; + hw->hwprobe = NULL; + + hw->hwcpu->hwport[hw->port_no] = NULL; + + hw->hwcpu->internal_used--; /* Decrement card usage */ + hw->hwcpu = NULL; + + if (hw == WAN_LIST_FIRST(&sdlahw_head)){ + WAN_LIST_FIRST(&sdlahw_head) = WAN_LIST_NEXT(hw, next); + }else{ + WAN_LIST_REMOVE(hw, next); + } + wan_free(hw); + + if (hwprobe->internal_used == 0){ + if (hwprobe == WAN_LIST_FIRST(&sdlahw_probe_head)){ + WAN_LIST_FIRST(&sdlahw_probe_head) = WAN_LIST_NEXT(hwprobe, next); + }else{ + WAN_LIST_REMOVE(hwprobe, next); + } + wan_free(hwprobe); + }else{ + DEBUG_EVENT("%s: Error: HWPROBE is still in used %d\n", + __FUNCTION__, hwprobe->internal_used); + } + return 0; } -/* -***************************************************************************** -** sdla_cpu_search -***************************************************************************** -*/ -static sdlahw_t* -sdla_hw_search(unsigned char hw_type, int slot_no, int bus_no, int ioport, int cpu_no) +static sdlahw_t* sdla_hw_search(sdlahw_cpu_t *hwcpu, int port_no) { sdlahw_t* tmp_hw; WAN_LIST_FOREACH(tmp_hw, &sdlahw_head, next){ - if (tmp_hw->hwcard == NULL){ - DEBUG_EVENT("%s: Critical Error: line %d\n", - __FUNCTION__,__LINE__); + WAN_ASSERT_RC(tmp_hw->hwcpu == NULL, NULL); + if (tmp_hw->hwcpu != hwcpu || tmp_hw->port_no != port_no){ continue; } - if (tmp_hw->hwcard->hw_type != hw_type){ - continue; - } - switch(hw_type){ - case SDLA_PCI_CARD: - if (tmp_hw->hwcard->slot_no == slot_no && - tmp_hw->hwcard->bus_no == bus_no && - tmp_hw->cpu_no == cpu_no){ - return tmp_hw; - } - break; - case SDLA_ISA_CARD: - if (tmp_hw->hwcard->ioport == ioport){ - return tmp_hw; - } - break; - } + return tmp_hw; } return NULL; } - /* ***************************************************************************** ***************************************************************************** @@ -2584,21 +3696,28 @@ EXPORT_SYMBOL(sdla_register); void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname) { - sdlahw_card_t* hwcard = NULL; - sdlahw_t* hw = NULL; - + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu; + sdlahw_t *hw = NULL; + +#if defined(__WINDOWS__) + hw = hw_iface->hw; +#else if (sdla_register_check(conf, devname)){ return NULL; } - hw = sdla_find_adapter(conf, devname); - if (hw == NULL || hw->hwcard == NULL || hw->used >= hw->max_ports){ +#endif + if (hw == NULL || hw->used){ return NULL; } - hwcard = hw->hwcard; + WAN_ASSERT_RC(hw->hwcpu == NULL, NULL); + WAN_ASSERT_RC(hw->hwcpu->hwcard == NULL, NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; hw_iface->setup = sdla_setup; - hw_iface->hw_down = sdla_down; + hw_iface->hw_down = sdla_down; #if defined(CONFIG_PRODUCT_WANPIPE_GENERIC) hw_iface->load = sdla_load; #endif @@ -2610,6 +3729,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname hw_iface->poke = sdla_poke; hw_iface->poke_byte = sdla_poke_byte; hw_iface->getcfg = sdla_getcfg; + hw_iface->setcfg = sdla_setcfg; #if defined(WAN_ISA_SUPPORT) hw_iface->isa_read_1 = sdla_isa_read_1; hw_iface->isa_write_1 = sdla_isa_write_1; @@ -2632,11 +3752,13 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname hw_iface->get_hwprobe = sdla_get_hwprobe; hw_iface->hw_lock = sdla_hw_lock; hw_iface->hw_unlock = sdla_hw_unlock; + hw_iface->hw_ec_trylock = sdla_hw_ec_trylock; hw_iface->hw_ec_lock = sdla_hw_ec_lock; hw_iface->hw_ec_unlock = sdla_hw_ec_unlock; hw_iface->pci_map_dma = sdla_pci_map_dma; hw_iface->pci_unmap_dma = sdla_pci_unmap_dma; hw_iface->hw_same = sdla_is_same_hwcard; + hw_iface->hwcpu_same = sdla_is_same_hwcpu; hw_iface->fe_test_and_set_bit = sdla_hw_fe_test_and_set_bit; hw_iface->fe_set_bit = sdla_hw_fe_set_bit; hw_iface->fe_test_bit = sdla_hw_fe_test_bit; @@ -2652,7 +3774,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname devname, SDLA_DECODE_CARDTYPE(hwcard->cfg_type), hwcard->ioport, - hw->irq); + hwcpu->irq); break; case WANOPT_S51X: @@ -2672,7 +3794,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname DEBUG_EVENT("%s: Found: %s card, CPU %c, PciSlot=%d, PciBus=%d\n", devname, SDLA_DECODE_CARDTYPE(hwcard->cfg_type), - SDLA_GET_CPU(hw->cpu_no), + SDLA_GET_CPU(hwcpu->cpu_no), hwcard->slot_no, hwcard->bus_no); break; @@ -2688,7 +3810,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname DEBUG_EVENT("%s: Found: %s card, CPU %c, PciSlot=%d, PciBus=%d\n", devname, SDLA_DECODE_CARDTYPE(hwcard->cfg_type), - SDLA_GET_CPU(hw->cpu_no), + SDLA_GET_CPU(hwcpu->cpu_no), hwcard->slot_no, hwcard->bus_no); break; @@ -2702,6 +3824,8 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname case WANOPT_AFT_ANALOG: case WANOPT_AFT_ISDN: case WANOPT_AFT_56K: + case WANOPT_AFT_SERIAL: + hwcard->type = SDLA_AFT; hw_iface->set_bit = sdla_set_bit; hw_iface->clear_bit = sdla_clear_bit; @@ -2713,41 +3837,82 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname hw_iface->pci_write_config_dword = sdla_pci_write_config_dword; hw_iface->pci_bridge_read_config_dword = sdla_pci_bridge_read_config_dword; + hw_iface->pci_bridge_read_config_byte = sdla_pci_bridge_read_config_byte; hw_iface->pci_bridge_write_config_dword = sdla_pci_bridge_write_config_dword; + hw_iface->pci_bridge_write_config_byte = sdla_pci_bridge_write_config_byte; hw_iface->read_cpld = sdla_hw_read_cpld; hw_iface->write_cpld = sdla_hw_write_cpld; - switch(hw->hwcard->adptr_type){ + /* PCI DMA interface access */ + hw_iface->busdma_descr_alloc = sdla_busdma_descr_alloc; + hw_iface->busdma_descr_free = sdla_busdma_descr_free; + hw_iface->busdma_tag_create = sdla_busdma_tag_create; + hw_iface->busdma_tag_destroy = sdla_busdma_tag_destroy; + hw_iface->busdma_create = sdla_busdma_create; + hw_iface->busdma_destroy = sdla_busdma_destroy; + hw_iface->busdma_alloc = sdla_busdma_alloc; + hw_iface->busdma_free = sdla_busdma_free; + hw_iface->busdma_load = sdla_busdma_load; + hw_iface->busdma_unload = sdla_busdma_unload; + hw_iface->busdma_map = sdla_busdma_map; + hw_iface->busdma_unmap = sdla_busdma_unmap; + hw_iface->busdma_sync = sdla_busdma_sync; + /* Old PCI DMA interface access */ + hw_iface->pci_map_dma = sdla_pci_map_dma; + hw_iface->pci_unmap_dma = sdla_pci_unmap_dma; + + hw_iface->get_hwec_index = sdla_get_hwec_index; + + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ + if (hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ hw_iface->fe_read = sdla_te1_read_fe; hw_iface->fe_write = sdla_te1_write_fe; }else{ hw_iface->fe_read = sdla_shark_te1_read_fe; + hw_iface->__fe_read = __sdla_shark_te1_read_fe; hw_iface->fe_write = sdla_shark_te1_write_fe; } break; case A104_ADPTR_4TE1: case A108_ADPTR_8TE1: hw_iface->fe_read = sdla_shark_te1_read_fe; + hw_iface->__fe_read = __sdla_shark_te1_read_fe; hw_iface->fe_write = sdla_shark_te1_write_fe; break; case AFT_ADPTR_56K: hw_iface->fe_read = sdla_shark_56k_read_fe; + hw_iface->__fe_read = __sdla_shark_56k_read_fe; hw_iface->fe_write = sdla_shark_56k_write_fe; break; case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: hw_iface->fe_read = sdla_shark_rm_read_fe; + hw_iface->__fe_read = __sdla_shark_rm_read_fe; hw_iface->fe_write = sdla_shark_rm_write_fe; - case AFT_ADPTR_ISDN: - DEBUG_EVENT("%s: Front-End interface functions are not defined!\n", - devname); break; + case A300_ADPTR_U_1TE3: + hw_iface->fe_read = sdla_te3_read_fe; + hw_iface->fe_write = sdla_te3_write_fe; + break; +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + case AFT_ADPTR_ISDN: + hw_iface->fe_read = sdla_shark_bri_read_fe; + hw_iface->fe_write = sdla_shark_bri_write_fe; + break; +#endif + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + hw_iface->fe_read = sdla_shark_serial_read_fe; + hw_iface->fe_write = sdla_shark_serial_write_fe; + break; + } - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: case A104_ADPTR_4TE1: @@ -2756,10 +3921,14 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname case A400_ADPTR_ANALOG: case AFT_ADPTR_ISDN: case AFT_ADPTR_56K: + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: DEBUG_EVENT("%s: Found: %s card, CPU %c, PciSlot=%d, PciBus=%d, Port=%d\n", devname, SDLA_DECODE_CARDTYPE(hwcard->cfg_type), - SDLA_GET_CPU(hw->cpu_no), + SDLA_GET_CPU(hwcpu->cpu_no), hwcard->slot_no, hwcard->bus_no, (conf) ? conf->comm_port : hw->used); @@ -2768,7 +3937,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname DEBUG_EVENT("%s: Found: %s card, CPU %c, PciSlot=%d, PciBus=%d\n", devname, SDLA_DECODE_CARDTYPE(hwcard->cfg_type), - SDLA_GET_CPU(hw->cpu_no), + SDLA_GET_CPU(hwcpu->cpu_no), hwcard->slot_no, hwcard->bus_no); break; @@ -2776,9 +3945,10 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname break; default: - DEBUG_EVENT("%s: ERROR, invalid card type! 0x%X\n", - devname, - hwcard->cfg_type); + DEBUG_EVENT("%s:%d: %s: (2) ERROR, invalid card type! 0x%X\n", + __FUNCTION__,__LINE__, + devname, + hwcard->cfg_type); return NULL; } @@ -2786,13 +3956,23 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname /* NC: * Increment the usage count when we know * for sure that the hw has been taken */ - hw->hwport[(conf)?conf->comm_port:hw->used].used++; - hw->hwport[(conf)?conf->comm_port:hw->used].devname = devname; - if (!hw->used){ - hw->devname = devname; - } hw->used++; + hw->hwcpu->used++; + hw->devname = devname; + /* ISDN-BRI logial used cnt */ + if (hwcard->adptr_type == AFT_ADPTR_ISDN){ + int port; + /* Add special code for BRI */ + port = hw->port_no / 2; + port *= 2; + hw->hwcpu->reg_port[port]++; + hw->hwcpu->reg_port[port+1]++; + }else{ + hw->hwcpu->reg_port[0]++; + } + /* Set bit for specific port */ + wan_set_bit(hw->port_no, &hw->hwcpu->reg_port_map); return hw; } @@ -2806,24 +3986,31 @@ EXPORT_SYMBOL(sdla_unregister); int sdla_unregister(void** p_hw, char* devname) { sdlahw_t* hw = *(sdlahw_t**)p_hw; - int port; + sdlahw_cpu_t *hwcpu; - if (hw){ - for(port = 0; port < SDLA_MAX_PORTS; port++){ - if (hw->hwport[port].devname == devname){ - hw->hwport[port].devname = NULL; - hw->hwport[port].used--; - break; - } - } + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; - hw->used--; - if (!hw->used){ - hw->devname = NULL; - } - - *p_hw = NULL; + /* ISDN-BRI logial used cnt */ + if (hwcpu->hwcard->adptr_type == AFT_ADPTR_ISDN){ + int port; + /* Add special code for BRI */ + port = hw->port_no / 2; + port *= 2; + hw->hwcpu->reg_port[port]--; + hw->hwcpu->reg_port[port+1]--; + }else{ + hw->hwcpu->reg_port[0]--; } + /* Clear bit for specific port */ + wan_clear_bit(hw->port_no, &hw->hwcpu->reg_port_map); + + hw->used--; + hw->hwcpu->used--; + hw->devname = SDLA_HWPROBE_NAME; + *p_hw = NULL; return 0; } @@ -2935,6 +4122,16 @@ static int sdla_register_check (wandev_conf_t* conf, char* devname) } break; + case WANOPT_AFT_ISDN: + if (conf->auto_pci_cfg && sdla_adapter_cnt.aft200_adapters > 1){ + DEBUG_EVENT( "%s: HW Auto PCI failed: Multiple AFT-ISDN BRI cards found! \n" + "%s: Disable the Autodetect feature and supply\n" + "%s: the PCI Slot and Bus numbers for each card.\n", + devname,devname,devname); + return -EINVAL; + } + break; + case WANOPT_AFT300: if (conf->auto_pci_cfg && sdla_adapter_cnt.aft300_adapters > 1){ DEBUG_EVENT( "%s: HW Auto PCI failed: Multiple AFT-300 cards found! \n" @@ -2956,6 +4153,16 @@ static int sdla_register_check (wandev_conf_t* conf, char* devname) } break; + case WANOPT_AFT_SERIAL: + if (conf->auto_pci_cfg && sdla_adapter_cnt.aft_serial_adapters > 1){ + DEBUG_EVENT( "%s: HW Auto PCI failed: Multiple AFT-SERIAL cards found! \n" + "%s: Disable the Autodetect feature and supply\n" + "%s: the PCI Slot and Bus numbers for each card.\n", + devname,devname,devname); + return -EINVAL; + } + break; + default: DEBUG_EVENT("%s: Unsupported Sangoma Card (0x%X) requested by user!\n", devname,conf->card_type); @@ -2980,16 +4187,21 @@ static int sdla_register_check (wandev_conf_t* conf, char* devname) static int sdla_setup (void* phw, wandev_conf_t* conf) { sdlahw_card_t* hwcard = NULL; + sdlahw_cpu_t* hwcpu = NULL; sdlahw_t* hw = (sdlahw_t*)phw; +#if defined(WAN_ISA_SUPPORT) unsigned* irq_opt = NULL; /* IRQ options */ unsigned* dpmbase_opt = NULL; /* DPM window base options */ unsigned* pclk_opt = NULL; /* CPU clock rate options */ +#endif int err=0; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; /* ALEX VVVV*/ /* for an S514 adapter, pass the CPU number and the slot number read */ /* from 'router.conf' to the 'sdla_setup()' function via the 'port' */ @@ -3031,9 +4243,9 @@ static int sdla_setup (void* phw, wandev_conf_t* conf) #if 0 hw->port = conf->ioport; #endif - hw->irq = (conf && conf->irq == 9) ? 2 : conf->irq; + hwcpu->irq = (conf && conf->irq == 9) ? 2 : conf->irq; if(conf && conf->maddr){ - hw->dpmbase = (sdla_mem_handle_t)phys_to_virt(conf->maddr); + hwcpu->dpmbase = (sdla_mem_handle_t)phys_to_virt(conf->maddr); } break; @@ -3055,37 +4267,42 @@ static int sdla_setup (void* phw, wandev_conf_t* conf) } hw->dpmbase = (sdla_mem_handle_t)conf->maddr; #endif - hw->fwid = SFID_ADSL; + hwcpu->fwid = SFID_ADSL; break; case SDLA_AFT: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: case A104_ADPTR_4TE1: case A108_ADPTR_8TE1: case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: + case AFT_ADPTR_ISDN: case AFT_ADPTR_56K: - if (hw->used > 1){ - if (conf) conf->irq = hw->irq; + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + if (hwcpu->used > 1){ + if (conf) conf->irq = hwcpu->irq; return 0; } break; } - hw->fwid = SFID_AFT; + hwcpu->fwid = SFID_AFT; break; default: DEBUG_EVENT("%s: Invalid card type %x\n", - hw->devname, hw->hwcard->type); + hw->devname, hwcard->type); return -EINVAL; } - hw->dpmsize = SDLA_WINDOWSIZE; - hw->pclk = (conf) ? conf->hw_opt[1] : 0; + hwcpu->dpmsize = SDLA_WINDOWSIZE; + hwcpu->pclk = (conf) ? conf->hw_opt[1] : 0; if (sdla_detect(hw) != 0) { return -ENODEV; @@ -3100,45 +4317,44 @@ static int sdla_setup (void* phw, wandev_conf_t* conf) DEBUG_EVENT("%s: found S%04u card at port 0x%X.\n", hw->devname, hwcard->type, hwcard->ioport); - hw->dpmsize = SDLA_WINDOWSIZE; + hwcpu->dpmsize = SDLA_WINDOWSIZE; - switch(hwcard->type){ #if defined(WAN_ISA_SUPPORT) + switch(hwcard->type){ case SDLA_S502A: - hw->io_range = S502A_IORANGE; + hwcpu->io_range = S502A_IORANGE; irq_opt = s502a_irq_options; dpmbase_opt = s502a_dpmbase_options; pclk_opt = s502a_pclk_options; break; case SDLA_S502E: - hw->io_range = S502E_IORANGE; + hwcpu->io_range = S502E_IORANGE; irq_opt = s502e_irq_options; dpmbase_opt = s508_dpmbase_options; pclk_opt = s502e_pclk_options; break; case SDLA_S503: - hw->io_range = S503_IORANGE; + hwcpu->io_range = S503_IORANGE; irq_opt = s503_irq_options; dpmbase_opt = s508_dpmbase_options; pclk_opt = s503_pclk_options; break; case SDLA_S507: - hw->io_range = S507_IORANGE; + hwcpu->io_range = S507_IORANGE; irq_opt = s508_irq_options; dpmbase_opt = s507_dpmbase_options; pclk_opt = s507_pclk_options; break; case SDLA_S508: - hw->io_range = S508_IORANGE; + hwcpu->io_range = S508_IORANGE; irq_opt = s508_irq_options; dpmbase_opt = s508_dpmbase_options; pclk_opt = s508_pclk_options; break; -#endif default: DEBUG_EVENT("%s: Unknown card type (%02X)!\n", hw->devname, hwcard->type); @@ -3146,26 +4362,26 @@ static int sdla_setup (void* phw, wandev_conf_t* conf) } /* Verify IRQ configuration options */ - if (!sdla_get_option_index(irq_opt, hw->irq)) { + if (!sdla_get_option_index(irq_opt, hwcpu->irq)) { DEBUG_EVENT("%s: IRQ %d is illegal!\n", - hw->devname, hw->irq); + hw->devname, hwcpu->irq); return -EINVAL; } /* Verify CPU clock rate configuration options */ - if (hw->pclk == 0) - hw->pclk = pclk_opt[1]; /* use default */ + if (hwcpu->pclk == 0) + hwcpu->pclk = pclk_opt[1]; /* use default */ - else if (!sdla_get_option_index(pclk_opt, hw->pclk)) { + else if (!sdla_get_option_index(pclk_opt, hwcpu->pclk)) { DEBUG_EVENT("%s: CPU clock %u is illegal!\n", - hw->devname, hw->pclk); + hw->devname, hwcpu->pclk); return -EINVAL; } DEBUG_EVENT("%s: assuming CPU clock rate of %u kHz.\n", - hw->devname, hw->pclk); + hw->devname, hwcpu->pclk); /* Setup adapter dual-port memory window and test memory */ - if (hw->dpmbase == 0) { + if (hwcpu->dpmbase == 0) { err = sdla_autodpm(hw); if (err) { DEBUG_EVENT("%s: can't find available memory region!\n", @@ -3174,60 +4390,61 @@ static int sdla_setup (void* phw, wandev_conf_t* conf) } } else if (!sdla_get_option_index(dpmbase_opt, - virt_to_phys((void*)hw->dpmbase))) { + virt_to_phys((void*)hwcpu->dpmbase))) { DEBUG_EVENT("%s: memory address 0x%lX is illegal!\n", hw->devname, - (unsigned long)virt_to_phys((void*)hw->dpmbase)); + (unsigned long)virt_to_phys((void*)hwcpu->dpmbase)); return -EINVAL; } else if (sdla_setdpm(hw)) { DEBUG_EVENT("%s: 8K memory region at 0x%lX is not available!\n", hw->devname, - (unsigned long)virt_to_phys((void*)hw->dpmbase)); + (unsigned long)virt_to_phys((void*)hwcpu->dpmbase)); return -EINVAL; } DEBUG_EVENT("%s: dual-port memory window is set at 0x%lX.\n", - hw->devname, (unsigned long)virt_to_phys((void*)hw->dpmbase)); + hw->devname, (unsigned long)virt_to_phys((void*)hwcpu->dpmbase)); /* If we find memory in 0xE**** Memory region, * warn the user to disable the SHADOW RAM. * Since memory corruption can occur if SHADOW is * enabled. This can causes random crashes ! */ - if (virt_to_phys((void*)hw->dpmbase) >= 0xE0000){ + if (virt_to_phys((void*)hwcpu->dpmbase) >= 0xE0000){ DEBUG_EVENT("\n(WARNING) %s: !!!!!!!! WARNING !!!!!!!!\n",hw->devname); DEBUG_EVENT("(WANRINIG) %s: WANPIPE is using 0x%lX memory region !!!\n", hw->devname, - (unsigned long)virt_to_phys((void*)hw->dpmbase)); + (unsigned long)virt_to_phys((void*)hwcpu->dpmbase)); DEBUG_EVENT("(WARNING) Please disable the SHADOW RAM, otherwise\n"); DEBUG_EVENT("(WARNING) your system might crash randomly from time to time !\n"); DEBUG_EVENT("(WARNING) %s: !!!!!!!! WARNING !!!!!!!!\n\n",hw->devname); } +#endif break; case SDLA_S514: - if (conf) conf->irq = hw->irq; + if (conf) conf->irq = hwcpu->irq; if (conf && conf->config_id == WANCONFIG_DEBUG){ - hw->memory = MAX_SIZEOF_S514_MEMORY; + hwcpu->memory = MAX_SIZEOF_S514_MEMORY; return 0; } - hw->memory = sdla_test_memregion(hw, MAX_SIZEOF_S514_MEMORY); - if(hw->memory < (256 * 1024)) { + hwcpu->memory = sdla_test_memregion(hw, MAX_SIZEOF_S514_MEMORY); + if(hwcpu->memory < (256 * 1024)) { DEBUG_EVENT("%s: error in testing S514 memory (0x%lX)\n", - hw->devname, hw->memory); + hw->devname, hwcpu->memory); sdla_down(hw); return -EINVAL; } break; case SDLA_ADSL: - if (conf) conf->irq = hw->irq; + if (conf) conf->irq = hwcpu->irq; return 0; break; case SDLA_AFT: - if (conf) conf->irq = hw->irq; + if (conf) conf->irq = hwcpu->irq; return 0; break; @@ -3238,7 +4455,7 @@ static int sdla_setup (void* phw, wandev_conf_t* conf) } DEBUG_EVENT("%s: found %luK bytes of on-board memory\n", - hw->devname, hw->memory / 1024); + hw->devname, hwcpu->memory / 1024); /* Load firmware. If loader fails then shut down adapter */ if (conf){ @@ -3258,13 +4475,16 @@ static int sdla_setup (void* phw, wandev_conf_t* conf) */ static unsigned char sdla_make_config_byte (sdlahw_t* hw) { - sdlahw_card_t* card = NULL; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu; unsigned char byte = 0; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - switch (hw->pclk) { + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + switch (hwcpu->pclk) { case 5000: byte = 0x01; break; case 7200: byte = 0x02; break; case 8000: byte = 0x03; break; @@ -3272,7 +4492,7 @@ static unsigned char sdla_make_config_byte (sdlahw_t* hw) case 16000: byte = 0x05; break; } - switch (card->type) { + switch (hwcard->type) { case SDLA_S502E: byte |= 0x80; break; case SDLA_S503: byte |= 0x40; break; } @@ -3287,11 +4507,14 @@ static unsigned char sdla_make_config_byte (sdlahw_t* hw) static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo) { sdlahw_card_t* card = NULL; + sdlahw_cpu_t *hwcpu; unsigned int offset = 0; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; if (!sfminfo->datasize) return 0; /* nothing to do */ if (sdla_mapmem(hw, sfminfo->dataoffs) != 0) @@ -3300,7 +4523,7 @@ static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo) if (card->type == SDLA_S514){ offset = sfminfo->dataoffs; }else{ - offset = sfminfo->dataoffs - (unsigned long)hw->vector; + offset = sfminfo->dataoffs - (unsigned long)hwcpu->vector; } sdla_bus_set_region_1(hw, 0x00, 0x00, sfminfo->datasize); @@ -3331,7 +4554,8 @@ static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo) */ static int sdla_start (sdlahw_t* hw, unsigned addr) { - sdlahw_card_t* card = NULL; + sdlahw_card_t* hwcard = NULL; + sdlahw_cpu_t* hwcpu; unsigned int offset = 0; int err; #if defined(WAN_ISA_SUPPORT) @@ -3341,11 +4565,13 @@ static int sdla_start (sdlahw_t* hw, unsigned addr) WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - if (!card->ioport && (card->type != SDLA_S514)) return -EFAULT; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + if (!hwcard->ioport && (hwcard->type != SDLA_S514)) return -EFAULT; - switch (card->type) { + switch (hwcard->type) { #if defined(WAN_ISA_SUPPORT) case SDLA_S502A: offset = 0x66; @@ -3367,18 +4593,18 @@ static int sdla_start (sdlahw_t* hw, unsigned addr) if (err) return err; sdla_bus_write_1(hw, offset, 0xC3); - sdla_bus_write_2(hw, offset + 1, addr); + sdla_bus_write_2(hw, offset + 1, (u16)addr); - switch (card->type) { + switch (hwcard->type) { #if defined(WAN_ISA_SUPPORT) case SDLA_S502A: sdla_isa_write_1(hw, 0x00, 0x10); /* issue NMI to CPU */ - hw->regs[0] = 0x10; + hwcpu->regs[0] = 0x10; break; case SDLA_S502E: sdla_isa_write_1(hw, 0x03, 0x01); /* start CPU */ - hw->regs[3] = 0x01; + hwcpu->regs[3] = 0x01; for (i = 0; i < SDLA_IODELAY; ++i); sdla_isa_read_1(hw, 0x00, &tmp); if (tmp & 0x01) { /* verify */ @@ -3388,15 +4614,15 @@ static int sdla_start (sdlahw_t* hw, unsigned addr) * mirror. */ sdla_isa_write_1(hw, 0x00, 0); /* disable interrupts */ - hw->regs[0] = 0; + hwcpu->regs[0] = 0; } else return -EIO; break; case SDLA_S503: - tmp = hw->regs[0] | 0x09; /* set bits 0 and 3 */ + tmp = hwcpu->regs[0] | 0x09; /* set bits 0 and 3 */ sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; /* update mirror */ + hwcpu->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); sdla_isa_read_1(hw, 0x00, &tmp); if (!(tmp & 0x01)) /* verify */ @@ -3404,9 +4630,9 @@ static int sdla_start (sdlahw_t* hw, unsigned addr) break; case SDLA_S507: - tmp = hw->regs[0] | 0x02; + tmp = hwcpu->regs[0] | 0x02; sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; /* update mirror */ + hwcpu->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); sdla_isa_read_1(hw, 0x00, &tmp); if (!(tmp & 0x04)) /* verify */ @@ -3414,9 +4640,9 @@ static int sdla_start (sdlahw_t* hw, unsigned addr) break; case SDLA_S508: - tmp = hw->regs[0] | 0x02; + tmp = hwcpu->regs[0] | 0x02; sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; /* update mirror */ + hwcpu->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); sdla_isa_read_1(hw, 0x01, &tmp); if (!(tmp & 0x02)) /* verify */ @@ -3442,6 +4668,7 @@ static int sdla_start (sdlahw_t* hw, unsigned addr) static int sdla_load (void* phw, void* psfm, unsigned len) { sdlahw_card_t* hwcard = NULL; + sdlahw_cpu_t* hwcpu = NULL; sdlahw_t* hw = (sdlahw_t*)phw; sfm_t* sfm = (sfm_t*)psfm; unsigned char test[256]; @@ -3449,8 +4676,10 @@ static int sdla_load (void* phw, void* psfm, unsigned len) WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; /* Verify firmware signature */ if (strcmp(sfm->signature, SFM_SIGNATURE)) { @@ -3481,7 +4710,7 @@ static int sdla_load (void* phw, void* psfm, unsigned len) if (hwcard->type == SDLA_S514){ DEBUG_EVENT("%s: loading S514 adapter, CPU %c\n", - hw->devname, SDLA_GET_CPU(hw->cpu_no)); + hw->devname, SDLA_GET_CPU(hwcpu->cpu_no)); } /* Scan through the list of compatible adapters and make sure our @@ -3499,7 +4728,7 @@ static int sdla_load (void* phw, void* psfm, unsigned len) /* Make sure there is enough on-board memory */ - if (hw->memory < sfm->info.memsize){ + if (hwcpu->memory < sfm->info.memsize){ DEBUG_EVENT("%s: firmware needs %u bytes of on-board memory!\n", hw->devname, sfm->info.memsize); return -EINVAL; @@ -3540,7 +4769,7 @@ static int sdla_load (void* phw, void* psfm, unsigned len) return -EIO; } - hw->fwid = sfm->info.codeid; /* set firmware ID */ + hwcpu->fwid = sfm->info.codeid; /* set firmware ID */ return 0; } @@ -3551,35 +4780,39 @@ static int sdla_load (void* phw, void* psfm, unsigned len) */ static int sdla_halt (void* phw) { - sdlahw_card_t* card = NULL; - sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; + sdlahw_t *hw = (sdlahw_t*)phw; #if defined(WAN_ISA_SUPPORT) int i; #endif WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - if(!card->ioport && (card->type != SDLA_S514)) + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + if(!hwcard->ioport && (hwcard->type != SDLA_S514)) return -EFAULT; - switch (card->type) { + switch (hwcard->type) { #if defined(WAN_ISA_SUPPORT) case SDLA_S502A: sdla_isa_write_1(hw, 0x00, 0x08); /* halt CPU */ sdla_isa_write_1(hw, 0x00, 0x08); sdla_isa_write_1(hw, 0x00, 0x08); - hw->regs[0] = 0x08; + hwcpu->regs[0] = 0x08; sdla_isa_write_1(hw, 0x01, 0xFF); /* close memory window */ - hw->regs[1] = 0xFF; + hwcpu->regs[1] = 0xFF; break; case SDLA_S502E: sdla_isa_write_1(hw, 0x03, 0); /* stop CPU */ sdla_isa_write_1(hw, 0x00, 0); /* reset board */ for (i = 0; i < S502E_IORANGE; ++i) - hw->regs[i] = 0 + hwcpu->regs[i] = 0 ; break; @@ -3587,7 +4820,7 @@ static int sdla_halt (void* phw) case SDLA_S507: case SDLA_S508: sdla_isa_write_1(hw, 0x00, 0); /* reset board logic */ - hw->regs[0] = 0; + hwcpu->regs[0] = 0; break; #endif case SDLA_S514: @@ -3606,8 +4839,9 @@ static int sdla_halt (void* phw) */ static int sdla_down (void* phw) { - sdlahw_card_t* card = NULL; - sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; + sdlahw_t *hw = (sdlahw_t*)phw; unsigned int CPU_no; u32 int_config, int_status; #if defined(WAN_ISA_SUPPORT) @@ -3616,34 +4850,36 @@ static int sdla_down (void* phw) WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - switch (card->type) { + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + switch (hwcard->type) { #if defined(WAN_ISA_SUPPORT) case SDLA_S502A: - if (!card->ioport){ + if (!hwcard->ioport){ return -EFAULT; } sdla_isa_write_1(hw, 0x00, 0x08); /* halt CPU */ sdla_isa_write_1(hw, 0x00, 0x08); sdla_isa_write_1(hw, 0x00, 0x08); - hw->regs[0] = 0x08; + hwcpu->regs[0] = 0x08; sdla_isa_write_1(hw, 0x01, 0xFF); /* close memory window */ - hw->regs[1] = 0xFF; + hwcpu->regs[1] = 0xFF; break; case SDLA_S502E: - if (!card->ioport){ + if (!hwcard->ioport){ return -EFAULT; } sdla_isa_write_1(hw, 0x03, 0); /* stop CPU */ sdla_isa_write_1(hw, 0x00, 0); /* reset board */ for (i = 0; i < S502E_IORANGE; ++i) - hw->regs[i] = 0 + hwcpu->regs[i] = 0 ; break; @@ -3651,42 +4887,42 @@ static int sdla_down (void* phw) case SDLA_S507: case SDLA_S508: - if (!card->ioport){ + if (!hwcard->ioport){ return -EFAULT; } sdla_isa_write_1(hw, 0x00, 0); /* reset board logic */ - hw->regs[0] = 0; + hwcpu->regs[0] = 0; break; #endif case SDLA_S514: /* halt the adapter */ sdla_io_write_1(hw, 0x00, S514_CPU_HALT); - CPU_no = hw->cpu_no; + CPU_no = hwcpu->cpu_no; /* disable the PCI IRQ and disable memory access */ sdla_pci_read_config_dword(hw, PCI_INT_CONFIG, &int_config); - int_config &= (hw->cpu_no == SDLA_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B; + int_config &= (hwcpu->cpu_no == SDLA_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B; sdla_pci_write_config_dword(hw, PCI_INT_CONFIG, int_config); sdla_read_int_stat(hw, &int_status); sdla_intack(hw, int_status); - if (hw->cpu_no == SDLA_CPU_A){ + if (hwcpu->cpu_no == SDLA_CPU_A){ sdla_pci_write_config_dword(hw, PCI_MAP0_DWORD, PCI_CPU_A_MEM_DISABLE); }else{ sdla_pci_write_config_dword(hw, PCI_MAP1_DWORD, PCI_CPU_B_MEM_DISABLE); } /* free up the allocated virtual memory */ - if (hw->status & SDLA_MEM_MAPPED){ - sdla_bus_space_unmap(hw, hw->dpmbase, MAX_SIZEOF_S514_MEMORY); - hw->status &= ~SDLA_MEM_MAPPED; + if (hwcpu->status & SDLA_MEM_MAPPED){ + sdla_bus_space_unmap(hw, hwcpu->dpmbase, MAX_SIZEOF_S514_MEMORY); + hwcpu->status &= ~SDLA_MEM_MAPPED; } - if (hw->status & SDLA_IO_MAPPED){ - sdla_bus_space_unmap(hw, hw->vector, 16); - hw->status &= ~SDLA_IO_MAPPED; + if (hwcpu->status & SDLA_IO_MAPPED){ + sdla_bus_space_unmap(hw, hwcpu->vector, 16); + hwcpu->status &= ~SDLA_IO_MAPPED; } break; @@ -3711,15 +4947,20 @@ static int sdla_down (void* phw) case SDLA_AFT: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: case A104_ADPTR_4TE1: case A108_ADPTR_8TE1: case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: + case AFT_ADPTR_ISDN: case AFT_ADPTR_56K: - if (hw->used > 1){ + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: + if (hwcpu->used > 1){ break; } /* fall throught */ @@ -3740,16 +4981,19 @@ static int sdla_down (void* phw) */ static int sdla_inten (sdlahw_t* hw) { - sdlahw_card_t* card = NULL; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; #if defined(WAN_ISA_SUPPORT) int i; u8 tmp; #endif WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - switch (card->type) { + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + switch (hwcard->type) { #if defined(WAN_ISA_SUPPORT) case SDLA_S502E: /* Note thar interrupt control operations on S502E are allowed @@ -3759,15 +5003,15 @@ static int sdla_inten (sdlahw_t* hw) if (tmp & 0x01) { sdla_isa_write_1(hw, 0x00, 0x02); /* bit1 = 1, bit2 = 0 */ sdla_isa_write_1(hw, 0x00, 0x06); /* bit1 = 1, bit2 = 1 */ - hw->regs[0] = 0x06; + hwcpu->regs[0] = 0x06; } else return -EIO; break; case SDLA_S503: - tmp = hw->regs[0] | 0x04; + tmp = hwcpu->regs[0] | 0x04; sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; /* update mirror */ + hwcpu->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ sdla_isa_read_1(hw, 0x00, &tmp); if (!(tmp & 0x02)) /* verify */ @@ -3775,9 +5019,9 @@ static int sdla_inten (sdlahw_t* hw) break; case SDLA_S508: - tmp = hw->regs[0] | 0x10; + tmp = hwcpu->regs[0] | 0x10; sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; /* update mirror */ + hwcpu->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ sdla_isa_read_1(hw, 0x01, &tmp); if (!(tmp & 0x10)) /* verify */ @@ -3865,14 +5109,18 @@ static int sdla_intde (sdlahw_t* hw) */ static int sdla_read_int_stat (void* phw, u32* int_status) { - sdlahw_card_t* card = NULL; - sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; + sdlahw_t *hw = (sdlahw_t*)phw; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - switch(card->type){ + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + switch(hwcard->type){ case SDLA_S514: case SDLA_ADSL: case SDLA_AFT: @@ -3886,17 +5134,21 @@ static int sdla_read_int_stat (void* phw, u32* int_status) */ static int sdla_intack (void* phw, u32 int_status) { - sdlahw_card_t* card = NULL; - sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; + sdlahw_t *hw = (sdlahw_t*)phw; #if defined(WAN_ISA_SUPPORT) u8 tmp; #endif WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - switch (card->type){ + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + switch (hwcard->type){ #if defined(WAN_ISA_SUPPORT) case SDLA_S502E: /* To acknoledge hardware interrupt we have to toggle bit 3 of @@ -3906,11 +5158,11 @@ static int sdla_intack (void* phw, u32 int_status) */ sdla_isa_read_1(hw, 0x00, &tmp); if (tmp & 0x01) { - tmp = hw->regs[0] & ~0x04; + tmp = hwcpu->regs[0] & ~0x04; sdla_isa_write_1(hw, 0x00, tmp); tmp |= 0x04; sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; + hwcpu->regs[0] = tmp; } else return -EIO; break; @@ -3918,11 +5170,11 @@ static int sdla_intack (void* phw, u32 int_status) case SDLA_S503: sdla_isa_read_1(hw, 0x00, &tmp); if (tmp & 0x04) { - tmp = hw->regs[0] & ~0x08; + tmp = hwcpu->regs[0] & ~0x08; sdla_isa_write_1(hw, 0x00, tmp); tmp |= 0x08; sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; + hwcpu->regs[0] = tmp; } break; @@ -3993,13 +5245,18 @@ static int sdla_intr (sdlahw_t* hw) static int sdla_cmd (void* phw, unsigned long offset, wan_mbox_t* mbox) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t* hwcpu = NULL; int len = sizeof(wan_cmd_t); int err = 0; u8 value; SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; len += mbox->wan_data_len; + DEBUG_CMD("%s: Executing %02X command...\n", + hw->devname,mbox->wan_command); /* Sangoma ISA card -> sdla_bus_read_1(hw, offset, &value); */ sdla_peek(hw, offset, (void*)&value, 1); if (value != 0x00){ @@ -4026,6 +5283,8 @@ static int sdla_cmd (void* phw, unsigned long offset, wan_mbox_t* mbox) return WAN_CMD_TIMEOUT; } + DEBUG_CMD("%s: Executing %02X command...done!\n", + hw->devname,mbox->wan_command); return mbox->wan_return_code; } @@ -4037,9 +5296,9 @@ static int sdla_cmd (void* phw, unsigned long offset, wan_mbox_t* mbox) */ static int sdla_exec (sdlahw_t* hw, unsigned long offset) { - volatile unsigned long tstop; - volatile unsigned long nloops; - u8 value; + volatile wan_ticks_t tstop = 0; + volatile int nloops = 0; + u8 value, buf[10]; #if 0 /* Sangoma ISA card -> sdla_bus_read_1(hw, offset, &value); */ @@ -4060,11 +5319,12 @@ static int sdla_exec (sdlahw_t* hw, unsigned long offset) for (nloops = 1; value == 0x01; ++ nloops){ WP_DELAY(EXEC_DELAY); if (SYSTEM_TICKS > tstop || nloops > MAX_NLOOPS){ - DEBUG_EVENT("%s: Timeout %lu (%lu>%lu) Ticks (max=%lu) Loops %lu (max=%u)\n", + DEBUG_EVENT( + "%s: Timeout %ld (%lu>%lu) Ticks (max=%lu) Loops %u (max=%u)\n", __FUNCTION__, - (SYSTEM_TICKS-tstop+EXEC_TIMEOUT), + (unsigned long)(SYSTEM_TICKS-tstop+EXEC_TIMEOUT), (unsigned long)SYSTEM_TICKS, - tstop, + (unsigned long)tstop, (unsigned long)EXEC_TIMEOUT, nloops, MAX_NLOOPS); @@ -4081,7 +5341,9 @@ static int sdla_exec (sdlahw_t* hw, unsigned long offset) } /* Sangoma ISA card -> sdla_bus_read_1(hw, offset, &value); */ - sdla_peek(hw, offset, (void*)&value, 1); + buf[0] = 0; + sdla_peek(hw, offset, (void*)&buf[0], 1); + value = buf[0]; } return nloops; @@ -4099,7 +5361,8 @@ static int sdla_exec (sdlahw_t* hw, unsigned long offset) */ static int sdla_peek (void* phw, unsigned long addr, void* pbuf, unsigned len) { - sdlahw_card_t* card = NULL; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; sdlahw_t* hw = (sdlahw_t*)phw; unsigned char* buf = (unsigned char*)pbuf; int err = 0; @@ -4107,18 +5370,21 @@ static int sdla_peek (void* phw, unsigned long addr, void* pbuf, unsigned len) WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - if (addr + len > hw->memory) /* verify arguments */ + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + if (addr + len > hwcpu->memory) /* verify arguments */ return -EINVAL; - switch(card->type){ + switch(hwcard->type){ case SDLA_S508: { - unsigned long oldvec = (unsigned long)hw->vector; + unsigned long oldvec = (unsigned long)hwcpu->vector; unsigned long curvec; /* current DPM window vector */ - unsigned winsize = hw->dpmsize; + unsigned winsize = hwcpu->dpmsize; unsigned curpos, curlen; /* current offset and block size */ while (len && !err) { @@ -4147,7 +5413,7 @@ static int sdla_peek (void* phw, unsigned long addr, void* pbuf, unsigned len) default: DEBUG_EVENT("%s: Invalid card type 0x%X\n", - __FUNCTION__,card->type); + __FUNCTION__,hwcard->type); err = -EINVAL; break; } @@ -4200,26 +5466,30 @@ static void sdla_peek_by_4 (sdlahw_t* hw, unsigned long offset, void* pbuf, unsi */ static int sdla_poke (void* phw, unsigned long addr, void* pbuf, unsigned len) { - sdlahw_card_t* card = NULL; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu = NULL; sdlahw_t* hw = (sdlahw_t*)phw; - unsigned char * buf = pbuf; + unsigned char *buf = pbuf; int err = 0; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - if (addr + len > hw->memory){ /* verify arguments */ + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + if (addr + len > hwcpu->memory){ /* verify arguments */ return -EINVAL; } - switch (card->type){ + switch (hwcard->type){ case SDLA_S508: { - unsigned long oldvec = (unsigned long)hw->vector; + unsigned long oldvec = (unsigned long)hwcpu->vector; unsigned long curvec; /* current DPM window vector */ - unsigned winsize = hw->dpmsize; + unsigned winsize = hwcpu->dpmsize; unsigned curpos, curlen; /* current offset and block size */ while (len && !err) { @@ -4247,7 +5517,7 @@ static int sdla_poke (void* phw, unsigned long addr, void* pbuf, unsigned len) default: DEBUG_EVENT("%s: Invalid card type 0x%X\n", - __FUNCTION__,card->type); + __FUNCTION__,hwcard->type); err = -EINVAL; break; } @@ -4340,21 +5610,24 @@ static int sdla_clear_bit (void* phw, unsigned long offset, u8 value) */ static int sdla_init_pci_slot(sdlahw_t *hw) { - sdlahw_card_t* card = NULL; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu; u32 int_status; int volatile found=0; int i=0; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; /* Check if this is a very first load for a specific * pci card. If it is, clear the interrput bits, and * set the flag indicating that this card was initialized. */ for (i=0; (islot_no){ + if (pci_slot_ar[i] == hwcard->slot_no){ found=1; break; } @@ -4374,12 +5647,12 @@ static int sdla_init_pci_slot(sdlahw_t *hw) DEBUG_EVENT( "Please contact Sangoma Technologies\n"); return 1; } - pci_slot_ar[i] = card->slot_no; + pci_slot_ar[i] = hwcard->slot_no; } return 0; } - +#if defined(WAN_ISA_SUPPORT) /* * ============================================================================ * Check memory region to see if it's available. @@ -4387,10 +5660,15 @@ static int sdla_init_pci_slot(sdlahw_t *hw) */ static unsigned int sdla_check_memregion(sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; unsigned int offset = 0x0; - unsigned int len = hw->dpmsize; + unsigned int len = 0; u8 value; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + len = hwcpu->dpmsize; sdla_bus_read_1(hw, offset, &value); for(; len && (value == 0xFF); --len){ /* attempt to write 0 */ @@ -4407,22 +5685,26 @@ static unsigned int sdla_check_memregion(sdlahw_t* hw) return len; } +#endif +#if defined(WAN_ISA_SUPPORT) /*============================================================================ * Autoselect memory region. * o try all available DMP address options from the top down until success. */ static int sdla_autodpm (sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; int i, err = -EINVAL; unsigned* opt; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - switch (card->type){ -#if defined(WAN_ISA_SUPPORT) + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + switch (hwcard->type){ case SDLA_S502A: opt = s502a_dpmbase_options; break; @@ -4436,7 +5718,6 @@ static int sdla_autodpm (sdlahw_t* hw) case SDLA_S507: opt = s507_dpmbase_options; break; -#endif default: return -EINVAL; } @@ -4446,45 +5727,50 @@ static int sdla_autodpm (sdlahw_t* hw) * We don't want to test A**** addresses, since * they are usually used for Video */ for (i = 8; i <= opt[0] && err; i++) { - hw->dpmbase = (sdla_mem_handle_t)phys_to_virt(opt[i]); + hwcpu->dpmbase = (sdla_mem_handle_t)phys_to_virt(opt[i]); err = sdla_setdpm(hw); } return err; } +#endif +#if defined(WAN_ISA_SUPPORT) /*============================================================================ * Initialize SDLA hardware: setup memory window, IRQ, etc. */ static int sdla_init (sdlahw_t* hw) { - sdlahw_card_t* card = NULL; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu; int i; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; for (i = 0; i < SDLA_MAXIORANGE; ++i){ - hw->regs[i] = 0; + hwcpu->regs[i] = 0; } - switch (card->type) { -#if defined(WAN_ISA_SUPPORT) + switch (hwcard->type) { case SDLA_S502A: return sdla_init_s502a(hw); case SDLA_S502E: return sdla_init_s502e(hw); case SDLA_S503: return sdla_init_s503(hw); case SDLA_S507: return sdla_init_s507(hw); case SDLA_S508: return sdla_init_s508(hw); -#endif } return -EINVAL; } +#endif /*============================================================================ * Map shared memory window into SDLA address space. */ static int sdla_mapmem (void* phw, unsigned long addr) { - sdlahw_card_t* card = NULL; + sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t* hwcpu = NULL; sdlahw_t* hw = (sdlahw_t*)phw; #if defined(WAN_ISA_SUPPORT) u8 tmp; @@ -4492,25 +5778,27 @@ static int sdla_mapmem (void* phw, unsigned long addr) WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - switch (card->type){ + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + switch (hwcard->type){ #if defined(WAN_ISA_SUPPORT) case SDLA_S502A: case SDLA_S502E: if (addr < S502_MAXMEM) { /* verify parameter */ tmp = addr >> 13; /* convert to register mask */ sdla_isa_write_1(hw, 0x02, tmp); - hw->regs[2] = tmp; + hwcpu->regs[2] = tmp; } else return -EINVAL; break; case SDLA_S503: if (addr < S503_MAXMEM) { /* verify parameter */ - tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70); + tmp = (hwcpu->regs[0] & 0x8F) | ((addr >> 9) & 0x70); sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; + hwcpu->regs[0] = tmp; } else return -EINVAL; break; @@ -4522,7 +5810,7 @@ static int sdla_mapmem (void* phw, unsigned long addr) return -EIO; tmp = addr >> 13; /* convert to register mask */ sdla_isa_write_1(hw, 0x02, tmp); - hw->regs[2] = tmp; + hwcpu->regs[2] = tmp; } else return -EINVAL; break; @@ -4531,7 +5819,7 @@ static int sdla_mapmem (void* phw, unsigned long addr) if (addr < S508_MAXMEM) { tmp = addr >> 13; /* convert to register mask */ sdla_isa_write_1(hw, 0x02, tmp); - hw->regs[2] = tmp; + hwcpu->regs[2] = tmp; } else return -EINVAL; break; @@ -4544,7 +5832,7 @@ static int sdla_mapmem (void* phw, unsigned long addr) default: return -EINVAL; } - hw->vector = (sdla_mem_handle_t)(addr & 0xFFFFE000L); + hwcpu->vector = (sdla_mem_handle_t)(addr & 0xFFFFE000L); return 0; } @@ -4618,6 +5906,7 @@ static unsigned sdla_test_memregion (sdlahw_t* hw, unsigned len) #endif } +#if defined(WAN_ISA_SUPPORT) /*============================================================================ * Test adapter on-board memory. * o slide DPM window from the bottom up and test adapter memory segment by @@ -4626,20 +5915,25 @@ static unsigned sdla_test_memregion (sdlahw_t* hw, unsigned len) */ static unsigned long sdla_memtest (sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; unsigned long memsize; unsigned winsize; - for (memsize = 0, winsize = hw->dpmsize; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + for (memsize = 0, winsize = hwcpu->dpmsize; !sdla_mapmem(hw, memsize) && (sdla_test_memregion(hw, winsize) == winsize) ; memsize += winsize) ; - hw->memory = memsize; + hwcpu->memory = memsize; return memsize; } +#endif - +#if defined(WAN_ISA_SUPPORT) /*============================================================================ * Set up adapter dual-port memory window. * o shut down adapter @@ -4651,8 +5945,12 @@ static unsigned long sdla_memtest (sdlahw_t* hw) */ static int sdla_setdpm (sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; int err; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; /* Shut down card and verify memory region */ sdla_down(hw); if (sdla_check_memregion(hw)) @@ -4665,7 +5963,7 @@ static int sdla_setdpm (sdlahw_t* hw) err = sdla_init(hw); if (err) return err; - if (sdla_memtest(hw) < hw->dpmsize) { /* less than window size */ + if (sdla_memtest(hw) < hwcpu->dpmsize) {/* less than window size */ sdla_down(hw); return -EIO; } @@ -4673,6 +5971,7 @@ static int sdla_setdpm (sdlahw_t* hw) sdla_mapmem(hw, 0L); /* set window vector at bottom */ return 0; } +#endif /*============================================================================ * Detect S502A adapter. @@ -4691,14 +5990,17 @@ static int sdla_setdpm (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_detect_s502a (sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t* hwcard; + sdlahw_cpu_t* hwcpu; int i, j; u8 tmp; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - if (!sdla_get_option_index(s502_port_options, card->ioport)) + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + if (!sdla_get_option_index(s502_port_options, hwcard->ioport)) return 0; for (j = 1; j < SDLA_MAXIORANGE; ++j) { @@ -4742,21 +6044,25 @@ static int sdla_detect_s502a (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_init_s502a (sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; int tmp, i; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; if (!sdla_detect_s502a(hw)) return -ENODEV; - hw->regs[0] = 0x08; - hw->regs[1] = 0xFF; + hwcpu->regs[0] = 0x08; + hwcpu->regs[1] = 0xFF; /* Verify configuration options */ - i = sdla_get_option_index(s502a_dpmbase_options, virt_to_phys((void*)hw->dpmbase)); + i = sdla_get_option_index(s502a_dpmbase_options, virt_to_phys((void*)hwcpu->dpmbase)); if (i == 0) return -EINVAL; tmp = s502a_hmcr[i - 1]; - switch (hw->dpmsize) { + switch (hwcpu->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -4770,8 +6076,8 @@ static int sdla_init_s502a (sdlahw_t* hw) /* Setup dual-port memory window (this also enables memory access) */ sdla_isa_write_1(hw, 0x01, tmp); - hw->regs[1] = tmp; - hw->regs[0] = 0x08; + hwcpu->regs[1] = tmp; + hwcpu->regs[0] = 0x08; return 0; } #endif @@ -4791,12 +6097,15 @@ static int sdla_init_s502a (sdlahw_t* hw) static int sdla_detect_s502e (sdlahw_t* hw) { sdlahw_card_t* card; + sdlahw_cpu_t* hwcpu; int i, j; u8 tmp; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; if (!sdla_get_option_index(s502_port_options, card->ioport)) return 0; for (j = 1; j < SDLA_MAXIORANGE; ++j) { @@ -4829,19 +6138,23 @@ static int sdla_detect_s502e (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_init_s502e (sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; int i; u8 tmp; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; if (!sdla_detect_s502e(hw)) return -ENODEV; /* Verify configuration options */ - i = sdla_get_option_index(s508_dpmbase_options, virt_to_phys((void*)hw->dpmbase)); + i = sdla_get_option_index(s508_dpmbase_options, virt_to_phys((void*)hwcpu->dpmbase)); if (i == 0) return -EINVAL; tmp = s502e_hmcr[i - 1]; - switch (hw->dpmsize) { + switch (hwcpu->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -4855,11 +6168,11 @@ static int sdla_init_s502e (sdlahw_t* hw) /* Setup dual-port memory window */ sdla_isa_write_1(hw, 0x01, tmp); - hw->regs[1] = tmp; + hwcpu->regs[1] = tmp; /* Enable memory access */ sdla_isa_write_1(hw, 0x00, 0x02); - hw->regs[0] = 0x02; + hwcpu->regs[0] = 0x02; for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ sdla_isa_read_1(hw, 0x00, &tmp); return (tmp & 0x02) ? 0 : -EIO; @@ -4881,14 +6194,18 @@ static int sdla_init_s502e (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_detect_s503 (sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; int i, j; u8 tmp; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - if (!sdla_get_option_index(s503_port_options, card->ioport)) + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + if (!sdla_get_option_index(s503_port_options, hwcard->ioport)) return 0; for (j = 1; j < SDLA_MAXIORANGE; ++j) { sdla_isa_read_1(hw, j, &tmp); @@ -4921,18 +6238,22 @@ static int sdla_detect_s503 (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_init_s503 (sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; int tmp, i; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; if (!sdla_detect_s503(hw)) return -ENODEV; /* Verify configuration options */ - i = sdla_get_option_index(s508_dpmbase_options, virt_to_phys((void*)hw->dpmbase)); + i = sdla_get_option_index(s508_dpmbase_options, virt_to_phys((void*)hwcpu->dpmbase)); if (i == 0) return -EINVAL; tmp = s502e_hmcr[i - 1]; - switch (hw->dpmsize) { + switch (hwcpu->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -4946,11 +6267,11 @@ static int sdla_init_s503 (sdlahw_t* hw) /* Setup dual-port memory window */ sdla_isa_write_1(hw, 0x01, tmp); - hw->regs[1] = tmp; + hwcpu->regs[1] = tmp; /* Enable memory access */ sdla_isa_write_1(hw, 0x00, 0x02); - hw->regs[0] = 0x02; /* update mirror */ + hwcpu->regs[0] = 0x02; /* update mirror */ return 0; } #endif @@ -4970,14 +6291,18 @@ static int sdla_init_s503 (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_detect_s507 (sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t* hwcard; + sdlahw_cpu_t *hwcpu; int i, j; u8 tmp, tmp1; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - if (!sdla_get_option_index(s508_port_options, card->ioport)) + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + if (!sdla_get_option_index(s508_port_options, hwcard->ioport)) return 0; sdla_isa_read_1(hw, 0x00, &tmp); for (j = 1; j < S507_IORANGE; ++j) { @@ -5010,19 +6335,25 @@ static int sdla_detect_s507 (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_init_s507 (sdlahw_t* hw) { + sdlahw_cpu_t *hwcpu; int i; u8 tmp; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + if (!sdla_detect_s507(hw)) return -ENODEV; /* Verify configuration options */ - i = sdla_get_option_index(s507_dpmbase_options, virt_to_phys((void*)hw->dpmbase)); + i = sdla_get_option_index(s507_dpmbase_options, virt_to_phys((void*)hwcpu->dpmbase)); if (i == 0) return -EINVAL; tmp = s507_hmcr[i - 1]; - switch (hw->dpmsize) { + switch (hwcpu->dpmsize) { case 0x2000: tmp |= 0x01; break; @@ -5036,7 +6367,7 @@ static int sdla_init_s507 (sdlahw_t* hw) /* Enable adapter's logic */ sdla_isa_write_1(hw, 0x00, 0x01); - hw->regs[0] = 0x01; + hwcpu->regs[0] = 0x01; for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ sdla_isa_read_1(hw, 0x00, &tmp); if (!(tmp & 0x20)) @@ -5044,16 +6375,16 @@ static int sdla_init_s507 (sdlahw_t* hw) /* Setup dual-port memory window */ sdla_isa_write_1(hw, 0x01, tmp); - hw->regs[1] = tmp; + hwcpu->regs[1] = tmp; /* Enable memory access */ - tmp = hw->regs[0] | 0x04; - if (hw->irq) { - i = sdla_get_option_index(s508_irq_options, hw->irq); + tmp = hwcpu->regs[0] | 0x04; + if (hwcpu->irq) { + i = sdla_get_option_index(s508_irq_options, hwcpu->irq); if (i) tmp |= s507_irqmask[i - 1]; } sdla_isa_write_1(hw, 0x00, tmp); - hw->regs[0] = tmp; /* update mirror */ + hwcpu->regs[0] = tmp; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ sdla_isa_read_1(hw, 0x00, &tmp); return (tmp & 0x08) ? 0 : -EIO; @@ -5067,15 +6398,20 @@ static int sdla_init_s507 (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_init_s508 (sdlahw_t* hw) { - int i; - u8 tmp; + sdlahw_cpu_t *hwcpu; + int i; + u8 tmp; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; if (sdla_detect_s508(hw)){ return -ENODEV; } /* Verify configuration options */ - i = sdla_get_option_index(s508_dpmbase_options, virt_to_phys((void*)hw->dpmbase)); + i = sdla_get_option_index(s508_dpmbase_options, virt_to_phys((void*)hwcpu->dpmbase)); if (i == 0){ return -EINVAL; } @@ -5083,11 +6419,11 @@ static int sdla_init_s508 (sdlahw_t* hw) /* Setup memory configuration */ tmp = s508_hmcr[i - 1]; sdla_isa_write_1(hw, 0x01, tmp); - hw->regs[1] = tmp; + hwcpu->regs[1] = tmp; /* Enable memory access */ sdla_isa_write_1(hw, 0x00, 0x04); - hw->regs[0] = 0x04; /* update mirror */ + hwcpu->regs[0] = 0x04; /* update mirror */ for (i = 0; i < SDLA_IODELAY; ++i); /* delay */ sdla_isa_read_1(hw, 0x01, &tmp); return (tmp & 0x04) ? 0 : -EIO; @@ -5109,17 +6445,20 @@ static int sdla_init_s508 (sdlahw_t* hw) #if defined(WAN_ISA_SUPPORT) static int sdla_detect_s508 (sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; int i; u8 tmp; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; /* Sangoma ISa card */ - hw->status |= SDLA_MEM_MAPPED; - hw->status |= SDLA_IO_MAPPED; - if (!sdla_get_option_index(s508_port_options, card->ioport)){ + hwcpu->status |= SDLA_MEM_MAPPED; + hwcpu->status |= SDLA_IO_MAPPED; + if (!sdla_get_option_index(s508_port_options, hwcard->ioport)){ return -EINVAL; } sdla_isa_write_1(hw, 0x0, 0x00); @@ -5148,19 +6487,22 @@ static int sdla_detect_s508 (sdlahw_t* hw) */ static int sdla_detect_s514 (sdlahw_t* hw) { - sdlahw_card_t* card; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; u32 ut_u32; u8 ut_u8; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; sdla_pci_read_config_dword(hw, - (hw->cpu_no == SDLA_CPU_A) ? PCI_MEM_BASE0_DWORD : - PCI_MEM_BASE1_DWORD, (u32*)&hw->mem_base_addr); - if (!hw->mem_base_addr){ - if(hw->cpu_no == SDLA_CPU_B){ + (hwcpu->cpu_no == SDLA_CPU_A) ? PCI_MEM_BASE0_DWORD : + PCI_MEM_BASE1_DWORD, (u32*)&hwcpu->mem_base_addr); + if (!hwcpu->mem_base_addr){ + if(hwcpu->cpu_no == SDLA_CPU_B){ DEBUG_EVENT( "%s: CPU #B not present on the card\n", hw->devname); }else{ @@ -5170,13 +6512,13 @@ static int sdla_detect_s514 (sdlahw_t* hw) return -EINVAL; } DEBUG_EVENT( "%s: S514 PCI memory at 0x%lX\n", - hw->devname, (unsigned long)hw->mem_base_addr); + hw->devname, (unsigned long)hwcpu->mem_base_addr); /* enable the PCI memory */ sdla_pci_read_config_dword(hw, - (hw->cpu_no == SDLA_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, &ut_u32); + (hwcpu->cpu_no == SDLA_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, &ut_u32); sdla_pci_write_config_dword(hw, - (hw->cpu_no == SDLA_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, + (hwcpu->cpu_no == SDLA_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD, (ut_u32 | PCI_MEMORY_ENABLE)); /* check the IRQ allocated and enable IRQ usage */ @@ -5191,14 +6533,14 @@ static int sdla_detect_s514 (sdlahw_t* hw) return 0; } - sdla_pci_read_config_byte(hw, PCI_INT_LINE_BYTE, (u8*)&hw->irq); - if(hw->irq == PCI_IRQ_NOT_ALLOCATED) { + sdla_pci_read_config_byte(hw, PCI_INT_LINE_BYTE, (u8*)&hwcpu->irq); + if(hwcpu->irq == PCI_IRQ_NOT_ALLOCATED) { DEBUG_EVENT("%s: IRQ not allocated to S514 adapter\n", hw->devname); return -EINVAL; } #if defined(__LINUX__) - hw->irq = card->pci_dev->irq; + hwcpu->irq = hwcard->pci_dev->irq; #endif /* BUG FIX : Mar 6 2000 @@ -5214,7 +6556,7 @@ static int sdla_detect_s514 (sdlahw_t* hw) } sdla_pci_read_config_dword(hw, PCI_INT_CONFIG, &ut_u32); - ut_u32 |= (hw->cpu_no == SDLA_CPU_A) ? + ut_u32 |= (hwcpu->cpu_no == SDLA_CPU_A) ? PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B; sdla_pci_write_config_dword(hw, PCI_INT_CONFIG, ut_u32); @@ -5230,39 +6572,39 @@ static int sdla_detect_s514 (sdlahw_t* hw) * the value of the irq is not valid until pci_enable_device() * is executied */ #if defined(__LINUX__) - hw->irq = card->pci_dev->irq; + hwcpu->irq = hwcard->pci_dev->irq; #endif DEBUG_EVENT( "%s: IRQ %d allocated to the S514 card\n", - hw->devname, hw->irq); + hw->devname, hwcpu->irq); - hw->status |= SDLA_PCI_ENABLE; + hwcpu->status |= SDLA_PCI_ENABLE; /* map the physical PCI memory to virtual memory */ - sdla_bus_space_map(hw, 0x0, MAX_SIZEOF_S514_MEMORY, &hw->dpmbase); - if (!hw->dpmbase){ + sdla_bus_space_map(hw, 0x0, MAX_SIZEOF_S514_MEMORY, &hwcpu->dpmbase); + if (!hwcpu->dpmbase){ DEBUG_EVENT("%s: PCI virtual memory allocation failed\n", hw->devname); return -EINVAL; } /* map the physical control register memory to virtual memory */ - sdla_bus_space_map(hw, S514_CTRL_REG_BYTE, 16, &hw->vector); - if (!hw->vector){ - sdla_bus_space_unmap(hw, hw->dpmbase, MAX_SIZEOF_S514_MEMORY); + sdla_bus_space_map(hw, S514_CTRL_REG_BYTE, 16, &hwcpu->vector); + if (!hwcpu->vector){ + sdla_bus_space_unmap(hw, hwcpu->dpmbase, MAX_SIZEOF_S514_MEMORY); DEBUG_EVENT("%s: PCI virtual memory allocation failed\n", hw->devname); - hw->dpmbase=0; + hwcpu->dpmbase=0; return -EINVAL; } - hw->status |= SDLA_MEM_MAPPED; + hwcpu->status |= SDLA_MEM_MAPPED; #if defined(__NetBSD__) || defined(__OpenBSD__) - hw->ioh = hw->vector; + hwcpu->ioh = hw->vector; #endif - hw->status |= SDLA_IO_MAPPED; + hwcpu->status |= SDLA_IO_MAPPED; /* halt the adapter */ sdla_io_write_1(hw, 0x0, S514_CPU_HALT); @@ -5279,11 +6621,14 @@ static int sdla_detect_s514 (sdlahw_t* hw) static int sdla_detect_pulsar(sdlahw_t* hw) { sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; int err; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; if ((err = sdla_memory_map(hw, SDLA_CPU_A))){ return err; @@ -5297,20 +6642,20 @@ static int sdla_detect_pulsar(sdlahw_t* hw) } #endif DEBUG_EVENT( "%s: ADSL PCI memory at 0x%lX\n", - hw->devname, (unsigned long)hw->mem_base_addr); + hw->devname, (unsigned long)hwcpu->mem_base_addr); - sdla_pci_read_config_byte(hw, PCI_INT_LINE_BYTE, (u8*)&hw->irq); - if(hw->irq == PCI_IRQ_NOT_ALLOCATED) { + sdla_pci_read_config_byte(hw, PCI_INT_LINE_BYTE, (u8*)&hwcpu->irq); + if(hwcpu->irq == PCI_IRQ_NOT_ALLOCATED) { DEBUG_EVENT( "%s: IRQ not allocated to S514 adapter\n", hw->devname); return -EINVAL; } #if defined(__LINUX__) - hw->irq = hwcard->pci_dev->irq; + hwcpu->irq = hwcard->pci_dev->irq; #endif DEBUG_EVENT( "%s: IRQ %d allocated to the ADSL card\n", - hw->devname, hw->irq); + hw->devname, hwcpu->irq); #if 0 if (sdla_pci_enable_device(hw)){ @@ -5354,15 +6699,16 @@ static int sdla_detect_pulsar(sdlahw_t* hw) static int sdla_memory_map(sdlahw_t* hw, int cpu_no) { sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; void *presource; int err=-EINVAL; unsigned char reserve_name[50]; - - WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; presource =NULL; switch (hwcard->type){ @@ -5373,35 +6719,40 @@ static int sdla_memory_map(sdlahw_t* hw, int cpu_no) #endif case SDLA_ADSL: - hw->memory=GSI_PCI_MEMORY_SIZE; + hwcpu->memory=GSI_PCI_MEMORY_SIZE; cpu_no=SDLA_CPU_A; sprintf(reserve_name,"WANPIPE ADSL"); break; case SDLA_AFT: sprintf(reserve_name,"WANPIPE AFT"); - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ - hw->memory = AFT_PCI_MEM_SIZE; + if (hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ + hwcpu->memory = AFT_PCI_MEM_SIZE; }else{ - hw->memory = AFT2_PCI_MEM_SIZE; + hwcpu->memory = AFT2_PCI_MEM_SIZE; } break; case A104_ADPTR_4TE1: case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: - hw->memory = AFT4_PCI_MEM_SIZE; + case AFT_ADPTR_ISDN: + hwcpu->memory = AFT4_PCI_MEM_SIZE; break; + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_RS232: case A108_ADPTR_8TE1: - hw->memory = AFT8_PCI_MEM_SIZE; + hwcpu->memory = AFT8_PCI_MEM_SIZE; break; case AFT_ADPTR_56K: - hw->memory = AFT2_PCI_MEM_SIZE; + hwcpu->memory = AFT2_PCI_MEM_SIZE; break; default: - hw->memory = AFT_PCI_MEM_SIZE; + hwcpu->memory = AFT_PCI_MEM_SIZE; break; } break; @@ -5419,16 +6770,16 @@ static int sdla_memory_map(sdlahw_t* hw, int cpu_no) hw->devname); return -EINVAL; } - hw->status |= SDLA_PCI_ENABLE; + hwcpu->status |= SDLA_PCI_ENABLE; - if (!(hw->status & SDLA_MEM_RESERVED)){ + if (!(hwcpu->status & SDLA_MEM_RESERVED)){ #if defined(__LINUX__) - err = pci_request_region(hw->hwcard->pci_dev, (cpu_no == SDLA_CPU_A)?0:1 ,reserve_name); + err = pci_request_region(hwcard->pci_dev, (cpu_no == SDLA_CPU_A)?0:1 ,reserve_name); #else err = sdla_request_mem_region( hw, - hw->mem_base_addr, - hw->memory, + hwcpu->mem_base_addr, + hwcpu->memory, reserve_name, &presource); #endif @@ -5440,11 +6791,11 @@ static int sdla_memory_map(sdlahw_t* hw, int cpu_no) err = -EINVAL; goto aft_pci_error; } - hw->status |= SDLA_MEM_RESERVED; + hwcpu->status |= SDLA_MEM_RESERVED; } #if defined(__LINUX__) && defined(DMA_32BIT_MASK) - if((err = pci_set_dma_mask(hw->hwcard->pci_dev, DMA_32BIT_MASK))) { + if((err = pci_set_dma_mask(hwcard->pci_dev, DMA_32BIT_MASK))) { DEBUG_EVENT("%s: Error: No usable DMA configuration, aborting.\n", hw->devname); err = -EINVAL; @@ -5455,9 +6806,9 @@ static int sdla_memory_map(sdlahw_t* hw, int cpu_no) (cpu_no == SDLA_CPU_A) ? PCI_IO_BASE_DWORD : PCI_MEM_BASE0_DWORD, - &hw->mem_base_addr); + &hwcpu->mem_base_addr); - if (!hw->mem_base_addr){ + if (!hwcpu->mem_base_addr){ if(cpu_no == SDLA_CPU_B){ DEBUG_EVENT( "%s: Error: CPU #B not present on adapter\n", hw->devname); @@ -5469,19 +6820,19 @@ static int sdla_memory_map(sdlahw_t* hw, int cpu_no) goto aft_pci_error; } - if (!(hw->status & SDLA_MEM_MAPPED)){ + if (!(hwcpu->status & SDLA_MEM_MAPPED)){ /* map the physical PCI memory to virtual memory */ sdla_bus_space_map(hw, 0x0, - hw->memory, - &hw->dpmbase); - if (!hw->dpmbase){ + hwcpu->memory, + &hwcpu->dpmbase); + if (!hwcpu->dpmbase){ DEBUG_EVENT( "%s: Error: AFT PCI virtual memory ioremap failed\n", hw->devname); err = -EINVAL; goto aft_pci_error; } - hw->status |= SDLA_MEM_MAPPED; + hwcpu->status |= SDLA_MEM_MAPPED; } sdla_pci_set_master(hw); @@ -5501,10 +6852,18 @@ aft_pci_error: static int sdla_memory_unmap(sdlahw_t* hw) { sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + +#if defined(__WINDOWS__) + return 0; +#endif + switch (hwcard->type){ #if defined(WAN_ISA_SUPPORT) case SDLA_S508: @@ -5517,33 +6876,32 @@ static int sdla_memory_unmap(sdlahw_t* hw) DEBUG_TEST("NCDEBUG: MEMORY UNMAPPING AFT\n"); /* free up the allocated virtual memory */ - if (hw->status & SDLA_MEM_MAPPED){ + if (hwcpu->status & SDLA_MEM_MAPPED){ sdla_bus_space_unmap( hw, - hw->dpmbase, - hw->memory); - hw->status &= ~SDLA_MEM_MAPPED; + hwcpu->dpmbase, + hwcpu->memory); + hwcpu->status &= ~SDLA_MEM_MAPPED; } - if (hw->status & SDLA_MEM_RESERVED){ + if (hwcpu->status & SDLA_MEM_RESERVED){ #if defined(__LINUX__) - pci_release_region(hw->hwcard->pci_dev,(hw->cpu_no == SDLA_CPU_A)?0:1); + pci_release_region(hwcard->pci_dev,(hwcpu->cpu_no == SDLA_CPU_A)?0:1); #else sdla_release_mem_region( hw, - hw->mem_base_addr, - hw->memory); + hwcpu->mem_base_addr, + hwcpu->memory); #endif - hw->status &= ~SDLA_MEM_RESERVED; + hwcpu->status &= ~SDLA_MEM_RESERVED; } - if (hw->status & SDLA_PCI_ENABLE){ + if (hwcpu->status & SDLA_PCI_ENABLE){ /* FIXME: No allowed to do this because bar1 might * still be used. Need a pci dev counter */ /* sdla_pci_disable_device(hw); */ - hw->status &= ~SDLA_PCI_ENABLE; + hwcpu->status &= ~SDLA_PCI_ENABLE; } - break; } return 0; @@ -5555,25 +6913,28 @@ static int sdla_memory_unmap(sdlahw_t* hw) static int sdla_detect_aft(sdlahw_t* hw) { sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; int err; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; - if ((err = sdla_memory_map(hw, hw->cpu_no))){ + if ((err = sdla_memory_map(hw, hwcpu->cpu_no))){ return err; } DEBUG_EVENT( "%s: AFT PCI memory at 0x%lX\n", - hw->devname, (unsigned long)hw->mem_base_addr); + hw->devname, (unsigned long)hwcpu->mem_base_addr); #if defined(__LINUX__) - hw->irq = hwcard->pci_dev->irq; + hwcpu->irq = hwcard->pci_dev->irq; #else - sdla_pci_read_config_byte(hw, PCI_INT_LINE_BYTE, (u8*)&hw->irq); + sdla_pci_read_config_byte(hw, PCI_INT_LINE_BYTE, (u8*)&hwcpu->irq); #endif - if(hw->irq == PCI_IRQ_NOT_ALLOCATED) { + if(hwcpu->irq == PCI_IRQ_NOT_ALLOCATED) { sdla_memory_unmap(hw); DEBUG_EVENT( "%s: IRQ not allocated to AFT adapter\n", hw->devname); @@ -5581,16 +6942,88 @@ static int sdla_detect_aft(sdlahw_t* hw) } DEBUG_EVENT( "%s: IRQ %d allocated to the AFT PCI card\n", - hw->devname, hw->irq); + hw->devname, hwcpu->irq); /* Set PCI Latency of 0xFF*/ - sdla_pci_write_config_dword(hw, XILINX_PCI_LATENCY_REG, XILINX_PCI_LATENCY); - + sdla_pci_write_config_dword(hw, XILINX_PCI_LATENCY_REG, XILINX_PCI_LATENCY); return 0; } +/*============================================================================ +** Compare current hw adapter for auto pci configuration. +**/ +static int sdla_cmp_adapter_auto(sdlahw_t *hw, wandev_conf_t* conf) +{ + sdlahw_cpu_t *hwcpu = NULL; + int cpu_no = SDLA_CPU_A; + + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + switch(conf->card_type){ + case WANOPT_S51X: + case WANOPT_ADSL: + case WANOPT_AFT: + case WANOPT_AFT300: + case WANOPT_AFT_ANALOG: + case WANOPT_AFT_ISDN: + case WANOPT_AFT_56K: + case WANOPT_AFT101: + case WANOPT_AFT102: + case WANOPT_AFT104: + case WANOPT_AFT108: + + if (hwcpu->cpu_no == cpu_no && + conf->card_type == WANOPT_AFT && + hwcpu->hwcard->cfg_type == WANOPT_AFT101) { + /* Remap the card type to standard + A104 Shark style. We are allowing + and old config file for A101/2-SH */ + conf->config_id = WANCONFIG_AFT_TE1; + conf->card_type = WANOPT_AFT104; + conf->fe_cfg.line_no=1; + return 0; + } + + /* Allow old A102 config for A102 SHARK */ + if (hwcpu->cpu_no == cpu_no && + conf->card_type == WANOPT_AFT && + hwcpu->hwcard->cfg_type == WANOPT_AFT102) { + /* Remap the card type to standard + A104 Shark style. We are allowing + and old config file for A101/2-SH */ + conf->config_id = WANCONFIG_AFT_TE1; + conf->card_type = WANOPT_AFT104; + if (cpu_no == SDLA_CPU_A) { + conf->fe_cfg.line_no=1; + } else { + conf->fe_cfg.line_no=2; + } + return 0; + } + + if (conf->config_id == WANCONFIG_AFT_TE1){ + if (hwcpu->cpu_no == cpu_no && + hw->port_no == conf->fe_cfg.line_no-1 && + (hwcpu->hwcard->cfg_type == WANOPT_AFT101 || + hwcpu->hwcard->cfg_type == WANOPT_AFT102 || + hwcpu->hwcard->cfg_type == WANOPT_AFT104 || + hwcpu->hwcard->cfg_type == WANOPT_AFT108)) { + return 0; + } + }else{ + if (hwcpu->cpu_no == cpu_no && + hwcpu->hwcard->cfg_type == conf->card_type){ + return 0; + } + } + break; + } + return 1; +} + /*============================================================================ * Find the S514 PCI adapter in the PCI bus. * If conf argument is NULL, return fisrt not used adapter (CONFIG_PRODUCT_WANPIPE_GENERIC) @@ -5598,7 +7031,8 @@ static int sdla_detect_aft(sdlahw_t* hw) */ static sdlahw_t* sdla_find_adapter(wandev_conf_t* conf, char* devname) { - sdlahw_t* hw = NULL; + sdlahw_t *hw = NULL; + sdlahw_cpu_t *hwcpu = NULL; int cpu_no = SDLA_CPU_A; if (conf && conf->S514_CPU_no[0] == 'B'){ @@ -5609,180 +7043,156 @@ static sdlahw_t* sdla_find_adapter(wandev_conf_t* conf, char* devname) WAN_LIST_FOREACH(hw, &sdlahw_head, next){ + WAN_ASSERT_RC(hw->hwcpu == NULL, NULL); + hwcpu = hw->hwcpu; if (conf == NULL){ - if (hw->used < hw->max_ports){ + if (hw->used == 0/*hwcpu->used < hwcpu->max_ports*/){ return hw; } continue; } + if (conf->auto_pci_cfg){ + if (!sdla_cmp_adapter_auto(hw, conf)){ + goto adapter_found; + } + } switch(conf->card_type){ #if defined(WAN_ISA_SUPPORT) case WANOPT_S50X: - if (hw->hwcard->ioport == conf->ioport){ + if (hwcpu->hwcard->ioport == conf->ioport){ goto adapter_found; } break; #endif - case WANOPT_S51X: case WANOPT_ADSL: - case WANOPT_AFT: case WANOPT_AFT300: case WANOPT_AFT_ANALOG: case WANOPT_AFT_56K: - if (conf->auto_pci_cfg){ - /* Allow old A101 config for A101 SHARK */ - if (hw->cpu_no == cpu_no && - conf->card_type == WANOPT_AFT && - hw->hwcard->cfg_type == WANOPT_AFT101) { - /* Remap the card type to standard - A104 Shark style. We are allowing - and old config file for A101/2-SH */ - conf->config_id = WANCONFIG_AFT_TE1; - conf->card_type = WANOPT_AFT104; - conf->fe_cfg.line_no=1; - goto adapter_found; - } + if ((hwcpu->hwcard->slot_no == conf->PCI_slot_no) && + (hwcpu->hwcard->bus_no == conf->pci_bus_no) && + (hwcpu->hwcard->cfg_type == conf->card_type)){ + goto adapter_found; + } + break; - /* Allow old A102 config for A102 SHARK */ - if (hw->cpu_no == cpu_no && - conf->card_type == WANOPT_AFT && - hw->hwcard->cfg_type == WANOPT_AFT102) { - /* Remap the card type to standard - A104 Shark style. We are allowing - and old config file for A101/2-SH */ - conf->config_id = WANCONFIG_AFT_TE1; - conf->card_type = WANOPT_AFT104; - if (cpu_no == SDLA_CPU_A) { - conf->fe_cfg.line_no=1; - } else { - conf->fe_cfg.line_no=2; - } - goto adapter_found; - } + case WANOPT_AFT_SERIAL: - if (conf->card_type == WANOPT_S51X && - IS_56K_MEDIA(&conf->fe_cfg) && - hw->hwcard->cfg_type == WANOPT_AFT_56K) { - /* Remap the old 56K card type to standard - AFT 56K Shark style. We are allowing - and old config file for 56K */ - conf->card_type = WANOPT_AFT_56K; - conf->config_id = WANCONFIG_AFT_56K; - conf->fe_cfg.line_no=1; - goto adapter_found; - } + if ((hwcpu->hwcard->slot_no == conf->PCI_slot_no) && + (hwcpu->hwcard->bus_no == conf->pci_bus_no) && + (hwcpu->hwcard->cfg_type == conf->card_type) && + (hw->port_no == conf->fe_cfg.line_no-1)){ + goto adapter_found; + } + break; - if (hw->cpu_no == cpu_no && - hw->hwcard->cfg_type == conf->card_type){ + case WANOPT_S51X: + if (IS_56K_MEDIA(&conf->fe_cfg) && + hwcpu->hwcard->slot_no == conf->PCI_slot_no && + hwcpu->hwcard->bus_no == conf->pci_bus_no && + hwcpu->hwcard->cfg_type == WANOPT_AFT_56K) { + /* Remap the old 56K card type to standard + AFT 56K Shark style. We are allowing + and old config file for 56K */ + conf->card_type = WANOPT_AFT_56K; + conf->config_id = WANCONFIG_AFT_56K; + conf->fe_cfg.line_no=1; + goto adapter_found; + }else if ((hwcpu->hwcard->slot_no == conf->PCI_slot_no) && + (hwcpu->hwcard->bus_no == conf->pci_bus_no) && + (hwcpu->cpu_no == cpu_no) && + (hw->port_no == conf->comm_port) && + (hwcpu->hwcard->cfg_type == conf->card_type)){ goto adapter_found; - } - }else{ + } + break; - /* Allow old A101 config for A101 SHARK */ - if (conf->card_type == WANOPT_AFT && - hw->hwcard->slot_no == conf->PCI_slot_no && - hw->hwcard->bus_no == conf->pci_bus_no && - hw->hwcard->cfg_type == WANOPT_AFT101) { - /* Remap the card type to standard - A104 Shark style. We are allowing - and old config file for A101/2-SH */ - conf->config_id = WANCONFIG_AFT_TE1; - conf->card_type = WANOPT_AFT104; + case WANOPT_AFT: + /* Allow old A101 config for A101 SHARK */ + if (conf->card_type == WANOPT_AFT && + hwcpu->hwcard->slot_no == conf->PCI_slot_no && + hwcpu->hwcard->bus_no == conf->pci_bus_no && + hwcpu->hwcard->cfg_type == WANOPT_AFT101) { + /* Remap the card type to standard + A104 Shark style. We are allowing + and old config file for A101/2-SH */ + conf->config_id = WANCONFIG_AFT_TE1; + conf->card_type = WANOPT_AFT104; + conf->fe_cfg.line_no=1; + goto adapter_found; + } + + /* Allow old A102 config for A102 SHARK */ + if (conf->card_type == WANOPT_AFT && + hwcpu->hwcard->slot_no == conf->PCI_slot_no && + hwcpu->hwcard->bus_no == conf->pci_bus_no && + hwcpu->hwcard->cfg_type == WANOPT_AFT102) { + /* Remap the card type to standard + A104 Shark style. We are allowing + and old config file for A101/2-SH */ + conf->config_id = WANCONFIG_AFT_TE1; + conf->card_type = WANOPT_AFT104; + if (cpu_no == SDLA_CPU_A) { conf->fe_cfg.line_no=1; - goto adapter_found; - - } - - /* Allow old A102 config for A102 SHARK */ - if (conf->card_type == WANOPT_AFT && - hw->hwcard->slot_no == conf->PCI_slot_no && - hw->hwcard->bus_no == conf->pci_bus_no && - hw->hwcard->cfg_type == WANOPT_AFT102) { - /* Remap the card type to standard - A104 Shark style. We are allowing - and old config file for A101/2-SH */ - conf->config_id = WANCONFIG_AFT_TE1; - conf->card_type = WANOPT_AFT104; - if (cpu_no == SDLA_CPU_A) { - conf->fe_cfg.line_no=1; - } else { - conf->fe_cfg.line_no=2; - } - goto adapter_found; + } else { + conf->fe_cfg.line_no=2; } + goto adapter_found; + } - if (conf->card_type == WANOPT_S51X && - IS_56K_MEDIA(&conf->fe_cfg) && - hw->hwcard->slot_no == conf->PCI_slot_no && - hw->hwcard->bus_no == conf->pci_bus_no && - hw->hwcard->cfg_type == WANOPT_AFT_56K) { - /* Remap the old 56K card type to standard - AFT 56K Shark style. We are allowing - and old config file for 56K */ - conf->card_type = WANOPT_AFT_56K; - conf->config_id = WANCONFIG_AFT_56K; - conf->fe_cfg.line_no=1; - goto adapter_found; - - } + if (conf->card_type == WANOPT_S51X && + IS_56K_MEDIA(&conf->fe_cfg) && + hwcpu->hwcard->slot_no == conf->PCI_slot_no && + hwcpu->hwcard->bus_no == conf->pci_bus_no && + hwcpu->hwcard->cfg_type == WANOPT_AFT_56K) { + /* Remap the old 56K card type to standard + AFT 56K Shark style. We are allowing + and old config file for 56K */ + conf->card_type = WANOPT_AFT_56K; + conf->config_id = WANCONFIG_AFT_56K; + conf->fe_cfg.line_no=1; + goto adapter_found; + + } - - if ((hw->hwcard->slot_no == conf->PCI_slot_no) && - (hw->hwcard->bus_no == conf->pci_bus_no) && - (hw->cpu_no == cpu_no) && - (hw->hwcard->cfg_type == conf->card_type)){ - goto adapter_found; - } + if ((hwcpu->hwcard->slot_no == conf->PCI_slot_no) && + (hwcpu->hwcard->bus_no == conf->pci_bus_no) && + (hwcpu->cpu_no == cpu_no) && + (hwcpu->hwcard->cfg_type == conf->card_type)){ + goto adapter_found; } break; + case WANOPT_AFT_ISDN: + if ((hwcpu->hwcard->slot_no == conf->PCI_slot_no) && + (hwcpu->hwcard->bus_no == conf->pci_bus_no) && + (hw->port_no == conf->fe_cfg.line_no-1) && + (hwcpu->hwcard->cfg_type == conf->card_type)){ + goto adapter_found; + } + break; + case WANOPT_AFT101: case WANOPT_AFT102: case WANOPT_AFT104: case WANOPT_AFT108: - if (conf->auto_pci_cfg){ - - switch (hw->hwcard->cfg_type){ - case WANOPT_AFT101: - case WANOPT_AFT102: - case WANOPT_AFT104: - case WANOPT_AFT108: - goto adapter_found; - break; - default: - break; - } - }else{ - - if ((hw->hwcard->slot_no == conf->PCI_slot_no) && - (hw->hwcard->bus_no == conf->pci_bus_no)){ - - switch (hw->hwcard->cfg_type){ - case WANOPT_AFT101: - case WANOPT_AFT102: - case WANOPT_AFT104: - case WANOPT_AFT108: - goto adapter_found; - break; - default: - break; - } - } + if ((hwcpu->hwcard->slot_no == conf->PCI_slot_no) && + (hwcpu->hwcard->bus_no == conf->pci_bus_no) && + (hw->port_no == conf->fe_cfg.line_no-1)){ + goto adapter_found; } break; - default: DEBUG_EVENT("%s: Unknown card type (%x) requested by user!\n", devname, conf->card_type); return NULL; } - } + }/* WAN_LIST_FOREACH */ adapter_found: - if (hw){ - switch(hw->hwcard->adptr_type){ + if (hw && hwcpu){ + switch(hwcpu->hwcard->adptr_type){ case S5144_ADPTR_1_CPU_T1E1: case S5147_ADPTR_2_CPU_T1E1: case A101_ADPTR_1TE1: @@ -5792,8 +7202,19 @@ adapter_found: conf->comm_port = 0; conf->fe_cfg.line_no = 0; break; +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI) + case AFT_ADPTR_ISDN: + if (conf->fe_cfg.line_no < 1 || conf->fe_cfg.line_no > MAX_BRI_LINES){ + DEBUG_EVENT("%s: Error, Invalid port selected %d (Min=1 Max=%d)\n", + devname, conf->fe_cfg.line_no, MAX_BRI_LINES); + return NULL; + } + conf->fe_cfg.line_no--; + conf->comm_port = conf->fe_cfg.line_no; + break; +#endif case A101_ADPTR_2TE1: - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ + if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ conf->comm_port = 0; conf->fe_cfg.line_no = 0; break; @@ -5824,8 +7245,28 @@ adapter_found: conf->fe_cfg.line_no--; conf->comm_port = conf->fe_cfg.line_no; break; + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + if (conf->fe_cfg.line_no < 1 || conf->fe_cfg.line_no > 2){ + DEBUG_EVENT("%s: Error, Invalid port selected %d (Min=1 Max=2)\n", + devname, conf->fe_cfg.line_no); + return NULL; + } + conf->fe_cfg.line_no--; + conf->comm_port = conf->fe_cfg.line_no; + break; + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_RS232: + if (conf->fe_cfg.line_no < 1 || conf->fe_cfg.line_no > 4){ + DEBUG_EVENT("%s: Error, Invalid port selected %d (Min=1 Max=4)\n", + devname, conf->fe_cfg.line_no); + return NULL; + } + conf->fe_cfg.line_no--; + conf->comm_port = conf->fe_cfg.line_no; + break; } - if (hw->hwport[conf->comm_port].used == 0){ + if (hw->used == 0){ return hw; } switch(conf->card_type){ @@ -5846,11 +7287,14 @@ adapter_found: case WANOPT_AFT108: case WANOPT_AFT300: case WANOPT_AFT_ANALOG: + case WANOPT_AFT_ISDN: case WANOPT_AFT_56K: - switch(hw->hwcard->adptr_type){ + case WANOPT_AFT_SERIAL: + + switch(hwcpu->hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ + if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ DEBUG_EVENT( "%s: Error, %s resources busy: (bus #%d, slot #%d, cpu %c)\n", devname, @@ -5903,7 +7347,7 @@ adapter_found: break; } return NULL; - } + }/* if (hw) */ if (conf){ switch(conf->card_type){ @@ -5939,7 +7383,10 @@ adapter_found: case WANOPT_AFT108: case WANOPT_AFT300: case WANOPT_AFT_ANALOG: + case WANOPT_AFT_ISDN: case WANOPT_AFT_56K: + case WANOPT_AFT_SERIAL: + DEBUG_EVENT( "%s: Error, %s card not found on bus #%d, slot #%d, cpu %c, line %d\n", devname, @@ -5959,7 +7406,7 @@ adapter_found: }else{ DEBUG_EVENT("%s: Error, Failed to find new Sangoma card!\n", devname); - } + }/* if (conf) */ return NULL; } @@ -5978,11 +7425,14 @@ adapter_found: static int sdla_detect (sdlahw_t* hw) { sdlahw_card_t *hwcard = NULL; + sdlahw_cpu_t *hwcpu; int err = 0; WAN_ASSERT(hw == NULL); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; switch (hwcard->type){ #if defined(WAN_ISA_SUPPORT) case SDLA_S508: @@ -6020,13 +7470,17 @@ static int sdla_detect (sdlahw_t* hw) static int sdla_is_te1(void* phw) { - sdlahw_card_t* hwcard = NULL; - sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard = NULL; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + switch(hwcard->adptr_type){ case S5144_ADPTR_1_CPU_T1E1: case S5147_ADPTR_2_CPU_T1E1: @@ -6043,13 +7497,16 @@ static int sdla_is_te1(void* phw) } static int sdla_is_56k(void* phw) { - sdlahw_card_t* hwcard = NULL; - sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard = NULL; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; if (hwcard->adptr_type == S5145_ADPTR_1_CPU_56K){ return 0; } @@ -6062,12 +7519,16 @@ static int sdla_is_56k(void* phw) static int sdla_check_mismatch(void* phw, unsigned char media) { sdlahw_card_t* hwcard = NULL; + sdlahw_cpu_t* hwcpu = NULL; sdlahw_t* hw = (sdlahw_t*)phw; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + if (media == WAN_MEDIA_T1 || media == WAN_MEDIA_E1){ if (hwcard->adptr_type != S5144_ADPTR_1_CPU_T1E1 && @@ -6105,8 +7566,27 @@ static int sdla_is_same_hwcard(void* phw1, void *phw2) { sdlahw_t* hw1 = (sdlahw_t*)phw1; sdlahw_t* hw2 = (sdlahw_t*)phw2; + sdlahw_cpu_t *hwcpu1, *hwcpu2; - if (hw1->hwcard == hw2->hwcard){ + WAN_ASSERT_RC(hw1->hwcpu == NULL, 0); + WAN_ASSERT_RC(hw2->hwcpu == NULL, 0); + hwcpu1 = hw1->hwcpu; + hwcpu2 = hw2->hwcpu; + + if (hwcpu1->hwcard == hwcpu2->hwcard){ + return 1; + } + return 0; +} + +static int sdla_is_same_hwcpu(void* phw1, void *phw2) +{ + sdlahw_t* hw1 = (sdlahw_t*)phw1; + sdlahw_t* hw2 = (sdlahw_t*)phw2; + + WAN_ASSERT_RC(hw1 == NULL, 0); + WAN_ASSERT_RC(hw2 == NULL, 0); + if (hw1->hwcpu == hw2->hwcpu){ return 1; } return 0; @@ -6122,41 +7602,85 @@ static int sdla_is_same_hwcard(void* phw1, void *phw2) static int sdla_set_intrhand(void* phw, wan_pci_ifunc_t *isr_func, void* arg, int line_no) { + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; sdlahw_t* hw = (sdlahw_t*)phw; +#if defined(SDLA_AUTO_PROBE) + struct sdla_softc *adapter; +#else sdladev_t* adapter = NULL; +#endif #if defined(__FreeBSD__) && (__FreeBSD_version >= 450000) int error = 0; #endif + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; SDLA_MAGIC(hw); - adapter = (sdladev_t*)hw->dev; + +#if defined(SDLA_AUTO_PROBE) + adapter = device_get_softc(hwcard->pci_dev); +# if __FreeBSD_version < 700031 + error = bus_setup_intr( + hwcard->pci_dev, + adapter->irq_res, + INTR_TYPE_NET/*|INTR_MPSAFE*/, + isr_func, arg, &hwcpu->irqh[line_no]); +# else + error = bus_setup_intr( + hwcard->pci_dev, + adapter->irq_res, + INTR_TYPE_NET/*|INTR_MPSAFE*/,NULL, + isr_func, arg, &hwcpu->irqh[line_no]); +# endif + if (error){ + DEBUG_EVENT( + "%s: Failed set interrupt handler for Port %d (er=%d)!\n", + device_get_name(hwcard->pci_dev), line_no, + error); + return error; + } +#else + adapter = (sdladev_t*)hwcpu->sdla_dev; WAN_ASSERT(adapter == NULL); WAN_ASSERT(adapter->sc == NULL); -#if defined(__FreeBSD__) && (__FreeBSD_version >= 450000) +# if defined(__FreeBSD__) && (__FreeBSD_version >= 450000) +# if __FreeBSD_version < 700031 error = bus_setup_intr( adapter->dev, - adapter->sc->irq_res, - INTR_TYPE_NET, - isr_func, - arg, - &hw->irqh[line_no]); + adapter->sc->irq_res, + INTR_TYPE_NET, isr_func, arg, + &hwcpu->irqh[line_no]); +# else + error = bus_setup_intr( + adapter->dev, + adapter->sc->irq_res, + INTR_TYPE_NET, NULL, isr_func, arg, + &hwcpu->irqh[line_no]); +# endif if (error){ - DEBUG_EVENT("%s: Failed set interrupt handler for CPU A!\n", - device_get_name(adapter->dev)); + DEBUG_EVENT( + "%s: Failed set interrupt handler for Port %d (er=%d)!\n", + device_get_name(adapter->dev), line_no, + error); return error; } -#else +# else if (adapter->intr_arg[line_no].ready){ adapter->intr_arg[line_no].isr = isr_func; adapter->intr_arg[line_no].arg = arg; }else{ return -EINVAL; } +# endif #endif - return 0; + return 0; } #endif @@ -6169,26 +7693,57 @@ sdla_set_intrhand(void* phw, wan_pci_ifunc_t *isr_func, void* arg, int line_no) #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) static int sdla_restore_intrhand(void* phw, int line_no) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdladev_t* adapter = NULL; - + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; +#if defined(SDLA_AUTO_PROBE) + struct sdla_softc *adapter; +#else + sdladev_t *adapter = NULL; +#endif +#if defined(__FreeBSD__) && (__FreeBSD_version >= 450000) + int error; +#endif + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard= hwcpu->hwcard; SDLA_MAGIC(hw); - adapter = (sdladev_t*)hw->dev; + +#if defined(SDLA_AUTO_PROBE) + adapter = device_get_softc(hwcard->pci_dev); + error = bus_teardown_intr( + hwcard->pci_dev,adapter->irq_res,hwcpu->irqh[line_no]); + if (error){ + DEBUG_EVENT( + "%s: Failed unregister interrupt handler for Port %d (%d)!\n", + device_get_name(hwcard->pci_dev), line_no, + error); + return -EINVAL; + } + hwcpu->irqh[line_no] = NULL; + +#else + + adapter = (sdladev_t*)hwcpu->sdla_dev; WAN_ASSERT(adapter == NULL); WAN_ASSERT(adapter->sc == NULL); -#if defined(__FreeBSD__) && (__FreeBSD_version >= 450000) - - if (bus_teardown_intr(adapter->dev, adapter->sc->irq_res, hw->irqh[line_no])){ - DEBUG_EVENT("%s: Failed unregister interrupt handler!\n", - device_get_name(adapter->dev)); +# if defined(__FreeBSD__) && (__FreeBSD_version >= 450000) + error = bus_teardown_intr(adapter->dev, adapter->sc->irq_res, hwcpu->irqh[line_no]); + if (error){ + DEBUG_EVENT( + "%s: Failed unregister interrupt handler for Port %d (%d)!\n", + device_get_name(adapter->dev), line_no, + error); return -EINVAL; - } -#else +# else /* Restore local vector */ adapter->intr_arg[line_no].isr = NULL; adapter->intr_arg[line_no].arg = NULL; +# endif #endif return 0; } @@ -6199,51 +7754,55 @@ static int sdla_restore_intrhand(void* phw, int line_no) static int sdla_getcfg(void* phw, int type, void* value) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t* hwcpu; sdlahw_card_t* hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + switch(type){ case SDLA_HWTYPE: - *(u16*)value = hwcard->hw_type; + *(u16*)value = (u16)hwcard->hw_type; break; case SDLA_CARDTYPE: - *(u16*)value = hwcard->type; + *(u16*)value = (u16)hwcard->type; break; case SDLA_MEMBASE: - *(sdla_mem_handle_t*)value = hw->dpmbase; + *(sdla_mem_handle_t*)value = hwcpu->dpmbase; break; case SDLA_MEMEND: - *(u32*)value = ((unsigned long)hw->dpmbase + hw->dpmsize - 1); + *(u32*)value = ((unsigned long)hwcpu->dpmbase + hwcpu->dpmsize - 1); break; case SDLA_MEMSIZE: - *(u16*)value = hw->dpmsize; + *(u16*)value = (u16)hwcpu->dpmsize; break; case SDLA_MEMORY: - *(u32*)value = hw->memory; + *(u32*)value = hwcpu->memory; break; case SDLA_IRQ: - *(u16*)value = hw->irq; + *(u16*)value = (u16)hwcpu->irq; break; case SDLA_IOPORT: - *(u16*)value = hwcard->ioport; + *(u16*)value = (u16)hwcard->ioport; break; case SDLA_IORANGE: - *(u16*)value = hw->io_range; + *(u16*)value = (u16)hwcpu->io_range; break; case SDLA_ADAPTERTYPE: - *(u16*)value = hwcard->adptr_type; + *(u16*)value = (u16)hwcard->adptr_type; break; case SDLA_CPU: - *(u16*)value = hw->cpu_no; + *(u16*)value = (u16)hwcpu->cpu_no; break; case SDLA_SLOT: - *(u16*)value = hwcard->slot_no; + *(u16*)value = (u16)hwcard->slot_no; break; case SDLA_BUS: - *(u16*)value = hwcard->bus_no; + *(u16*)value = (u16)hwcard->bus_no; break; case SDLA_DMATAG: #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -6256,7 +7815,7 @@ static int sdla_getcfg(void* phw, int type, void* value) *(u8*)value = hwcard->pci_extra_ver; break; case SDLA_BASEADDR: - *(u32*)value = hw->mem_base_addr; + *(u32*)value = hwcpu->mem_base_addr; break; case SDLA_COREREV: *(u8*)value = hwcard->core_rev; @@ -6264,8 +7823,12 @@ static int sdla_getcfg(void* phw, int type, void* value) case SDLA_COREID: *(u8*)value = hwcard->core_id; break; - case SDLA_USEDCNT: - *(u32*)value = hw->used; + case SDLA_HWCPU_USEDCNT: +#if defined(__WINDOWS__) + *(u32*)value = get_usage_counter(hw->p_sdla); +#else + *(u32*)value = hwcpu->used; +#endif break; case SDLA_ADAPTERSUBTYPE: *(u8*)value = hwcard->adptr_subtype; @@ -6273,19 +7836,65 @@ static int sdla_getcfg(void* phw, int type, void* value) case SDLA_HWEC_NO: *(u16*)value = hwcard->hwec_chan_no; break; + case SDLA_PCIEXPRESS: + *(u8*)value = (u8)sdla_is_pciexpress(hw); + break; + case SDLA_PORTS_NO: + *(u16*)value = (u16)hwcpu->max_ports; + break; + case SDLA_PORT_MAP: + *(u32*)value = hwcpu->port_map; + break; + case SDLA_HWPORTUSED: + *(u16*)value = (u16)hw->used; + DEBUG_BRI("SDLA_HWPORTUSED: %d\n", hw->used); + break; + case SDLA_HWPORTREG: + *(u16*)value = (u16)hw->hwcpu->reg_port[hw->port_no]; + break; + case SDLA_RECOVERY_CLOCK_FLAG: + *(u32*)value = hwcard->recovery_clock_flag; + break; + case SDLA_HWPORTREGMAP: + *(u32*)value = (u32)hw->hwcpu->reg_port_map; + break; } return 0; } -static int sdla_get_hwcard(void* phw, void** phwcard) +static int sdla_setcfg(void* phw, int type, void* value) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t* hwcpu; + sdlahw_card_t* hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; - *phwcard = hw->hwcard; + switch(type){ + case SDLA_RECOVERY_CLOCK_FLAG: + hwcard->recovery_clock_flag = *(u32*)value; + break; + } + return 0; +} + +static int sdla_get_hwcard(void* phw, void** phwcard) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + SDLA_MAGIC(hw); + + *phwcard = hwcpu->hwcard; return 0; } @@ -6297,8 +7906,8 @@ static int sdla_get_hwprobe(void* phw, int port, void** hwinfo) WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - if (hw->hwport[port].hwprobe){ - *hwinfo = hw->hwport[port].hwprobe->hw_info; + if (hw->hwprobe){ + *hwinfo = hw->hwprobe->hw_info; } return 0; } @@ -6311,6 +7920,7 @@ static int sdla_get_hwprobe(void* phw, int port, void** hwinfo) ***************************************************************************** */ +#if defined(WAN_ISA_SUPPORT) /*============================================================================ * Get option's index into the options list. * Return option's index (1 .. N) or zero if option is invalid. @@ -6324,6 +7934,7 @@ static int sdla_get_option_index (unsigned* optlist, unsigned optval) return i; return 0; } +#endif /*============================================================================ * Calculate 16-bit CRC using CCITT polynomial. @@ -6349,16 +7960,22 @@ static unsigned short sdla_checksum (unsigned char* buf, unsigned len) static int sdla_io_read_1(void* phw, unsigned int offset, u8* value) { - sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; WAN_ASSERT2(hw == NULL, 0); - if (!(hw->status & SDLA_IO_MAPPED)) return 0; + WAN_ASSERT2(hw->hwcpu == NULL, 0); + hwcpu = hw->hwcpu; + + if (!(hwcpu->status & SDLA_IO_MAPPED)) return 0; #if defined(__FreeBSD__) - *value = readb ((u8*)hw->vector + offset); + *value = readb ((u8*)hwcpu->vector + offset); #elif defined(__NetBSD__) || defined(__OpenBSD__) - *value = bus_space_read_1(hw->hwcard->memt, hw->vector, offset); + *value = bus_space_read_1(hwcpu->hwcard->memt, hwcpu->vector, offset); #elif defined(__LINUX__) - *value = wp_readb((hw->vector + offset)); + *value = wp_readb((hwcpu->vector + offset)); +#elif defined(__WINDOWS__) + *value = READ_REGISTER_UCHAR((PUCHAR)((PUCHAR)hwcpu->vector + offset)); #else # warning "sdla_io_read_1: Not supported yet!" #endif @@ -6367,16 +7984,22 @@ static int sdla_io_read_1(void* phw, unsigned int offset, u8* value) static int sdla_io_write_1(void* phw, unsigned int offset, u8 value) { - sdlahw_t* hw = (sdlahw_t*)phw; - + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + WAN_ASSERT(hw == NULL); - if (!(hw->status & SDLA_IO_MAPPED)) return 0; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + if (!(hwcpu->status & SDLA_IO_MAPPED)) return 0; #if defined(__FreeBSD__) - writeb ((u8*)hw->vector+offset, value); + writeb ((u8*)hwcpu->vector+offset, value); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_write_1(hw->hwcard->memt, hw->vector, offset, value); + bus_space_write_1(hwcpu->hwcard->memt, hwcpu->vector, offset, value); #elif defined(__LINUX__) - wp_writeb(value, hw->vector + offset); + wp_writeb(value, hwcpu->vector + offset); +#elif defined(__WINDOWS__) + WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)hwcpu->vector + offset), value); #else # warning "sdla_io_write_1: Not supported yet!" #endif @@ -6386,16 +8009,23 @@ static int sdla_io_write_1(void* phw, unsigned int offset, u8 value) int sdla_bus_write_1(void* phw, unsigned int offset, u8 value) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - if (!(hw->status & SDLA_MEM_MAPPED)) return 0; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; #if defined(__FreeBSD__) - writeb(((u8*)hw->dpmbase + offset), value); + writeb(((u8*)hwcpu->dpmbase + offset), value); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_write_1(hw->hwcard->memt, hw->dpmbase, offset, value); + bus_space_write_1(hwcpu->hwcard->memt, hwcpu->dpmbase, offset, value); #elif defined(__LINUX__) - wp_writeb(value, hw->dpmbase + offset); + /*DEBUG_BRI("%s(): offset: 0x%X, value: 0x%X\n", __FUNCTION__, offset, value);*/ + wp_writeb(value, hwcpu->dpmbase + offset); +#elif defined(__WINDOWS__) + WRITE_REGISTER_UCHAR((PUCHAR)((PUCHAR)hwcpu->dpmbase + offset), value); #else # warning "sdla_bus_write_1: Not supported yet!" #endif @@ -6405,16 +8035,23 @@ int sdla_bus_write_1(void* phw, unsigned int offset, u8 value) int sdla_bus_write_2(void* phw, unsigned int offset, u16 value) { sdlahw_t* hw = (sdlahw_t*)phw; - + sdlahw_cpu_t *hwcpu; + WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - if (!(hw->status & SDLA_MEM_MAPPED)) return 0; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; #if defined(__FreeBSD__) - writew(((u8*)hw->dpmbase + offset), value); + writew(((u8*)hwcpu->dpmbase + offset), value); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_write_2(hw->hwcard->memt, hw->dpmbase, offset, value); + bus_space_write_2(hwcpu->hwcard->memt, hwcpu->dpmbase, offset, value); #elif defined(__LINUX__) - wp_writew(value,hw->dpmbase+offset); + /*DEBUG_BRI("%s(): offset: 0x%X, value: 0x%X\n", __FUNCTION__, offset, value);*/ + wp_writew(value,hwcpu->dpmbase+offset); +#elif defined(__WINDOWS__) + WRITE_REGISTER_USHORT((PUSHORT)((PUCHAR)hwcpu->dpmbase + offset), value); #else # warning "sdla_bus_write_2: Not supported yet!" #endif @@ -6424,16 +8061,27 @@ int sdla_bus_write_2(void* phw, unsigned int offset, u16 value) int sdla_bus_write_4(void* phw, unsigned int offset, u32 value) { sdlahw_t* hw = (sdlahw_t*)phw; - + sdlahw_cpu_t *hwcpu; + WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - if (!(hw->status & SDLA_MEM_MAPPED)) return 0; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; + + DEBUG_TEST("%s(): Offset=0x%04X Data=0x%08X\n", __FUNCTION__, + offset, value); + #if defined(__FreeBSD__) - writel(((u8*)hw->dpmbase + offset), value); + writel(((u8*)hwcpu->dpmbase + offset), value); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_write_4(hw->hwcard->memt, hw->dpmbase, offset, value); + bus_space_write_4(hwcpu->hwcard->memt, hwcpu->dpmbase, offset, value); #elif defined(__LINUX__) - wp_writel(value,(u8*)hw->dpmbase + offset); + /*DEBUG_BRI("%s(): offset: 0x%X, value: 0x%X\n", __FUNCTION__, offset, value);*/ + wp_writel(value,(u8*)hwcpu->dpmbase + offset); +#elif defined(__WINDOWS__) + WRITE_REGISTER_ULONG((PULONG)((PUCHAR)hwcpu->dpmbase + offset), value); #else # warning "sdla_bus_write_4: Not supported yet!" #endif @@ -6443,16 +8091,22 @@ int sdla_bus_write_4(void* phw, unsigned int offset, u32 value) int sdla_bus_read_1(void* phw, unsigned int offset, u8* value) { sdlahw_t* hw = (sdlahw_t*)phw; - + sdlahw_cpu_t *hwcpu; + WAN_ASSERT2(hw == NULL, 0); SDLA_MAGIC(hw); - if (!(hw->status & SDLA_MEM_MAPPED)) return 0; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; #if defined(__FreeBSD__) - *value = readb(((u8*)hw->dpmbase + offset)); + *value = readb(((u8*)hwcpu->dpmbase + offset)); #elif defined(__NetBSD__) || defined(__OpenBSD__) - *value = bus_space_read_1(hw->hwcard->memt, hw->dpmbase, offset); + *value = bus_space_read_1(hwcpu->hwcard->memt, hwcpu->dpmbase, offset); #elif defined(__LINUX__) - *value = wp_readb((hw->dpmbase + offset)); + *value = wp_readb((hwcpu->dpmbase + offset)); +#elif defined(__WINDOWS__) + *value = READ_REGISTER_UCHAR((PUCHAR)((PUCHAR)hwcpu->dpmbase + offset)); #else # warning "sdla_bus_read_1: Not supported yet!" #endif @@ -6461,17 +8115,23 @@ int sdla_bus_read_1(void* phw, unsigned int offset, u8* value) int sdla_bus_read_2(void* phw, unsigned int offset, u16* value) { - sdlahw_t* hw = (sdlahw_t*)phw; - + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + WAN_ASSERT2(hw == NULL, 0); SDLA_MAGIC(hw); - if (!(hw->status & SDLA_MEM_MAPPED)) return 0; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; #if defined(__FreeBSD__) - *value = readw(((u8*)hw->dpmbase + offset)); + *value = readw(((u8*)hwcpu->dpmbase + offset)); #elif defined(__NetBSD__) || defined(__OpenBSD__) - *value = bus_space_read_2(hw->hwcard->memt, hw->dpmbase, offset); + *value = bus_space_read_2(hwcpu->hwcard->memt, hwcpu->dpmbase, offset); #elif defined(__LINUX__) - *value = readw(((unsigned char*)hw->dpmbase+offset)); + *value = readw(((unsigned char*)hwcpu->dpmbase+offset)); +#elif defined(__WINDOWS__) + *value = READ_REGISTER_USHORT((PUSHORT)((PUCHAR)hwcpu->dpmbase + offset)); #else # warning "sdla_bus_read_2: Not supported yet!" #endif @@ -6481,34 +8141,42 @@ int sdla_bus_read_2(void* phw, unsigned int offset, u16* value) int sdla_bus_read_4(void* phw, unsigned int offset, u32* value) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; int retry=5; + WAN_ASSERT2(hw == NULL, 0); - WAN_ASSERT2(hw->dpmbase == 0, 0); SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT2(hw->hwcpu->dpmbase == 0, 0); + hwcpu = hw->hwcpu; + if (!(hwcpu->status & SDLA_MEM_MAPPED)) return 0; do { #if defined(__FreeBSD__) - *value = readl(((u8*)hw->dpmbase + offset)); + *value = readl(((u8*)hw->hwcpu->dpmbase + offset)); #elif defined(__NetBSD__) || defined(__OpenBSD__) - *value = bus_space_read_4(hw->hwcard->memt, hwcpu->dpmbase, offset); + *value = bus_space_read_4(hw->hwcard->memt, hwcpu->hwcpu->dpmbase, offset); #elif defined(__LINUX__) - *value = wp_readl((unsigned char*)hw->dpmbase + offset); + *value = wp_readl((unsigned char*)hw->hwcpu->dpmbase + offset); +#elif defined(__WINDOWS__) + *value = READ_REGISTER_ULONG((PULONG)((PUCHAR)hwcpu->dpmbase + offset)); #else *value = 0; # warning "sdla_bus_read_4: Not supported yet!" #endif +#if 1 if (offset == 0x40 && *value == (u32)-1) { if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s:%d: Error: Illegal Register read: 0x%04X = 0x%08X\n", + DEBUG_EVENT("%s:%d: wanpipe PCI Error: Illegal Register read: 0x%04X = 0x%08X\n", __FUNCTION__,__LINE__,offset,*value); } } else { /* only check for register 0x40 */ break; } - +#endif }while(--retry); return 0; @@ -6518,11 +8186,14 @@ static int sdla_pci_read_config_dword(void* phw, int reg, u32* value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* card; + sdlahw_cpu_t* hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) *value = pci_read_config(card->pci_dev, reg, 4); @@ -6533,6 +8204,8 @@ static int sdla_pci_read_config_dword(void* phw, int reg, u32* value) *value = pci_conf_read(card->pci_dev->pa_pc, card->pci_dev->pa_tag, reg); #elif defined(__LINUX__) pci_read_config_dword(card->pci_dev, reg, value); +#elif defined(__WINDOWS__) + pci_read_config_dword(card->pci_dev, reg, value); #else # warning "sdla_pci_read_config_dword: Not supported yet!" #endif @@ -6543,14 +8216,17 @@ static int sdla_pci_read_config_word(void* phw, int reg, u16* value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* card; + sdlahw_cpu_t* hwcpu; #if defined(__NetBSD__) || defined(__OpenBSD__) u32 tmp = 0x00; #endif WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) *value = pci_read_config(card->pci_dev, reg, 2); @@ -6562,6 +8238,8 @@ static int sdla_pci_read_config_word(void* phw, int reg, u16* value) *value = (u16)((tmp >> 16) & 0xFFFF); #elif defined(__LINUX__) pci_read_config_word(card->pci_dev, reg, value); +#elif defined(__WINDOWS__) + pci_read_config_word(card->pci_dev, reg, value); #else # warning "sdla_pci_read_config_word: Not supported yet!" #endif @@ -6570,27 +8248,32 @@ static int sdla_pci_read_config_word(void* phw, int reg, u16* value) static int sdla_pci_read_config_byte(void* phw, int reg, u8* value) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* card; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; #if defined(__NetBSD__) || defined(__OpenBSD__) u32 tmp = 0x00; #endif WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) - *value = pci_read_config(card->pci_dev, reg, 1); + *value = pci_read_config(hwcard->pci_dev, reg, 1); # else - *value = pci_cfgread(card->pci_dev, reg, 1); + *value = pci_cfgread(hwcard->pci_dev, reg, 1); # endif #elif defined(__NetBSD__) || defined(__OpenBSD__) - tmp = pci_conf_read(card->pci_dev->pa_pc, card->pci_dev->pa_tag, reg); + tmp = pci_conf_read(hwcard->pci_dev->pa_pc, hwcard->pci_dev->pa_tag, reg); *value = (u8)(tmp & 0xFF); #elif defined(__LINUX__) - pci_read_config_byte(card->pci_dev, reg, value); + pci_read_config_byte(hwcard->pci_dev, reg, value); +#elif defined(__WINDOWS__) + pci_read_config_byte(hwcard->pci_dev, reg, value); #else # warning "sdla_pci_read_config_byte: Not supported yet!" #endif @@ -6599,23 +8282,28 @@ static int sdla_pci_read_config_byte(void* phw, int reg, u8* value) static int sdla_pci_write_config_dword(void* phw, int reg, u32 value) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* card; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) - pci_write_config(card->pci_dev, reg, value, 4); + pci_write_config(hwcard->pci_dev, reg, value, 4); # else - pci_conf_write(card->pci_dev, reg, 4); + pci_conf_write(hwcard->pci_dev, reg, 4); # endif #elif defined(__NetBSD__) || defined(__OpenBSD__) - pci_conf_write(card->pci_dev->pa_pc, card->pci_dev->pa_tag, reg, value); + pci_conf_write(hwcard->pci_dev->pa_pc, hwcard->pci_dev->pa_tag, reg, value); #elif defined(__LINUX__) - pci_write_config_dword(card->pci_dev, reg, value); + pci_write_config_dword(hwcard->pci_dev, reg, value); +#elif defined(__WINDOWS__) + pci_write_config_dword(hwcard->pci_dev, reg, value); #else # warning "sdla_pci_write_config_dword: Not supported yet!" #endif @@ -6624,23 +8312,29 @@ static int sdla_pci_write_config_dword(void* phw, int reg, u32 value) static int sdla_pci_write_config_word(void* phw, int reg, u16 value) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* card; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) - pci_write_config(card->pci_dev, reg, value, 2); + pci_write_config(hwcard->pci_dev, reg, value, 2); # else - pci_conf_write(card->pci_dev, reg, value, 2); + pci_conf_write(hwcard->pci_dev, reg, value, 2); # endif #elif defined(__NetBSD__) || defined(__OpenBSD__) - pci_conf_write(card->pci_dev->pa_pc, card->pci_dev->pa_tag, reg, value); + pci_conf_write(hwcard->pci_dev->pa_pc, hwcard->pci_dev->pa_tag, reg, value); #elif defined(__LINUX__) - pci_write_config_word(card->pci_dev, reg, value); + pci_write_config_word(hwcard->pci_dev, reg, value); +#elif defined(__WINDOWS__) + pci_write_config_word(hwcard->pci_dev, reg, value); #else # warning "sdla_pci_write_config_word: Not supported yet!" #endif @@ -6651,11 +8345,14 @@ static int sdla_pci_write_config_byte(void* phw, int reg, u8 value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* card; + sdlahw_cpu_t* hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) pci_write_config(card->pci_dev, reg, value, 1); @@ -6666,25 +8363,31 @@ static int sdla_pci_write_config_byte(void* phw, int reg, u8 value) pci_conf_write(card->pci_dev->pa_pc, card->pci_dev->pa_tag, reg, value); #elif defined(__LINUX__) pci_write_config_byte(card->pci_dev, reg, value); +#elif defined(__WINDOWS__) + pci_write_config_byte(card->pci_dev, reg, value); #else # warning "sdla_pci_write_config_byte: Not supported yet!" #endif return 0; } -static int sdla_pci_bridge_read_config_dword(void* phw, int reg, u32* value) +int sdla_pci_bridge_read_config_dword(void* phw, int reg, u_int32_t* value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* card; + sdlahw_cpu_t* hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - if (hw->hwcard->pci_bridge_dev == NULL){ + + if (!sdla_is_pciexpress(hw)){ *value = 0xFFFFFFFF; - return 0; + return 0; } - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) *value = pci_read_config(card->pci_bridge_dev, reg, 4); @@ -6695,56 +8398,140 @@ static int sdla_pci_bridge_read_config_dword(void* phw, int reg, u32* value) *value = pci_conf_read(card->pci_bridge_dev->pa_pc, card->pci_bridge_dev->pa_tag, reg); #elif defined(__LINUX__) pci_read_config_dword(card->pci_bridge_dev, reg, value); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # warning "sdla_pci_bridge_read_config_dword: Not supported yet!" #endif return 0; } -static int sdla_pci_bridge_write_config_dword(void* phw, int reg, u32 value) + +static int sdla_pci_bridge_read_config_byte(void* phw, int reg, u_int8_t* value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* card; + sdlahw_cpu_t* hwcpu; +#if defined(__NetBSD__) || defined(__OpenBSD__) + u32 tmp = 0x00; +#endif WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - if (hw->hwcard->pci_bridge_dev == NULL){ + + if (!sdla_is_pciexpress(hw)){ + *value = 0xFF; return 0; } - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + card = hwcpu->hwcard; #if defined(__FreeBSD__) # if (__FreeBSD_version > 400000) - pci_write_config(card->pci_bridge_dev, reg, value, 4); + *value = pci_read_config(card->pci_bridge_dev, reg, 1); # else - pci_conf_write(card->pci_bridge_dev, reg, 4); + *value = ci_cfgread(card->pci_bridge_dev, reg, 1); # endif #elif defined(__NetBSD__) || defined(__OpenBSD__) - pci_conf_write(card->pci_bridge_dev->pa_pc, card->pci_bridge_dev->pa_tag, reg, value); + tmp = pci_conf_read(card->pci_bridge_dev->pa_pc, card->pci_bridge_dev->pa_tag, reg); + *value = tmp & 0xFF; #elif defined(__LINUX__) - pci_write_config_dword(card->pci_bridge_dev, reg, value); + pci_read_config_byte(card->pci_bridge_dev, reg, value); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "sdla_pci_bridge_read_config_byte: Not supported yet!" +#endif + return 0; +} + +int sdla_pci_bridge_write_config_dword(void* phw, int reg, u_int32_t value) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + if (!sdla_is_pciexpress(hw)){ + return 0; + } +#if defined(__FreeBSD__) +# if (__FreeBSD_version > 400000) + pci_write_config(hwcard->pci_bridge_dev, reg, value, 4); +# else + pci_conf_write(hwcard->pci_bridge_dev, reg, 4); +# endif +#elif defined(__NetBSD__) || defined(__OpenBSD__) + pci_conf_write(hwcard->pci_bridge_dev->pa_pc, hwcard->pci_bridge_dev->pa_tag, reg, value); +#elif defined(__LINUX__) + pci_write_config_dword(hwcard->pci_bridge_dev, reg, value); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # warning "sdla_pci_bridge_write_config_dword: Not supported yet!" #endif return 0; } +static int sdla_pci_bridge_write_config_byte(void* phw, int reg, u_int8_t value) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); + + if (!sdla_is_pciexpress(hw)){ + return 0; + } + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; +#if defined(__FreeBSD__) +# if (__FreeBSD_version > 400000) + pci_write_config(hwcard->pci_bridge_dev, reg, value, 1); +# else + pci_conf_write(hwcard->pci_bridge_dev, reg, 1); +# endif +#elif defined(__NetBSD__) || defined(__OpenBSD__) + pci_conf_write(hwcard->pci_bridge_dev->pa_pc, hwcard->pci_bridge_dev->pa_tag, reg, value); +#elif defined(__LINUX__) + pci_write_config_byte(hwcard->pci_bridge_dev, reg, value); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "sdla_pci_bridge_write_config_byte: Not supported yet!" +#endif + return 0; +} #if defined(WAN_ISA_SUPPORT) static int sdla_isa_read_1(void* phw, unsigned int offset, u8* value) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* card; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; #if defined(__FreeBSD__) - *value = inb (card->ioport + offset); + *value = inb (hwcard->ioport + offset); #elif defined(__NetBSD__) || defined(__OpenBSD__) - *value = bus_space_read_1(card->iot, hw->ioh, offset); + *value = bus_space_read_1(hwcard->iot, hw->ioh, offset); #elif defined(__LINUX__) - *value = inb(card->ioport + offset); + *value = inb(hwcard->ioport + offset); #else # warning "sdla_isa_read_1: Not supported yet!" #endif @@ -6755,20 +8542,24 @@ static int sdla_isa_read_1(void* phw, unsigned int offset, u8* value) #if defined(WAN_ISA_SUPPORT) static int sdla_isa_write_1(void* phw, unsigned int offset, u8 value) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* card; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - card = hw->hwcard; - hw->regs[offset] = value; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + hwcpu->regs[offset] = value; #if defined(__FreeBSD__) - outb (card->ioport + offset, value); + outb (hwcard->ioport + offset, value); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_write_1(card->iot, hw->ioh, offset, value); + bus_space_write_1(hwcard->iot, hwcpu->ioh, offset, value); #elif defined(__LINUX__) - outb(value, card->ioport + offset); + outb(value, hwcard->ioport + offset); #else # warning "sdla_isa_write_1: Not supported yet!" #endif @@ -6778,68 +8569,657 @@ static int sdla_isa_write_1(void* phw, unsigned int offset, u8 value) static int sdla_hw_lock(void *phw, wan_smp_flag_t *flag) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* hwcard; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; +#if defined(__WINDOWS__) + { + sdla_t *card = hw->p_sdla; + + DBG_FE_LOCK("%s():%s: p_sdla: 0x%p, card lock: 0x%p\n", + __FUNCTION__, card->devname, hw->p_sdla, get_card_spin_lock(hw->p_sdla)); + } + wan_spin_lock(get_card_spin_lock(hw->p_sdla)); +#else wan_spin_lock(&hwcard->pcard_lock); +#endif return 0; } static int sdla_hw_unlock(void *phw, wan_smp_flag_t *flag) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* hwcard; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; +#if defined(__WINDOWS__) + { + sdla_t *card = hw->p_sdla; + + DBG_FE_LOCK("%s():%s: p_sdla: 0x%p, card lock: 0x%p\n", + __FUNCTION__, card->devname, hw->p_sdla, get_card_spin_lock(hw->p_sdla)); + } + wan_spin_unlock(get_card_spin_lock(hw->p_sdla)); +#else wan_spin_unlock(&hwcard->pcard_lock); +#endif return 0; } +static int sdla_hw_ec_trylock(void *phw, wan_smp_flag_t *flag) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + return wan_spin_trylock(&hwcard->pcard_ec_lock); +} + static int sdla_hw_ec_lock(void *phw, wan_smp_flag_t *flag) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* hwcard; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; wan_spin_lock(&hwcard->pcard_ec_lock); return 0; } static int sdla_hw_ec_unlock(void *phw, wan_smp_flag_t *flag) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* hwcard; + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; wan_spin_unlock(&hwcard->pcard_ec_lock); return 0; } -static sdla_dma_addr_t sdla_pci_map_dma(void *phw, void *buf, int len, int ctrl) +/***************************************************************************** +** BUS DMA Access +*****************************************************************************/ +static wan_dma_descr_t *sdla_busdma_descr_alloc(void *phw, int num) { - sdlahw_t* hw = (sdlahw_t*)phw; - sdlahw_card_t* hwcard; + sdlahw_t *hw = (sdlahw_t*)phw; + wan_dma_descr_t *dma_descr = NULL; + + WAN_ASSERT_RC(hw == NULL, NULL); + SDLA_MAGIC_RC(hw, NULL); + + return dma_descr; +} +static void sdla_busdma_descr_free(void *phw, wan_dma_descr_t *dma_descr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + + WAN_ASSERT_VOID(hw == NULL); + SDLA_MAGIC_VOID(hw); + if (dma_descr) wan_free(dma_descr); + return; +} +#if defined(__FreeBSD__) +static void +sdla_busdma_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error) +{ + wan_dma_descr_t *dma_descr; + sdla_dma_addr_t paddr; + bus_size_t plen; + + WAN_ASSERT_VOID(arg == NULL); + if (error){ + DEBUG_EVENT( + "ERROR [%s:%d]: Failed to load DMA buffer (nseg=%d:err=%d)!\n", + __FUNCTION__,__LINE__, nseg, error); + return; + } + dma_descr = (wan_dma_descr_t*)arg; + + paddr = seg->ds_addr; + plen = seg->ds_len; + if (paddr & (dma_descr->alignment-1)){ + dma_descr->dma_offset = + dma_descr->alignment - + (paddr & (dma_descr->alignment-1)); + DEBUG_EVENT( + "ERROR [%s:%d]: Invalid Phys DMA Addr %lX Shift dma paddr %d\n", + __FUNCTION__,__LINE__, + (unsigned long)paddr,dma_descr->dma_offset); + error = bus_dmamap_load( + dma_descr->dmat, + dma_descr->dmam, + (char*)dma_descr->dma_virt+dma_descr->dma_offset, + plen, + sdla_busdma_callback, dma_descr, + BUS_DMA_NOWAIT); + return; + } + dma_descr->dma_addr = paddr; + dma_descr->dma_len = plen; + wan_set_bit(SDLA_DMA_FLAG_READY, &dma_descr->flag); + DEBUG_DMA("%s:%d DMA Loaded paddr %X plen %d (dma_descr:%p)\n", + __FUNCTION__,__LINE__, + dma_descr->dma_addr, + dma_descr->dma_len, + dma_descr); + return; +} +#endif +/* + * + * dma_alignment - value should be multiple 2,4 + */ +static int +sdla_busdma_tag_create( void *phw, + wan_dma_descr_t *dma_descr, + u32 dma_alignment, + u32 dma_max_len, + int ndescr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + wan_dma_descr_t *dma_descr_next = NULL; + int i; +#if defined(__FreeBSD__) + int err; +#endif + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(dma_alignment == 0); + SDLA_MAGIC(hw); +#if defined(__FreeBSD__) + err = bus_dma_tag_create( + NULL, /* NULL */ + dma_alignment, /*alignemnt*/ + 512, /*boundary*/ +#ifdef __amd64__ + BUS_SPACE_MAXADDR, /*lowaddr*/ +#else + BUS_SPACE_MAXADDR_32BIT, /*lowaddr*/ +#endif + BUS_SPACE_MAXADDR, /*highaddr*/ + NULL, /*filter*/ + NULL, /*filterarg*/ + dma_max_len, /*maxsize*/ +# if (__FreeBSD_version >= 502000) + 10, /*nsegments*/ +# else + BUS_SPACE_UNRESTRICTED, /*nsegments*/ +# endif + dma_max_len, /*maxsegsz*/ + BUS_DMA_ALLOCNOW, /*flags*/ +# if (__FreeBSD_version >= 502000) + busdma_lock_mutex, /*lockfunc*/ + &Giant, /*lockfuncarg*/ +# endif + &dma_descr->dmat); + if (err) { + DEBUG_EVENT("%s: Failed to create DMA tag (%d:%d:err=%d)!\n", + hw->devname, + dma_max_len,dma_alignment, err); + return -EINVAL; + } +#elif defined(__LINUX__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA TAG Create is not defined!" +#endif + dma_descr_next = dma_descr; + for(i = 0; i < ndescr; i++){ +#if defined(__FreeBSD__) + dma_descr_next->dmat = dma_descr->dmat; +#endif + dma_descr_next->alignment = dma_alignment; + dma_descr_next->max_len = dma_max_len; + wan_set_bit(SDLA_DMA_FLAG_INIT, &dma_descr_next->flag); + dma_descr_next++; + } + return 0; +} +static int +sdla_busdma_tag_destroy(void *phw, wan_dma_descr_t *dma_descr, int ndescr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + wan_dma_descr_t *dma_descr_next = NULL; + int i; +#if defined(__FreeBSD__) + int err; +#endif WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + if (!wan_test_bit(SDLA_DMA_FLAG_INIT, &dma_descr->flag)){ + DEBUG_DMA("%s: Internal Error: %s:%d!\n", + hw->devname, + __FUNCTION__,__LINE__); + return -EINVAL; + } +#if defined(__FreeBSD__) + err = bus_dma_tag_destroy(dma_descr->dmat); + if (err){ + DEBUG_EVENT("%s: Failed to destroy DMA tag (err=%d)!\n", + hw->devname, err); + return -EINVAL; + } +#elif defined(__LINUX__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA TAG Destroy is not defined!" +#endif + dma_descr_next = dma_descr; + for(i = 0; i < ndescr; i++){ +#if defined(__FreeBSD__) + dma_descr_next->dmat = 0; +#endif + dma_descr_next->alignment = 0; + dma_descr_next->max_len = 0; + wan_clear_bit(SDLA_DMA_FLAG_INIT, &dma_descr_next->flag); + dma_descr_next++; + } + return 0; +} +/* FIXME: This function is not in used (alignment is not support) */ +static int sdla_busdma_create(void *phw, wan_dma_descr_t *dma_descr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; +#if defined(__FreeBSD__) + int err; +#endif + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); +#if defined(__FreeBSD__) + err = bus_dmamap_create(dma_descr->dmat,0,&dma_descr->dmam); + if (err) { + DEBUG_EVENT( + "%s: Failed to allocate and initialize DMA map (err=%d))!\n", + hw->devname,err); + return -EINVAL; + } +#elif defined(__LINUX__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Create is not defined!" +#endif + return 0; +} +/* FIXME: This function is not in used (alignment is not support) */ +static int sdla_busdma_destroy(void *phw, wan_dma_descr_t *dma_descr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; +#if defined(__FreeBSD__) + int err; +#endif + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); +#if defined(__FreeBSD__) + err = bus_dmamap_destroy(dma_descr->dmat,dma_descr->dmam); + if (err) { + DEBUG_EVENT("%s: Failed to free all DMA resources (err=%d))!\n", + hw->devname,err); + return -EINVAL; + } +#elif defined(__LINUX__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Destroy is not defined!" +#endif + return 0; +} + +/* Allocate virtual buffer for DMA with dma_max_len */ +static int sdla_busdma_alloc(void *phw, wan_dma_descr_t *dma_descr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; +#if defined(__FreeBSD__) + int err; +#endif + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); + if (!wan_test_bit(SDLA_DMA_FLAG_INIT, &dma_descr->flag)){ + DEBUG_DMA("%s: Internal Error: %s:%d!\n", + hw->devname, __FUNCTION__,__LINE__); + return -EINVAL; + } +#if defined(__FreeBSD__) + err = bus_dmamem_alloc( dma_descr->dmat, + &dma_descr->dma_virt, + BUS_DMA_NOWAIT|BUS_DMA_ZERO/*BUS_DMA_NOWAIT*/, + &dma_descr->dmam); + if (err || dma_descr->dma_virt == NULL){ + DEBUG_EVENT( + "%s: Unable to allocate DMA virtual memory (err=%d)!\n", + hw->devname, err); + return -ENOMEM; + } + + err = bus_dmamap_load( dma_descr->dmat, + dma_descr->dmam, + dma_descr->dma_virt, + dma_descr->max_len, + sdla_busdma_callback, dma_descr, + BUS_DMA_NOWAIT); + if (err){ + DEBUG_EVENT("%s: Unable to load DMA buffer (%d:err=%d)!\n", + hw->devname, dma_descr->max_len, err); + bus_dmamem_free( + dma_descr->dmat, + dma_descr->dma_virt, + dma_descr->dmam); + return -EINVAL; + } + wan_set_bit(SDLA_DMA_FLAG_ALLOC, &dma_descr->flag); +#elif defined(__LINUX__) +# if 0 + dma_descr->dma_virt = pci_alloc_consistent( + NULL, + dma_descr->max_len, + (dma_addr_t*)&dma_descr->dma_addr); + if (dma_descr->dma_virt == NULL){ + DEBUG_EVENT( + "%s: Unable to allocate DMA virtual memory (err=%d)!\n", + hw->devname, err); + return -ENOMEM; + } + if (dma_descr->dma_addr & dma_descr->alignment){ + dma_descr->dma_offset = + dma_descr->alignment - + (dma_descr->dma_addr & dma_descr->alignment) + + 1; + (u8*)dma_descr->dma_virt += dma_descr->dma_offset; + dma_descr->dma_addr += dma_descr->dma_offset; + }else{ + dma_descr->dma_offset = 0; + } +# endif + wan_set_bit(SDLA_DMA_FLAG_ALLOC, &dma_descr->flag); + wan_set_bit(SDLA_DMA_FLAG_READY, &dma_descr->flag); +#elif defined(__OpenBSD__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Alloc is not defined!" +#endif + return 0; +} +static void sdla_busdma_free(void *phw, wan_dma_descr_t *dma_descr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + + WAN_ASSERT_VOID(hw == NULL); + SDLA_MAGIC_VOID(hw); + + if (!wan_test_bit(SDLA_DMA_FLAG_ALLOC, &dma_descr->flag)){ + DEBUG_DMA("%s: Internal Error: %s:%d!\n", + hw->devname, __FUNCTION__,__LINE__); + return; + } + wan_clear_bit(SDLA_DMA_FLAG_READY, &dma_descr->flag); +#if defined(__FreeBSD__) + bus_dmamap_unload(dma_descr->dmat,dma_descr->dmam); + bus_dmamem_free(dma_descr->dmat,dma_descr->dma_virt,dma_descr->dmam); +#elif defined(__LINUX__) +# if 0 + if (dma_descr->dma_offset){ + (u8*)dma_descr->dma_virt-= dma_descr->dma_offset; + dma_descr->dma_addr -= dma_descr->dma_offset; + } + pci_free_consistent( NULL, + dma_descr->max_len, + dma_descrdma_descr->dma_virt, + dma_descr->dma_addr); +# endif +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Free is not defined!" +#endif + wan_clear_bit(SDLA_DMA_FLAG_ALLOC, &dma_descr->flag); + dma_descr->dma_virt = NULL; + dma_descr->dma_addr = 0; + return; +} + +/* FIXME: This function is not in used */ +static int sdla_busdma_load(void *phw, wan_dma_descr_t *dma_descr, u32 len) +{ + sdlahw_t *hw = (sdlahw_t*)phw; +#if defined(__FreeBSD__) + int err; +#endif + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); +#if defined(__FreeBSD__) + err = bus_dmamap_load( dma_descr->dmat, + dma_descr->dmam, + dma_descr->dma_virt, + len, + sdla_busdma_callback, dma_descr, + BUS_DMA_NOWAIT); + if (err){ + DEBUG_EVENT("%s: Unable to load DMA buffer (%d:err=%d)!\n", + hw->devname, len, err); + return -EINVAL; + } +#elif defined(__LINUX__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Load is not defined!" +#endif + return 0; +} + +/* FIXME: This function is not in used */ +static void sdla_busdma_unload(void *phw, wan_dma_descr_t *dma_descr) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + + WAN_ASSERT_VOID(hw == NULL); + SDLA_MAGIC_VOID(hw); +#if defined(__FreeBSD__) + bus_dmamap_unload(dma_descr->dmat, dma_descr->dmam); +#elif defined(__LINUX__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Unload is not defined!" +#endif + return; +} +static void +sdla_busdma_map(void *phw, wan_dma_descr_t *dma_descr, void *buf, int buflen, int map_len, int dir) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT_VOID(hw == NULL); + SDLA_MAGIC_VOID(hw); + WAN_ASSERT_VOID(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT_VOID(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; + + if (!wan_test_bit(SDLA_DMA_FLAG_READY, &dma_descr->flag)){ + DEBUG_DMA("%s: Internal Error: %s:%d: DMA is not ready!\n", + hw->devname, __FUNCTION__,__LINE__); + return; + } +#if defined(__FreeBSD__) + if (dir == SDLA_DMA_PREWRITE){ + bcopy(buf, dma_descr->dma_virt, buflen); + } +#elif defined(__LINUX__) + dma_descr->dma_offset = 0; + dma_descr->dma_addr = + cpu_to_le32(pci_map_single(hwcard->pci_dev,buf,map_len,dir)); + if (dma_descr->dma_addr & (dma_descr->alignment-1)){ + dma_descr->dma_offset = + dma_descr->alignment - + (dma_descr->dma_addr & (dma_descr->alignment-1)); + dma_descr->dma_virt = buf + dma_descr->dma_offset; + dma_descr->dma_addr += dma_descr->dma_offset; + }else{ + dma_descr->dma_virt = buf; + dma_descr->dma_offset = 0; + } +#elif defined(__OpenBSD__) + dma_descr->dma_addr = virt_to_phys(buf); + if (dma_descr->dma_addr & (dma_descr->alignment-1)){ + dma_descr->dma_offset = + dma_descr->alignment - + (dma_descr->dma_addr & (dma_descr->alignment-1)); + dma_descr->dma_virt = buf + dma_descr->dma_offset; + dma_descr->dma_addr = virt_to_phys(dma_descrt->dma_virt)); + } else { + dma_descr->dma_virt = buf; + dma_descr->dma_offset =0; + } +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA map is not defined!" +#endif + dma_descr->dma_len = buflen; + dma_descr->dma_map_len = map_len; + return; +} +static void sdla_busdma_unmap(void *phw, wan_dma_descr_t *dma_descr, int dir) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT_VOID(hw == NULL); + SDLA_MAGIC_VOID(hw); + WAN_ASSERT_VOID(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT_VOID(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; + + if (!wan_test_bit(SDLA_DMA_FLAG_READY, &dma_descr->flag)){ + DEBUG_DMA("%s: Internal Error: %s:%d: DMA is not ready!\n", + hw->devname, __FUNCTION__,__LINE__); + return; + } +#if defined(__FreeBSD__) + if (dma_descr->skb && dir == SDLA_DMA_POSTREAD){ + caddr_t data = NULL; + + /* Apr 19, 2007 new line : + ** data = wan_skb_put(dma_descr->skb, dma_descr->dma_len);*/ + /* Nov 2, 2007 do not update anything in mbuf. The code + ** who called me will update all length of mbuf */ + data = wan_skb_tail(dma_descr->skb); + bcopy(dma_descr->dma_virt, data, dma_descr->dma_len); + } +#elif defined(__LINUX__) + if (dma_descr->dma_addr){ + dma_descr->dma_addr -= dma_descr->dma_offset; + pci_unmap_single( hwcard->pci_dev, + dma_descr->dma_addr, + dma_descr->dma_map_len, + dir); + } + dma_descr->dma_addr = 0; +#elif defined(__OpenBSD__) + dma_descr->dma_addr = 0; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Unmap is not defined!" +#endif + dma_descr->dma_len = 0; + dma_descr->dma_map_len = 0; + return; +} +static void +sdla_busdma_sync(void *phw, wan_dma_descr_t *dma_descr, int ndescr, int single, int dir) +{ + sdlahw_t *hw = (sdlahw_t*)phw; +#if defined(__FreeBSD__) + int cnt = 0; +#endif + + WAN_ASSERT_VOID(hw == NULL); + SDLA_MAGIC_VOID(hw); + if (!wan_test_bit(SDLA_DMA_FLAG_READY, &dma_descr->flag)){ + DEBUG_DMA("%s: Internal Error: %s:%d: DMA is not ready!\n", + hw->devname, __FUNCTION__,__LINE__); + return; + } +#if defined(__FreeBSD__) + for (cnt=0;cntdmat, dma_descr->dmam, dir); + if (single) break; + dma_descr++; + } +#elif defined(__LINUX__) +#elif defined(__OpenBSD__) +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL +#else +# warning "BUSDMA Sync is not defined!" +#endif + return; +} + + +static sdla_dma_addr_t sdla_pci_map_dma(void *phw, void *buf, int len, int ctrl) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_card_t *hwcard; + sdlahw_cpu_t *hwcpu; + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; #if defined(__LINUX__) return cpu_to_le32(pci_map_single(hwcard->pci_dev, buf, len, ctrl)); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return (sdla_dma_addr_t)NULL; #else return virt_to_phys(buf); #endif @@ -6849,28 +9229,43 @@ static int sdla_pci_unmap_dma(void *phw, sdla_dma_addr_t buf, int len, int ctrl) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* hwcard; + sdlahw_cpu_t* hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; #if defined(__LINUX__) pci_unmap_single(hwcard->pci_dev, buf, len, ctrl); #endif return 0; } +/*****************************************************************************/ int sdla_hw_fe_test_and_set_bit(void *phw, int value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* hwcard; + sdlahw_cpu_t* hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; + +#if defined(__WINDOWS__) + { + sdla_t *card = hw->p_sdla; + DBG_FE_LOCK("%s():%s: bitNum: %i, &hwcard->fe_rw_flag: 0x%p, fe_rw_flag: 0x%X\n", + __FUNCTION__, card->devname, value, &hwcard->fe_rw_flag, hwcard->fe_rw_flag); + } +#endif return wan_test_and_set_bit(value, &hwcard->fe_rw_flag); } @@ -6878,11 +9273,21 @@ int sdla_hw_fe_test_bit(void *phw, int value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* hwcard; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; +#if defined(__WINDOWS__) + { + sdla_t *card = hw->p_sdla; + DBG_FE_LOCK("%s():%s: bitNum: %i, &hwcard->fe_rw_flag: 0x%p, fe_rw_flag: 0x%X\n", + __FUNCTION__, card->devname, value, &hwcard->fe_rw_flag, hwcard->fe_rw_flag); + } +#endif return wan_test_bit(value, &hwcard->fe_rw_flag); } @@ -6890,12 +9295,22 @@ int sdla_hw_fe_clear_bit(void *phw, int value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* hwcard; + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; wan_clear_bit(value, &hwcard->fe_rw_flag); +#if defined(__WINDOWS__) + { + sdla_t *card = hw->p_sdla; + DBG_FE_LOCK("%s():%s: bitNum: %i, &hwcard->fe_rw_flag: 0x%p, fe_rw_flag: 0x%X\n", + __FUNCTION__, card->devname, value, &hwcard->fe_rw_flag, hwcard->fe_rw_flag); + } +#endif return 0; } @@ -6903,12 +9318,21 @@ int sdla_hw_fe_set_bit(void *phw, int value) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_card_t* hwcard; - + sdlahw_cpu_t *hwcpu; WAN_ASSERT(hw == NULL); SDLA_MAGIC(hw); - WAN_ASSERT(hw->hwcard == NULL); - hwcard = hw->hwcard; + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + WAN_ASSERT(hwcpu->hwcard == NULL); + hwcard = hwcpu->hwcard; wan_set_bit(value, &hwcard->fe_rw_flag); +#if defined(__WINDOWS__) + { + sdla_t *card = hw->p_sdla; + DBG_FE_LOCK("%s():%s: bitNum: %i, &hwcard->fe_rw_flag: 0x%p, fe_rw_flag: 0x%X\n", + __FUNCTION__, card->devname, value, &hwcard->fe_rw_flag, hwcard->fe_rw_flag); + } +#endif return 0; } @@ -6916,11 +9340,14 @@ int sdla_hw_fe_set_bit(void *phw, int value) static int sdla_hw_read_cpld(void *phw, u16 off, u8 *data) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; u16 org_off; -#if 1 - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ - switch(hw->hwcard->adptr_type){ + WAN_ASSERT(hw->hwcpu == NULL); + hwcpu = hw->hwcpu; + + if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ + switch(hwcpu->hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: off &= ~AFT_BIT_DEV_ADDR_CLEAR; @@ -6945,15 +9372,15 @@ static int sdla_hw_read_cpld(void *phw, u16 off, u8 *data) sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); break; default: - DEBUG_EVENT("%s: ERROR: Invalid read access to cpld!\n", + DEBUG_EVENT("%s: ERROR: Invalid read access to cpld (Normal)!\n", hw->devname); return -EINVAL; } - }else if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ - switch(hw->hwcard->core_id){ + }else if (hwcpu->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + switch(hwcpu->hwcard->core_id){ case AFT_PMC_FE_CORE_ID: - switch(hw->hwcard->adptr_type){ + switch(hwcpu->hwcard->adptr_type){ case A104_ADPTR_4TE1: off &= ~AFT4_BIT_DEV_ADDR_CLEAR; off |= AFT4_BIT_DEV_ADDR_CPLD; @@ -6967,13 +9394,13 @@ static int sdla_hw_read_cpld(void *phw, u16 off, u8 *data) sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); break; default: - DEBUG_EVENT("%s: ERROR: Invalid read access to cpld!\n", + DEBUG_EVENT("%s: ERROR: Invalid read access to cpld (PMC)!\n", hw->devname); return -EINVAL; } break; case AFT_DS_FE_CORE_ID: - switch(hw->hwcard->adptr_type){ + switch(hwcpu->hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: case A104_ADPTR_4TE1: @@ -6991,15 +9418,16 @@ static int sdla_hw_read_cpld(void *phw, u16 off, u8 *data) sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); break; default: - DEBUG_EVENT("%s: ERROR: Invalid read access to cpld!\n", + DEBUG_EVENT("%s: ERROR: Invalid read access to cpld (DS)!\n", hw->devname); return -EINVAL; } break; default: - switch(hw->hwcard->adptr_type){ + switch(hwcpu->hwcard->adptr_type){ case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: + case AFT_ADPTR_ISDN: off &= ~AFT4_BIT_DEV_ADDR_CLEAR; off |= AFT4_BIT_DEV_ADDR_CPLD; /* Save current original address */ @@ -7017,9 +9445,29 @@ static int sdla_hw_read_cpld(void *phw, u16 off, u8 *data) sdla_bus_write_2(hw, AFT56K_MCPU_INTERFACE_ADDR, off); sdla_bus_read_1(hw, AFT56K_MCPU_INTERFACE, data); + break; + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_RS232: + + + off &= ~AFT_SERIAL_BIT_DEV_ADDR_CLEAR; + off |= AFT_SERIAL_BIT_DEV_ADDR_CPLD; + + /* Save current original address */ + sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); + WP_DELAY(5); + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); + WP_DELAY(5); + sdla_bus_read_1(hw, AFT_MCPU_INTERFACE, data); + /* Restore the original address */ + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); + + break; default: - DEBUG_EVENT("%s: ERROR: Invalid read access to cpld!\n", + DEBUG_EVENT("%s: ERROR: Invalid read access to cpld (SHARK)!\n", hw->devname); return -EINVAL; } @@ -7030,81 +9478,23 @@ static int sdla_hw_read_cpld(void *phw, u16 off, u8 *data) hw->devname); return -EINVAL; } -#else - switch(hw->hwcard->adptr_type){ - case A101_ADPTR_1TE1: - case A101_ADPTR_2TE1: - off &= ~AFT_BIT_DEV_ADDR_CLEAR; - off |= AFT_BIT_DEV_ADDR_CPLD; - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - sdla_bus_read_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - case A104_ADPTR_4TE1: - off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - off |= AFT4_BIT_DEV_ADDR_CPLD; - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - WP_DELAY(5); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - WP_DELAY(5); - sdla_bus_read_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - case A108_ADPTR_8TE1: - off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - off |= AFT8_BIT_DEV_ADDR_CPLD; - - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - WP_DELAY(5); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - WP_DELAY(5); - sdla_bus_read_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - case A200_ADPTR_ANALOG: - case A400_ADPTR_ANALOG: - off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - off |= AFT4_BIT_DEV_ADDR_CPLD; - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - WP_DELAY(5); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - WP_DELAY(5); - sdla_bus_read_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - default: - DEBUG_EVENT("%s: ERROR: Invalid read access to cpld!\n", - hw->devname); - return -EINVAL; - } -#endif return 0; } static int sdla_hw_write_cpld(void *phw, u16 off, u8 data) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; u16 org_off; - DEBUG_56K("%s: hw->hwcard->adptr_type: 0x%X\n", - hw->devname, hw->hwcard->adptr_type); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; -#if 1 - if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ - switch(hw->hwcard->adptr_type){ + if (hwcard->adptr_subtype == AFT_SUBTYPE_NORMAL){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: off &= ~AFT_BIT_DEV_ADDR_CLEAR; @@ -7129,15 +9519,15 @@ static int sdla_hw_write_cpld(void *phw, u16 off, u8 data) sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); break; default: - DEBUG_EVENT("%s: ERROR: (1)Invalid write access to cpld!\n", - hw->devname); + DEBUG_EVENT("%s: (line: %d) ERROR: Invalid write access to cpld!\n", + hw->devname, __LINE__); return -EINVAL; } - }else if (hw->hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ - switch(hw->hwcard->core_id){ + }else if (hwcard->adptr_subtype == AFT_SUBTYPE_SHARK){ + switch(hwcard->core_id){ case AFT_PMC_FE_CORE_ID: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A104_ADPTR_4TE1: off &= ~AFT4_BIT_DEV_ADDR_CLEAR; off |= AFT4_BIT_DEV_ADDR_CPLD; @@ -7151,13 +9541,14 @@ static int sdla_hw_write_cpld(void *phw, u16 off, u8 data) sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); break; default: - DEBUG_EVENT("%s: ERROR: (2)Invalid write access to cpld!\n", - hw->devname); + DEBUG_EVENT("%s: (%d)ERROR: Invalid write access to cpld!\n", + hw->devname, __LINE__); return -EINVAL; } break; + case AFT_DS_FE_CORE_ID: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A101_ADPTR_1TE1: case A101_ADPTR_2TE1: case A104_ADPTR_4TE1: @@ -7173,16 +9564,19 @@ static int sdla_hw_write_cpld(void *phw, u16 off, u8 data) /* Restore the original address */ sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); break; + default: - DEBUG_EVENT("%s: ERROR: (3)Invalid write access to cpld!\n", + DEBUG_EVENT("%s: (1)ERROR: Invalid write access to cpld!\n", hw->devname); return -EINVAL; } break; + default: - switch(hw->hwcard->adptr_type){ + switch(hwcard->adptr_type){ case A200_ADPTR_ANALOG: case A400_ADPTR_ANALOG: + case AFT_ADPTR_ISDN://???? off &= ~AFT4_BIT_DEV_ADDR_CLEAR; off |= AFT4_BIT_DEV_ADDR_CPLD; /* Save current original address */ @@ -7200,77 +9594,66 @@ static int sdla_hw_write_cpld(void *phw, u16 off, u8 data) sdla_bus_write_2(hw, AFT56K_MCPU_INTERFACE_ADDR, off); sdla_bus_write_1(hw, AFT56K_MCPU_INTERFACE, data); break; + case AFT_ADPTR_2SERIAL_V35X21: + case AFT_ADPTR_2SERIAL_RS232: + case AFT_ADPTR_4SERIAL_V35X21: + case AFT_ADPTR_4SERIAL_RS232: + + off &= ~AFT_SERIAL_BIT_DEV_ADDR_CLEAR; + off |= AFT_SERIAL_BIT_DEV_ADDR_CPLD; + /* Save current original address */ + sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); + WP_DELAY(5); + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); + WP_DELAY(5); + sdla_bus_write_1(hw, AFT_MCPU_INTERFACE, data); + /* Restore the original address */ + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); + break; + default: - DEBUG_EVENT("%s: ERROR: (4)Invalid write access to cpld!\n", - hw->devname); + DEBUG_EVENT("%s: (line: %d)ERROR: Invalid write access to cpld!\n", + hw->devname, __LINE__); return -EINVAL; } break; } }else{ - DEBUG_EVENT("%s: ERROR: (5)Invalid write access to cpld!\n", - hw->devname); + DEBUG_EVENT("%s: (line: %d)ERROR: Invalid write access to cpld!\n", + hw->devname, __LINE__); return -EINVAL; } -#else - switch(hw->hwcard->adptr_type){ - case A101_ADPTR_1TE1: - case A101_ADPTR_2TE1: - off &= ~AFT_BIT_DEV_ADDR_CLEAR; - off |= AFT_BIT_DEV_ADDR_CPLD; - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - sdla_bus_write_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - case A104_ADPTR_4TE1: - off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - off |= AFT4_BIT_DEV_ADDR_CPLD; - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - WP_DELAY(5); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - WP_DELAY(5); - sdla_bus_write_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - case A108_ADPTR_8TE1: - off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - off |= AFT8_BIT_DEV_ADDR_CPLD; - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - WP_DELAY(5); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - WP_DELAY(5); - sdla_bus_write_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - case A200_ADPTR_ANALOG: - case A400_ADPTR_ANALOG: - off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - off |= AFT4_BIT_DEV_ADDR_CPLD; - /* Save current original address */ - sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, &org_off); - WP_DELAY(5); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, off); - WP_DELAY(5); - sdla_bus_write_1(hw, AFT_MCPU_INTERFACE, data); - /* Restore the original address */ - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); - break; - - default: - DEBUG_EVENT("%s: ERROR: Invalid read access to cpld!\n", - hw->devname); - return -EINVAL; - } -#endif return 0; } + +static int sdla_is_pciexpress(void *phw) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; + + if (hwcard->pci_bridge_dev == NULL) return 0; + return 1; +} + + +static int sdla_get_hwec_index(void *phw) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + + WAN_ASSERT(hw == NULL); + SDLA_MAGIC(hw); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + + if (hw->hwcpu->hwcard->hwec_chan_no == 0) return -EINVAL; + return hw->hwcpu->hwcard->hwec_ind; +} + diff --git a/patches/kdrivers/src/net/sdladrv_fe.c b/patches/kdrivers/src/net/sdladrv_fe.c index 065fc5b..ee0f256 100644 --- a/patches/kdrivers/src/net/sdladrv_fe.c +++ b/patches/kdrivers/src/net/sdladrv_fe.c @@ -12,6 +12,8 @@ * 2 of the License, or (at your option) any later version. * ============================================================================ * Aug 10, 2006 Alex Feldman Initial version +* +* July 5, 2007 David Rokhvarg Added support of A500 - ISDN BRI card. *****************************************************************************/ /***************************************************************************** @@ -38,6 +40,16 @@ # include # include # include +#elif defined(__WINDOWS__) +# include +# include +# include +# include +# include +# include /* SDLA firmware module definitions */ +# include /* SDLA PCI hardware definitions */ +# include +# include /* API definitions */ #elif defined(__LINUX__)||defined(__KERNEL__) # define _K22X_MODULE_FIX_ # include @@ -53,6 +65,13 @@ # error "Unsupported Operating System!" #endif +#if defined(WAN_DEBUG_FE) +# warning "WAN_DEBUG_FE - Debugging Enabled" +#endif +#if defined(WAN_DEBUG_REG) +# warning "WAN_DEBUG_REG - Debugging Enabled" +#endif + /*************************************************************************** **** M A C R O S / D E F I N E S **** ***************************************************************************/ @@ -69,19 +88,32 @@ u_int8_t sdla_te1_read_fe (void* phw, ...); static int __sdla_shark_te1_write_fe(void *phw, ...); int sdla_shark_te1_write_fe(void *phw, ...); -static u_int8_t __sdla_shark_te1_read_fe (void *phw, ...); +u_int8_t __sdla_shark_te1_read_fe (void *phw, ...); u_int8_t sdla_shark_te1_read_fe (void *phw, ...); static int __sdla_shark_rm_write_fe (void* phw, ...); int sdla_shark_rm_write_fe (void* phw, ...); -static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...); +u_int8_t __sdla_shark_rm_read_fe (void* phw, ...); u_int8_t sdla_shark_rm_read_fe (void* phw, ...); static int __sdla_shark_56k_write_fe(void *phw, ...); int sdla_shark_56k_write_fe(void *phw, ...); -static u_int8_t __sdla_shark_56k_read_fe (void *phw, ...); +u_int8_t __sdla_shark_56k_read_fe (void *phw, ...); u_int8_t sdla_shark_56k_read_fe (void *phw, ...); +static int __write_bri_fe_byte(void*,u_int8_t,u_int8_t,u_int8_t); +int sdla_shark_bri_write_fe (void* phw, ...); +static u_int8_t __read_bri_fe_byte(void*,u_int8_t,u_int8_t,u_int8_t,u_int8_t); +u_int8_t sdla_shark_bri_read_fe (void* phw, ...); + +static int __sdla_shark_serial_write_fe(void *phw, ...); +int sdla_shark_serial_write_fe(void *phw, ...); +u_int32_t __sdla_shark_serial_read_fe (void *phw, ...); +u_int32_t sdla_shark_serial_read_fe (void *phw, ...); + +int sdla_te3_write_fe(void *phw, ...); +u_int8_t sdla_te3_read_fe(void *phw, ...); + extern int sdla_bus_write_1(void* phw, unsigned int offset, u8 value); extern int sdla_bus_write_2(void* phw, unsigned int offset, u16 value); extern int sdla_bus_write_4(void* phw, unsigned int offset, u32 value); @@ -103,6 +135,52 @@ extern int sdla_hw_fe_set_bit(void *phw, int value); ***************************************************************************/ +/*************************************************************************** + Front End DS31/E3 interface +***************************************************************************/ +int sdla_te3_write_fe(void *phw, ...) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + va_list args; + int off, value; + + WAN_ASSERT(phw == NULL); + va_start(args, phw); + off = va_arg(args, int); + value = va_arg(args, int); + va_end(args); + + off &= ~AFT_BIT_DEV_ADDR_CLEAR; + + DEBUG_TEST("%s: WRITE FRAMER OFFSET=0x%02X DATA=0x%02X\n", + hw->devname, framer_off,framer_data); + + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE, (u16)value); + return 0; +} + +u_int8_t sdla_te3_read_fe(void *phw, ...) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + va_list args; + int off; + u_int8_t value; + + WAN_ASSERT(phw == NULL); + va_start(args, phw); + off = va_arg(args, int); + va_end(args); + + off &= ~AFT_BIT_DEV_ADDR_CLEAR; + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); + sdla_bus_read_1(hw,AFT_MCPU_INTERFACE, &value); + + DEBUG_TEST("%s: READ FRAMER OFFSET=0x%02X DATA=0x%02X\n", + hw->devname, off, value); + return value; +} + /*************************************************************************** Front End T1/E1 interface for Normal cards @@ -111,19 +189,19 @@ int sdla_te1_write_fe(void* phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u16 qaccess, off, line_no; - u8 value; + int qaccess, off, line_no, value; + // u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; va_start(args, phw); - qaccess = (u16)va_arg(args, int); - line_no = (u16)va_arg(args, int); - off = (u16)va_arg(args, int); - value = (u8)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); + value = va_arg(args, int); va_end(args); off &= ~BIT_DEV_ADDR_CLEAR; - sdla_bus_write_2(hw, XILINX_MCPU_INTERFACE_ADDR, off); + sdla_bus_write_2(hw, XILINX_MCPU_INTERFACE_ADDR, (u16)off); /* AF: Sep 10, 2003 * IMPORTANT * This delays are required to avoid bridge optimization @@ -132,7 +210,7 @@ int sdla_te1_write_fe(void* phw, ...) if (!qaccess){ WP_DELAY(5); } - sdla_bus_write_1(hw, XILINX_MCPU_INTERFACE, value); + sdla_bus_write_1(hw, XILINX_MCPU_INTERFACE, (u8)value); if (!qaccess){ WP_DELAY(5); } @@ -147,18 +225,18 @@ u_int8_t sdla_te1_read_fe (void* phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u_int16_t qaccess, line_no, off; + int qaccess, line_no, off; u_int8_t tmp; // u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; va_start(args, phw); - qaccess = (u_int16_t)va_arg(args, int); - line_no = (u_int16_t)va_arg(args, int); - off = (u_int8_t)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); va_end(args); off &= ~BIT_DEV_ADDR_CLEAR; - sdla_bus_write_2(hw, XILINX_MCPU_INTERFACE_ADDR, off); + sdla_bus_write_2(hw, XILINX_MCPU_INTERFACE_ADDR, (u16)off); sdla_bus_read_1(hw,XILINX_MCPU_INTERFACE, &tmp); if (!qaccess){ @@ -173,25 +251,32 @@ u_int8_t sdla_te1_read_fe (void* phw, ...) static int __sdla_shark_te1_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; va_list args; - u_int16_t org_off, qaccess, line_no, off; - u_int8_t value; -// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; + int org_off=0, qaccess=0, line_no=0, off=0, value=0; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; va_start(args, phw); qaccess = (u_int16_t)va_arg(args, int); line_no = (u_int16_t)va_arg(args, int); off = (u_int16_t)va_arg(args, int); value = (u_int8_t)va_arg(args, int); va_end(args); + WAN_ASSERT(qaccess != 0 && qaccess != 1); - if (hw->hwcard->core_id == AFT_PMC_FE_CORE_ID){ - off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - }else if (hw->hwcard->core_id == AFT_DS_FE_CORE_ID){ + if (hwcard->core_id == AFT_PMC_FE_CORE_ID){ + off &= ~AFT4_BIT_DEV_ADDR_CLEAR; + }else if (hwcard->core_id == AFT_DS_FE_CORE_ID){ if (off & 0x800) off |= 0x2000; if (off & 0x1000) off |= 0x4000; off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - if (hw->hwcard->adptr_type == A101_ADPTR_2TE1 && line_no == 1){ + if ((hwcard->adptr_type == A101_ADPTR_2TE1 || + hwcard->adptr_type == A101_ADPTR_1TE1) && line_no == 1){ off |= AFT8_BIT_DEV_MAXIM_ADDR_CPLD; } } @@ -214,7 +299,7 @@ static int __sdla_shark_te1_write_fe (void *phw, ...) WP_DELAY(5); } - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, org_off); + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)org_off); if (!qaccess){ WP_DELAY(5); @@ -226,9 +311,9 @@ int sdla_shark_te1_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u_int16_t qaccess, line_no, off; - u_int8_t value; + int qaccess=0, line_no=0, off=0, value=0; + WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_EVENT( @@ -238,53 +323,60 @@ int sdla_shark_te1_write_fe (void *phw, ...) } return -EINVAL; } - va_start(args, phw); - qaccess = (u_int16_t)va_arg(args, int); - line_no = (u_int16_t)va_arg(args, int); - off = (u_int16_t)va_arg(args, int); - value = (u_int8_t)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); + value = va_arg(args, int); va_end(args); + DEBUG_REG("%s: Writting T1/E1 Reg: Line:%d: %02X=%02X\n", + hw->devname, line_no, off, value); __sdla_shark_te1_write_fe(hw, qaccess, line_no, off, value); - sdla_hw_fe_clear_bit(hw,0); - return 0; + return 0; } /*============================================================================ * Read TE1 Front end registers */ -static u_int8_t __sdla_shark_te1_read_fe (void *phw, ...) +u_int8_t __sdla_shark_te1_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; + sdlahw_cpu_t *hwcpu; + sdlahw_card_t *hwcard; va_list args; - u_int16_t org_off, qaccess, line_no, off; - u_int8_t tmp; -// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; + int org_off=0, qaccess=0, line_no=0, off=0, tmp=0; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + hwcpu = hw->hwcpu; + hwcard = hwcpu->hwcard; va_start(args, phw); qaccess = (u_int16_t)va_arg(args, int); line_no = (u_int16_t)va_arg(args, int); - off = (u_int8_t)va_arg(args, int); + off = (u_int16_t)va_arg(args, int); va_end(args); + WAN_ASSERT(qaccess != 0 && qaccess != 1); - if (hw->hwcard->core_id == AFT_PMC_FE_CORE_ID){ + if (hwcard->core_id == AFT_PMC_FE_CORE_ID){ off &= ~AFT4_BIT_DEV_ADDR_CLEAR; - }else if (hw->hwcard->core_id == AFT_DS_FE_CORE_ID){ + }else if (hwcard->core_id == AFT_DS_FE_CORE_ID){ if (off & 0x800) off |= 0x2000; if (off & 0x1000) off |= 0x4000; off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - if (hw->hwcard->adptr_type == A101_ADPTR_2TE1 && line_no == 1){ + if ((hwcard->adptr_type == A101_ADPTR_1TE1 || + hwcard->adptr_type == A101_ADPTR_2TE1) && line_no == 1){ off |= AFT8_BIT_DEV_MAXIM_ADDR_CPLD; } } sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16*)&org_off); - sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); + sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); - sdla_bus_read_1(hw,AFT_MCPU_INTERFACE, (u8*)&tmp); + sdla_bus_read_1(hw,AFT_MCPU_INTERFACE, (u8*)&tmp); if (!qaccess){ WP_DELAY(5); } @@ -294,16 +386,17 @@ static u_int8_t __sdla_shark_te1_read_fe (void *phw, ...) if (!qaccess){ WP_DELAY(5); } - return tmp; + return (u8)tmp; } u_int8_t sdla_shark_te1_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u_int16_t qaccess, line_no, off; + int qaccess=0, line_no=0, off=0; u_int8_t tmp; + WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", @@ -313,14 +406,15 @@ u_int8_t sdla_shark_te1_read_fe (void *phw, ...) } va_start(args, phw); - qaccess = (u_int16_t)va_arg(args, int); - line_no = (u_int16_t)va_arg(args, int); - off = (u_int16_t)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); va_end(args); tmp = __sdla_shark_te1_read_fe(hw, qaccess, line_no, off); - sdla_hw_fe_clear_bit(hw,0); + DEBUG_REG("%s: Reading T1/E1 Reg: Line:%d: %02X=%02X\n", + hw->devname, line_no, off, tmp); return tmp; } @@ -335,15 +429,13 @@ static int __sdla_shark_56k_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u_int16_t qaccess, line_no, off; - u_int8_t value; -// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; + int qaccess, line_no, off, value; va_start(args, phw); - qaccess = (u_int16_t)va_arg(args, int); - line_no = (u_int16_t)va_arg(args, int); - off = (u_int16_t)va_arg(args, int); - value = (u_int8_t)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); + value = va_arg(args, int); va_end(args); off &= ~AFT8_BIT_DEV_ADDR_CLEAR; @@ -363,9 +455,9 @@ int sdla_shark_56k_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u_int16_t qaccess, line_no, off; - u_int8_t value; + int qaccess, line_no, off, value; + WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_EVENT( @@ -377,40 +469,38 @@ int sdla_shark_56k_write_fe (void *phw, ...) } va_start(args, phw); - qaccess = (u_int16_t)va_arg(args, int); - line_no = (u_int16_t)va_arg(args, int); - off = (u_int16_t)va_arg(args, int); - value = (u_int8_t)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); + value = va_arg(args, int); va_end(args); __sdla_shark_56k_write_fe(hw, qaccess, line_no, off, value); sdla_hw_fe_clear_bit(hw,0); - return 0; + return 0; } /*============================================================================ * Read 56k Front end registers */ -static u_int8_t __sdla_shark_56k_read_fe (void *phw, ...) +u_int8_t __sdla_shark_56k_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u_int16_t qaccess, line_no, off; - u_int32_t tmp; -// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; + int qaccess, line_no, off, tmp; va_start(args, phw); - qaccess = (u_int16_t)va_arg(args, int); - line_no = (u_int16_t)va_arg(args, int); - off = (u_int8_t)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); va_end(args); off &= ~AFT8_BIT_DEV_ADDR_CLEAR; - sdla_bus_write_2(hw,0x46, (u16)off); + sdla_bus_write_2(hw, AFT56K_MCPU_INTERFACE_ADDR, (u16)off); - sdla_bus_read_4(hw,0x44, &tmp); + sdla_bus_read_4(hw, AFT56K_MCPU_INTERFACE, &tmp); if (!qaccess){ WP_DELAY(5); @@ -423,9 +513,9 @@ u_int8_t sdla_shark_56k_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; - u_int16_t qaccess, line_no, off; - u_int8_t tmp; + int qaccess, line_no, off, tmp; + WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", @@ -435,15 +525,15 @@ u_int8_t sdla_shark_56k_read_fe (void *phw, ...) } va_start(args, phw); - qaccess = (u_int16_t)va_arg(args, int); - line_no = (u_int16_t)va_arg(args, int); - off = (u_int16_t)va_arg(args, int); + qaccess = va_arg(args, int); + line_no = va_arg(args, int); + off = va_arg(args, int); va_end(args); tmp = __sdla_shark_56k_read_fe(hw, qaccess, line_no, off); sdla_hw_fe_clear_bit(hw,0); - return tmp; + return (u8)tmp; } @@ -463,6 +553,10 @@ static int __sdla_shark_rm_write_fe (void* phw, ...) unsigned char cs = 0x00, ctrl_byte = 0x00; int i; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); @@ -508,7 +602,7 @@ static int __sdla_shark_rm_write_fe (void* phw, ...) ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) - if (hw->hwcard->core_rev > 3){ + if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; @@ -545,7 +639,7 @@ static int __sdla_shark_rm_write_fe (void* phw, ...) ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) - if (hw->hwcard->core_rev > 3){ + if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; @@ -566,7 +660,7 @@ static int __sdla_shark_rm_write_fe (void* phw, ...) sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #if defined(SPI2STEP) WP_DELAY(1); - if (hw->hwcard->core_rev > 3){ + if (hw->hwcpu->hwcard->core_rev > 3){ data |= MOD_SPI_START; }else{ data |= MOD_SPI_V3_START; @@ -609,6 +703,7 @@ int sdla_shark_rm_write_fe (void* phw, ...) int fline; #endif + WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); @@ -632,13 +727,15 @@ int sdla_shark_rm_write_fe (void* phw, ...) return -EINVAL; } + DEBUG_REG("%s: Remora Direct Register %d = %02X\n", + hw->devname, reg, value); __sdla_shark_rm_write_fe(hw, mod_no, type, chain, reg, value); sdla_hw_fe_clear_bit(hw,0); return 0; } -static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) +u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; @@ -647,6 +744,10 @@ static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) unsigned char cs = 0x00, ctrl_byte = 0x00; int i; + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); @@ -691,7 +792,7 @@ static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) - if (hw->hwcard->core_rev > 3){ + if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; @@ -728,7 +829,7 @@ static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) - if (hw->hwcard->core_rev > 3){ + if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; @@ -749,18 +850,20 @@ static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #if defined(SPI2STEP) WP_DELAY(1); - if (hw->hwcard->core_rev > 3){ + if (hw->hwcpu->hwcard->core_rev > 3){ data |= MOD_SPI_START; }else{ data |= MOD_SPI_V3_START; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #endif - DEBUG_TEST("%s: %s: Module %d - Execute SPI command %08X\n", +#if 0 + DEBUG_EVENT("%s: %s: Module %d - Execute SPI command %08X\n", hw->devname, __FUNCTION__, mod_no, data); +#endif for (i=0;i<10;i++){ WP_DELAY(10); sdla_bus_read_4(hw, SPI_INTERFACE_REG, &data); @@ -770,9 +873,9 @@ static u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) } if (data & MOD_SPI_BUSY){ - DEBUG_EVENT("%s: Module %d: Critical Error (%s:%d) Data=0x%0X!\n", + DEBUG_EVENT("%s: Module %d: Critical Error (%s:%d)!\n", hw->devname, mod_no, - __FUNCTION__,__LINE__,data); + __FUNCTION__,__LINE__); return 0xFF; } @@ -790,6 +893,7 @@ u_int8_t sdla_shark_rm_read_fe (void* phw, ...) int fline; #endif + WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); @@ -812,9 +916,460 @@ u_int8_t sdla_shark_rm_read_fe (void* phw, ...) return 0x00; } data = __sdla_shark_rm_read_fe (hw, mod_no, type, chain, reg); + //DEBUG_REG("%s: Remora Read Reg %X = %02X\n", + // hw->devname, reg, data); sdla_hw_fe_clear_bit(hw,0); return data; } +/*************************************************************************** + ISDN BRI Front End interface +***************************************************************************/ +#define SPI_DELAY if(1)WP_DELAY(10) + +#undef SPI_MAX_RETRY_COUNT +#define SPI_MAX_RETRY_COUNT 10000 + +#define SPI_BREAK if(1)break +#define FAST_SPI 0 +/*============================================================================ + * Write ISDN BRI Front end registers + */ +static +int +__write_bri_fe_byte ( + void* phw, + u_int8_t mod_no, + u_int8_t addr, + u_int8_t value) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + bri_reg_t data, dummy; + u_int32_t *data_ptr = (u_int32_t*)&data; + u_int32_t *dummy_ptr = (u_int32_t*)&dummy; + u_int32_t retry_counter; + u_int8_t rm_no=0xFF; + + WAN_ASSERT(hw == NULL); + + DEBUG_REG("%s():%s: mod_no:%d addr=0x%X (%d) value=0x%02X\n", + __FUNCTION__, + hw->devname, + mod_no, + addr, + addr, + value); + + /* Input mod_no is an even number between 0 and 22 (including). + Calculate rm_no - should be between 0 and 3 (including). + */ + rm_no = mod_no / (MAX_BRI_MODULES_PER_REMORA*2); +#if 0 + DEBUG_BRI("%s(input): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + /* Translate mod_no to be between 0 and 2 (including) */ + mod_no = (mod_no / 2) % MAX_BRI_MODULES_PER_REMORA; +#if 0 + DEBUG_BRI("%s(updated): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + if(rm_no > MAX_BRI_REMORAS - 1){ + DEBUG_EVENT("%s:%s(): Line:%d: invalid rm_no: %d!!(mod_no: %d)\n", + hw->devname, __FUNCTION__, __LINE__, rm_no, mod_no); + return 0; + } + + /* setup address offset for fe */ + data.reset = 0; + data.start = 1; + data.reserv1 = 0; + + data.remora_addr = rm_no; + data.mod_addr = mod_no; + + data.data = addr; + data.contrl = 0; + data.contrl |= ADDR_BIT; + + /* DEBUG_BRI("1. data: 0x%08X\n", *data_ptr); */ + /* check spi not busy */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){ + SPI_DELAY; + } else { + SPI_BREAK; + } + } + SPI_DELAY; + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); + return 0; + } + + sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); + + /* start read spi operation */ + data.reset=0; + data.start=1; + data.reserv1=0; + + data.remora_addr = rm_no; + data.mod_addr = mod_no; + + data.data = value; + data.contrl = 0; + + /* DEBUG_BRI("2. data: 0x%08X\n", *data_ptr); */ +#if FAST_SPI + SPI_DELAY; +#else + /* wait for end of spi operation */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} + } + SPI_DELAY; + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + + /* write the actual data */ + sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); + return 0; +} + +int sdla_shark_bri_write_fe (void* phw, ...) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + va_list args; + int mod_no, reg, value; +#if defined(WAN_DEBUG_FE) + char *fname; + int fline; +#endif + + va_start(args, phw); + mod_no = va_arg(args, int); + reg = va_arg(args, int); + value = va_arg(args, int); +#if defined(WAN_DEBUG_FE) + fname = va_arg(args, char*); + fline = va_arg(args, int); +#endif + va_end(args); + + if (sdla_hw_fe_test_and_set_bit(hw,0)){ +#if defined(WAN_DEBUG_FE) + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", + hw->devname, __FUNCTION__,__LINE__, fname, fline); +#else + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + hw->devname, __FUNCTION__,__LINE__); +#endif + return -EINVAL; + } + + __write_bri_fe_byte(hw, (u8)mod_no, (u8)reg, (u8)value); + + sdla_hw_fe_clear_bit(hw,0); + return 0; +} + +/*============================================================================ + * Read ISDN BRI Front end registers + */ +static +u_int8_t +__read_bri_fe_byte( + void* phw, + u_int8_t mod_no, + u_int8_t reg, + u_int8_t type, + u_int8_t optional_arg) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + bri_reg_t data, dummy; + u_int32_t *data_ptr = (u_int32_t*)&data; + u_int32_t *dummy_ptr = (u_int32_t*)&dummy; + u_int32_t retry_counter; + u_int8_t rm_no=0xFF; + u_int8_t value; + + WAN_ASSERT(hw == NULL); + + DEBUG_REG("%s():%s\n", __FUNCTION__, hw->devname); + + if(type != MOD_TYPE_NT && type != MOD_TYPE_TE){ + DEBUG_BRI("%s(): Warning: unknown module type! (%d)\n", __FUNCTION__, type); + } + + /* setup address offset for fe */ + data.reset = 0; + data.start = 1; + data.reserv1= 0; + + if(type == MOD_TYPE_NONE){ + /* the only case we get here is if running module detection code. */ + rm_no = optional_arg; + }else{ + /* Input mod_no is an even number between 0 and 22 (including). + Calculate rm_no - should be between 0 and 3 (including). + */ + if(mod_no % 2){ + DEBUG_BRI("%s(): Warning: module number (%d) is not even!!\n", + __FUNCTION__, mod_no); + } + rm_no = mod_no / (MAX_BRI_MODULES_PER_REMORA*2); +#if 0 + DEBUG_BRI("%s(input): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + /* Translate mod_no to be between 0 and 2 (including) */ + mod_no = (mod_no / 2) % MAX_BRI_MODULES_PER_REMORA; + } +#if 0 + DEBUG_BRI("%s(updated): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); +#endif + if(rm_no > MAX_BRI_REMORAS - 1){ + DEBUG_EVENT("%s:%s(): Line:%d: invalid rm_no: %d!!(mod_no: %d)\n", + hw->devname, __FUNCTION__, __LINE__, rm_no, mod_no); + return 0; + } + + data.remora_addr = rm_no; + data.mod_addr = mod_no; + + data.data = reg; + data.contrl = 0; + data.contrl |= ADDR_BIT; + + /* check spi not busy */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} + } + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); + return 0; + } + + /* DEBUG_BRI("1. data: 0x%08X\n", *data_ptr); */ + /* setup the address */ + sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); + + /* DEBUG_BRI("2. data: 0x%08X\n", *data_ptr); */ + /* wait for end of spi operation */ +#if !FAST_SPI + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} + } + SPI_DELAY; + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + + /* setup data for read spi operation */ + data.reset=0; + data.start=1; + data.reserv1=0; + + data.remora_addr = rm_no; + data.mod_addr = mod_no; + + data.data = 0; + data.contrl = 0; + data.contrl |= READ_BIT; + +#if FAST_SPI + SPI_DELAY; +#else + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); + if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} + } + SPI_DELAY; + if(dummy.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + /* start read spi operation */ + sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); + +#if FAST_SPI + SPI_DELAY; +#else + /* wait for end of spi operation */ + for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ + sdla_bus_read_4(hw, SPI_INTERFACE_REG, data_ptr); + if(data.start == 1){ SPI_DELAY; }else{ SPI_BREAK; } + } + SPI_DELAY; + if(data.start == 1){ + DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); + return 0; + } +#endif + //DEBUG_BRI("3. data: 0x%08X\n", *data_ptr); + + value = (u_int8_t)data.data; + + DEBUG_REG("%s():%s: mod_no:%d reg=0x%X (%d) value=0x%02X\n", + __FUNCTION__, + hw->devname, + mod_no, + reg, + reg, + value); + return value; +} + +u_int8_t sdla_shark_bri_read_fe (void* phw, ...) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + va_list args; + int mod_no, type, optional_arg, reg; + u_int8_t data = 0; +#if defined(WAN_DEBUG_FE) + char *fname; + int fline; +#endif + + va_start(args, phw); + mod_no = va_arg(args, int); + type = va_arg(args, int); + optional_arg = va_arg(args, int); + reg = va_arg(args, int); +#if defined(WAN_DEBUG_FE) + fname = va_arg(args, char*); + fline = va_arg(args, int); +#endif + va_end(args); + + if (sdla_hw_fe_test_and_set_bit(hw,0)){ +#if defined(WAN_DEBUG_FE) + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", + hw->devname, __FUNCTION__,__LINE__,fname,fline); +#else + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + hw->devname, __FUNCTION__,__LINE__); +#endif + return 0x00; + } + + data = __read_bri_fe_byte (hw, (u8)mod_no, (u8)reg, (u8)type, (u8)optional_arg); + + sdla_hw_fe_clear_bit(hw,0); + return data; +} + +/*************************************************************************** + Front End AFT Serial interface for Shark subtype cards +***************************************************************************/ +#define AFT_SERIAL_FE_INTERFACE_ADDR 0x210 +#define AFT_SERIAL_PORT_REG(line,reg) (reg+(0x4000*line)) +/*============================================================================ + * Read AFT Serial Front end registers + */ +static int __sdla_shark_serial_write_fe (void *phw, ...) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + va_list args; + unsigned int addr; + int line_no, off, value; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + va_start(args, phw); + line_no = (int)va_arg(args, int); + off = (int)va_arg(args, int); + value = (int)va_arg(args, int); + va_end(args); + + addr = AFT_SERIAL_PORT_REG(line_no,AFT_SERIAL_FE_INTERFACE_ADDR); + sdla_bus_write_4(hw, addr, value); + return 0; +} + +int sdla_shark_serial_write_fe (void *phw, ...) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + va_list args; + int line_no, off, value; + + if (sdla_hw_fe_test_and_set_bit(hw,0)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT( + "%s: %s:%d: Critical Error: Re-entry in FE!\n", + hw->devname, + __FUNCTION__,__LINE__); + } + return -EINVAL; + } + + va_start(args, phw); + line_no = (int)va_arg(args, int); + off = (int)va_arg(args, int); + value = (int)va_arg(args, int); + va_end(args); + + __sdla_shark_serial_write_fe(hw, line_no, off, value); + + sdla_hw_fe_clear_bit(hw,0); + return 0; +} + +/*============================================================================ + * Read AFT Serial Front end registers + */ +u_int32_t __sdla_shark_serial_read_fe (void *phw, ...) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + va_list args; + unsigned int addr; + int off, line_no, value; + + WAN_ASSERT(hw == NULL); + WAN_ASSERT(hw->hwcpu == NULL); + WAN_ASSERT(hw->hwcpu->hwcard == NULL); + va_start(args, phw); + line_no = (int)va_arg(args, int); + off = (int)va_arg(args, int); + va_end(args); + + addr = AFT_SERIAL_PORT_REG(line_no,AFT_SERIAL_FE_INTERFACE_ADDR); + sdla_bus_read_4(hw, addr, (u32*)&value); + return value; +} + +u_int32_t sdla_shark_serial_read_fe(void *phw, ...) +{ + sdlahw_t* hw = (sdlahw_t*)phw; + va_list args; + int line_no, off, value; + + if (sdla_hw_fe_test_and_set_bit(hw,0)){ + if (WAN_NET_RATELIMIT()){ + DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", + hw->devname, __FUNCTION__,__LINE__); + } + return 0x00; + } + + va_start(args, phw); + line_no = va_arg(args, int); + off = va_arg(args, int); + va_end(args); + + value = __sdla_shark_serial_read_fe(hw, line_no, off); + + sdla_hw_fe_clear_bit(hw,0); + return value; +} diff --git a/patches/kdrivers/src/net/sdladrv_utils.c b/patches/kdrivers/src/net/sdladrv_utils.c new file mode 100644 index 0000000..fcd11b2 --- /dev/null +++ b/patches/kdrivers/src/net/sdladrv_utils.c @@ -0,0 +1,295 @@ +/***************************************************************************** +* sdladrv_utils.c SDLADRV utils functions. +* +* +* Author: Alex Feldman +* +* Copyright: (c) 2007 Sangoma Technologies Inc. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* ============================================================================ +* Jan 20, 2007 Alex Feldman Initial version +* +*****************************************************************************/ + + +/*************************************************************************** +**** I N C L U D E F I L E S **** +***************************************************************************/ +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#elif defined(__WINDOWS__) +# include +# include +# include +# include +# include +# include /* SDLA firmware module definitions */ +# include /* SDLA PCI hardware definitions */ +# include +# include /* API definitions */ +#elif defined(__LINUX__)||defined(__KERNEL__) +# define _K22X_MODULE_FIX_ +# include +# include +# include +# include +# include +# include /* SDLA firmware module definitions */ +# include /* SDLA PCI hardware definitions */ +# include +# include /* API definitions */ +#else +# error "Unsupported Operating System!" +#endif + +/*************************************************************************** +**** M A C R O S / D E F I N E S **** +***************************************************************************/ +//This is the address of the ECCTL register , page 149 of PEX8111 datasheet. +#define SDLA_PLX_EECTL 0x1004 + +//Change this accordingly.!!! +#define SDLA_PLX_EEPROM_SIZE 0xFF + +#define SDLA_PLX_EEPROM_BUSY 19 +#define SDLA_PLX_EEPROM_CS_ENABLE 18 +#define SDLA_PLX_EEPROM_BYTE_READ_START 17 +#define SDLA_PLX_EEPROM_READ_DATA 8 +#define SDLA_PLX_EEPROM_WRITE_DATA 0 +#define SDLA_PLX_EEPROM_BYTE_WRITE_START 16 + +//EEPROM COMMANDS +#define SDLA_PLX_READ_STATUS_EE_OPCODE 0x05 +#define SDLA_PLX_WREN_EE_OPCODE 0x06 +#define SDLA_PLX_WRITE_EE_OPCODE 0x02 +#define SDLA_PLX_READ_EE_OPCODE 0x03 + + +/*************************************************************************** +**** F U N C T I O N P R O T O T Y P E S **** +***************************************************************************/ + +/*************************************************************************** +**** G L O B A L D A T A **** +***************************************************************************/ + +/*************************************************************************** +**** F U N C T I O N D E F I N I T I O N **** +***************************************************************************/ +static void sdla_plx_8111Read(void *phw, int addr, int *data); +static void sdla_plx_8111Write(void *phw, int addr, int data); +static int sdla_plx_EE_waitidle(void *phw); +static int sdla_plx_EE_off(void *phw); +static unsigned char sdla_plx_EE_readbyte(void *phw); +static int sdla_plx_EE_writebyte(void *phw, unsigned char); + +unsigned char sdla_plxctrl_status(void *phw); +unsigned char sdla_plxctrl_read8(void *phw, short); +void sdla_plxctrl_write8(void *phw, short, unsigned char); +void sdla_plxctrl_erase(void *phw); + +extern int sdla_pci_bridge_read_config_dword(void*, int, u_int32_t*); +extern int sdla_pci_bridge_write_config_dword(void*, int, u_int32_t); + +/************************************************************************/ +/* GLOBAL VARIABLES */ +/************************************************************************/ + +/************************************************************************/ +/* FUNCTION PROTOTYPES */ +/************************************************************************/ + +/////////////////////////////////////////////////////////////////// +//Write the value read into the dst pointer. +static void sdla_plx_8111Read(void *phw, int addr, int *data) +{ + WAN_ASSERT_VOID(phw == NULL); + if (addr < 0x1000){ + sdla_pci_bridge_read_config_dword(phw, addr, data); + }else if (addr >= 0x1000 && addr <= 0x1FFF){ + sdla_pci_bridge_write_config_dword(phw, 0x84, addr); + sdla_pci_bridge_read_config_dword(phw, 0x88, data); + } +} + +/////////////////////////////////////////////////////////////////// +static void sdla_plx_8111Write(void *phw, int addr, int data) +{ + WAN_ASSERT_VOID(phw == NULL); + if (addr < 0x1000){ + sdla_pci_bridge_write_config_dword(phw, addr, data); + }else if (addr >= 0x1000 && addr <= 0x1FFF){ + sdla_pci_bridge_write_config_dword(phw, 0x84, addr); + sdla_pci_bridge_write_config_dword(phw, 0x88, data); + } +} + +/////////////////////////////////////////////////////////////////// +static int sdla_plx_EE_waitidle(void *phw) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + int eeCtl, ii; + + WAN_ASSERT(phw == NULL); + for (ii = 0; ii < 100; ii++){ + /* read current value in EECTL */ + sdla_plx_8111Read(phw, SDLA_PLX_EECTL, &eeCtl); + /* loop until idle */ + if ((eeCtl & (1 << SDLA_PLX_EEPROM_BUSY)) == 0){ + return(eeCtl); + } + } + DEBUG_EVENT("%s: ERROR: EEPROM Busy timeout!\n", + hw->devname); + return -EINVAL; +} + +/////////////////////////////////////////////////////////////////// +static int sdla_plx_EE_off(void *phw) +{ + + WAN_ASSERT(phw == NULL); + /* make sure EEPROM is idle */ + sdla_plx_EE_waitidle(phw); + /* turn off everything (especially SDLA_PLX_EEPROM_CS_ENABLE)*/ + sdla_plx_8111Write(phw, SDLA_PLX_EECTL, 0); + return 0; +} + +/////////////////////////////////////////////////////////////////// +static unsigned char sdla_plx_EE_readbyte(void *phw) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + int i, eeCtl = 0x00; + unsigned char data = 0x00; + + WAN_ASSERT_RC(phw == NULL, 0xFF); + eeCtl = sdla_plx_EE_waitidle(phw); + + eeCtl = 0; + eeCtl |= (1 << SDLA_PLX_EEPROM_CS_ENABLE) | + (1 << SDLA_PLX_EEPROM_BYTE_READ_START); + sdla_plx_8111Write(phw, SDLA_PLX_EECTL, eeCtl); /* start reading */ + for (i=0;i<1000;i++){ + sdla_plx_8111Read(phw, SDLA_PLX_EECTL, &eeCtl); + if ((eeCtl & (1 << SDLA_PLX_EEPROM_BYTE_READ_START)) == 0){ + break; + } + } + if ((eeCtl & (1 << SDLA_PLX_EEPROM_BYTE_READ_START)) != 0){ + DEBUG_EVENT("%s: Timeout on PLX READ!\n", + hw->devname); + return 0xFF; + } + + eeCtl = sdla_plx_EE_waitidle(phw); /* wait until read is done */ + sdla_plx_8111Read(phw, SDLA_PLX_EECTL, &eeCtl); + data = (eeCtl >> SDLA_PLX_EEPROM_READ_DATA) & 0xFF; + + /* extract read data from EECTL */ + return data; +} + +/////////////////////////////////////////////////////////////////// +static int sdla_plx_EE_writebyte(void *phw, unsigned char val) +{ + sdlahw_t *hw = (sdlahw_t*)phw; + int i, eeCtl = 0; /* make sure EEPROM is idle */ + + WAN_ASSERT(phw == NULL); + eeCtl = sdla_plx_EE_waitidle(phw); /* make sure EEPROM is idle */ + /* clear current WRITE value */ + eeCtl = 0; + eeCtl &= ~(0xff << SDLA_PLX_EEPROM_WRITE_DATA); + eeCtl |= (1 << SDLA_PLX_EEPROM_CS_ENABLE) | + (1 << SDLA_PLX_EEPROM_BYTE_WRITE_START) | + ((val & 0xff) << SDLA_PLX_EEPROM_WRITE_DATA); + sdla_plx_8111Write(phw, SDLA_PLX_EECTL, eeCtl); + + for (i=0;i<1000;i++){ + sdla_plx_8111Read(phw, SDLA_PLX_EECTL, &eeCtl); + if ((eeCtl & (1 << SDLA_PLX_EEPROM_BYTE_WRITE_START)) == 0){ + break; + } + } + if ((eeCtl & (1 << SDLA_PLX_EEPROM_BYTE_WRITE_START)) != 0){ + DEBUG_EVENT("%s: Timeout on PLX write!\n", + hw->devname); + return -EINVAL; + } + return 0; +} + + +/*************************************************************************** +**** These are the high level functions **** +***************************************************************************/ + +/////////////////////////////////////////////////////////////////// +unsigned char sdla_plxctrl_status(void *phw) +{ + unsigned char status = 0; + + WAN_ASSERT_RC(phw == NULL, 0xFF); + sdla_plx_EE_writebyte(phw, SDLA_PLX_READ_STATUS_EE_OPCODE); + status = sdla_plx_EE_readbyte(phw); /* get EEPROM status */ + sdla_plx_EE_off(phw); /* turn off EEPROM */ + + return status; +} + +void sdla_plxctrl_write8(void *phw, short addr, unsigned char data) +{ + + WAN_ASSERT_VOID(phw == NULL); + sdla_plx_EE_writebyte(phw, SDLA_PLX_WREN_EE_OPCODE); /* must first write-enable */ + sdla_plx_EE_off(phw); /* turn off EEPROM */ + sdla_plx_EE_writebyte(phw, SDLA_PLX_WRITE_EE_OPCODE); /* opcode to write bytes */ + + /* Send low byte of address */ + sdla_plx_EE_writebyte(phw, (unsigned char)(addr & 0xFF)); + + sdla_plx_EE_writebyte(phw, 0xFF & data); /* send data to be written */ + + sdla_plx_EE_off(phw); /* turn off EEPROM */ + return; +} + +/////////////////////////////////////////////////////////////////// +unsigned char sdla_plxctrl_read8(void *phw, short addr) +{ + unsigned char ch; + + WAN_ASSERT_RC(phw == NULL, 0xFF); + sdla_plx_EE_writebyte(phw, SDLA_PLX_READ_EE_OPCODE); + sdla_plx_EE_writebyte(phw, (unsigned char)(addr & 0xFF)); + + ch = sdla_plx_EE_readbyte(phw); + sdla_plx_EE_off(phw); + return ch; +} + +void sdla_plxctrl_erase(void *phw) +{ + int t; + + WAN_ASSERT_VOID(phw == NULL); + for(t = 0; t < SDLA_PLX_EEPROM_SIZE; t++){ + sdla_plxctrl_write8(phw, t, 0xFF); + } + return; +} + diff --git a/patches/kdrivers/src/net/sdlamain.c b/patches/kdrivers/src/net/sdlamain.c index 5025e06..c87e3ae 100644 --- a/patches/kdrivers/src/net/sdlamain.c +++ b/patches/kdrivers/src/net/sdlamain.c @@ -184,10 +184,24 @@ #define wp_xilinx_init(card,conf) (-EPROTONOSUPPORT) #endif +#ifndef CONFIG_PRODUCT_WANPIPE_AFT_BRI + #define wp_aft_bri_init(card,conf) (-EPROTONOSUPPORT) +#endif + +#ifndef CONFIG_PRODUCT_WANPIPE_AFT_SERIAL + #define wp_aft_serial_init(card,conf) (-EPROTONOSUPPORT) +#endif + #ifndef CONFIG_PRODUCT_WANPIPE_AFT_TE1 #define wp_aft_te1_init(card,conf) (-EPROTONOSUPPORT) +#endif + +#ifndef CONFIG_PRODUCT_WANPIPE_AFT_RM #define wp_aft_analog_init(card,conf) (-EPROTONOSUPPORT) - #define aft_global_hw_device_init() +#endif + +#ifndef CONFIG_PRODUCT_WANPIPE_AFT_56K + #define wp_aft_56k_init(card,conf) (-EPROTONOSUPPORT) #endif #ifndef CONFIG_PRODUCT_WANPIPE_AFT_TE3 @@ -378,6 +392,7 @@ int __init wanpipe_init(void) ncards=0; + if (WANPIPE_VERSION_BETA){ DEBUG_EVENT("%s Beta %s.%s %s %s\n", fullname, WANPIPE_VERSION, WANPIPE_SUB_VERSION, @@ -403,12 +418,12 @@ int __init wanpipe_init(void) wanpipe_debug=NULL; for (i=0;ilist; - kfree(tmpcard); + wan_free(tmpcard); tmpcard=tmp; } card_list=NULL; @@ -429,7 +444,7 @@ int __init wanpipe_init(void) sprintf(card->devname, "%s%d", drvname, ++cnt); wandev->magic = ROUTER_MAGIC; wandev->name = card->devname; - wandev->private = card; + wandev->priv = card; wandev->enable_tx_int = 0; wandev->setup = &setup; wandev->shutdown = &shutdown; @@ -449,7 +464,7 @@ int __init wanpipe_init(void) for (tmpcard=card_list;tmpcard;){ unregister_wan_device(tmpcard->devname); tmp=tmpcard->list; - kfree(tmpcard); + wan_free(tmpcard); tmpcard=tmp; } card_list=NULL; @@ -474,11 +489,14 @@ int __init wanpipe_init(void) wanpipe_globals_util_init(); +#if defined(CONFIG_PRODUCT_WANPIPE_AFT_CORE) aft_global_hw_device_init(); +#endif #if 0 wp_tasklet_per_cpu_init(); #endif + return err; } @@ -492,6 +510,7 @@ void __exit wanpipe_exit(void) { sdla_t *tmpcard, *tmp; + wanpipe_unregister_fw_from_api(); if (!card_list) @@ -500,7 +519,7 @@ void __exit wanpipe_exit(void) for (tmpcard=card_list;tmpcard;){ unregister_wan_device(tmpcard->devname); tmp=tmpcard->list; - kfree(tmpcard); + wan_free(tmpcard); tmpcard=tmp; } @@ -511,9 +530,6 @@ void __exit wanpipe_exit(void) DEBUG_EVENT("\n"); DEBUG_EVENT("wanpipe: WANPIPE Modules Unloaded.\n"); -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("wanpipe: Total Mem %d\n",atomic_read(&wan_debug_mem)); -#endif } module_init(wanpipe_init); @@ -544,18 +560,19 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf) int err = 0; int irq=0; + /* Sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL) || (conf == NULL)){ + if ((wandev == NULL) || (wandev->priv == NULL) || (conf == NULL)){ DEBUG_EVENT("%s: Failed Sdlamain Setup wandev %p, card %p, conf %p !\n", wandev->name, - wandev,wandev->private, + wandev,wandev->priv, conf); return -EFAULT; } DEBUG_EVENT("%s: Starting WAN Setup\n", wandev->name); - card = wandev->private; + card = wandev->priv; if (wandev->state != WAN_UNCONFIGURED){ DEBUG_EVENT("%s: Device already configured\n", wandev->name); @@ -590,14 +607,23 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf) conf->card_type = WANOPT_AFT300; conf->S514_CPU_no[0] = 'A'; break; + case WANCONFIG_AFT_ISDN_BRI: + conf->card_type = WANOPT_AFT_ISDN; + conf->S514_CPU_no[0] = 'A'; + break; case WANCONFIG_AFT_56K: conf->card_type = WANOPT_AFT_56K; conf->S514_CPU_no[0] = 'A'; break; + case WANCONFIG_AFT_SERIAL: + conf->card_type = WANOPT_AFT_SERIAL; + conf->S514_CPU_no[0] = 'A'; + break; } wandev->card_type = conf->card_type; + card->hw = sdla_register(&card->hw_iface, conf, card->devname); if (card->hw == NULL){ return -EINVAL; @@ -654,8 +680,11 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf) case WANOPT_AFT: case WANOPT_AFT104: case WANOPT_AFT300: + case WANOPT_AFT_ISDN: case WANOPT_AFT_ANALOG: case WANOPT_AFT_56K: + case WANOPT_AFT_SERIAL: + err=0; if ((err=check_aft_conflicts(card,conf,&irq)) != 0){ sdla_unregister(&card->hw, card->devname); @@ -664,7 +693,7 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf) break; default: - DEBUG_EVENT("%s: ERROR, invalid card type 0x%0X!\n", + DEBUG_EVENT("%s: (1) ERROR, invalid card type 0x%0X!\n", card->devname,conf->card_type); sdla_unregister(&card->hw, card->devname); return -EINVAL; @@ -909,6 +938,18 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf) err = wp_aft_analog_init(card,conf); break; + case WANCONFIG_AFT_ISDN_BRI: + DEBUG_EVENT("%s: Starting AFT ISDN BRI Hardware Init.\n", + card->devname); + err = wp_aft_bri_init(card,conf); + break; + + case WANCONFIG_AFT_SERIAL: + DEBUG_EVENT("%s: Starting AFT Serial (V32/RS232) Hardware Init.\n", + card->devname); + err = wp_aft_serial_init(card,conf); + break; + case WANCONFIG_AFT_TE3: DEBUG_EVENT("%s: Starting AFT TE3 Hardware Init.\n", card->devname); @@ -1354,7 +1395,7 @@ static int shutdown (wan_device_t* wandev, wandev_conf_t* conf) int err=0; /* sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL)){ + if ((wandev == NULL) || (wandev->priv == NULL)){ return -EFAULT; } @@ -1362,7 +1403,7 @@ static int shutdown (wan_device_t* wandev, wandev_conf_t* conf) return 0; } - card = wandev->private; + card = wandev->priv; if (card->tty_opt){ if (card->tty_open){ @@ -1509,13 +1550,13 @@ static int ioctl (wan_device_t* wandev, unsigned cmd, unsigned long arg) int err; /* sanity checks */ - if ((wandev == NULL) || (wandev->private == NULL)) + if ((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; //ALEX-HWABSTR // if (wandev->state == WAN_UNCONFIGURED) // return -ENODEV; - card = wandev->private; + card = wandev->priv; if (test_bit(SEND_CRIT, (void*)&wandev->critical)) { return -EAGAIN; @@ -1523,11 +1564,11 @@ static int ioctl (wan_device_t* wandev, unsigned cmd, unsigned long arg) switch (cmd) { case WANPIPE_DUMP: - err = ioctl_dump(wandev->private, (void*)arg); + err = ioctl_dump(wandev->priv, (void*)arg); break; case WANPIPE_EXEC: - err = ioctl_exec(wandev->private, (void*)arg, cmd); + err = ioctl_exec(wandev->priv, (void*)arg, cmd); break; default: err = -EINVAL; @@ -1565,7 +1606,7 @@ static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump) return -EINVAL; } - data = kmalloc(dump.length, GFP_KERNEL); + data = wan_kmalloc(dump.length); if (data == NULL){ return -ENOMEM; } @@ -1575,7 +1616,7 @@ static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump) if(copy_to_user((void *)dump.ptr, data, dump.length)){ err = -EFAULT; } - kfree(data); + wan_free(data); return err; } @@ -1935,7 +1976,7 @@ void add_gateway(sdla_t *card, netdevice_t *dev) static int debugging (wan_device_t* wandev) { - sdla_t* card = (sdla_t*)wandev->private; + sdla_t* card = (sdla_t*)wandev->priv; if (wandev->state == WAN_UNCONFIGURED){ return 0; diff --git a/patches/kdrivers/src/net/wanpipe_abstr.c b/patches/kdrivers/src/net/wanpipe_abstr.c index 0aeb5a5..40168af 100644 --- a/patches/kdrivers/src/net/wanpipe_abstr.c +++ b/patches/kdrivers/src/net/wanpipe_abstr.c @@ -32,6 +32,9 @@ # include # include # include +#elif defined(__WINDOWS__) +# include +# include #elif defined(__KERNEL__) # include # include @@ -140,7 +143,11 @@ void wpabs_skb_free(void* skb) /* ** wpabs_skb_copyback() - */ +#if defined(__WINDOWS__) || defined(__FreeBSD__) +void wpabs_skb_copyback(void* skb, int off, int len, caddr_t cp) +#else void wpabs_skb_copyback(void* skb, int off, int len, unsigned long cp) +#endif { wan_skb_copyback(skb, off, len, (caddr_t)cp); } @@ -304,7 +311,7 @@ void *wpabs_netif_alloc(unsigned char *dev_name,int ifType, int *err) void wpabs_netif_free(void *dev) { - return wan_netif_free(dev); + wan_netif_free(dev); } @@ -318,7 +325,7 @@ unsigned char* wpabs_netif_name(void *dev) */ int wpabs_netif_queue_stopped(void* dev) { - return WAN_NETIF_QUEUE_STOPPED((netdevice_t*)dev); + return WAN_NETIF_QUEUE_STOPPED(((netdevice_t*)dev)); } /* @@ -358,7 +365,12 @@ void wpabs_add_timer(void* timer_info, unsigned long delay) /* ** wpabs_init_timer */ -void wpabs_init_timer(void* timer_info, void* timer_func, unsigned long data) +void wpabs_init_timer(void* timer_info, void* timer_func, +#if defined(__WINDOWS__) + wan_timer_arg_t data) +#else + unsigned long data) +#endif { wan_timer_t* timer = (wan_timer_t*)timer_info; @@ -385,12 +397,20 @@ void wpabs_del_timer(void* timer_info) unsigned long* wpabs_dma_get_vaddr(void* pcard, void* dma_descr) { +#if defined(__WINDOWS__) + return ((wan_dma_descr_t*)dma_descr)->vAddr; +#else return wan_dma_get_vaddr(pcard,dma_descr); +#endif } unsigned long wpabs_dma_get_paddr(void* pcard, void* dma_descr) { +#if defined(__WINDOWS__) + return ((wan_dma_descr_t*)dma_descr)->physicalAddr.u.LowPart; +#else return wan_dma_get_paddr(pcard,dma_descr); +#endif } void* wpabs_malloc(int size) @@ -481,7 +501,7 @@ void* wpabs_spinlock_alloc(void) } void wpabs_spinlock_free(void* lock) { - return wan_free(lock); + wan_free(lock); } /* @@ -508,12 +528,12 @@ void wpabs_spin_unlock_irqrestore(void* lock,unsigned long *flags) /* ** */ -void wpabs_spin_lock_init(void* lock) +void wpabs_spin_lock_init(void* lock, char *name) { wan_spinlock_t* SpinLock = (wan_spinlock_t*)lock; WAN_ASSERT1(SpinLock == NULL); - wan_spin_lock_init(SpinLock); + wan_spin_lock_irq_init(SpinLock, name); } @@ -570,7 +590,6 @@ void wpabs_write_rw_unlock_irq(void* lock,unsigned long *flags) /* ** */ - void wpabs_debug_event(const char * fmt, ...) { #ifdef WAN_DEBUG_EVENT @@ -710,6 +729,8 @@ int wpabs_test_and_set_bit(int bit, void *ptr) } wan_set_bit(bit,ptr); return 0; +#elif defined(__WINDOWS__) + return test_and_set_bit(bit,ptr); #else # error "Error: wpabs_test_and_set_bit() not implemented!" #endif @@ -733,11 +754,11 @@ int wpabs_clear_bit(int bit, void *ptr) return 0; } -unsigned long wpabs_get_systemticks(void) +wan_ticks_t wpabs_get_systemticks(void) { return SYSTEM_TICKS; } - + unsigned long wpabs_get_hz(void) { return HZ; @@ -935,6 +956,9 @@ unsigned long wan_get_ip_addr(void* dev, int option) #elif defined(__NetBSD__) || defined(__OpenBSD__) addr = (struct sockaddr_in *)ifa->ifa_addr; return htonl(addr->sin_addr.s_addr); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else return ifaddr->ifa_local; #endif @@ -948,6 +972,9 @@ unsigned long wan_get_ip_addr(void* dev, int option) return addr->sin_addr.s_addr; #elif defined(__NetBSD__) || defined(__OpenBSD__) return 0; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else return ifaddr->ifa_address; #endif @@ -956,6 +983,9 @@ unsigned long wan_get_ip_addr(void* dev, int option) case WAN_NETMASK_IP: #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) return 0; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else return ifaddr->ifa_mask; #endif @@ -964,6 +994,9 @@ unsigned long wan_get_ip_addr(void* dev, int option) case WAN_BROADCAST_IP: #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) return 0; +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL + return 0; #else return ifaddr->ifa_broadcast; #endif @@ -1061,6 +1094,8 @@ int wpabs_net_ratelimit(void) ** For these OS always print all messages. */ return 1; +#elif defined(__WINDOWS__) + return 1; #else # error "wpabs_netrate_limit not supported" #endif @@ -1074,6 +1109,8 @@ void wpabs_get_random_bytes(void *ptr, int len) read_random(ptr,len); #elif defined(__OpenBSD__) get_random_bytes(ptr,len); +#elif defined(__WINDOWS__) + FUNC_NOT_IMPL #else # error "wpabs_get_random_bytes not supported" #endif diff --git a/patches/kdrivers/src/net/wanpipe_codec.c b/patches/kdrivers/src/net/wanpipe_codec.c index 13c1f03..566c809 100644 --- a/patches/kdrivers/src/net/wanpipe_codec.c +++ b/patches/kdrivers/src/net/wanpipe_codec.c @@ -26,7 +26,7 @@ # include # include # include -#elif (defined __WINDOWS__) +#elif defined(__WINDOWS__) # include # include # include @@ -44,6 +44,8 @@ wanpipe_codec_ops_t *WANPIPE_CODEC_OPS[WP_TDM_HW_CODING_MAX][WP_TDM_CODEC_MAX]; #ifdef __LINUX__ __init int wanpipe_codec_init(void) +#elif defined(__WINDOWS__) +int wanpipe_codec_init(void) #else __init int wanpipe_codec_init(void) #endif diff --git a/patches/kdrivers/src/net/wanpipe_codec_law.c b/patches/kdrivers/src/net/wanpipe_codec_law.c index a764c82..6f508c1 100644 --- a/patches/kdrivers/src/net/wanpipe_codec_law.c +++ b/patches/kdrivers/src/net/wanpipe_codec_law.c @@ -28,13 +28,11 @@ # include #elif (defined __WINDOWS__) # include -# include -# include -# include # include # include #define __init +#define inline __inline #define DBG_LAW if(1)DbgPrint diff --git a/patches/kdrivers/src/net/wanpipe_linux_iface.c b/patches/kdrivers/src/net/wanpipe_linux_iface.c index 97d8ff9..8450848 100644 --- a/patches/kdrivers/src/net/wanpipe_linux_iface.c +++ b/patches/kdrivers/src/net/wanpipe_linux_iface.c @@ -58,7 +58,6 @@ static int wan_iface_send(netskb_t*, netdevice_t*); static int wan_iface_ioctl(netdevice_t*, struct ifreq*, int); static struct net_device_stats* wan_iface_get_stats (netdevice_t*); static void wan_iface_tx_timeout (netdevice_t*); -static int wan_iface_change_mtu (netdevice_t *dev, int new_mtu); #ifdef CONFIG_PRODUCT_WANPIPE_GENERIC static int wan_iface_hdlc_attach(hdlc_device*, unsigned short,unsigned short); @@ -224,11 +223,11 @@ static int wan_iface_init(netdevice_t* dev) dev->open = &wan_iface_open; dev->stop = &wan_iface_close; + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &wan_iface_send; dev->get_stats = &wan_iface_get_stats; dev->tx_timeout = &wan_iface_tx_timeout; - dev->change_mtu = &wan_iface_change_mtu; - dev->watchdog_timeo = HZ*2; dev->hard_header_len = 32; dev->set_config = NULL; @@ -267,6 +266,9 @@ static int wan_iface_eth_init(netdevice_t* dev) dev->do_ioctl = &wan_iface_ioctl; dev->open = &wan_iface_open; dev->stop = &wan_iface_close; + + dev->hard_header = NULL; + dev->rebuild_header = NULL; dev->hard_start_xmit = &wan_iface_send; dev->get_stats = &wan_iface_get_stats; dev->tx_timeout = &wan_iface_tx_timeout; @@ -416,13 +418,12 @@ On shutdown, this is possible common = wan_netif_priv(dev); if (common && common->iface.get_stats){ return common->iface.get_stats(dev); + }else{ + return &gif_stats; } - return &gif_stats; + return NULL; } - - - /*============================================================================ * Handle transmit timeout event from netif watchdog */ @@ -443,25 +444,6 @@ static void wan_iface_tx_timeout (netdevice_t *dev) return; } - -static int wan_iface_change_mtu (netdevice_t *dev, int new_mtu) -{ - wanpipe_common_t *common; - - WAN_ASSERT(wan_netif_priv(dev) == NULL); - common = wan_netif_priv(dev); - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - if (common->iface.change_mtu){ - return common->iface.change_mtu(dev,new_mtu); - } - - return 0; -} - static int wan_iface_input(netdevice_t* dev, netskb_t* skb) { wanpipe_common_t *common; diff --git a/patches/kdrivers/src/net/wanpipe_multppp.c b/patches/kdrivers/src/net/wanpipe_multppp.c index bbe10ee..f02ab00 100644 --- a/patches/kdrivers/src/net/wanpipe_multppp.c +++ b/patches/kdrivers/src/net/wanpipe_multppp.c @@ -326,7 +326,7 @@ int wp_mprot_init (sdla_t* card, wandev_conf_t* conf) if (IS_TE1_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_te_iface_init(&card->wandev.fe_iface); + sdla_te_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -334,7 +334,7 @@ int wp_mprot_init (sdla_t* card, wandev_conf_t* conf) card->wandev.fe_enable_timer = chdlc_enable_timer; card->wandev.te_link_state = handle_front_end_state; - conf->interface = + conf->electrical_interface = (IS_T1_CARD(card)) ? WANOPT_V35 : WANOPT_RS232; if (card->u.c.comm_port == WANOPT_PRI){ @@ -344,7 +344,7 @@ int wp_mprot_init (sdla_t* card, wandev_conf_t* conf) }else if (IS_56K_MEDIA(&conf->fe_cfg)){ memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t)); - sdla_56k_iface_init(&card->wandev.fe_iface); + sdla_56k_iface_init(&card->fe, &card->wandev.fe_iface); card->fe.name = card->devname; card->fe.card = card; card->fe.write_fe_reg = write_front_end_reg; @@ -411,9 +411,9 @@ int wp_mprot_init (sdla_t* card, wandev_conf_t* conf) card->u.c.update_call_count = 0; card->wandev.ttl = conf->ttl; - card->wandev.interface = conf->interface; + card->wandev.electrical_interface = conf->electrical_interface; - if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&& + if ((card->u.c.comm_port == WANOPT_SEC && conf->electrical_interface == WANOPT_V35)&& card->type != SDLA_S514){ printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n", card->devname, PORT(card->u.c.comm_port)); @@ -571,13 +571,13 @@ int wp_mprot_init (sdla_t* card, wandev_conf_t* conf) */ static int update (wan_device_t* wandev) { - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; netdevice_t* dev; private_area_t* chan; unsigned long smp_flags; /* sanity checks */ - if((wandev == NULL) || (wandev->private == NULL)) + if((wandev == NULL) || (wandev->priv == NULL)) return -EFAULT; if(wandev->state == WAN_UNCONFIGURED) @@ -621,7 +621,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf) struct ppp_device *pppdev=NULL; struct sppp *sp=NULL; - sdla_t* card = wandev->private; + sdla_t* card = wandev->priv; private_area_t* chan; int err = 0; @@ -927,7 +927,7 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) { private_area_t *chan = dev->priv; sdla_t *card = chan->card; - unsigned long smp_flags; + unsigned long smp_flags=0; #ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG if (chan->common.usedby == ANNEXG && chan->annexg_dev){ @@ -974,6 +974,8 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) * since in some cases (mrouted) daemons continue * to call ioctl() after the device has gone down */ dev->do_ioctl = NULL; + dev->hard_header = NULL; + dev->rebuild_header = NULL; if (chan->common.prot_ptr){ kfree(chan->common.prot_ptr); @@ -990,15 +992,12 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev) port_set_state(card, WAN_DISCONNECTED); - wan_unreg_api(chan, card->devname); + if (chan->common.usedby == API){ + wan_unreg_api(chan, card->devname); + } /* TE1 - Unconfiging, only on shutdown */ if (IS_TE1_CARD(card)) { - - if (card->wandev.fe_iface.pre_release){ - card->wandev.fe_iface.pre_release(&card->fe); - } - if (card->wandev.fe_iface.unconfig){ card->wandev.fe_iface.unconfig(&card->fe); } @@ -1044,7 +1043,8 @@ static int if_init (netdevice_t* dev) dev->type = ARPHRD_PPP; dev->mtu = card->wandev.mtu; dev->hard_header_len = 0; - + dev->hard_header = NULL; + dev->rebuild_header = NULL; } /* Overwrite the sppp ioctl, because we need to run @@ -1292,7 +1292,7 @@ static int if_send (struct sk_buff* skb, netdevice_t* dev) } else { err=1; stop_net_queue(dev); - } + } }else{ ++card->wandev.stats.tx_packets; card->wandev.stats.tx_bytes += skb->len; @@ -1743,7 +1743,12 @@ STATIC WAN_IRQ_RETVAL wsppp_isr (sdla_t* card) start_net_queue(dev); wan_wakeup_api(chan); break; - } + } + + if (chan->common.usedby == API){ + WAN_NETIF_WAKE_QUEUE(dev); + wan_wakeup_api(chan); + } #ifdef CONFIG_PRODUCT_WANPIPE_ANNEXG if (chan->common.usedby == ANNEXG && @@ -1967,7 +1972,7 @@ static void rx_intr (sdla_t* card) if (chan->annexg_dev){ skb->protocol = htons(ETH_P_X25); skb->dev = chan->annexg_dev; - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); if (wan_skb_queue_len(&chan->rx_queue) > MAX_RX_QUEUE){ wan_skb_free(skb); @@ -1989,7 +1994,7 @@ static void rx_intr (sdla_t* card) } }else if (chan->common.usedby == STACK){ skb->dev = chan->annexg_dev; - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); if (wan_skb_queue_len(&chan->rx_queue) > MAX_RX_QUEUE){ wan_skb_free(skb); @@ -2019,7 +2024,7 @@ static void rx_intr (sdla_t* card) /* Pass it up the protocol stack */ skb->protocol = htons(ETH_P_WAN_PPP); skb->dev = dev; - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); wan_skb_queue_tail(&chan->rx_queue,skb); WAN_TASKLET_SCHEDULE((&chan->tasklet)); @@ -2097,7 +2102,7 @@ static int set_asy_config(sdla_t* card) if(card->wandev.clocking) cfg.baud_rate = card->wandev.bps; - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; cfg.modem_config_options = 0; @@ -2173,7 +2178,7 @@ static int set_chdlc_config(sdla_t* card) if(card->wandev.clocking) cfg.baud_rate = card->wandev.bps; - cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ? + cfg.line_config_options = (card->wandev.electrical_interface == WANOPT_RS232) ? INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35; cfg.modem_config_options = 0; @@ -2886,7 +2891,7 @@ dflt_1: /* Decapsulate pkt and pass it up the protocol stack */ new_skb->protocol = htons(ETH_P_IP); new_skb->dev = dev; - wan_skb_reset_mac_header(new_skb); + wan_skb_reset_mac_header(new_skb); netif_rx(new_skb); } else { @@ -3208,9 +3213,6 @@ static int config_chdlc (sdla_t *card) (IS_T1_CARD(card))?"T1":"E1"); return -EINVAL; } - if (card->wandev.fe_iface.post_init){ - err=card->wandev.fe_iface.post_init(&card->fe); - } } if (IS_56K_CARD(card)) { @@ -3225,9 +3227,6 @@ static int config_chdlc (sdla_t *card) card->devname); return -EINVAL; } - if (card->wandev.fe_iface.post_init){ - err=card->wandev.fe_iface.post_init(&card->fe); - } } @@ -3259,7 +3258,7 @@ static int config_chdlc (sdla_t *card) port_set_state(card, WAN_DISCONNECTED); return 0; } - } else { + }else{ if (chdlc_comm_enable(card) != 0) { printk(KERN_INFO "%s: Failed to enable chdlc communications!\n", card->devname); @@ -3387,7 +3386,7 @@ static int chdlc_set_dev_config(struct file *file, if (wandev == NULL) return cnt; - card = (sdla_t*)wandev->private; + card = (sdla_t*)wandev->priv; printk(KERN_INFO "%s: New device config (%s)\n", wandev->name, buffer); @@ -3505,7 +3504,7 @@ static void wp_bh (unsigned long data) memset(rx_hdr,0,sizeof(api_rx_hdr_t)); }else{ if (WAN_NET_RATELIMIT()){ - DEBUG_EVENT("%s: Error Rx pkt headroom %d < %u\n", + DEBUG_EVENT("%s: Error Rx pkt headroom %d < %d\n", chan->if_name, wan_skb_headroom(skb), sizeof(api_rx_hdr_t)); @@ -3592,7 +3591,7 @@ static netdevice_t * un_bind_annexg(wan_device_t *wandev, netdevice_t *annexg_de struct wan_dev_le *devle; netdevice_t *dev; unsigned long smp_flags=0; - sdla_t *card = wandev->private; + sdla_t *card = wandev->priv; WAN_LIST_FOREACH(devle, &card->wandev.dev_head, dev_link){ private_area_t* chan; @@ -3713,7 +3712,7 @@ static int digital_loop_test(sdla_t* card,wan_udp_pkt_t* wan_udp_pkt) skb->next = skb->prev = NULL; skb->dev = dev; skb->protocol = htons(ETH_P_IP); - wan_skb_reset_mac_header(skb); + wan_skb_reset_mac_header(skb); dev_queue_xmit(skb); return 0; diff --git a/patches/kdrivers/src/net/wanpipe_syncppp.c b/patches/kdrivers/src/net/wanpipe_syncppp.c index 3cea80d..423cd9c 100644 --- a/patches/kdrivers/src/net/wanpipe_syncppp.c +++ b/patches/kdrivers/src/net/wanpipe_syncppp.c @@ -35,8 +35,8 @@ * Version 2.0, Fri Aug 30 09:59:07 EDT 2002 * Version 2.1, Wed Mar 26 10:03:00 EDT 2003 * - * $Id: wanpipe_syncppp.c,v 1.29 2007/02/28 02:01:05 sangoma Exp $ - * $Id: wanpipe_syncppp.c,v 1.29 2007/02/28 02:01:05 sangoma Exp $ + * $Id: wanpipe_syncppp.c,v 1.31 2008/01/02 15:26:22 sangoma Exp $ + * $Id: wanpipe_syncppp.c,v 1.31 2008/01/02 15:26:22 sangoma Exp $ */ /* @@ -1398,19 +1398,8 @@ sppp_phase_name(enum ppp_phase phase) * Handle transmit packets. */ - - - - -#ifdef LINUX_FEAT_2624 -static int sppp_hard_header(struct sk_buff *skb, - struct net_device *dev, __u16 type, - const void *daddr, const void *saddr, - unsigned int len) -#else static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 type, void *daddr, void *saddr, unsigned int len) -#endif { struct sppp *sp = (struct sppp *)sppp_of(dev); struct ppp_header *h; @@ -1453,13 +1442,10 @@ static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 t return sizeof(struct ppp_header); } -#ifdef LINUX_FEAT_2624 -static const struct header_ops sppp_header_ops = { - .create = sppp_hard_header, -}; -#endif - - +static int sppp_rebuild_header(struct sk_buff *skb) +{ + return 0; +} /* * Send keepalive packets, every 10 seconds. @@ -2302,12 +2288,9 @@ void wp_sppp_attach(struct ppp_device *pd) * Device specific setup. All but interrupt handler and * hard_start_xmit. */ -#ifdef LINUX_FEAT_2624 - dev->header_ops = &sppp_header_ops; -#else + dev->hard_header = sppp_hard_header; -#endif - + dev->rebuild_header = sppp_rebuild_header; dev->tx_queue_len = 100; dev->type = ARPHRD_HDLC; dev->addr_len = 0; @@ -2323,7 +2306,8 @@ void wp_sppp_attach(struct ppp_device *pd) dev->stop = wp_sppp_close; #endif dev->change_mtu = wp_sppp_change_mtu; - + dev->hard_header_cache = NULL; + dev->header_cache_update = NULL; dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP; #if 0 @@ -3150,8 +3134,8 @@ static int __init sync_ppp_init(void) #if 0 dev_add_pack(&sppp_packet_type); #endif - wan_spin_lock_init(&spppq_lock); - wan_spin_lock_init(&authenticate_lock); + wan_spin_lock_init(&spppq_lock,"spppq_lock"); + wan_spin_lock_init(&authenticate_lock,"authenticate_lock"); sppp_keepalive_interval=10; sppp_max_keepalive_count=MAXALIVECNT; diff --git a/patches/kdrivers/src/net/wanpipe_tdm_api.c b/patches/kdrivers/src/net/wanpipe_tdm_api.c index 0949492..a7194a7 100644 --- a/patches/kdrivers/src/net/wanpipe_tdm_api.c +++ b/patches/kdrivers/src/net/wanpipe_tdm_api.c @@ -5,7 +5,7 @@ * * Authors: Nenad Corbic * -* Copyright: (c) 2003-2007 Sangoma Technologies Inc. +* Copyright: (c) 2003-2005 Sangoma Technologies Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,6 +16,7 @@ * Jul 27, 2006 David Rokhvarg Ported to Windows. *****************************************************************************/ + #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) # include # include @@ -24,14 +25,12 @@ # include #elif defined(__WINDOWS__) # include -# include -# include # include int aft_te1_insert_tdm_api_event_in_to_rx_queue( wanpipe_tdm_api_dev_t *tdm_api_dev, - wp_tdm_api_rx_hdr_t *tdm_api_rx_hdr + wp_tdm_api_event_t *pevent ); int @@ -40,8 +39,10 @@ queue_tdm_api_rx_dpc( ); #define DBG_TDMCODEC if(0)DbgPrint -#define DBG_TDM_RX if(0)DbgPrint -#define DBG_RBS if(0)DbgPrint +#define DBG_TDM_RX if(0)DbgPrint +#define DBG_RBS if(0)DbgPrint + +#define BUILD_TDMV_API #elif defined(__LINUX__) # include @@ -52,7 +53,6 @@ queue_tdm_api_rx_dpc( # include #endif -#include /*============================================================== Defines @@ -62,8 +62,8 @@ queue_tdm_api_rx_dpc( #define WP_TDMAPI_MINOR_OFFSET 0 #define WP_TDMAPI_MAX_MINORS 1024 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) || defined(__WINDOWS__) - +#if !defined(__WINDOWS__) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) #define WP_CLASS_DEV_CREATE(class, devt, device, name) \ @@ -84,6 +84,12 @@ static struct class_simple *wp_tdmapi_class = NULL; #endif #define UNIT(file) MINOR(file->f_dentry->d_inode->i_rdev) +#define BUILD_TDMV_API + +#endif/* #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */ +#endif/* #if !defined(__WINDOWS__) */ + +#if defined(BUILD_TDMV_API) #define WP_TDMAPI_SPAN_MASK 0xFFFF #define WP_TMDAPI_SPAN_SHIFT 5 //8 @@ -145,6 +151,7 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr); static unsigned int wp_tdmapi_poll(struct file *file, struct poll_table_struct *wait_table); static int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr); #endif +static int wanpipe_tdm_api_event_ioctl(wanpipe_tdm_api_dev_t*, wanpipe_tdm_api_cmd_t*); /*============================================================== Global Variables @@ -220,15 +227,12 @@ static void wp_wakeup_tdmapi(wanpipe_tdm_api_dev_t *tdm_api) wake_up_interruptible(&tdm_api->poll_wait); } } -#endif static struct cdev wptdm_cdev = { -#ifndef LINUX_FEAT_2624 .kobj = {.name = "wptdm", }, -#endif .owner = THIS_MODULE, }; - +#endif static int wp_tdmapi_reg_globals(void) { @@ -236,8 +240,8 @@ static int wp_tdmapi_reg_globals(void) rx_gains=NULL; tx_gains=NULL; - wan_spin_lock_init(&wp_tdmapi_hash_lock); - DEBUG_TEST("%s: Registering Wanpipe TDM Device!\n",__FUNCTION__); + wan_spin_lock_init(&wp_tdmapi_hash_lock, "wan_tdmapi_hash_lock"); + DEBUG_TDMAPI("%s: Registering Wanpipe TDM Device!\n",__FUNCTION__); #if !defined(__WINDOWS__) { #ifdef LINUX_2_4 @@ -334,7 +338,9 @@ int wanpipe_tdm_api_reg(wanpipe_tdm_api_dev_t *tdm_api) tdm_api->cfg.ec_tap =0; tdm_api->cfg.rbs_rx_bits =-1; tdm_api->cfg.hdlc =1; - tdm_api->tx_q_len = WP_TDM_MAX_HDLC_TX_Q_LEN; + + /* We are expecting tx_q_len for hdlc + * to be configured from upper layer */ } else { tdm_api->cfg.hw_mtu_mru =8; @@ -373,17 +379,27 @@ int wanpipe_tdm_api_reg(wanpipe_tdm_api_dev_t *tdm_api) } return err; } - wan_spin_lock_init(&tdm_api->lock); + wan_spin_lock_init(&tdm_api->lock, "wan_tdmapi_lock"); sprintf(tmp_name,"wptdm_s%dc%d",tdm_api->tdm_span,tdm_api->tdm_chan); + DEBUG_TDMAPI("%s: Configuring TDM API NAME=%s Qlen=%i\n", + card->devname,tmp_name, tdm_api->tx_q_len); + /* Initialize Event Callback functions */ card->wandev.event_callback.rbsbits = wp_tdmapi_rbsbits; card->wandev.event_callback.alarms = wp_tdmapi_alarms; - card->wandev.event_callback.dtmf = wp_tdmapi_dtmf; card->wandev.event_callback.hook = wp_tdmapi_hook; card->wandev.event_callback.ringdetect = wp_tdmapi_ringdetect; card->wandev.event_callback.ringtrip = wp_tdmapi_ringtrip; - + +#if defined(__WINDOWS__) + /* Analog always supports DTMF detection */ + tdm_api->dtmfsupport = WANOPT_YES; +#endif + + /* Always initialize the callback pointer */ + card->wandev.event_callback.dtmf = wp_tdmapi_dtmf; + if (tdm_api->cfg.rbs_tx_bits) { DEBUG_EVENT("%s: Setting Tx RBS/CAS Idle Bits = 0x%02X\n", tmp_name, @@ -461,16 +477,15 @@ int wanpipe_tdm_api_kick(wanpipe_tdm_api_dev_t *tdm_api) if (tdm_api == NULL || !wan_test_bit(0,&tdm_api->init)){ return -ENODEV; } - - if (is_tdm_api_stopped(tdm_api)){ + + if (is_tdm_api_stopped(tdm_api) || (unsigned)wan_skb_queue_len(&tdm_api->wp_tx_list) > tdm_api->tx_q_len){ wp_tdm_api_start(tdm_api); if (wan_test_bit(0,&tdm_api->used)) { - DEBUG_TEST("%s: KICK API\n",tdm_api->name); #if !defined(__WINDOWS__) wp_wakeup_tdmapi(tdm_api); #endif - } - } + } + } return 0; } @@ -530,7 +545,7 @@ static int wp_tdmapi_open(struct inode *inode, struct file *file) wan_spin_unlock_irq(&wp_tdmapi_hash_lock,&flags); - DEBUG_TEST ("%s: DRIVER OPEN S/C(%i/%i) API Ptr=%p\n", + DEBUG_TDMAPI ("%s: DRIVER OPEN S/C(%i/%i) API Ptr=%p\n", __FUNCTION__, tdm_span, tdm_chan, tdm_api); return 0; @@ -579,9 +594,9 @@ static ssize_t wp_tdmapi_read_msg(struct file *file, struct msghdr *msg, size_t if (count < wan_skb_len(skb) || wan_skb_len(skb) < sizeof(wp_tdm_api_rx_hdr_t)){ + DEBUG_TDMAPI("%s:%d TDMAPI READ: Error: Count=%i < Skb=%i < HDR=%i Critical Error\n", + __FUNCTION__,__LINE__,count,wan_skb_len(skb),sizeof(wp_tdm_api_rx_hdr_t)); wan_skb_free(skb); - DEBUG_EVENT("%s:%d TDMAPI READ: Critical Error\n", - __FUNCTION__,__LINE__); return -EFAULT; } @@ -752,15 +767,12 @@ static ssize_t wp_tdmapi_write_msg(struct file *file, struct msghdr *msg, size_t return -EINVAL; } #endif - if (count > (WP_TDM_API_MAX_LEN+sizeof(wp_tdm_api_tx_hdr_t))) { - DEBUG_TEST("%s: Error: TDM API Tx packet too big %d\n", - tdm_api->name,count); - return -EFBIG; - } - - skb_len=WP_TDM_API_MAX_LEN+sizeof(wp_tdm_api_tx_hdr_t); + skb_len=WP_TDM_API_MAX_LEN; } - + + DEBUG_TEST("%s: TX FRAME List=%i\n", + tdm_api->name, wan_skb_queue_len(&tdm_api->wp_tx_list)); + if (wan_skb_queue_len(&tdm_api->wp_tx_list) > tdm_api->tx_q_len){ wp_tdm_api_stop(tdm_api); return -EBUSY; @@ -1010,6 +1022,7 @@ static unsigned int wp_tdmapi_poll(struct file *file, struct poll_table_struct * !is_tdm_api_stopped(tdm_api)) { wp_tdmapi_tx(tdm_api); } + if (wan_skb_queue_len(&tdm_api->wp_tx_list) <= tdm_api->tx_q_len) { ret |= POLLOUT | POLLWRNORM; @@ -1038,11 +1051,11 @@ static unsigned int wp_tdmapi_poll(struct file *file, struct poll_table_struct * static void wanpipe_tdm_api_rbs_poll(wanpipe_tdm_api_dev_t *tdm_api) { - u8 rbs_bits; - netskb_t *skb; - wp_tdm_api_rx_hdr_t *rx_hdr = NULL; + u8 rbs_bits; + netskb_t *skb; + wp_tdm_api_event_t *pevent = NULL; #if defined(__WINDOWS__) - wp_tdm_api_rx_hdr_t tdm_api_hdr; + wp_tdm_api_event_t event; #endif if (!tdm_api->cfg.rbs_poll) { @@ -1063,36 +1076,32 @@ static void wanpipe_tdm_api_rbs_poll(wanpipe_tdm_api_dev_t *tdm_api) #endif tdm_api->read_rbs_bits( tdm_api->chan, -#if defined(__WINDOWS__) - tdm_api->tdm_chan + 1, -#else tdm_api->tdm_chan, -#endif &rbs_bits); if (tdm_api->cfg.rbs_rx_bits == rbs_bits) { return; } - DEBUG_TEST("%s: RBS BITS CHANGED O=0x%X N=0x%X\n", + DEBUG_TDMAPI("%s: RBS BITS CHANGED O=0x%X N=0x%X\n", tdm_api->name, tdm_api->cfg.rbs_rx_bits, rbs_bits); tdm_api->cfg.rbs_rx_bits = rbs_bits; #if defined(__WINDOWS__) - rx_hdr = &tdm_api_hdr; + pevent = &event; #else if (wan_skb_queue_len(&tdm_api->wp_event_list) > WP_TDM_MAX_EVENT_Q_LEN) { return; } - skb=wan_skb_alloc(sizeof(wp_tdm_api_rx_hdr_t)); + skb=wan_skb_alloc(sizeof(wp_tdm_api_event_t)); if (skb == NULL) return; - rx_hdr=(wp_tdm_api_rx_hdr_t*)wan_skb_put(skb,sizeof(wp_tdm_api_rx_hdr_t)); + pevent = (wp_tdm_api_event_t*)wan_skb_put(skb,sizeof(wp_tdm_api_event_t)); #endif/* #if !defined(__WINDOWS__) */ - memset(rx_hdr,0,sizeof(wp_tdm_api_rx_hdr_t)); - rx_hdr->wp_tdm_api_event_rbs_rx_bits = (u8)tdm_api->cfg.rbs_rx_bits; - rx_hdr->wp_tdm_api_event_type = WP_TDM_EVENT_RBS; + memset(pevent,0,sizeof(wp_tdm_api_event_t)); + pevent->wp_tdm_api_event_type = WP_TDMAPI_EVENT_RBS; + pevent->wp_tdm_api_event_rbs_bits = (u8)tdm_api->cfg.rbs_rx_bits; #if 0 /* FIXME: NENAD TO ADD Timestamp */ @@ -1100,8 +1109,8 @@ static void wanpipe_tdm_api_rbs_poll(wanpipe_tdm_api_dev_t *tdm_api) #endif #if defined(__WINDOWS__) - rx_hdr->wp_tdm_api_event_channel = (u_int16_t)tdm_api->tdm_chan + 1; - aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, rx_hdr); + pevent->channel = (u_int16_t)tdm_api->tdm_chan; + aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, pevent); queue_tdm_api_rx_dpc(tdm_api); #else wan_skb_queue_tail(&tdm_api->wp_event_list,skb); @@ -1111,42 +1120,40 @@ static void wanpipe_tdm_api_rbs_poll(wanpipe_tdm_api_dev_t *tdm_api) static void wanpipe_tdm_api_fe_alarm_event(wanpipe_tdm_api_dev_t *tdm_api, int state) { netskb_t *skb; - wp_tdm_api_rx_hdr_t *rx_hdr = NULL; + wp_tdm_api_event_t *pevent = NULL; #if defined(__WINDOWS__) - wp_tdm_api_rx_hdr_t tdm_api_hdr; + wp_tdm_api_event_t event; #endif - DEBUG_TEST("%s: TDM API State Event State=%i\n", + DEBUG_TDMAPI("%s: TDM API State Event State=%i\n", tdm_api->name, tdm_api->state); #if defined(__WINDOWS__) - rx_hdr = &tdm_api_hdr; + pevent = &event; #else if (wan_skb_queue_len(&tdm_api->wp_event_list) > WP_TDM_MAX_EVENT_Q_LEN) { return; } - skb=wan_skb_alloc(sizeof(wp_tdm_api_rx_hdr_t)); + skb=wan_skb_alloc(sizeof(wp_tdm_api_event_t)); if (skb == NULL) { return; } - rx_hdr=(wp_tdm_api_rx_hdr_t*)wan_skb_put(skb,sizeof(wp_tdm_api_rx_hdr_t)); + pevent = (wp_tdm_api_event_t*)wan_skb_put(skb,sizeof(wp_tdm_api_event_t)); #endif/* #if !defined(__WINDOWS__) */ - memset(rx_hdr,0,sizeof(wp_tdm_api_rx_hdr_t)); - if (state == WAN_CONNECTED) { - rx_hdr->wp_tdm_api_event_fe_alarm = 0; - } else { - rx_hdr->wp_tdm_api_event_fe_alarm = 1; - } - rx_hdr->wp_tdm_api_event_type = WP_TDM_EVENT_FE_ALARM; + memset(pevent,0,sizeof(wp_tdm_api_event_t)); + pevent->wp_tdm_api_event_type = WP_TDMAPI_EVENT_ALARM; + pevent->wp_tdm_api_event_alarm = (state == WAN_CONNECTED) ? 0 : 1; #if 0 /* FIXME: NENAD TO ADD Timestamp */ rx_hdr->event_time_stamp = gettimeofday(); #endif - rx_hdr->wp_tdm_api_event_channel = (u_int16_t)tdm_api->tdm_chan + 1; + + pevent->channel = (u_int16_t)tdm_api->tdm_chan; + #if defined(__WINDOWS__) - aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, rx_hdr); + aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, pevent); queue_tdm_api_rx_dpc(tdm_api); #else wan_skb_queue_tail(&tdm_api->wp_event_list,skb); @@ -1163,8 +1170,7 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) u32 cmd; wanpipe_codec_ops_t *wp_codec_ops; netskb_t *skb; - wan_event_ctrl_t event_ctrl; - sdla_t *card = (sdla_t*)tdm_api->card; + sdla_t *card = (sdla_t*)tdm_api->card; utdmapi = (wanpipe_tdm_api_cmd_t*)ifr->ifr_data; @@ -1197,7 +1203,12 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) case SIOC_WP_TDM_GET_USR_MTU_MRU: case SIOC_WP_TDM_GET_STATS: case SIOC_WP_TDM_GET_FULL_CFG: - case SIOC_WP_TDM_READ_EVENT: +#if !defined(__WINDOWS__) + case SIOC_WP_TDM_GET_FE_STATUS: + case SIOC_WP_TDM_SET_FE_STATUS: +#endif + case SIOC_WP_TDM_READ_EVENT: + case SIOC_WP_TDM_GET_FE_ALARMS: break; default: DEBUG_EVENT("%s: Invalid TDM API HDLC CMD %i\n", tdm_api->name,cmd); @@ -1308,24 +1319,6 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) } break; - case SIOC_WP_TDM_ENABLE_HWEC: - if (card->wandev.ec_enable) { - wan_smp_flag_t smp_flags1; - card->hw_iface.hw_lock(card->hw,&smp_flags1); - card->wandev.ec_enable(card, 1, tdm_api->tdm_chan-1); - card->hw_iface.hw_unlock(card->hw,&smp_flags1); - } - break; - - case SIOC_WP_TDM_DISABLE_HWEC: - if (card->wandev.ec_enable) { - wan_smp_flag_t smp_flags1; - card->hw_iface.hw_lock(card->hw,&smp_flags1); - card->wandev.ec_enable(card, 0, tdm_api->tdm_chan-1); - card->hw_iface.hw_unlock(card->hw,&smp_flags1); - } - break; - case SIOC_WP_TDM_SET_EC_TAP: switch (usr_tdm_api.ec_tap){ @@ -1347,6 +1340,25 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) case SIOC_WP_TDM_GET_EC_TAP: usr_tdm_api.ec_tap = tdm_api->cfg.ec_tap; break; + + + case SIOC_WP_TDM_ENABLE_HWEC: + if (card->wandev.ec_enable) { + wan_smp_flag_t smp_flags1; + card->hw_iface.hw_lock(card->hw,&smp_flags1); + card->wandev.ec_enable(card, 1, tdm_api->tdm_chan); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + } + break; + + case SIOC_WP_TDM_DISABLE_HWEC: + if (card->wandev.ec_enable) { + wan_smp_flag_t smp_flags1; + card->hw_iface.hw_lock(card->hw,&smp_flags1); + card->wandev.ec_enable(card, 0, tdm_api->tdm_chan); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + } + break; case SIOC_WP_TDM_GET_STATS: memcpy(&usr_tdm_api.stats,&tdm_api->cfg.stats,sizeof(tdm_api->cfg.stats)); @@ -1357,6 +1369,7 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) break; case SIOC_WP_TDM_ENABLE_RBS_EVENTS: + /* 'usr_tdm_api.rbs_poll' is the user provided 'number of polls per second' */ if (usr_tdm_api.rbs_poll < 20 || usr_tdm_api.rbs_poll > 100) { DEBUG_EVENT("%s: Error: Invalid RBS Poll Count Min=20 Max=100\n", tdm_api->name); @@ -1365,271 +1378,62 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) usr_tdm_api.rbs_poll=HZ/usr_tdm_api.rbs_poll; tdm_api->cfg.rbs_poll = usr_tdm_api.rbs_poll; + if (card->wandev.fe_iface.set_fe_sigctrl){ + card->wandev.fe_iface.set_fe_sigctrl( + &card->fe, + WAN_TE_SIG_POLL, + ENABLE_ALL_CHANNELS, + WAN_ENABLE); + } break; case SIOC_WP_TDM_DISABLE_RBS_EVENTS: tdm_api->cfg.rbs_poll=0; + if (card->wandev.fe_iface.set_fe_sigctrl){ + card->wandev.fe_iface.set_fe_sigctrl( + &card->fe, + WAN_TE_SIG_POLL, + ENABLE_ALL_CHANNELS, + WAN_DISABLE); + } break; - case SIOC_WP_TDM_ENABLE_DTMF_EVENTS: - // Octasic DTMF event - DEBUG_TDMAPI("%s: Enable HW EC DTMF event %X!\n", - tdm_api->name, tdm_api->active_ch); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_EC_DTMF; - event_ctrl.mode = WAN_EVENT_ENABLE; - event_ctrl.ts_map = tdm_api->active_ch; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } - break; - - case SIOC_WP_TDM_DISABLE_DTMF_EVENTS: - // Octasic DTMF event - DEBUG_TDMAPI("%s: Disable HW EC DTMF event!\n", - tdm_api->name); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_EC_DTMF; - event_ctrl.mode = WAN_EVENT_DISABLE; - event_ctrl.ts_map = tdm_api->active_ch; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } - break; - - case SIOC_WP_TDM_ENABLE_RM_DTMF_EVENTS: - // A200-Remora DTMF event - DEBUG_TDMAPI("%s: Enable A200-Remora DTMF event!\n", - tdm_api->name); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_DTMF; - event_ctrl.mode = WAN_EVENT_ENABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } - break; - case SIOC_WP_TDM_DISABLE_RM_DTMF_EVENTS: - // A200-Remora DTMF event - DEBUG_TDMAPI("%s: Disable A200-Remora DTMF event!\n", - tdm_api->name); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_DTMF; - event_ctrl.mode = WAN_EVENT_DISABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } - break; - - - case SIOC_WP_TDM_ENABLE_RXHOOK_EVENTS: - DEBUG_TDMAPI("%s: Enable A200-Remora Loop Closure event!\n", - tdm_api->name); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_LC; - event_ctrl.mode = WAN_EVENT_ENABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - - case SIOC_WP_TDM_DISABLE_RXHOOK_EVENTS: - DEBUG_TDMAPI("%s: Disable A200-Remora Loop Closure event!\n", - tdm_api->name); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_LC; - event_ctrl.mode = WAN_EVENT_DISABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - - case SIOC_WP_TDM_ENABLE_RING_DETECT_EVENTS: - DEBUG_TDMAPI("%s: Enable Ring Detection Event on module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_RING_DETECT; - event_ctrl.mode = WAN_EVENT_ENABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - case SIOC_WP_TDM_DISABLE_RING_DETECT_EVENTS: - DEBUG_TDMAPI("%s: Disable Ring Detection Event on module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_RING_DETECT; - event_ctrl.mode = WAN_EVENT_DISABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - - case SIOC_WP_TDM_ENABLE_RING_TRIP_DETECT_EVENTS: - DEBUG_TDMAPI("%s: Enable Ring Trip Detection Event on module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_RING_TRIP; - event_ctrl.mode = WAN_EVENT_ENABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - case SIOC_WP_TDM_DISABLE_RING_TRIP_DETECT_EVENTS: - DEBUG_TDMAPI("%s: Disable Ring Trip Detection Event on module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_RING_TRIP; - event_ctrl.mode = WAN_EVENT_DISABLE; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - - case SIOC_WP_TDM_TXSIG_KEWL: - DEBUG_TDMAPI("%s: TX Signalling KEWL on module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_TXSIG_KEWL; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - - case SIOC_WP_TDM_EVENT_TXSIG_START: - DEBUG_TDMAPI("%s: TX Signalling START for module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_TXSIG_START; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - case SIOC_WP_TDM_EVENT_TXSIG_OFFHOOK: - DEBUG_TDMAPI("%s: TX Signalling OFFHOOK for module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_TXSIG_OFFHOOK; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - case SIOC_WP_TDM_EVENT_TXSIG_ONHOOK: - DEBUG_TDMAPI("%s: TX Signalling ONHOOK for module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_TXSIG_ONHOOK; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - case SIOC_WP_TDM_EVENT_ONHOOKTRANSFER: - DEBUG_TDMAPI("%s: RM ONHOOKTRANSFER for module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); - event_ctrl.type = WAN_EVENT_RM_ONHOOKTRANSFER; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - event_ctrl.ohttimer = usr_tdm_api.event.wp_tdm_api_event_ohttimer; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - case SIOC_WP_TDM_EVENT_SETPOLARITY: - DEBUG_EVENT("%s: RM SETPOLARITY for module %d!\n", - tdm_api->name, - tdm_api->tdm_chan); - event_ctrl.type = WAN_EVENT_RM_SETPOLARITY; - event_ctrl.mod_no = tdm_api->tdm_chan-1; - event_ctrl.polarity = usr_tdm_api.event.wp_tdm_api_event_polarity; - if (tdm_api->event_ctrl){ - err = tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); - } else { - DEBUG_EVENT("%s: Error: event_ctrl not supported!\n", - tdm_api->name); - err = -EINVAL; - } - break; - case SIOC_WP_TDM_WRITE_RBS_BITS: wan_spin_unlock(&tdm_api->lock); err=tdm_api->write_rbs_bits( tdm_api->chan, -#if defined(__WINDOWS__) - tdm_api->tdm_chan + 1, -#else tdm_api->tdm_chan, -#endif (u8)usr_tdm_api.rbs_tx_bits); if (err) { DEBUG_EVENT("%s: WRITE RBS Error (%i)\n",tdm_api->name,err); } goto tdm_api_unlocked_exit; break; +#if !defined(__WINDOWS__) + case SIOC_WP_TDM_GET_FE_STATUS: + if (card->wandev.fe_iface.get_fe_status){ + wan_smp_flag_t smp_flags1; + card->hw_iface.hw_lock(card->hw,&smp_flags1); + card->wandev.fe_iface.get_fe_status( + &card->fe, &usr_tdm_api.fe_status); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + } + break; + + case SIOC_WP_TDM_SET_FE_STATUS: + if (card->wandev.fe_iface.set_fe_status){ + wan_smp_flag_t smp_flags1; + card->hw_iface.hw_lock(card->hw,&smp_flags1); + card->wandev.fe_iface.set_fe_status( + &card->fe, usr_tdm_api.fe_status); + card->hw_iface.hw_unlock(card->hw,&smp_flags1); + } + break; +#endif + case SIOC_WP_TDM_SET_EVENT: + err = wanpipe_tdm_api_event_ioctl(tdm_api, &usr_tdm_api); + break; case SIOC_WP_TDM_READ_EVENT: skb=wan_skb_dequeue(&tdm_api->wp_event_list); @@ -1637,7 +1441,7 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) err=-ENOBUFS; break; } - memcpy(&usr_tdm_api.event,wan_skb_data(skb),sizeof(wp_tdm_api_rx_hdr_t)); + memcpy(&usr_tdm_api.event,wan_skb_data(skb),sizeof(wp_tdm_api_event_t)); wan_skb_free(skb); break; @@ -1650,7 +1454,6 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) if (usr_tdm_api.data_len && utdmapi->data) { if (usr_tdm_api.data_len != 256) { err=-EINVAL; - break; } @@ -1665,7 +1468,8 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) } #if defined(__WINDOWS__) - memcpy(&usr_tdm_api, ifr, sizeof(wanpipe_tdm_api_cmd_t)); + /*FIXME: test the memcpy() here + memcpy(rx_gains, utdmapi->data, usr_tdm_api.data_len);*/ #else if (WAN_COPY_FROM_USER(rx_gains, utdmapi->data, @@ -1707,9 +1511,8 @@ int wanpipe_tdm_api_ioctl(wanpipe_tdm_api_dev_t *tdm_api, struct ifreq *ifr) } #if defined(__WINDOWS__) -//FIXME: implement -//#error "FIX API CMD" -// memcpy(&_api, ifr, sizeof(wanpipe_tdm_api_cmd_t)); + /*FIXME: test the memcpy() here + memcpy(tx_gains, utdmapi->data, usr_tdm_api.data_len);*/ #else if (WAN_COPY_FROM_USER(tx_gains, utdmapi->data, @@ -1759,7 +1562,202 @@ tdm_api_unlocked_exit: return err; } +static int +wanpipe_tdm_api_event_ioctl(wanpipe_tdm_api_dev_t *tdm_api, wanpipe_tdm_api_cmd_t *tdm_cmd) +{ + wp_tdm_api_event_t *tdm_event; + wan_event_ctrl_t event_ctrl; + if (tdm_api->event_ctrl == NULL){ + DEBUG_EVENT("%s: Error: Event control interface doesn't initialized!\n", + tdm_api->name); + return -EINVAL; + } + + tdm_event = &tdm_cmd->event; + memset(&event_ctrl, 0, sizeof(wan_event_ctrl_t)); + + switch(tdm_event->wp_tdm_api_event_type){ + case WP_TDMAPI_EVENT_DTMF: + // Octasic DTMF event + DEBUG_TDMAPI("%s: %s HW EC DTMF event %X!\n", + tdm_api->name, + WP_TDMAPI_EVENT_MODE_DECODE(tdm_event->wp_tdm_api_event_mode), + tdm_api->active_ch); + event_ctrl.type = WAN_EVENT_EC_DTMF; + if (tdm_event->wp_tdm_api_event_mode == WP_TDMAPI_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } +#if defined(__WINDOWS__) + if(tdm_event->channel < 1 || tdm_event->channel > NUM_OF_E1_CHANNELS - 1/* 31 */){ + DEBUG_TDMAPI("%s(): %s: Warning: DTMF control requested on invalid channel %u!\n", + __FUNCTION__, tdm_api->name, tdm_event->channel); + tdm_event->channel = 1;/* */ + } + event_ctrl.channel = tdm_event->channel; +#else + event_ctrl.channel = tdm_api->tdm_chan; +#endif + break; + + case WP_TDMAPI_EVENT_RM_DTMF: + // A200-Remora DTMF event + DEBUG_TDMAPI("%s: %s A200-Remora DTMF event!\n", + tdm_api->name, + WP_TDMAPI_EVENT_MODE_DECODE(tdm_event->wp_tdm_api_event_mode)); + event_ctrl.type = WAN_EVENT_RM_DTMF; + if (tdm_event->wp_tdm_api_event_mode == WP_TDMAPI_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_RXHOOK: + DEBUG_TDMAPI("%s: %s A200-Remora Loop Closure event!\n", + tdm_api->name, + WP_TDMAPI_EVENT_MODE_DECODE(tdm_event->wp_tdm_api_event_mode)); + event_ctrl.type = WAN_EVENT_RM_LC; + if (tdm_event->wp_tdm_api_event_mode == WP_TDMAPI_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_RING: + DEBUG_TDMAPI("%s: %s Ring Event on module %d!\n", + tdm_api->name, + WP_TDMAPI_EVENT_MODE_DECODE(tdm_event->wp_tdm_api_event_mode), + tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_RING; + if (tdm_event->wp_tdm_api_event_mode == WP_TDMAPI_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_RING_DETECT: + DEBUG_TDMAPI("%s: %s Ring Detection Event on module %d!\n", + tdm_api->name, + WP_TDMAPI_EVENT_MODE_DECODE(tdm_event->wp_tdm_api_event_mode), + tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_RING_DETECT; + if (tdm_event->wp_tdm_api_event_mode == WP_TDMAPI_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_RING_TRIP_DETECT: + DEBUG_TDMAPI("%s: %s Ring Trip Detection Event on module %d!\n", + tdm_api->name, + WP_TDMAPI_EVENT_MODE_DECODE(tdm_event->wp_tdm_api_event_mode), + tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_RING_TRIP; + if (tdm_event->wp_tdm_api_event_mode == WP_TDMAPI_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_TONE: + + DEBUG_TDMAPI("%s: %s Tone Event (%d)on module %d!\n", + tdm_api->name, + WP_TDMAPI_EVENT_MODE_DECODE(tdm_event->wp_tdm_api_event_mode), + tdm_event->wp_tdm_api_event_tone_type, + tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_TONE; + if (tdm_event->wp_tdm_api_event_mode == WP_TDMAPI_EVENT_ENABLE){ + event_ctrl.mode = WAN_EVENT_ENABLE; + switch(tdm_event->wp_tdm_api_event_tone_type){ + case WP_TDMAPI_EVENT_TONE_DIAL: + event_ctrl.tone = WAN_EVENT_TONE_DIAL; + break; + case WP_TDMAPI_EVENT_TONE_BUSY: + event_ctrl.tone = WAN_EVENT_TONE_BUSY; + break; + case WP_TDMAPI_EVENT_TONE_RING: + event_ctrl.tone = WAN_EVENT_TONE_RING; + break; + case WP_TDMAPI_EVENT_TONE_CONGESTION: + event_ctrl.tone = WAN_EVENT_TONE_CONGESTION; + break; + default: + DEBUG_EVENT("%s: Unsupported TDM API Tone Type %d!\n", + tdm_api->name, + tdm_event->wp_tdm_api_event_tone_type); + return -EINVAL; + } + }else{ + event_ctrl.mode = WAN_EVENT_DISABLE; + } + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_TXSIG_KEWL: + DEBUG_TDMAPI("%s: TX Signalling KEWL on module %d!\n", + tdm_api->name, tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_TXSIG_KEWL; + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_TXSIG_START: + DEBUG_TDMAPI("%s: TX Signalling START for module %d!\n", + tdm_api->name, tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_TXSIG_START; + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_TXSIG_OFFHOOK: + DEBUG_TDMAPI("%s: TX Signalling OFFHOOK for module %d!\n", + tdm_api->name, tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_TXSIG_OFFHOOK; + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_TXSIG_ONHOOK: + DEBUG_TDMAPI("%s: TX Signalling ONHOOK for module %d!\n", + tdm_api->name, tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_TXSIG_ONHOOK; + event_ctrl.mod_no = tdm_api->tdm_chan; + break; + + case WP_TDMAPI_EVENT_ONHOOKTRANSFER: + DEBUG_TDMAPI("%s: RM ONHOOKTRANSFER for module %d!\n", + tdm_api->name, tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_ONHOOKTRANSFER; + event_ctrl.mod_no = tdm_api->tdm_chan; + event_ctrl.ohttimer = tdm_event->wp_tdm_api_event_ohttimer; + break; + + case WP_TDMAPI_EVENT_SETPOLARITY: + DEBUG_EVENT("%s: RM SETPOLARITY for module %d!\n", + tdm_api->name, tdm_api->tdm_chan); + event_ctrl.type = WAN_EVENT_RM_SETPOLARITY; + event_ctrl.mod_no = tdm_api->tdm_chan; + event_ctrl.polarity = tdm_event->wp_tdm_api_event_polarity; + break; + default: + DEBUG_EVENT("%s: Unknown TDM API Event Type %02X!\n", + tdm_api->name, + tdm_event->type); + return -EINVAL; + } + + return tdm_api->event_ctrl(tdm_api->chan, &event_ctrl); +} static int wanpipe_tdm_api_tx (wanpipe_tdm_api_dev_t *tdm_api, u8 *tx_data, int len) { @@ -1947,6 +1945,8 @@ int wanpipe_tdm_api_rx_hdlc (wanpipe_tdm_api_dev_t *tdm_api, netskb_t *skb) return -EBUSY; } + DEBUG_TDMAPI("%s: TDM API RX HDLC FRAME %i\n",tdm_api->name, wan_skb_len(skb)); + wan_skb_queue_tail(&tdm_api->wp_rx_list,skb); wp_wakeup_tdmapi(tdm_api); tdm_api->cfg.stats.rx_packets++; @@ -1960,7 +1960,10 @@ static wanpipe_tdm_api_dev_t *wp_tdmapi_search(sdla_t *card, int fe_chan) int i = 0; #if defined(__WINDOWS__) - if(fe_chan >= MAX_TDM_API_CHANNELS){ + + DEBUG_TDMAPI("%s(): fe_chan: %d\n", __FUNCTION__, fe_chan); + + if(fe_chan < 0 || fe_chan >= MAX_TDM_API_CHANNELS){ DEBUG_EVENT("%s(): TDM API Error: Invalid Channel Number=%i!\n", __FUNCTION__, fe_chan); return NULL; @@ -2007,62 +2010,57 @@ static void wp_tdmapi_alarms(void* card_id, unsigned long alarams) static void wp_tdmapi_dtmf (void* card_id, wan_event_t *event) { - netskb_t *skb = NULL; + netskb_t *skb = NULL; wanpipe_tdm_api_dev_t *tdm_api = NULL; - sdla_t *card = (sdla_t*)card_id; - wp_tdm_api_rx_hdr_t *rx_hdr = NULL; + sdla_t *card = (sdla_t*)card_id; + wp_tdm_api_event_t *p_tdmapi_event = NULL; #if defined(__WINDOWS__) - wp_tdm_api_rx_hdr_t tdm_api_hdr; + wp_tdm_api_event_t tdmapi_event; #endif if (event->type == WAN_EVENT_EC_DTMF){ - DEBUG_TEST("%s: Received DTMF Event at TDM API (%d:%c:%s:%s)!\n", + DEBUG_TDMAPI("%s: Received DTMF Event at TDM API (%d:%c:%s:%s)!\n", card->devname, event->channel, event->digit, (event->dtmf_port == WAN_EC_CHANNEL_PORT_ROUT)?"ROUT":"SOUT", (event->dtmf_type == WAN_EC_TONE_PRESENT)?"PRESENT":"STOP"); }else if (event->type == WAN_EVENT_RM_DTMF){ - DEBUG_TEST("%s: Received DTMF Event at TDM API (%d:%c)!\n", + DEBUG_TDMAPI("%s: Received DTMF Event at TDM API (%d:%c)!\n", card->devname, event->channel, event->digit); } - tdm_api = wp_tdmapi_search(card, -#if defined(__WINDOWS__) - event->channel - 1); -#else - event->channel); -#endif + tdm_api = wp_tdmapi_search(card, event->channel); if (tdm_api == NULL){ return; } #if defined(__WINDOWS__) - rx_hdr = &tdm_api_hdr; + p_tdmapi_event = &tdmapi_event; #else if (wan_skb_queue_len(&tdm_api->wp_event_list) > WP_TDM_MAX_EVENT_Q_LEN) { return; } - skb=wan_skb_alloc(sizeof(wp_tdm_api_rx_hdr_t)); + skb=wan_skb_alloc(sizeof(wp_tdm_api_event_t)); if (skb == NULL) return; - rx_hdr=(wp_tdm_api_rx_hdr_t*)wan_skb_put(skb,sizeof(wp_tdm_api_rx_hdr_t)); + p_tdmapi_event = (wp_tdm_api_event_t*)wan_skb_put(skb,sizeof(wp_tdm_api_event_t)); #endif - memset(rx_hdr,0,sizeof(wp_tdm_api_rx_hdr_t)); - rx_hdr->wp_tdm_api_event_type = WP_TDM_EVENT_DTMF; - rx_hdr->wp_tdm_api_event_dtmf_digit = event->digit; - rx_hdr->wp_tdm_api_event_dtmf_type = event->dtmf_type; - rx_hdr->wp_tdm_api_event_dtmf_port = event->dtmf_port; + memset(p_tdmapi_event,0,sizeof(wp_tdm_api_event_t)); + p_tdmapi_event->type = WP_TDMAPI_EVENT_DTMF; + p_tdmapi_event->wp_tdm_api_event_dtmf_digit = event->digit; + p_tdmapi_event->wp_tdm_api_event_dtmf_type = event->dtmf_type; + p_tdmapi_event->wp_tdm_api_event_dtmf_port = event->dtmf_port; #if 0 rx_hdr->event_time_stamp = gettimeofday(); #endif #if defined(__WINDOWS__) - rx_hdr->wp_tdm_api_event_channel = (u_int16_t)event->channel; - aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, rx_hdr); + p_tdmapi_event->channel = (u_int16_t)event->channel; + aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, p_tdmapi_event); queue_tdm_api_rx_dpc(tdm_api); #else wan_skb_queue_tail(&tdm_api->wp_event_list,skb); @@ -2076,50 +2074,53 @@ static void wp_tdmapi_hook (void* card_id, wan_event_t *event) netskb_t *skb; wanpipe_tdm_api_dev_t *tdm_api = NULL; sdla_t *card = (sdla_t*)card_id; - wp_tdm_api_rx_hdr_t *rx_hdr = NULL; + wp_tdm_api_event_t *p_tdmapi_event = NULL; #if defined(__WINDOWS__) - wp_tdm_api_rx_hdr_t tdm_api_hdr; + wp_tdm_api_event_t tdmapi_event; #endif DEBUG_TDMAPI("%s: Received RM LC Event at TDM_API (%d:%s)!\n", card->devname, event->channel, (event->rxhook==WAN_EVENT_RXHOOK_OFF)?"OFF-HOOK":"ON-HOOK"); - - tdm_api = wp_tdmapi_search(card, -#if defined(__WINDOWS__) - event->channel - 1); -#else - event->channel); -#endif + tdm_api = wp_tdmapi_search(card, event->channel); if (tdm_api == NULL){ return; } #if defined(__WINDOWS__) - rx_hdr = &tdm_api_hdr; + p_tdmapi_event = &tdmapi_event; #else if (wan_skb_queue_len(&tdm_api->wp_event_list) > WP_TDM_MAX_EVENT_Q_LEN) { return; } - skb=wan_skb_alloc(sizeof(wp_tdm_api_rx_hdr_t)); + skb=wan_skb_alloc(sizeof(wp_tdm_api_event_t)); if (skb == NULL) return; - rx_hdr=(wp_tdm_api_rx_hdr_t*)wan_skb_put(skb,sizeof(wp_tdm_api_rx_hdr_t)); + p_tdmapi_event = (wp_tdm_api_event_t*)wan_skb_put(skb,sizeof(wp_tdm_api_event_t)); #endif - memset(rx_hdr,0,sizeof(wp_tdm_api_rx_hdr_t)); - rx_hdr->wp_tdm_api_event_type = WP_TDM_EVENT_RXHOOK; - rx_hdr->wp_tdm_api_event_channel = (u_int16_t)event->channel; - rx_hdr->wp_tdm_api_event_rxhook_state = event->rxhook; + memset(p_tdmapi_event, 0, sizeof(wp_tdm_api_event_t)); + p_tdmapi_event->type = WP_TDMAPI_EVENT_RXHOOK; + p_tdmapi_event->channel = (u_int16_t)event->channel; + switch(event->rxhook){ + case WAN_EVENT_RXHOOK_ON: + p_tdmapi_event->wp_tdm_api_event_hook_state = + WP_TDMAPI_EVENT_RXHOOK_ON; + break; + case WAN_EVENT_RXHOOK_OFF: + p_tdmapi_event->wp_tdm_api_event_hook_state = + WP_TDMAPI_EVENT_RXHOOK_OFF; + break; + } #if 0 rx_hdr->event_time_stamp = gettimeofday(); #endif #if defined(__WINDOWS__) - aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, rx_hdr); + aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, p_tdmapi_event); queue_tdm_api_rx_dpc(tdm_api); #else wan_skb_queue_tail(&tdm_api->wp_event_list,skb); @@ -2137,52 +2138,53 @@ call was answered. */ static void wp_tdmapi_ringtrip (void* card_id, wan_event_t *event) { - netskb_t *skb; + netskb_t *skb; wanpipe_tdm_api_dev_t *tdm_api = NULL; - sdla_t *card = (sdla_t*)card_id; - wp_tdm_api_rx_hdr_t *rx_hdr = NULL; + sdla_t *card = (sdla_t*)card_id; + wp_tdm_api_event_t *p_tdmapi_event = NULL; #if defined(__WINDOWS__) - wp_tdm_api_rx_hdr_t tdm_api_hdr; + wp_tdm_api_event_t tdmapi_event; #endif DEBUG_TDMAPI("%s: Received RM RING TRIP Event at TDM_API (%d:%s)!\n", card->devname, event->channel, - WAN_EVENT_RING_TRIP_DECODE(event->rxhook)); + WAN_EVENT_RING_TRIP_DECODE(event->ring_mode)); - tdm_api = wp_tdmapi_search(card, -#if defined(__WINDOWS__) - event->channel - 1); -#else - event->channel); -#endif + tdm_api = wp_tdmapi_search(card, event->channel); if (tdm_api == NULL){ return; } #if defined(__WINDOWS__) - rx_hdr = &tdm_api_hdr; + p_tdmapi_event = &tdmapi_event; #else if (wan_skb_queue_len(&tdm_api->wp_event_list) > WP_TDM_MAX_EVENT_Q_LEN) { return; } - skb=wan_skb_alloc(sizeof(wp_tdm_api_rx_hdr_t)); + skb=wan_skb_alloc(sizeof(wp_tdm_api_event_t)); if (skb == NULL) return; - rx_hdr=(wp_tdm_api_rx_hdr_t*)wan_skb_put(skb,sizeof(wp_tdm_api_rx_hdr_t)); + p_tdmapi_event = (wp_tdm_api_event_t*)wan_skb_put(skb,sizeof(wp_tdm_api_event_t)); #endif - memset(rx_hdr,0,sizeof(wp_tdm_api_rx_hdr_t)); - rx_hdr->wp_tdm_api_event_type = WP_TDM_EVENT_RING_TRIP; - rx_hdr->wp_tdm_api_event_channel = (u_int16_t)event->channel; - rx_hdr->wp_tdm_api_event_ring_state = event->rxhook; + memset(p_tdmapi_event, 0, sizeof(wp_tdm_api_event_t)); + p_tdmapi_event->type = WP_TDMAPI_EVENT_RING_TRIP_DETECT; + p_tdmapi_event->channel = (u_int16_t)event->channel; + if (event->ring_mode == WAN_EVENT_RING_TRIP_STOP){ + p_tdmapi_event->wp_tdm_api_event_ring_state = + WP_TDMAPI_EVENT_RING_TRIP_STOP; + }else if (event->ring_mode == WAN_EVENT_RING_TRIP_PRESENT){ + p_tdmapi_event->wp_tdm_api_event_ring_state = + WP_TDMAPI_EVENT_RING_TRIP_PRESENT; + } #if 0 rx_hdr->event_time_stamp = gettimeofday(); #endif #if defined(__WINDOWS__) - aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, rx_hdr); + aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, p_tdmapi_event); queue_tdm_api_rx_dpc(tdm_api); #else wan_skb_queue_tail(&tdm_api->wp_event_list,skb); @@ -2200,50 +2202,54 @@ static void wp_tdmapi_ringdetect (void* card_id, wan_event_t *event) netskb_t *skb; wanpipe_tdm_api_dev_t *tdm_api = NULL; sdla_t *card = (sdla_t*)card_id; - wp_tdm_api_rx_hdr_t *rx_hdr = NULL; + wp_tdm_api_event_t *p_tdmapi_event = NULL; #if defined(__WINDOWS__) - wp_tdm_api_rx_hdr_t tdm_api_hdr; + wp_tdm_api_event_t tdmapi_event; #endif DEBUG_TDMAPI("%s: Received RM RING DETECT Event at TDM_API (%d:%s)!\n", card->devname, event->channel, - WAN_EVENT_RING_DECODE(event->rxhook)); + WAN_EVENT_RING_DECODE(event->ring_mode)); - tdm_api = wp_tdmapi_search(card, -#if defined(__WINDOWS__) - event->channel - 1); -#else - event->channel); -#endif + tdm_api = wp_tdmapi_search(card, event->channel); if (tdm_api == NULL){ return; } #if defined(__WINDOWS__) - rx_hdr = &tdm_api_hdr; + p_tdmapi_event = &tdmapi_event; #else if (wan_skb_queue_len(&tdm_api->wp_event_list) > WP_TDM_MAX_EVENT_Q_LEN) { return; } - skb=wan_skb_alloc(sizeof(wp_tdm_api_rx_hdr_t)); + skb=wan_skb_alloc(sizeof(wp_tdm_api_event_t)); if (skb == NULL) return; - rx_hdr=(wp_tdm_api_rx_hdr_t*)wan_skb_put(skb,sizeof(wp_tdm_api_rx_hdr_t)); + p_tdmapi_event = (wp_tdm_api_event_t*)wan_skb_put(skb,sizeof(wp_tdm_api_event_t)); #endif - memset(rx_hdr,0,sizeof(wp_tdm_api_rx_hdr_t)); + memset(p_tdmapi_event, 0, sizeof(wp_tdm_api_event_t)); - rx_hdr->wp_tdm_api_event_type = WP_TDM_EVENT_RING_DETECT; - rx_hdr->wp_tdm_api_event_channel = (u_int16_t)event->channel; - rx_hdr->wp_tdm_api_event_ring_state = event->ring_mode; + p_tdmapi_event->type = WP_TDMAPI_EVENT_RING_DETECT; + p_tdmapi_event->channel = (u_int16_t)event->channel; + switch(event->ring_mode){ + case WAN_EVENT_RING_PRESENT: + p_tdmapi_event->wp_tdm_api_event_ring_state = + WP_TDMAPI_EVENT_RING_PRESENT; + break; + case WAN_EVENT_RING_STOP: + p_tdmapi_event->wp_tdm_api_event_ring_state = + WP_TDMAPI_EVENT_RING_STOP; + break; + } #if 0 rx_hdr->event_time_stamp = gettimeofday(); #endif #if defined(__WINDOWS__) - aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, rx_hdr); + aft_te1_insert_tdm_api_event_in_to_rx_queue(tdm_api, p_tdmapi_event); queue_tdm_api_rx_dpc(tdm_api); #else wan_skb_queue_tail(&tdm_api->wp_event_list,skb); @@ -2258,49 +2264,29 @@ static int store_tdm_api_pointer_in_card(sdla_t *card, wanpipe_tdm_api_dev_t *td { int i; - TDM_FUNC_DBG + TDM_FUNC_DBG(); - if (IS_TE1_CARD(card)) { - DEBUG_TDMAPI("TE1 card: original_active_ch: 0x%X\n", tdm_api->original_active_ch); + DEBUG_TDMAPI("%s(): original_active_ch: 0x%X\n", __FUNCTION__, tdm_api->original_active_ch); - for(i = 0; i < NUM_OF_E1_CHANNELS; i++){ - if(tdm_api->original_active_ch & (1 << i)){ + for(i = 0; i < NUM_OF_E1_CHANNELS; i++){ + if(tdm_api->original_active_ch & (1 << i)){ - DEBUG_TDMAPI("%s(): setting channel: %d\n", __FUNCTION__, i); + DEBUG_TDMAPI("%s(): setting channel: %d\n", __FUNCTION__, i); - if(i >= MAX_TDM_API_CHANNELS){ - DEBUG_EVENT("%s(): TDM API Error (TE1): Invalid Channel Number=%i (Span=%d)!\n", - __FUNCTION__, i, tdm_api->tdm_span); - return 1; - } + if(i >= MAX_TDM_API_CHANNELS){ + DEBUG_EVENT("%s(): TDM API Error (TE1): Invalid Channel Number=%i (Span=%d)!\n", + __FUNCTION__, i, tdm_api->tdm_span); + return 1; + } - if(card->wp_tdmapi_hash[i] != NULL){ - DEBUG_EVENT("%s(): TDM API Error (TE1): device SPAN=%i CHAN=%i already in use!\n", - __FUNCTION__, tdm_api->tdm_span, i); - return 1; - } - card->wp_tdmapi_hash[i] = tdm_api; - }//if() - }//for() - - }else{ - DEBUG_TDMAPI("Not a TE1 card\n"); - - DEBUG_TDMAPI("%s(): tdm_api->tdm_chan: %d\n", __FUNCTION__, tdm_api->tdm_chan); - - if(tdm_api->tdm_chan >= MAX_TDM_API_CHANNELS){ - DEBUG_EVENT("%s(): TDM API Error (Analog): Invalid Channel Number=%i (Span=%d)!\n", - __FUNCTION__, tdm_api->tdm_chan, tdm_api->tdm_span); - return 1; - } - - if(card->wp_tdmapi_hash[tdm_api->tdm_chan] != NULL){ - DEBUG_EVENT("%s(): TDM API Error (Analog): device SPAN=%i CHAN=%i already in use!\n", - __FUNCTION__, tdm_api->tdm_span, tdm_api->tdm_chan); - return 1; - } - card->wp_tdmapi_hash[tdm_api->tdm_chan] = tdm_api; - } + if(card->wp_tdmapi_hash[i] != NULL){ + DEBUG_EVENT("%s(): TDM API Error (TE1): device SPAN=%i CHAN=%i already in use!\n", + __FUNCTION__, tdm_api->tdm_span, i); + return 1; + } + card->wp_tdmapi_hash[i] = tdm_api; + }//if() + }//for() return 0; } @@ -2309,7 +2295,7 @@ static int remove_tdm_api_pointer_from_card(wanpipe_tdm_api_dev_t *tdm_api) sdla_t *card = NULL; int i; - TDM_FUNC_DBG + TDM_FUNC_DBG(); WAN_ASSERT(tdm_api == NULL); card = (sdla_t*)tdm_api->card; @@ -2320,41 +2306,27 @@ static int remove_tdm_api_pointer_from_card(wanpipe_tdm_api_dev_t *tdm_api) return 1; } - if (IS_TE1_CARD(card)) { + DEBUG_TDMAPI("%s(): original_active_ch: 0x%X\n", __FUNCTION__, tdm_api->original_active_ch); - DEBUG_TDMAPI("TE1 card: original_active_ch: 0x%X\n", tdm_api->original_active_ch); + for(i = 0; i < NUM_OF_E1_CHANNELS; i++){ + if(tdm_api->original_active_ch & (1 << i)){ - for(i = 0; i < NUM_OF_E1_CHANNELS; i++){ - if(tdm_api->original_active_ch & (1 << i)){ + DEBUG_TDMAPI("%s(): RE-setting channel: %d\n", __FUNCTION__, i); - DEBUG_TDMAPI("%s(): RE-setting channel: %d\n", __FUNCTION__, i); + if(i >= MAX_TDM_API_CHANNELS){ + DEBUG_EVENT("%s(): TDM API Error (TE1): Invalid Channel Number=%i (Span=%d)!\n", + __FUNCTION__, i, tdm_api->tdm_span); + return 1; + } - if(i >= MAX_TDM_API_CHANNELS){ - DEBUG_EVENT("%s(): TDM API Error (TE1): Invalid Channel Number=%i (Span=%d)!\n", - __FUNCTION__, i, tdm_api->tdm_span); - return 1; - } + if(card->wp_tdmapi_hash[i] == NULL){ + DEBUG_EVENT("%s: TDM API Warning (TE1): device SPAN=%i CHAN=%i was NOT in use!\n", + __FUNCTION__, tdm_api->tdm_span, tdm_api->tdm_chan); + } + card->wp_tdmapi_hash[i] = NULL; + }//if() + }//for() - if(card->wp_tdmapi_hash[i] == NULL){ - DEBUG_EVENT("%s: TDM API Warning (TE1): device SPAN=%i CHAN=%i was NOT in use!\n", - __FUNCTION__, tdm_api->tdm_span, tdm_api->tdm_chan); - } - card->wp_tdmapi_hash[i] = NULL; - }//if() - }//for() - }else{ - if(tdm_api->tdm_chan >= MAX_TDM_API_CHANNELS){ - DEBUG_EVENT("%s(): TDM API Error (Analog): Invalid Channel Number=%i (Span=%d)!\n", - __FUNCTION__, tdm_api->tdm_chan, tdm_api->tdm_span); - return 1; - } - - if(card->wp_tdmapi_hash[tdm_api->tdm_chan] == NULL){ - DEBUG_EVENT("%s: TDM API Warning (Analog): device SPAN=%i CHAN=%i was NOT in use!\n", - __FUNCTION__, tdm_api->tdm_span, tdm_api->tdm_chan); - } - card->wp_tdmapi_hash[tdm_api->tdm_chan] = NULL; - } return 0; } @@ -2515,4 +2487,4 @@ int wanpipe_tdm_api_rx_tx (wanpipe_tdm_api_dev_t *tdm_api, u8 *rx_data, u8 *tx_d return -EINVAL; } -#endif +#endif /* #if defined(BUILD_TDMV_API) */ diff --git a/patches/kdrivers/src/net/wanpipe_utils.c b/patches/kdrivers/src/net/wanpipe_utils.c index 176462f..ab5d887 100644 --- a/patches/kdrivers/src/net/wanpipe_utils.c +++ b/patches/kdrivers/src/net/wanpipe_utils.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: wanpipe_utils.c,v 1.93 2006/11/23 22:00:58 sangoma Exp $ + * $Id: wanpipe_utils.c,v 1.101 2008/02/04 18:02:20 sangoma Exp $ */ /* @@ -48,6 +48,7 @@ # if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC) # include # endif +# include # include # include /* WANPIPE common user API definitions */ #elif (defined __WINDOWS__) @@ -86,7 +87,7 @@ static void wanpipe_debug_timer(unsigned long arg); extern sdla_t* wanpipe_debug; int wan_get_dbg_msg(wan_device_t* wandev, void* u_dbg_msg); - +void wanpipe_set_dev_carrier_state(sdla_t* card, int state); unsigned char wp_brt[256]; @@ -184,6 +185,21 @@ void wanpipe_set_baud (void* card_id, unsigned int baud) card->wandev.bps=baud*1000; } +void wanpipe_set_dev_carrier_state(sdla_t* card, int state) +{ + netdevice_t *dev; + dev = WAN_DEVLE2DEV(WAN_LIST_FIRST(&card->wandev.dev_head)); + if (dev && WAN_NETIF_UP(dev)) { + if (state == WAN_CONNECTED) { + WAN_NETIF_CARRIER_ON(dev); + WAN_NETIF_WAKE_QUEUE(dev); + } else { + WAN_NETIF_CARRIER_OFF(dev); + WAN_NETIF_STOP_QUEUE(dev); + } + } +} + /* * ============================================================================ @@ -208,6 +224,10 @@ void wanpipe_set_state (void* card_id, int state) break; } card->wandev.state = state; + + if (card->wandev.config_id == WANCONFIG_ADSL) { + wanpipe_set_dev_carrier_state(card,state); + } } card->state_tick = SYSTEM_TICKS; } @@ -363,7 +383,6 @@ int wan_reply_udp(void* card_id, unsigned char *data, unsigned int mbox_len) - #if defined(__LINUX__) /* * =========================================================================== @@ -533,10 +552,10 @@ void wanpipe_debugging (unsigned long data) /* Sangoma T1/E1/56K cards */ /* Check Tv attributes */ if (card->wandev.fe_iface.read_alarm){ - card->wandev.fe_iface.read_alarm(&card->fe, 0); + card->wandev.fe_iface.read_alarm(&card->fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE); } if (card->wandev.fe_iface.read_alarm && - (status = card->wandev.fe_iface.read_alarm(&card->fe, 0))){ + (status = card->wandev.fe_iface.read_alarm(&card->fe, WAN_FE_ALARM_READ|WAN_FE_ALARM_UPDATE))){ DEBUG_DBG("%s: WAN_DBG: T1/E1/56K is not in Service, print Alarms!\n", card->devname); /* Not in service, Alarms */ @@ -1273,9 +1292,9 @@ void wpabs_set_baud (void* card_id, unsigned int baud) void* wpabs_dma_alloc(void* pcard, unsigned long max_length) { sdla_t* card = (sdla_t*)pcard; - wan_dma_descr_t* dma_descr = NULL; + wan_dma_descr_org_t *dma_descr = NULL; - dma_descr = wan_malloc(sizeof(wan_dma_descr_t)); + dma_descr = wan_malloc(sizeof(wan_dma_descr_org_t)); if (dma_descr == NULL){ return NULL; } @@ -1283,7 +1302,7 @@ void* wpabs_dma_alloc(void* pcard, unsigned long max_length) #if defined(__NetBSD__) || defined(__OpenBSD__) card->hw_iface.getcfg(card->hw, SDLA_DMATAG, &dma_descr->dmat); #endif - if (wan_dma_alloc(card->hw, dma_descr)){ + if (wan_dma_alloc_org(card->hw, dma_descr)){ wan_free(dma_descr); return NULL; } @@ -1294,7 +1313,7 @@ int wpabs_dma_free(void* pcard, void* dma_descr) { int err=0; sdla_t* card = (sdla_t*)pcard; - err=wan_dma_free(card->hw, (wan_dma_descr_t*)dma_descr); + err=wan_dma_free_org(card->hw, (wan_dma_descr_org_t*)dma_descr); wan_free(dma_descr); return err; } @@ -1338,7 +1357,13 @@ int init_atm_idle_buffer(unsigned char *buff, int buff_len, char *if_name, char int atm_add_data_to_skb(void* skb, void *data, int data_len, char *if_name) { unsigned char *skb_data_ptr; - + + if (data_len != ATM_CELL_SIZE) { + DEBUG_EVENT("%s: %s(): Error, invalid datalen=%i\n", + if_name, __FUNCTION__, data_len); + return 1; + } + DEBUG_ATM("%s(): data_len=%d, skb tail room=%d\n", __FUNCTION__, data_len, wan_skb_tailroom(skb)); @@ -1388,10 +1413,14 @@ int atm_pad_idle_cells_in_tx_skb(void *skb, void *tx_idle_skb, char *if_name) return 0; } + + + void *atm_tx_skb_dequeue(void* wp_tx_pending_list, void *tx_idle_skb, char *if_name) { void *tx_skb, *single_cell_skb; int max_num_of_cells_fit_in_tx_buffer, i; + int err; if(wan_skb_queue_len(wp_tx_pending_list) == 0){ return NULL; @@ -1418,16 +1447,25 @@ void *atm_tx_skb_dequeue(void* wp_tx_pending_list, void *tx_idle_skb, char *if_n break; } - atm_add_data_to_skb( tx_skb, + err=atm_add_data_to_skb(tx_skb, wan_skb_data(single_cell_skb), wan_skb_len (single_cell_skb), if_name); wan_skb_free(single_cell_skb); + if (err) { + wan_skb_free(tx_skb); + return NULL; + } } - /* try to add idle cells, if no space it won't do anything */ - atm_pad_idle_cells_in_tx_skb(tx_skb, tx_idle_skb, if_name); + /* try to add idle cells, if no space it won't do anything */ + err=atm_pad_idle_cells_in_tx_skb(tx_skb, tx_idle_skb, if_name); + if (err) { + wan_skb_free(tx_skb); + return NULL; + } + return tx_skb; } diff --git a/patches/kdrivers/src/wan_aften/wan_aften.c b/patches/kdrivers/src/wan_aften/wan_aften.c index 12d573c..d719b8b 100644 --- a/patches/kdrivers/src/wan_aften/wan_aften.c +++ b/patches/kdrivers/src/wan_aften/wan_aften.c @@ -28,12 +28,16 @@ extern wan_iface_t wan_iface; static int wan_aften_init(void*); static int wan_aften_exit(void*); +#if 0 +static int wan_aften_shutdown(void*); +static int wan_aften_ready_unload(void*); +#endif static int wan_aften_setup(sdla_t *card, netdevice_t *dev); -static int wan_aften_shutdown(sdla_t *card); +static int wan_aften_release(sdla_t *card); static int wan_aften_update_ports(void); -static int wan_aften_open(netdevice_t *dev); -static int wan_aften_close(netdevice_t *dev); -static int wan_aften_ioctl (netdevice_t *dev, struct ifreq *ifr, int cmd); +static int wan_aften_open(netdevice_t*); +static int wan_aften_close(netdevice_t*); +static int wan_aften_ioctl (netdevice_t*, struct ifreq*, wan_ioctl_cmd_t); #if defined(__OpenBSD__) struct cdevsw wan_aften_devsw = { @@ -43,7 +47,7 @@ WAN_MODULE_DEFINE( "Alex Feldman ", "WAN AFT Enable", "GPL", - wan_aften_init, wan_aften_exit, + wan_aften_init, wan_aften_exit,/* wan_aften_shutdown, wan_aften_ready_unload,*/ &wan_aften_devsw); #else WAN_MODULE_DEFINE( @@ -51,7 +55,7 @@ WAN_MODULE_DEFINE( "Alex Feldman ", "WAN AFT Enable", "GPL", - wan_aften_init, wan_aften_exit, + wan_aften_init, wan_aften_exit,/*wan_aften_shutdown, wan_aften_ready_unload,*/ NULL); #endif WAN_MODULE_DEPEND(wan_aften, sdladrv, 1, SDLADRV_MAJOR_VER, SDLADRV_MAJOR_VER); @@ -137,7 +141,7 @@ static int wan_aften_init(void *arg) wandev = &card->wandev; wandev->magic = ROUTER_MAGIC; wandev->name = card->devname; - wandev->private = card; + wandev->priv = card; devle->dev = dev; /* Set device pointer */ @@ -198,8 +202,8 @@ static int wan_aften_exit(void *arg) WAN_LIST_REMOVE(devle, dev_link); wan_free(devle); } - DEBUG_EVENT("%s: Shutdown device\n", card->devname); - wan_aften_shutdown(card); + DEBUG_EVENT("%s: Release device\n", card->devname); + wan_aften_release(card); card_list = card->list; wan_free(card); card = card_list; @@ -212,13 +216,23 @@ static int wan_aften_exit(void *arg) DEBUG_EVENT("\n"); DEBUG_EVENT("%s Unloaded.\n", wan_fullname); -#if defined(WAN_DEBUG_MEM) - DEBUG_EVENT("%s: Total Mem %d\n", - wan_drvname, wan_atomic_read(&wan_debug_mem)); -#endif return err; } +#if 0 +int wan_aften_shutdown(void *arg) +{ + DEBUG_EVENT("Shutting down WAN_AFTEN module ...\n"); + return 0; +} + +int wan_aften_ready_unload(void *arg) +{ + DEBUG_EVENT("Is WAN_AFTEN module ready to unload...\n"); + return 0; +} +#endif + static int wan_aften_setup(sdla_t *card, netdevice_t *dev) { struct wan_aften_priv *priv = wan_netif_priv(dev); @@ -250,11 +264,38 @@ static int wan_aften_setup(sdla_t *card, netdevice_t *dev) WAN_HWCALL(pci_read_config_dword, (card->hw, PCI_MEM_BASE0_DWORD, &priv->base_addr1)); - DEBUG_TEST("%s: BaseClass %X BaseAddr 0x%X IRQ %d\n", + DEBUG_EVENT("%s: BaseClass %X BaseAddr %X:%X IRQ %d\n", wan_netif_name(dev), priv->base_class, priv->base_addr0, + priv->base_addr1, priv->irq); + + /* Save pci bridge config (if needed) */ + WAN_HWCALL(getcfg, (card->hw, SDLA_PCIEXPRESS, &priv->pci_express_bridge)); + if (priv->pci_express_bridge){ + int off = 0; + + WAN_HWCALL(pci_bridge_read_config_dword, + (card->hw, 0x04, &priv->pci_bridge_base_class)); + WAN_HWCALL(pci_bridge_read_config_dword, + (card->hw, PCI_IO_BASE_DWORD, &priv->pci_bridge_base_addr0)); + WAN_HWCALL(pci_bridge_read_config_dword, + (card->hw, PCI_MEM_BASE0_DWORD, &priv->pci_bridge_base_addr1)); + WAN_HWCALL(pci_bridge_read_config_byte, + (card->hw, PCI_INT_LINE_BYTE, &priv->pci_bridge_irq)); + for(off=0;off<=15;off++){ + WAN_HWCALL(pci_bridge_read_config_dword, + (card->hw, off*4, &priv->pci_bridge_cfg[off])); + } + DEBUG_EVENT("%s: PCI_ExpressBridge: BaseClass %X BaseAddr %X:%X IRQ %d\n", + wan_netif_name(dev), + priv->pci_bridge_base_class, + priv->pci_bridge_base_addr0, + priv->pci_bridge_base_addr1, + priv->pci_bridge_irq); + } + #if defined(ENABLED_IRQ) if(request_irq(irq, wan_aften_isr, SA_SHIRQ, card->devname, card)){ DEBUG_EVENT("%s: Can't reserve IRQ %d!\n", @@ -270,7 +311,7 @@ wan_aften_setup_error: } -static int wan_aften_shutdown(sdla_t *card) +static int wan_aften_release(sdla_t *card) { #if defined(ENABLED_IRQ) struct wan_aften_priv *priv = wan_netif_priv(dev); @@ -503,6 +544,21 @@ static int wan_aften_set_pci_bios(sdla_t *card) priv->base_addr1, priv->irq); + if (priv->pci_express_bridge){ + int off = 0; + WAN_HWCALL(pci_bridge_write_config_dword, + (card->hw, 0x04, priv->pci_bridge_base_class)); + WAN_HWCALL(pci_bridge_write_config_dword, + (card->hw, PCI_IO_BASE_DWORD, priv->pci_bridge_base_addr0)); + WAN_HWCALL(pci_bridge_write_config_dword, + (card->hw, PCI_MEM_BASE0_DWORD, priv->pci_bridge_base_addr1)); + WAN_HWCALL(pci_bridge_write_config_byte, + (card->hw, PCI_INT_LINE_BYTE, priv->pci_bridge_irq)); + for(off=0;off<=15;off++){ + WAN_HWCALL(pci_bridge_write_config_dword, + (card->hw, off*4, priv->pci_bridge_cfg[off])); + } + } WP_DELAY(200); card->hw_iface.pci_write_config_dword( card->hw, 0x04, priv->base_class); @@ -692,7 +748,8 @@ static int wan_aften_close(netdevice_t *dev) return 0; } -static int wan_aften_ioctl (netdevice_t *dev, struct ifreq *ifr, int cmd) +static int +wan_aften_ioctl (netdevice_t *dev, struct ifreq *ifr, wan_ioctl_cmd_t cmd) { sdla_t *card; struct wan_aften_priv *priv= wan_netif_priv(dev); diff --git a/patches/kdrivers/src/wan_aften/wan_aften.h b/patches/kdrivers/src/wan_aften/wan_aften.h index 68305b8..01c92c8 100644 --- a/patches/kdrivers/src/wan_aften/wan_aften.h +++ b/patches/kdrivers/src/wan_aften/wan_aften.h @@ -36,6 +36,17 @@ struct wan_aften_priv { unsigned int irq; unsigned int slot; unsigned int bus; + + u_int8_t pci_express_bridge; + + unsigned int pci_bridge_base_class; + unsigned int pci_bridge_base_addr0; + unsigned int pci_bridge_base_addr1; + u_int8_t pci_bridge_irq; + unsigned int pci_bridge_slot; + unsigned int pci_bridge_bus; + u_int32_t pci_bridge_cfg[16]; + }; #endif diff --git a/patches/kdrivers/src/wan_aften/wan_aften_src.o b/patches/kdrivers/src/wan_aften/wan_aften_src.o index bb39aff2b2312bd952b23bc739a62d2064c5c55d..51246ed4d03c6132061b34645e73d69503b92b39 100644 GIT binary patch literal 226164 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 literal 208336 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